diff --git a/build/package.d.ts b/build/package.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/package.json b/build/package.json new file mode 100644 index 0000000000..1beb7de7e7 --- /dev/null +++ b/build/package.json @@ -0,0 +1,142 @@ +{ + "name": "vega-lite", + "author": "Jeffrey Heer, Dominik Moritz, Kanit \"Ham\" Wongsuphasawat", + "version": "2.6.0", + "collaborators": [ + "Kanit Wongsuphasawat (http://kanitw.yellowpigz.com)", + "Dominik Moritz (https://www.domoritz.de)", + "Jeffrey Heer (http://jheer.org)" + ], + "homepage": "https://vega.github.io/vega-lite/", + "description": "Vega-Lite is a concise high-level language for interactive visualization.", + "main": "build/vega-lite.js", + "unpkg": "build/vega-lite.min.js", + "jsdelivr": "build/vega-lite.min.js", + "module": "build/src/index", + "types": "build/src/index.d.ts", + "bin": { + "vl2png": "./bin/vl2png", + "vl2svg": "./bin/vl2svg", + "vl2vg": "./bin/vl2vg" + }, + "directories": { + "test": "test" + }, + "scripts": { + "prebuild": "mkdir -p build/src", + "build": "npm run build:only", + "build:only": "tsc && rollup -c", + "postbuild": "uglifyjs build/vega-lite.js -cm --source-map content=build/vega-lite.js.map,filename=build/vega-lite.min.js.map -o build/vega-lite.min.js && npm run schema", + "build:examples": "npm run data && TZ=America/Los_Angeles scripts/build-examples.sh", + "build:examples-full": "TZ=America/Los_Angeles scripts/build-examples.sh 1", + "build:example": "TZ=America/Los_Angeles scripts/build-example.sh", + "build:toc": "bundle exec jekyll build -q && scripts/generate-toc", + "build:site": "tsc -p site && webpack --config site/webpack.config.js", + "build:versions": "scripts/update-version.sh", + "check:examples": "scripts/check-examples.sh", + "check:schema": "scripts/check-schema.sh", + "clean": "rm -rf build && rm -f examples/compiled/*.png && find site/examples ! -name 'index.md' -type f -delete", + "data": "rsync -r node_modules/vega-datasets/data/* data", + "deploy": "scripts/deploy.sh", + "deploy:gh": "scripts/deploy-gh.sh", + "deploy:schema": "scripts/deploy-schema.sh", + "preschema": "npm run prebuild", + "schema": "node --stack-size=1200 ./node_modules/.bin/ts-json-schema-generator --path tsconfig.json --type TopLevelSpec > build/vega-lite-schema.json && npm run renameschema && cp build/vega-lite-schema.json _data/", + "renameschema": "scripts/rename-schema.sh", + "presite": "npm run prebuild && npm run data && npm run build:site && npm run build:toc && npm run build:versions && scripts/create-example-pages", + "site": "bundle exec jekyll serve --incremental", + "lint": "tslint -p . -e 'package.json'", + "test": "jest test/ && npm run lint && npm run schema && jest examples/ && npm run test:runtime", + "test:inspect": "node --inspect-brk ./node_modules/.bin/jest --runInBand test", + "test:runtime": "TZ=America/Los_Angeles TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' wdio wdio.conf.js", + "test:runtime:generate": "rm -Rf test-runtime/resources && VL_GENERATE_TESTS=true npm run test:runtime", + "watch:build": "npm run build:only && concurrently --kill-others -n Typescript,Rollup 'tsc -w' 'rollup -c -w'", + "watch:site": "concurrently --kill-others -n Typescript,Webpack 'tsc -p site --watch' 'webpack --config site/webpack.config.js --mode development --watch'", + "watch:test": "jest --watch" + }, + "repository": { + "type": "git", + "url": "https://github.com/vega/vega-lite.git" + }, + "license": "BSD-3-Clause", + "bugs": { + "url": "https://github.com/vega/vega-lite/issues" + }, + "devDependencies": { + "@types/chai": "^4.1.4", + "@types/d3": "^5.0.0", + "@types/highlight.js": "^9.12.3", + "@types/jest": "^23.1.1", + "@types/mkdirp": "^0.5.2", + "@types/node": "^9.0.0", + "@types/webdriverio": "^4.10.2", + "ajv": "^6.5.1", + "chai": "^4.1.2", + "cheerio": "^1.0.0-rc.2", + "chromedriver": "^2.40.0", + "codecov": "^3.0.2", + "concurrently": "^3.6.0", + "d3": "^5.5.0", + "highlight.js": "^9.12.0", + "jest": "^23.1.0", + "mkdirp": "^0.5.1", + "rollup": "^0.59.4", + "rollup-plugin-commonjs": "^9.1.3", + "rollup-plugin-json": "^3.0.0", + "rollup-plugin-node-resolve": "^3.3.0", + "rollup-plugin-sourcemaps": "^0.4.2", + "source-map-support": "^0.5.6", + "svg2png-many": "^0.0.7", + "ts-jest": "^22.4.6", + "ts-json-schema-generator": "^0.28.0", + "ts-node": "^6.1.1", + "tslint": "5.10.0", + "tslint-eslint-rules": "^5.3.1", + "typescript": "^2.9.2", + "uglify-js": "^3.4.1", + "vega": "^4.0.0-rc.3", + "vega-datasets": "^1.19.0", + "vega-embed": "^3.16.0", + "vega-tooltip": "^0.11.0", + "wdio-chromedriver-service": "^0.1.3", + "wdio-dot-reporter": "0.0.9", + "wdio-mocha-framework": "^0.5.13", + "wdio-static-server-service": "^1.0.1", + "webdriverio": "^4.13.0", + "webpack": "^4.12.0", + "webpack-cli": "^3.0.8", + "yaml-front-matter": "^4.0.0" + }, + "dependencies": { + "@types/json-stable-stringify": "^1.0.32", + "json-stable-stringify": "^1.0.1", + "tslib": "^1.9.2", + "vega-event-selector": "^2.0.0", + "vega-typings": "^0.3.17", + "vega-util": "^1.7.0", + "yargs": "^11.0.0" + }, + "jest": { + "transform": { + "^.+\\.tsx?$": "ts-jest" + }, + "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", + "moduleFileExtensions": [ + "ts", + "tsx", + "js", + "jsx", + "json", + "node" + ], + "testPathIgnorePatterns": [ + "node_modules", + "test-runtime", + "/build", + "_site", + "src" + ], + "coverageDirectory": "./coverage/", + "collectCoverage": false + } +} diff --git a/build/package.json.map b/build/package.json.map new file mode 100644 index 0000000000..0ca2dae6b9 --- /dev/null +++ b/build/package.json.map @@ -0,0 +1 @@ +{"version":3,"file":"package.json","sourceRoot":"","sources":["../package.json"],"names":[],"mappings":"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","sourcesContent":["{\n \"name\": \"vega-lite\",\n \"author\": \"Jeffrey Heer, Dominik Moritz, Kanit \\\"Ham\\\" Wongsuphasawat\",\n \"version\": \"2.5.1\",\n \"collaborators\": [\n \"Kanit Wongsuphasawat (http://kanitw.yellowpigz.com)\",\n \"Dominik Moritz (https://www.domoritz.de)\",\n \"Jeffrey Heer (http://jheer.org)\"\n ],\n \"homepage\": \"https://vega.github.io/vega-lite/\",\n \"description\": \"Vega-Lite is a concise high-level language for interactive visualization.\",\n \"main\": \"build/vega-lite.js\",\n \"unpkg\": \"build/vega-lite.min.js\",\n \"jsdelivr\": \"build/vega-lite.min.js\",\n \"module\": \"build/src/index\",\n \"types\": \"build/src/index.d.ts\",\n \"bin\": {\n \"vl2png\": \"./bin/vl2png\",\n \"vl2svg\": \"./bin/vl2svg\",\n \"vl2vg\": \"./bin/vl2vg\"\n },\n \"directories\": {\n \"test\": \"test\"\n },\n \"scripts\": {\n \"prebuild\": \"mkdir -p build/src\",\n \"build\": \"npm run build:only\",\n \"build:only\": \"tsc && rollup -c\",\n \"postbuild\": \"uglifyjs build/vega-lite.js -cm --source-map content=build/vega-lite.js.map,filename=build/vega-lite.min.js.map -o build/vega-lite.min.js && npm run schema\",\n \"build:examples\": \"npm run data && TZ=America/Los_Angeles scripts/build-examples.sh\",\n \"build:examples-full\": \"TZ=America/Los_Angeles scripts/build-examples.sh 1\",\n \"build:example\": \"TZ=America/Los_Angeles scripts/build-example.sh\",\n \"build:toc\": \"bundle exec jekyll build -q && scripts/generate-toc\",\n \"build:site\": \"tsc -p site && webpack --config site/webpack.config.js\",\n \"build:versions\": \"scripts/update-version.sh\",\n \"check:examples\": \"scripts/check-examples.sh\",\n \"check:schema\": \"scripts/check-schema.sh\",\n \"clean\": \"rm -rf build && rm -f examples/compiled/*.png && find site/examples ! -name 'index.md' -type f -delete\",\n \"data\": \"rsync -r node_modules/vega-datasets/data/* data\",\n \"deploy\": \"scripts/deploy.sh\",\n \"deploy:gh\": \"scripts/deploy-gh.sh\",\n \"deploy:schema\": \"scripts/deploy-schema.sh\",\n \"preschema\": \"npm run prebuild\",\n \"schema\": \"node --stack-size=1200 ./node_modules/.bin/ts-json-schema-generator --path tsconfig.json --type TopLevelSpec > build/vega-lite-schema.json && npm run renameschema && cp build/vega-lite-schema.json _data/\",\n \"renameschema\": \"scripts/rename-schema.sh\",\n \"presite\": \"npm run prebuild && npm run data && npm run build:site && npm run build:toc && npm run build:versions && scripts/create-example-pages\",\n \"site\": \"bundle exec jekyll serve --incremental\",\n \"lint\": \"tslint -p . -e 'package.json'\",\n \"test\": \"jest test/ && npm run lint && npm run schema && jest examples/ && npm run test:runtime\",\n \"test:inspect\": \"node --inspect-brk ./node_modules/.bin/jest --runInBand test\",\n \"test:runtime\": \"TZ=America/Los_Angeles TS_NODE_COMPILER_OPTIONS='{\\\"module\\\":\\\"commonjs\\\"}' wdio wdio.conf.js\",\n \"test:runtime:generate\": \"rm -Rf test-runtime/resources && VL_GENERATE_TESTS=true npm run test:runtime\",\n \"watch:build\": \"npm run build:only && concurrently --kill-others -n Typescript,Rollup 'tsc -w' 'rollup -c -w'\",\n \"watch:site\": \"concurrently --kill-others -n Typescript,Webpack 'tsc -p site --watch' 'webpack --config site/webpack.config.js --mode development --watch'\",\n \"watch:test\": \"jest --watch\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/vega/vega-lite.git\"\n },\n \"license\": \"BSD-3-Clause\",\n \"bugs\": {\n \"url\": \"https://github.com/vega/vega-lite/issues\"\n },\n \"devDependencies\": {\n \"@types/chai\": \"^4.1.4\",\n \"@types/d3\": \"^5.0.0\",\n \"@types/highlight.js\": \"^9.12.3\",\n \"@types/jest\": \"^23.1.1\",\n \"@types/mkdirp\": \"^0.5.2\",\n \"@types/node\": \"^9.0.0\",\n \"@types/webdriverio\": \"^4.10.2\",\n \"ajv\": \"^6.5.1\",\n \"chai\": \"^4.1.2\",\n \"cheerio\": \"^1.0.0-rc.2\",\n \"chromedriver\": \"^2.40.0\",\n \"codecov\": \"^3.0.2\",\n \"concurrently\": \"^3.6.0\",\n \"d3\": \"^5.5.0\",\n \"highlight.js\": \"^9.12.0\",\n \"jest\": \"^23.1.0\",\n \"mkdirp\": \"^0.5.1\",\n \"rollup\": \"^0.59.4\",\n \"rollup-plugin-commonjs\": \"^9.1.3\",\n \"rollup-plugin-json\": \"^3.0.0\",\n \"rollup-plugin-node-resolve\": \"^3.3.0\",\n \"rollup-plugin-sourcemaps\": \"^0.4.2\",\n \"source-map-support\": \"^0.5.6\",\n \"svg2png-many\": \"^0.0.7\",\n \"ts-jest\": \"^22.4.6\",\n \"ts-json-schema-generator\": \"^0.28.0\",\n \"ts-node\": \"^6.1.1\",\n \"tslint\": \"5.10.0\",\n \"tslint-eslint-rules\": \"^5.3.1\",\n \"typescript\": \"^2.9.2\",\n \"uglify-js\": \"^3.4.1\",\n \"vega\": \"^4.0.0-rc.3\",\n \"vega-datasets\": \"^1.19.0\",\n \"vega-embed\": \"^3.15.0\",\n \"vega-tooltip\": \"^0.11.0\",\n \"wdio-chromedriver-service\": \"^0.1.3\",\n \"wdio-dot-reporter\": \"0.0.9\",\n \"wdio-mocha-framework\": \"^0.5.13\",\n \"wdio-static-server-service\": \"^1.0.1\",\n \"webdriverio\": \"^4.13.0\",\n \"webpack\": \"^4.12.0\",\n \"webpack-cli\": \"^3.0.8\",\n \"yaml-front-matter\": \"^4.0.0\"\n },\n \"dependencies\": {\n \"@types/json-stable-stringify\": \"^1.0.32\",\n \"json-stable-stringify\": \"^1.0.1\",\n \"tslib\": \"^1.9.2\",\n \"vega-event-selector\": \"^2.0.0\",\n \"vega-typings\": \"^0.3.16\",\n \"vega-util\": \"^1.7.0\",\n \"yargs\": \"^11.0.0\"\n },\n \"jest\": {\n \"transform\": {\n \"^.+\\\\.tsx?$\": \"ts-jest\"\n },\n \"testRegex\": \"(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.(jsx?|tsx?)$\",\n \"moduleFileExtensions\": [\n \"ts\",\n \"tsx\",\n \"js\",\n \"jsx\",\n \"json\",\n \"node\"\n ],\n \"testPathIgnorePatterns\": [\n \"node_modules\",\n \"test-runtime\",\n \"/build\",\n \"_site\",\n \"src\"\n ],\n \"coverageDirectory\": \"./coverage/\",\n \"collectCoverage\": false\n }\n}\n"]} \ No newline at end of file diff --git a/build/site/bundle.js b/build/site/bundle.js new file mode 100644 index 0000000000..85718e8958 --- /dev/null +++ b/build/site/bundle.js @@ -0,0 +1,24 @@ +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}([function(e,t,n){"use strict";var r=function(e,t,n){return e.fields=t||[],e.fname=n,e};function i(e){return null==e?null:e.fname}function a(e){return null==e?null:e.fields}var o=function(e){throw Error(e)},s=function(e){var t,n,r,i=[],a=null,s=0,l=e.length,c="";function u(){i.push(c+e.substring(t,n)),c="",t=n+1}for(e+="",t=n=0;nt&&u(),s=t=n+1):"]"===r&&(s||o("Access path missing open bracket: "+e),s>0&&u(),s=0,t=n+1):n>t?u():t=n+1}return s&&o("Access path missing closing bracket: "+e),a&&o("Access path missing closing quote: "+e),n>t&&(n++,u()),i},l=Array.isArray,c=function(e){return e===Object(e)},u=function(e){return"string"==typeof e};function d(e){return l(e)?"["+e.map(d)+"]":c(e)||u(e)?JSON.stringify(e).replace("\u2028","\\u2028").replace("\u2029","\\u2029"):e}var f=function(e,t){var n=s(e),i="return _["+n.map(d).join("][")+"];";return r(Function("_",i),[e=1===n.length?n[0]:e],t||e)},p=[],m=f("id"),g=r(function(e){return e},p,"identity"),h=r(function(){return 0},p,"zero"),b=r(function(){return 1},p,"one"),v=r(function(){return!0},p,"true"),_=r(function(){return!1},p,"false");function y(e,t,n){var r=[t].concat([].slice.call(n));console[e].apply(console,r)}var x=function(e){var t=e||0;return{level:function(e){return arguments.length?(t=+e,this):t},error:function(){return t>=1&&y("error","ERROR",arguments),this},warn:function(){return t>=2&&y("warn","WARN",arguments),this},info:function(){return t>=3&&y("log","INFO",arguments),this},debug:function(){return t>=4&&y("log","DEBUG",arguments),this}}},E=function(e){return e[e.length-1]},S=function(e){return null==e||""===e?null:+e};function w(e){return function(t){return e*Math.exp(t)}}function C(e){return function(t){return Math.log(e*t)}}function O(e){return function(t){return t<0?-Math.pow(-t,e):Math.pow(t,e)}}function M(e,t,n,r){var i=n(e[0]),a=n(E(e)),o=(a-i)*t;return[r(i-o),r(a-o)]}function N(e,t){return M(e,t,S,g)}function T(e,t){var n=Math.sign(e[0]);return M(e,t,C(n),w(n))}function D(e,t,n){return M(e,t,O(n),O(1/n))}function A(e,t,n,r,i){var a=r(e[0]),o=r(E(e)),s=null!=t?r(t):(a+o)/2;return[i(s+(a-s)*n),i(s+(o-s)*n)]}function k(e,t,n){return A(e,t,n,S,g)}function R(e,t,n){var r=Math.sign(e[0]);return A(e,t,n,C(r),w(r))}function I(e,t,n,r){return A(e,t,n,O(r),O(1/r))}var L=function(e){return null!=e?l(e)?e:[e]:[]},P=function(e){return"function"==typeof e},F=function(e,t){var n,i,o,l,c,u,f,p,m,g=[],h=(e=L(e)).map(function(e,t){return null==e?null:(g.push(t),P(e)?e:s(e).map(d).join("]["))}),b=g.length-1,v=L(t),_="var u,v;return ";if(b<0)return null;for(i=0;i<=b;++i)o=h[n=g[i]],P(o)?(l="(u=this."+(u="f"+n)+"(a))",c="(v=this."+u+"(b))",(f=f||{})[u]=o):(l="(u=a["+o+"])",c="(v=b["+o+"])"),u="((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))","descending"!==v[n]?(m=1,p=-1):(m=-1,p=1),_+="("+l+"<"+c+"||u==null)&&v!=null?"+p+":(u>v||v==null)&&u!=null?"+m+":"+u+"!==u&&v===v?"+p+":v!==v&&u===u?"+m+(n=r){n=i=r;break}for(a=o=s;++sr&&(n=r,a=s),i=r){n=i=r;break}for(a=o=s;++sr&&(n=r,a=s),i0?n[l++]:t[s++];for(;s=0;)n+=e;return n},X=function(e,t,n,r){var i=n||" ",a=e+"",o=t-a.length;return o<=0?a:"left"===r?Z(i,o)+a:"center"===r?Z(i,~~(o/2))+a+Z(i,Math.ceil(o/2)):a+Z(i,o)},J=function(e){return null==e||""===e?null:!(!e||"false"===e||"0"===e)&&!!e};function ee(e){return V(e)?e:W(e)?e:Date.parse(e)}var te=function(e,t){return t=t||ee,null==e||""===e?null:t(e)},ne=function(e){return null==e||""===e?null:e+""},re=function(e){for(var t={},n=0,r=e.length;n (http://kanitw.yellowpigz.com)","Dominik Moritz (https://www.domoritz.de)","Jeffrey Heer (http://jheer.org)"],homepage:"https://vega.github.io/vega-lite/",description:"Vega-Lite is a concise high-level language for interactive visualization.",main:"build/vega-lite.js",unpkg:"build/vega-lite.min.js",jsdelivr:"build/vega-lite.min.js",module:"build/src/index",types:"build/src/index.d.ts",bin:{vl2png:"./bin/vl2png",vl2svg:"./bin/vl2svg",vl2vg:"./bin/vl2vg"},directories:{test:"test"},scripts:{prebuild:"mkdir -p build/src",build:"npm run build:only","build:only":"tsc && rollup -c",postbuild:"uglifyjs build/vega-lite.js -cm --source-map content=build/vega-lite.js.map,filename=build/vega-lite.min.js.map -o build/vega-lite.min.js && npm run schema","build:examples":"npm run data && TZ=America/Los_Angeles scripts/build-examples.sh","build:examples-full":"TZ=America/Los_Angeles scripts/build-examples.sh 1","build:example":"TZ=America/Los_Angeles scripts/build-example.sh","build:toc":"bundle exec jekyll build -q && scripts/generate-toc","build:site":"tsc -p site && webpack --config site/webpack.config.js","build:versions":"scripts/update-version.sh","check:examples":"scripts/check-examples.sh","check:schema":"scripts/check-schema.sh",clean:"rm -rf build && rm -f examples/compiled/*.png && find site/examples ! -name 'index.md' -type f -delete",data:"rsync -r node_modules/vega-datasets/data/* data",deploy:"scripts/deploy.sh","deploy:gh":"scripts/deploy-gh.sh","deploy:schema":"scripts/deploy-schema.sh",preschema:"npm run prebuild",schema:"node --stack-size=1200 ./node_modules/.bin/ts-json-schema-generator --path tsconfig.json --type TopLevelSpec > build/vega-lite-schema.json && npm run renameschema && cp build/vega-lite-schema.json _data/",renameschema:"scripts/rename-schema.sh",presite:"npm run prebuild && npm run data && npm run build:site && npm run build:toc && npm run build:versions && scripts/create-example-pages",site:"bundle exec jekyll serve --incremental",lint:"tslint -p . -e 'package.json'",test:"jest test/ && npm run lint && npm run schema && jest examples/ && npm run test:runtime","test:inspect":"node --inspect-brk ./node_modules/.bin/jest --runInBand test","test:runtime":'TZ=America/Los_Angeles TS_NODE_COMPILER_OPTIONS=\'{"module":"commonjs"}\' wdio wdio.conf.js',"test:runtime:generate":"rm -Rf test-runtime/resources && VL_GENERATE_TESTS=true npm run test:runtime","watch:build":"npm run build:only && concurrently --kill-others -n Typescript,Rollup 'tsc -w' 'rollup -c -w'","watch:site":"concurrently --kill-others -n Typescript,Webpack 'tsc -p site --watch' 'webpack --config site/webpack.config.js --mode development --watch'","watch:test":"jest --watch"},repository:{type:"git",url:"https://github.com/vega/vega-lite.git"},license:"BSD-3-Clause",bugs:{url:"https://github.com/vega/vega-lite/issues"},devDependencies:{"@types/chai":"^4.1.4","@types/d3":"^5.0.0","@types/highlight.js":"^9.12.3","@types/jest":"^23.1.1","@types/mkdirp":"^0.5.2","@types/node":"^9.0.0","@types/webdriverio":"^4.10.2",ajv:"^6.5.1",chai:"^4.1.2",cheerio:"^1.0.0-rc.2",chromedriver:"^2.40.0",codecov:"^3.0.2",concurrently:"^3.6.0",d3:"^5.5.0","highlight.js":"^9.12.0",jest:"^23.1.0",mkdirp:"^0.5.1",rollup:"^0.59.4","rollup-plugin-commonjs":"^9.1.3","rollup-plugin-json":"^3.0.0","rollup-plugin-node-resolve":"^3.3.0","rollup-plugin-sourcemaps":"^0.4.2","source-map-support":"^0.5.6","svg2png-many":"^0.0.7","ts-jest":"^22.4.6","ts-json-schema-generator":"^0.28.0","ts-node":"^6.1.1",tslint:"5.10.0","tslint-eslint-rules":"^5.3.1",typescript:"^2.9.2","uglify-js":"^3.4.1",vega:"^4.0.0-rc.3","vega-datasets":"^1.19.0","vega-embed":"^3.16.0","vega-tooltip":"^0.11.0","wdio-chromedriver-service":"^0.1.3","wdio-dot-reporter":"0.0.9","wdio-mocha-framework":"^0.5.13","wdio-static-server-service":"^1.0.1",webdriverio:"^4.13.0",webpack:"^4.12.0","webpack-cli":"^3.0.8","yaml-front-matter":"^4.0.0"},dependencies:{"@types/json-stable-stringify":"^1.0.32","json-stable-stringify":"^1.0.1",tslib:"^1.9.2","vega-event-selector":"^2.0.0","vega-typings":"^0.3.17","vega-util":"^1.7.0",yargs:"^11.0.0"},jest:{transform:{"^.+\\.tsx?$":"ts-jest"},testRegex:"(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",moduleFileExtensions:["ts","tsx","js","jsx","json","node"],testPathIgnorePatterns:["node_modules","test-runtime","/build","_site","src"],coverageDirectory:"./coverage/",collectCoverage:!1}}},function(e,t,n){var r=n(194);r.registerLanguage("1c",n(193)),r.registerLanguage("abnf",n(192)),r.registerLanguage("accesslog",n(191)),r.registerLanguage("actionscript",n(190)),r.registerLanguage("ada",n(189)),r.registerLanguage("apache",n(188)),r.registerLanguage("applescript",n(187)),r.registerLanguage("cpp",n(186)),r.registerLanguage("arduino",n(185)),r.registerLanguage("armasm",n(184)),r.registerLanguage("xml",n(183)),r.registerLanguage("asciidoc",n(182)),r.registerLanguage("aspectj",n(181)),r.registerLanguage("autohotkey",n(180)),r.registerLanguage("autoit",n(179)),r.registerLanguage("avrasm",n(178)),r.registerLanguage("awk",n(177)),r.registerLanguage("axapta",n(176)),r.registerLanguage("bash",n(175)),r.registerLanguage("basic",n(174)),r.registerLanguage("bnf",n(173)),r.registerLanguage("brainfuck",n(172)),r.registerLanguage("cal",n(171)),r.registerLanguage("capnproto",n(170)),r.registerLanguage("ceylon",n(169)),r.registerLanguage("clean",n(168)),r.registerLanguage("clojure",n(167)),r.registerLanguage("clojure-repl",n(166)),r.registerLanguage("cmake",n(165)),r.registerLanguage("coffeescript",n(164)),r.registerLanguage("coq",n(163)),r.registerLanguage("cos",n(162)),r.registerLanguage("crmsh",n(161)),r.registerLanguage("crystal",n(160)),r.registerLanguage("cs",n(159)),r.registerLanguage("csp",n(158)),r.registerLanguage("css",n(157)),r.registerLanguage("d",n(156)),r.registerLanguage("markdown",n(155)),r.registerLanguage("dart",n(154)),r.registerLanguage("delphi",n(153)),r.registerLanguage("diff",n(152)),r.registerLanguage("django",n(151)),r.registerLanguage("dns",n(150)),r.registerLanguage("dockerfile",n(149)),r.registerLanguage("dos",n(148)),r.registerLanguage("dsconfig",n(147)),r.registerLanguage("dts",n(146)),r.registerLanguage("dust",n(145)),r.registerLanguage("ebnf",n(144)),r.registerLanguage("elixir",n(143)),r.registerLanguage("elm",n(142)),r.registerLanguage("ruby",n(141)),r.registerLanguage("erb",n(140)),r.registerLanguage("erlang-repl",n(139)),r.registerLanguage("erlang",n(138)),r.registerLanguage("excel",n(137)),r.registerLanguage("fix",n(136)),r.registerLanguage("flix",n(135)),r.registerLanguage("fortran",n(134)),r.registerLanguage("fsharp",n(133)),r.registerLanguage("gams",n(132)),r.registerLanguage("gauss",n(131)),r.registerLanguage("gcode",n(130)),r.registerLanguage("gherkin",n(129)),r.registerLanguage("glsl",n(128)),r.registerLanguage("go",n(127)),r.registerLanguage("golo",n(126)),r.registerLanguage("gradle",n(125)),r.registerLanguage("groovy",n(124)),r.registerLanguage("haml",n(123)),r.registerLanguage("handlebars",n(122)),r.registerLanguage("haskell",n(121)),r.registerLanguage("haxe",n(120)),r.registerLanguage("hsp",n(119)),r.registerLanguage("htmlbars",n(118)),r.registerLanguage("http",n(117)),r.registerLanguage("hy",n(116)),r.registerLanguage("inform7",n(115)),r.registerLanguage("ini",n(114)),r.registerLanguage("irpf90",n(113)),r.registerLanguage("java",n(112)),r.registerLanguage("javascript",n(111)),r.registerLanguage("jboss-cli",n(110)),r.registerLanguage("json",n(109)),r.registerLanguage("julia",n(108)),r.registerLanguage("julia-repl",n(107)),r.registerLanguage("kotlin",n(106)),r.registerLanguage("lasso",n(105)),r.registerLanguage("ldif",n(104)),r.registerLanguage("leaf",n(103)),r.registerLanguage("less",n(102)),r.registerLanguage("lisp",n(101)),r.registerLanguage("livecodeserver",n(100)),r.registerLanguage("livescript",n(99)),r.registerLanguage("llvm",n(98)),r.registerLanguage("lsl",n(97)),r.registerLanguage("lua",n(96)),r.registerLanguage("makefile",n(95)),r.registerLanguage("mathematica",n(94)),r.registerLanguage("matlab",n(93)),r.registerLanguage("maxima",n(92)),r.registerLanguage("mel",n(91)),r.registerLanguage("mercury",n(90)),r.registerLanguage("mipsasm",n(89)),r.registerLanguage("mizar",n(88)),r.registerLanguage("perl",n(87)),r.registerLanguage("mojolicious",n(86)),r.registerLanguage("monkey",n(85)),r.registerLanguage("moonscript",n(84)),r.registerLanguage("n1ql",n(83)),r.registerLanguage("nginx",n(82)),r.registerLanguage("nimrod",n(81)),r.registerLanguage("nix",n(80)),r.registerLanguage("nsis",n(79)),r.registerLanguage("objectivec",n(78)),r.registerLanguage("ocaml",n(77)),r.registerLanguage("openscad",n(76)),r.registerLanguage("oxygene",n(75)),r.registerLanguage("parser3",n(74)),r.registerLanguage("pf",n(73)),r.registerLanguage("php",n(72)),r.registerLanguage("pony",n(71)),r.registerLanguage("powershell",n(70)),r.registerLanguage("processing",n(69)),r.registerLanguage("profile",n(68)),r.registerLanguage("prolog",n(67)),r.registerLanguage("protobuf",n(66)),r.registerLanguage("puppet",n(65)),r.registerLanguage("purebasic",n(64)),r.registerLanguage("python",n(63)),r.registerLanguage("q",n(62)),r.registerLanguage("qml",n(61)),r.registerLanguage("r",n(60)),r.registerLanguage("rib",n(59)),r.registerLanguage("roboconf",n(58)),r.registerLanguage("routeros",n(57)),r.registerLanguage("rsl",n(56)),r.registerLanguage("ruleslanguage",n(55)),r.registerLanguage("rust",n(54)),r.registerLanguage("scala",n(53)),r.registerLanguage("scheme",n(52)),r.registerLanguage("scilab",n(51)),r.registerLanguage("scss",n(50)),r.registerLanguage("shell",n(49)),r.registerLanguage("smali",n(48)),r.registerLanguage("smalltalk",n(47)),r.registerLanguage("sml",n(46)),r.registerLanguage("sqf",n(45)),r.registerLanguage("sql",n(44)),r.registerLanguage("stan",n(43)),r.registerLanguage("stata",n(42)),r.registerLanguage("step21",n(41)),r.registerLanguage("stylus",n(40)),r.registerLanguage("subunit",n(39)),r.registerLanguage("swift",n(38)),r.registerLanguage("taggerscript",n(37)),r.registerLanguage("yaml",n(36)),r.registerLanguage("tap",n(35)),r.registerLanguage("tcl",n(34)),r.registerLanguage("tex",n(33)),r.registerLanguage("thrift",n(32)),r.registerLanguage("tp",n(31)),r.registerLanguage("twig",n(30)),r.registerLanguage("typescript",n(29)),r.registerLanguage("vala",n(28)),r.registerLanguage("vbnet",n(27)),r.registerLanguage("vbscript",n(26)),r.registerLanguage("vbscript-html",n(25)),r.registerLanguage("verilog",n(24)),r.registerLanguage("vhdl",n(23)),r.registerLanguage("vim",n(22)),r.registerLanguage("x86asm",n(21)),r.registerLanguage("xl",n(20)),r.registerLanguage("xquery",n(19)),r.registerLanguage("zephir",n(18)),e.exports=r},function(e,t,n){"use strict";n.r(t);var r={};n.r(r),n.d(r,"aggregate",function(){return Bi}),n.d(r,"bin",function(){return ji}),n.d(r,"collect",function(){return Gi}),n.d(r,"compare",function(){return $i}),n.d(r,"countpattern",function(){return Wi}),n.d(r,"cross",function(){return Ki}),n.d(r,"density",function(){return Ji}),n.d(r,"extent",function(){return na}),n.d(r,"facet",function(){return aa}),n.d(r,"field",function(){return sa}),n.d(r,"filter",function(){return ca}),n.d(r,"flatten",function(){return da}),n.d(r,"fold",function(){return fa}),n.d(r,"formula",function(){return pa}),n.d(r,"generate",function(){return ma}),n.d(r,"impute",function(){return ba}),n.d(r,"joinaggregate",function(){return va}),n.d(r,"key",function(){return ya}),n.d(r,"lookup",function(){return Ea}),n.d(r,"multiextent",function(){return Sa}),n.d(r,"multivalues",function(){return Ca}),n.d(r,"params",function(){return Ma}),n.d(r,"pivot",function(){return Na}),n.d(r,"prefacet",function(){return Da}),n.d(r,"project",function(){return Aa}),n.d(r,"proxy",function(){return ka}),n.d(r,"relay",function(){return Ra}),n.d(r,"sample",function(){return Ia}),n.d(r,"sequence",function(){return La}),n.d(r,"sieve",function(){return Pa}),n.d(r,"subflow",function(){return ra}),n.d(r,"tupleindex",function(){return Fa}),n.d(r,"values",function(){return Ba}),n.d(r,"window",function(){return Ga});var i={};n.r(i),n.d(i,"bound",function(){return Xu}),n.d(i,"identifier",function(){return td}),n.d(i,"mark",function(){return nd}),n.d(i,"overlap",function(){return rd}),n.d(i,"render",function(){return ld}),n.d(i,"viewlayout",function(){return xd});var a={};n.r(a),n.d(a,"interpolate",function(){return Op}),n.d(a,"interpolateArray",function(){return gp}),n.d(a,"interpolateBasis",function(){return ip}),n.d(a,"interpolateBasisClosed",function(){return ap}),n.d(a,"interpolateDate",function(){return hp}),n.d(a,"interpolateNumber",function(){return bp}),n.d(a,"interpolateObject",function(){return vp}),n.d(a,"interpolateRound",function(){return Mp}),n.d(a,"interpolateString",function(){return Cp}),n.d(a,"interpolateTransformCss",function(){return kp}),n.d(a,"interpolateTransformSvg",function(){return Rp}),n.d(a,"interpolateZoom",function(){return Pp}),n.d(a,"interpolateRgb",function(){return dp}),n.d(a,"interpolateRgbBasis",function(){return pp}),n.d(a,"interpolateRgbBasisClosed",function(){return mp}),n.d(a,"interpolateHsl",function(){return Bp}),n.d(a,"interpolateHslLong",function(){return Up}),n.d(a,"interpolateLab",function(){return jp}),n.d(a,"interpolateHcl",function(){return qp}),n.d(a,"interpolateHclLong",function(){return Gp}),n.d(a,"interpolateCubehelix",function(){return Hp}),n.d(a,"interpolateCubehelixLong",function(){return Wp}),n.d(a,"piecewise",function(){return Vp}),n.d(a,"quantize",function(){return Kp});var o={};n.r(o),n.d(o,"schemeCategory10",function(){return og}),n.d(o,"schemeAccent",function(){return sg}),n.d(o,"schemeDark2",function(){return lg}),n.d(o,"schemePaired",function(){return cg}),n.d(o,"schemePastel1",function(){return ug}),n.d(o,"schemePastel2",function(){return dg}),n.d(o,"schemeSet1",function(){return fg}),n.d(o,"schemeSet2",function(){return pg}),n.d(o,"schemeSet3",function(){return mg}),n.d(o,"interpolateBrBG",function(){return bg}),n.d(o,"schemeBrBG",function(){return hg}),n.d(o,"interpolatePRGn",function(){return _g}),n.d(o,"schemePRGn",function(){return vg}),n.d(o,"interpolatePiYG",function(){return xg}),n.d(o,"schemePiYG",function(){return yg}),n.d(o,"interpolatePuOr",function(){return Sg}),n.d(o,"schemePuOr",function(){return Eg}),n.d(o,"interpolateRdBu",function(){return Cg}),n.d(o,"schemeRdBu",function(){return wg}),n.d(o,"interpolateRdGy",function(){return Mg}),n.d(o,"schemeRdGy",function(){return Og}),n.d(o,"interpolateRdYlBu",function(){return Tg}),n.d(o,"schemeRdYlBu",function(){return Ng}),n.d(o,"interpolateRdYlGn",function(){return Ag}),n.d(o,"schemeRdYlGn",function(){return Dg}),n.d(o,"interpolateSpectral",function(){return Rg}),n.d(o,"schemeSpectral",function(){return kg}),n.d(o,"interpolateBuGn",function(){return Lg}),n.d(o,"schemeBuGn",function(){return Ig}),n.d(o,"interpolateBuPu",function(){return Fg}),n.d(o,"schemeBuPu",function(){return Pg}),n.d(o,"interpolateGnBu",function(){return Ug}),n.d(o,"schemeGnBu",function(){return Bg}),n.d(o,"interpolateOrRd",function(){return zg}),n.d(o,"schemeOrRd",function(){return jg}),n.d(o,"interpolatePuBuGn",function(){return Gg}),n.d(o,"schemePuBuGn",function(){return qg}),n.d(o,"interpolatePuBu",function(){return Hg}),n.d(o,"schemePuBu",function(){return $g}),n.d(o,"interpolatePuRd",function(){return Vg}),n.d(o,"schemePuRd",function(){return Wg}),n.d(o,"interpolateRdPu",function(){return Qg}),n.d(o,"schemeRdPu",function(){return Kg}),n.d(o,"interpolateYlGnBu",function(){return Zg}),n.d(o,"schemeYlGnBu",function(){return Yg}),n.d(o,"interpolateYlGn",function(){return Jg}),n.d(o,"schemeYlGn",function(){return Xg}),n.d(o,"interpolateYlOrBr",function(){return th}),n.d(o,"schemeYlOrBr",function(){return eh}),n.d(o,"interpolateYlOrRd",function(){return rh}),n.d(o,"schemeYlOrRd",function(){return nh}),n.d(o,"interpolateBlues",function(){return ah}),n.d(o,"schemeBlues",function(){return ih}),n.d(o,"interpolateGreens",function(){return sh}),n.d(o,"schemeGreens",function(){return oh}),n.d(o,"interpolateGreys",function(){return ch}),n.d(o,"schemeGreys",function(){return lh}),n.d(o,"interpolatePurples",function(){return dh}),n.d(o,"schemePurples",function(){return uh}),n.d(o,"interpolateReds",function(){return ph}),n.d(o,"schemeReds",function(){return fh}),n.d(o,"interpolateOranges",function(){return gh}),n.d(o,"schemeOranges",function(){return mh}),n.d(o,"interpolateCubehelixDefault",function(){return hh}),n.d(o,"interpolateRainbow",function(){return yh}),n.d(o,"interpolateWarm",function(){return bh}),n.d(o,"interpolateCool",function(){return vh}),n.d(o,"interpolateSinebow",function(){return wh}),n.d(o,"interpolateViridis",function(){return Oh}),n.d(o,"interpolateMagma",function(){return Mh}),n.d(o,"interpolateInferno",function(){return Nh}),n.d(o,"interpolatePlasma",function(){return Th});var s={};n.r(s),n.d(s,"axisticks",function(){return jh}),n.d(s,"datajoin",function(){return zh}),n.d(s,"encode",function(){return $h}),n.d(s,"legendentries",function(){return Yh}),n.d(s,"linkpath",function(){return nb}),n.d(s,"pie",function(){return ob}),n.d(s,"scale",function(){return db}),n.d(s,"sortitems",function(){return mb}),n.d(s,"stack",function(){return gb}),n.d(s,"validTicks",function(){return Fh});var l={};n.r(l),n.d(l,"contour",function(){return Lb}),n.d(l,"geojson",function(){return Fb}),n.d(l,"geopath",function(){return Qx}),n.d(l,"geopoint",function(){return Yx}),n.d(l,"geoshape",function(){return Zx}),n.d(l,"graticule",function(){return Xx}),n.d(l,"projection",function(){return Jx});var c={};n.r(c),n.d(c,"force",function(){return QE});var u={};n.r(u),n.d(u,"nest",function(){return YS}),n.d(u,"pack",function(){return ew}),n.d(u,"partition",function(){return rw}),n.d(u,"stratify",function(){return aw}),n.d(u,"tree",function(){return lw}),n.d(u,"treelinks",function(){return uw}),n.d(u,"treemap",function(){return pw});var d={};n.r(d),n.d(d,"voronoi",function(){return Zw});var f={};n.r(f),n.d(f,"wordcloud",function(){return yO});var p={};n.r(p),n.d(p,"crossfilter",function(){return CO}),n.d(p,"resolvefilter",function(){return MO});var m={};n.r(m),n.d(m,"symbols",function(){return iz}),n.d(m,"gradient",function(){return az}),n.d(m,"labels",function(){return oz});var g={},h={},b=34,v=10,_=13;function y(e){return new Function("d","return {"+e.map(function(e,t){return JSON.stringify(e)+": d["+t+"]"}).join(",")+"}")}var x=function(e){var t=new RegExp('["'+e+"\n\r]"),n=e.charCodeAt(0);function r(e,t){var r,i=[],a=e.length,o=0,s=0,l=a<=0,c=!1;function u(){if(l)return h;if(c)return c=!1,g;var t,r,i=o;if(e.charCodeAt(i)===b){for(;o++=a?l=!0:(r=e.charCodeAt(o++))===v?c=!0:r===_&&(c=!0,e.charCodeAt(o)===v&&++o),e.slice(i+1,t-1).replace(/""/g,'"')}for(;o=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),A.hasOwnProperty(t)?{space:A[t],local:e}:e};var R=function(e){var t=k(e);return(t.local?function(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}:function(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===D&&t.documentElement.namespaceURI===D?t.createElement(e):t.createElementNS(n,e)}})(t)};function I(){}var L=function(e){return null==e?I:function(){return this.querySelector(e)}};function P(){return[]}var F=function(e){return function(){return this.matches(e)}};if("undefined"!=typeof document){var B=document.documentElement;if(!B.matches){var U=B.webkitMatchesSelector||B.msMatchesSelector||B.mozMatchesSelector||B.oMatchesSelector;F=function(e){return function(){return U.call(this,e)}}}}var j=F,z=function(e){return new Array(e.length)};function q(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}q.prototype={constructor:q,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};var G="$";function $(e,t,n,r,i,a){for(var o,s=0,l=t.length,c=a.length;st?1:e>=t?0:NaN}var V=function(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView};function K(e){return e.trim().split(/^|\s+/)}function Q(e){return e.classList||new Y(e)}function Y(e){this._node=e,this._names=K(e.getAttribute("class")||"")}function Z(e,t){for(var n=Q(e),r=-1,i=t.length;++r=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function J(){this.textContent=""}function ee(){this.innerHTML=""}function te(){this.nextSibling&&this.parentNode.appendChild(this)}function ne(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function re(){return null}function ie(){var e=this.parentNode;e&&e.removeChild(this)}function ae(){return this.parentNode.insertBefore(this.cloneNode(!1),this.nextSibling)}function oe(){return this.parentNode.insertBefore(this.cloneNode(!0),this.nextSibling)}var se={},le=null;"undefined"!=typeof document&&("onmouseenter"in document.documentElement||(se={mouseenter:"mouseover",mouseleave:"mouseout"}));function ce(e,t,n){return e=ue(e,t,n),function(t){var n=t.relatedTarget;n&&(n===this||8&n.compareDocumentPosition(this))||e.call(this,t)}}function ue(e,t,n){return function(r){var i=le;le=r;try{e.call(this,this.__data__,t,n)}finally{le=i}}}function de(e){return function(){var t=this.__on;if(t){for(var n,r=0,i=-1,a=t.length;r=x&&(x=y+1);!(_=b[x])&&++x=0;)(r=i[a])&&(o&&o!==r.nextSibling&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=W);for(var n=this._groups,r=n.length,i=new Array(r),a=0;a1?this.each((null==t?function(e){return function(){this.style.removeProperty(e)}}:"function"==typeof t?function(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}:function(e,t,n){return function(){this.style.setProperty(e,t,n)}})(e,t,null==n?"":n)):function(e,t){return e.style.getPropertyValue(t)||V(e).getComputedStyle(e,null).getPropertyValue(t)}(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?function(e){return function(){delete this[e]}}:"function"==typeof t?function(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}:function(e,t){return function(){this[e]=t}})(e,t)):this.node()[e]},classed:function(e,t){var n=K(e+"");if(arguments.length<2){for(var r=Q(this.node()),i=-1,a=n.length;++i=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}(e+""),o=a.length;if(!(arguments.length<2)){for(s=t?fe:de,null==n&&(n=!1),r=0;r=0&&n.splice(i,1)),n},n}var we=Symbol("vega_id"),Ce=1;function Oe(e){return!(!e||!Me(e))}function Me(e){return e[we]}function Ne(e,t){return e[we]=t,e}function Te(e){var t=e===Object(e)?e:{data:e};return Me(t)?t:Ne(t,Ce++)}function De(e){return Ae(e,Te({}))}function Ae(e,t){for(var n in e)t[n]=e[n];return t}function ke(e,t){return Ne(t,Me(e))}function Re(e){return e&&e.constructor===Ie}function Ie(){var e=[],t=[],n=[],r=[],i=[],a=!1;return{constructor:Ie,insert:function(t){for(var n=Object(Ee.h)(t),r=0,i=n.length;r0&&(h(f,d,u.value),o.modifies(d));for(l=0,c=i.length;l0&&h(e,u.field,u.value)}),o.modifies(u.field);if(a)o.mod=t.length||r.length?s.filter(function(e){return m[Me(e)]>0}):s.slice();else for(p in g)o.mod.push(g[p]);return o}}}var Le="_:mod:_";function Pe(){Object.defineProperty(this,Le,{writable:!0,value:{}})}var Fe=Pe.prototype;Fe.set=function(e,t,n,r){var i=this,a=i[e],o=i[Le];return null!=t&&t>=0?(a[t]!==n||r)&&(a[t]=n,o[t+":"+e]=-1,o[e]=-1):(a!==n||r)&&(i[e]=n,o[e]=Object(Ee.u)(n)?1+n.length:-1),i},Fe.modified=function(e,t){var n,r=this[Le];if(!arguments.length){for(n in r)if(r[n])return!0;return!1}if(Object(Ee.u)(e)){for(n=0;n=0?t+1e?(t=n,1):0})},We.debounce=function(e){var t=He();return this.targets().add(He(null,null,Object(Ee.k)(e,function(e){var n=e.dataflow;t.receive(e),n&&n.run&&n.run()}))),t},We.between=function(e,t){var n=!1;return e.targets().add(He(null,null,function(){n=!0})),t.targets().add(He(null,null,function(){n=!1})),this.filter(function(){return n})};var Ve=/^([A-Za-z]+:)?\/\//,Ke="file://",Qe=function(e){return{options:e||{},sanitize:Ze,load:Ye,file:Je,http:Xe}};function Ye(e,t){var n=this;return n.sanitize(e,t).then(function(e){var r=e.href;return e.localFile?n.file(r):n.http(r,t)})}function Ze(e,t){return t=Object(Ee.m)({},this.options,t),new Promise(function(n,r){var i,a,o,s,l={href:null};null!=e&&"string"==typeof e?(a=Ve.test(e),(s=t.baseURL)&&!a&&(tt(e,"/")||"/"===s[s.length-1]||(e="/"+e),e=s+e),o=(i=tt(e,Ke))||"file"===t.mode||"http"!==t.mode&&!a&&et(),i?e=e.slice(Ke.length):tt(e,"//")&&("file"===t.defaultProtocol?(e=e.slice(2),o=!0):e=(t.defaultProtocol||"http")+":"+e),Object.defineProperty(l,"localFile",{value:!!o}),l.href=e,t.target&&(l.target=t.target+""),n(l)):r("Sanitize failure, invalid URI: "+Object(Ee.M)(e))})}function Xe(e,t){return function(e,t){var r="function"==typeof fetch?fetch:n(17);return r?r(e,t):Promise.reject("No fetch method available.")}(e,Object(Ee.m)({},this.options.http,t)).then(function(e){if(!e.ok)throw e.status+""+e.statusText;return e.text()})}function Je(e){return new Promise(function(t,n){var r=et();r?r.readFile(e,function(e,r){e?n(e):t(r)}):n("No file system access for "+e)})}function et(){var e=n(16);return e&&Object(Ee.x)(e.readFile)?e:null}function tt(e,t){return null!=e&&0===e.lastIndexOf(t,0)}var nt={boolean:Ee.N,integer:Ee.P,number:Ee.P,date:Ee.O,string:Ee.R,unknown:Ee.s},rt=[function(e){return"true"===e||"false"===e||!0===e||!1===e},function(e){return ot(e)&&(e=+e)==~~e},ot,function(e){return!isNaN(Date.parse(e))}],it=["boolean","integer","number","date"];function at(e,t){return t.reduce(function(t,n){return t[n]=function(e,t){if(!e||!e.length)return"unknown";var n,r,i,a,o=0,s=e.length,l=rt.length,c=rt.map(function(e,t){return t+1});for(r=0,s=e.length;r1)r=function(e,t,n){var r,i=[],a=[];function o(e){var t=e<0?~e:e;(a[t]||(a[t]=[])).push({i:e,g:r})}function s(e){e.forEach(o)}function l(e){e.forEach(s)}return function e(t){switch(r=t,t.type){case"GeometryCollection":t.geometries.forEach(e);break;case"LineString":s(t.arcs);break;case"MultiLineString":case"Polygon":l(t.arcs);break;case"MultiPolygon":t.arcs.forEach(l)}}(t),a.forEach(null==n?function(e){i.push(e[0].i)}:function(e){n(e[0].g,e[e.length-1].g)&&i.push(e[0].i)}),i}(0,t,n);else for(i=0,r=new Array(a=e.arcs.length);i0))return s;do{s.push(o=new Date(+n)),t(n,a),e(n)}while(o=t)for(;e(t),!n(t);)t.setTime(t-1)},function(e,r){if(e>=e)if(r<0)for(;++r<=0;)for(;t(e,-1),!n(e););else for(;--r>=0;)for(;t(e,1),!n(e););})},n&&(i.count=function(t,r){return _t.setTime(+t),yt.setTime(+r),e(_t),e(yt),Math.floor(n(_t,yt))},i.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?i.filter(r?function(t){return r(t)%e==0}:function(t){return i.count(0,t)%e==0}):i:null}),i}var Et=xt(function(){},function(e,t){e.setTime(+e+t)},function(e,t){return t-e});Et.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?xt(function(t){t.setTime(Math.floor(t/e)*e)},function(t,n){t.setTime(+t+n*e)},function(t,n){return(n-t)/e}):Et:null};var St=Et,wt=(Et.range,6e4),Ct=6048e5,Ot=xt(function(e){e.setTime(1e3*Math.floor(e/1e3))},function(e,t){e.setTime(+e+1e3*t)},function(e,t){return(t-e)/1e3},function(e){return e.getUTCSeconds()}),Mt=Ot,Nt=(Ot.range,xt(function(e){e.setTime(Math.floor(e/wt)*wt)},function(e,t){e.setTime(+e+t*wt)},function(e,t){return(t-e)/wt},function(e){return e.getMinutes()})),Tt=Nt,Dt=(Nt.range,xt(function(e){var t=e.getTimezoneOffset()*wt%36e5;t<0&&(t+=36e5),e.setTime(36e5*Math.floor((+e-t)/36e5)+t)},function(e,t){e.setTime(+e+36e5*t)},function(e,t){return(t-e)/36e5},function(e){return e.getHours()})),At=Dt,kt=(Dt.range,xt(function(e){e.setHours(0,0,0,0)},function(e,t){e.setDate(e.getDate()+t)},function(e,t){return(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*wt)/864e5},function(e){return e.getDate()-1})),Rt=kt;kt.range;function It(e){return xt(function(t){t.setDate(t.getDate()-(t.getDay()+7-e)%7),t.setHours(0,0,0,0)},function(e,t){e.setDate(e.getDate()+7*t)},function(e,t){return(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*wt)/Ct})}var Lt=It(0),Pt=It(1),Ft=It(2),Bt=It(3),Ut=It(4),jt=It(5),zt=It(6),qt=(Lt.range,Pt.range,Ft.range,Bt.range,Ut.range,jt.range,zt.range,xt(function(e){e.setDate(1),e.setHours(0,0,0,0)},function(e,t){e.setMonth(e.getMonth()+t)},function(e,t){return t.getMonth()-e.getMonth()+12*(t.getFullYear()-e.getFullYear())},function(e){return e.getMonth()})),Gt=qt,$t=(qt.range,xt(function(e){e.setMonth(0,1),e.setHours(0,0,0,0)},function(e,t){e.setFullYear(e.getFullYear()+t)},function(e,t){return t.getFullYear()-e.getFullYear()},function(e){return e.getFullYear()}));$t.every=function(e){return isFinite(e=Math.floor(e))&&e>0?xt(function(t){t.setFullYear(Math.floor(t.getFullYear()/e)*e),t.setMonth(0,1),t.setHours(0,0,0,0)},function(t,n){t.setFullYear(t.getFullYear()+n*e)}):null};var Ht=$t,Wt=($t.range,xt(function(e){e.setUTCSeconds(0,0)},function(e,t){e.setTime(+e+t*wt)},function(e,t){return(t-e)/wt},function(e){return e.getUTCMinutes()})),Vt=Wt,Kt=(Wt.range,xt(function(e){e.setUTCMinutes(0,0,0)},function(e,t){e.setTime(+e+36e5*t)},function(e,t){return(t-e)/36e5},function(e){return e.getUTCHours()})),Qt=Kt,Yt=(Kt.range,xt(function(e){e.setUTCHours(0,0,0,0)},function(e,t){e.setUTCDate(e.getUTCDate()+t)},function(e,t){return(t-e)/864e5},function(e){return e.getUTCDate()-1})),Zt=Yt;Yt.range;function Xt(e){return xt(function(t){t.setUTCDate(t.getUTCDate()-(t.getUTCDay()+7-e)%7),t.setUTCHours(0,0,0,0)},function(e,t){e.setUTCDate(e.getUTCDate()+7*t)},function(e,t){return(t-e)/Ct})}var Jt=Xt(0),en=Xt(1),tn=Xt(2),nn=Xt(3),rn=Xt(4),an=Xt(5),on=Xt(6),sn=(Jt.range,en.range,tn.range,nn.range,rn.range,an.range,on.range,xt(function(e){e.setUTCDate(1),e.setUTCHours(0,0,0,0)},function(e,t){e.setUTCMonth(e.getUTCMonth()+t)},function(e,t){return t.getUTCMonth()-e.getUTCMonth()+12*(t.getUTCFullYear()-e.getUTCFullYear())},function(e){return e.getUTCMonth()})),ln=sn,cn=(sn.range,xt(function(e){e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},function(e,t){e.setUTCFullYear(e.getUTCFullYear()+t)},function(e,t){return t.getUTCFullYear()-e.getUTCFullYear()},function(e){return e.getUTCFullYear()}));cn.every=function(e){return isFinite(e=Math.floor(e))&&e>0?xt(function(t){t.setUTCFullYear(Math.floor(t.getUTCFullYear()/e)*e),t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},function(t,n){t.setUTCFullYear(t.getUTCFullYear()+n*e)}):null};var un=cn;cn.range;function dn(e){if(0<=e.y&&e.y<100){var t=new Date(-1,e.m,e.d,e.H,e.M,e.S,e.L);return t.setFullYear(e.y),t}return new Date(e.y,e.m,e.d,e.H,e.M,e.S,e.L)}function fn(e){if(0<=e.y&&e.y<100){var t=new Date(Date.UTC(-1,e.m,e.d,e.H,e.M,e.S,e.L));return t.setUTCFullYear(e.y),t}return new Date(Date.UTC(e.y,e.m,e.d,e.H,e.M,e.S,e.L))}function pn(e){return{y:e,m:0,d:1,H:0,M:0,S:0,L:0}}var mn,gn,hn,bn,vn,_n={"-":"",_:" ",0:"0"},yn=/^\s*\d+/,xn=/^%/,En=/[\\^$*+?|[\]().{}]/g;function Sn(e,t,n){var r=e<0?"-":"",i=(r?-e:e)+"",a=i.length;return r+(a68?1900:2e3),n+r[0].length):-1}function In(e,t,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(t.slice(n,n+6));return r?(e.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function Ln(e,t,n){var r=yn.exec(t.slice(n,n+2));return r?(e.m=r[0]-1,n+r[0].length):-1}function Pn(e,t,n){var r=yn.exec(t.slice(n,n+2));return r?(e.d=+r[0],n+r[0].length):-1}function Fn(e,t,n){var r=yn.exec(t.slice(n,n+3));return r?(e.m=0,e.d=+r[0],n+r[0].length):-1}function Bn(e,t,n){var r=yn.exec(t.slice(n,n+2));return r?(e.H=+r[0],n+r[0].length):-1}function Un(e,t,n){var r=yn.exec(t.slice(n,n+2));return r?(e.M=+r[0],n+r[0].length):-1}function jn(e,t,n){var r=yn.exec(t.slice(n,n+2));return r?(e.S=+r[0],n+r[0].length):-1}function zn(e,t,n){var r=yn.exec(t.slice(n,n+3));return r?(e.L=+r[0],n+r[0].length):-1}function qn(e,t,n){var r=yn.exec(t.slice(n,n+6));return r?(e.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function Gn(e,t,n){var r=xn.exec(t.slice(n,n+1));return r?n+r[0].length:-1}function $n(e,t,n){var r=yn.exec(t.slice(n));return r?(e.Q=+r[0],n+r[0].length):-1}function Hn(e,t,n){var r=yn.exec(t.slice(n));return r?(e.Q=1e3*+r[0],n+r[0].length):-1}function Wn(e,t){return Sn(e.getDate(),t,2)}function Vn(e,t){return Sn(e.getHours(),t,2)}function Kn(e,t){return Sn(e.getHours()%12||12,t,2)}function Qn(e,t){return Sn(1+Rt.count(Ht(e),e),t,3)}function Yn(e,t){return Sn(e.getMilliseconds(),t,3)}function Zn(e,t){return Yn(e,t)+"000"}function Xn(e,t){return Sn(e.getMonth()+1,t,2)}function Jn(e,t){return Sn(e.getMinutes(),t,2)}function er(e,t){return Sn(e.getSeconds(),t,2)}function tr(e){var t=e.getDay();return 0===t?7:t}function nr(e,t){return Sn(Lt.count(Ht(e),e),t,2)}function rr(e,t){var n=e.getDay();return e=n>=4||0===n?Ut(e):Ut.ceil(e),Sn(Ut.count(Ht(e),e)+(4===Ht(e).getDay()),t,2)}function ir(e){return e.getDay()}function ar(e,t){return Sn(Pt.count(Ht(e),e),t,2)}function or(e,t){return Sn(e.getFullYear()%100,t,2)}function sr(e,t){return Sn(e.getFullYear()%1e4,t,4)}function lr(e){var t=e.getTimezoneOffset();return(t>0?"-":(t*=-1,"+"))+Sn(t/60|0,"0",2)+Sn(t%60,"0",2)}function cr(e,t){return Sn(e.getUTCDate(),t,2)}function ur(e,t){return Sn(e.getUTCHours(),t,2)}function dr(e,t){return Sn(e.getUTCHours()%12||12,t,2)}function fr(e,t){return Sn(1+Zt.count(un(e),e),t,3)}function pr(e,t){return Sn(e.getUTCMilliseconds(),t,3)}function mr(e,t){return pr(e,t)+"000"}function gr(e,t){return Sn(e.getUTCMonth()+1,t,2)}function hr(e,t){return Sn(e.getUTCMinutes(),t,2)}function br(e,t){return Sn(e.getUTCSeconds(),t,2)}function vr(e){var t=e.getUTCDay();return 0===t?7:t}function _r(e,t){return Sn(Jt.count(un(e),e),t,2)}function yr(e,t){var n=e.getUTCDay();return e=n>=4||0===n?rn(e):rn.ceil(e),Sn(rn.count(un(e),e)+(4===un(e).getUTCDay()),t,2)}function xr(e){return e.getUTCDay()}function Er(e,t){return Sn(en.count(un(e),e),t,2)}function Sr(e,t){return Sn(e.getUTCFullYear()%100,t,2)}function wr(e,t){return Sn(e.getUTCFullYear()%1e4,t,4)}function Cr(){return"+0000"}function Or(){return"%"}function Mr(e){return+e}function Nr(e){return Math.floor(+e/1e3)}mn=function(e){var t=e.dateTime,n=e.date,r=e.time,i=e.periods,a=e.days,o=e.shortDays,s=e.months,l=e.shortMonths,c=Cn(i),u=On(i),d=Cn(a),f=On(a),p=Cn(o),m=On(o),g=Cn(s),h=On(s),b=Cn(l),v=On(l),_={a:function(e){return o[e.getDay()]},A:function(e){return a[e.getDay()]},b:function(e){return l[e.getMonth()]},B:function(e){return s[e.getMonth()]},c:null,d:Wn,e:Wn,f:Zn,H:Vn,I:Kn,j:Qn,L:Yn,m:Xn,M:Jn,p:function(e){return i[+(e.getHours()>=12)]},Q:Mr,s:Nr,S:er,u:tr,U:nr,V:rr,w:ir,W:ar,x:null,X:null,y:or,Y:sr,Z:lr,"%":Or},y={a:function(e){return o[e.getUTCDay()]},A:function(e){return a[e.getUTCDay()]},b:function(e){return l[e.getUTCMonth()]},B:function(e){return s[e.getUTCMonth()]},c:null,d:cr,e:cr,f:mr,H:ur,I:dr,j:fr,L:pr,m:gr,M:hr,p:function(e){return i[+(e.getUTCHours()>=12)]},Q:Mr,s:Nr,S:br,u:vr,U:_r,V:yr,w:xr,W:Er,x:null,X:null,y:Sr,Y:wr,Z:Cr,"%":Or},x={a:function(e,t,n){var r=p.exec(t.slice(n));return r?(e.w=m[r[0].toLowerCase()],n+r[0].length):-1},A:function(e,t,n){var r=d.exec(t.slice(n));return r?(e.w=f[r[0].toLowerCase()],n+r[0].length):-1},b:function(e,t,n){var r=b.exec(t.slice(n));return r?(e.m=v[r[0].toLowerCase()],n+r[0].length):-1},B:function(e,t,n){var r=g.exec(t.slice(n));return r?(e.m=h[r[0].toLowerCase()],n+r[0].length):-1},c:function(e,n,r){return w(e,t,n,r)},d:Pn,e:Pn,f:qn,H:Bn,I:Bn,j:Fn,L:zn,m:Ln,M:Un,p:function(e,t,n){var r=c.exec(t.slice(n));return r?(e.p=u[r[0].toLowerCase()],n+r[0].length):-1},Q:$n,s:Hn,S:jn,u:Nn,U:Tn,V:Dn,w:Mn,W:An,x:function(e,t,r){return w(e,n,t,r)},X:function(e,t,n){return w(e,r,t,n)},y:Rn,Y:kn,Z:In,"%":Gn};function E(e,t){return function(n){var r,i,a,o=[],s=-1,l=0,c=e.length;for(n instanceof Date||(n=new Date(+n));++s53)return null;"w"in a||(a.w=1),"Z"in a?(r=(i=(r=fn(pn(a.y))).getUTCDay())>4||0===i?en.ceil(r):en(r),r=Zt.offset(r,7*(a.V-1)),a.y=r.getUTCFullYear(),a.m=r.getUTCMonth(),a.d=r.getUTCDate()+(a.w+6)%7):(r=(i=(r=t(pn(a.y))).getDay())>4||0===i?Pt.ceil(r):Pt(r),r=Rt.offset(r,7*(a.V-1)),a.y=r.getFullYear(),a.m=r.getMonth(),a.d=r.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),i="Z"in a?fn(pn(a.y)).getUTCDay():t(pn(a.y)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,fn(a)):t(a)}}function w(e,t,n,r){for(var i,a,o=0,s=t.length,l=n.length;o=l)return-1;if(37===(i=t.charCodeAt(o++))){if(i=t.charAt(o++),!(a=x[i in _n?t.charAt(o++):i])||(r=a(e,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return _.x=E(n,_),_.X=E(r,_),_.c=E(t,_),y.x=E(n,y),y.X=E(r,y),y.c=E(t,y),{format:function(e){var t=E(e+="",_);return t.toString=function(){return e},t},parse:function(e){var t=S(e+="",dn);return t.toString=function(){return e},t},utcFormat:function(e){var t=E(e+="",y);return t.toString=function(){return e},t},utcParse:function(e){var t=S(e,fn);return t.toString=function(){return e},t}}}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]}),gn=mn.format,hn=mn.parse,bn=mn.utcFormat,vn=mn.utcParse;Date.prototype.toISOString||bn("%Y-%m-%dT%H:%M:%S.%LZ");+new Date("2000-01-01T00:00:00.000Z")||vn("%Y-%m-%dT%H:%M:%S.%LZ");var Tr=function(e,t,n){var r=function(e,t){return arguments.length>1?(vt[e]=t,this):vt.hasOwnProperty(e)?vt[e]:null}((t=t||{}).type||"json");return r||Object(Ee.l)("Unknown data format type: "+t.type),e=r(e,t),t.parse&&function(e,t,n){if(!e.length)return;n=n||hn;var r,i,a,o,s,l,c,u=e.columns||Object.keys(e[0]);"auto"===t&&(t=at(e,u));for(u=Object.keys(t),r=u.map(function(e){var r,i,a=t[e];if(a&&(0===a.indexOf("date:")||0===a.indexOf("utc:")))return("'"===(i=(r=a.split(/:(.+)?/,2))[1])[0]&&"'"===i[i.length-1]||'"'===i[0]&&'"'===i[i.length-1])&&(i=i.slice(1,-1)),"utc"===r[0]?vn(i):n(i);if(!nt[a])throw Error("Illegal format pattern: "+e+":"+a);return nt[a]}),o=0,l=e.length,c=u.length;ot&&r(i,a=e[o=n-1>>1])<0;)e[n]=a,n=o;return e[n]=i}function Wr(e,t,n){for(var r,i=t,a=e.length,o=e[t],s=2*t+1;s=0&&(s=r),e[t]=e[s],s=2*(t=s)+1;return e[t]=o,Hr(e,i,t,n)}function Vr(){this._log=Object(Ee.D)(),this.logLevel(Ee.b),this._clock=0,this._rank=0;try{this._loader=Qe()}catch(e){}this._touched=Se(Ee.r),this._pulses={},this._pulse=null,this._heap=new Gr(function(e,t){return e.qrank-t.qrank}),this._postrun=[]}$r.size=function(){return this.nodes.length},$r.clear=function(){return this.nodes=[],this},$r.peek=function(){return this.nodes[0]},$r.push=function(e){var t=this.nodes;return t.push(e),Hr(t,0,t.length-1,this.cmp)},$r.pop=function(){var e,t=this.nodes,n=t.pop();return t.length?(e=t[0],t[0]=n,Wr(t,0,this.cmp)):e=n,e},$r.replace=function(e){var t=this.nodes,n=t[0];return t[0]=e,Wr(t,0,this.cmp),n},$r.pushpop=function(e){var t=this.nodes,n=t[0];return t.length&&this.cmp(n,e)<0&&(t[0]=e,e=n,Wr(t,0,this.cmp)),e};var Kr=Vr.prototype;function Qr(e){return function(){return this._log[e].apply(this,arguments)}}function Yr(e,t){je.call(this,e,null,t)}Kr.stamp=function(){return this._clock},Kr.loader=function(e){return arguments.length?(this._loader=e,this):this._loader},Kr.cleanThreshold=1e4,Kr.add=function(e,t,n,r){var i,a=1;return e instanceof je?i=e:e&&e.prototype instanceof je?i=new e:Object(Ee.x)(e)?i=new je(null,e):(a=0,i=new je(e,t)),this.rank(i),a&&(r=n,n=t),n&&this.connect(i,i.parameters(n,r)),this.touch(i),i},Kr.connect=function(e,t){var n,r,i=e.rank;for(n=0,r=t.length;n=0;)i.push(t=n[r]),t===e&&Object(Ee.l)("Cycle detected in dataflow graph.")},Kr.pulse=function(e,t,n){this.touch(e,n||qr);var r=new Ir(this,this._clock+(this._pulse?0:1)),i=e.pulse&&e.pulse.source||[];return r.target=e,this._pulses[e.id]=t.pulse(r,i),this},Kr.touch=function(e,t){var n=t||qr;return this._pulse?this._enqueue(e):this._touched.add(e),n.skip&&e.skip(!0),this},Kr.update=function(e,t,n){var r=n||qr;return(e.set(t)||r.force)&&this.touch(e,r),this},Kr.changeset=Ie,Kr.ingest=function(e,t,n){return this.pulse(e,this.changeset().insert(Tr(t,n)))},Kr.request=function(e,t,n){var r=this,i=r._pending||function(e){var t,n,r=new Promise(function(e,r){t=e,n=r});return r.requests=0,r.done=function(){0==--r.requests&&e.runAfter(function(){e._pending=null;try{e.run(),t(e)}catch(e){n(e)}})},e._pending=r}(r);i.requests+=1,r.loader().load(t,{context:"dataflow"}).then(function(t){r.ingest(e,t,n)},function(e){r.error("Loading failed",t,e)}).catch(function(e){r.error("Data ingestion failed",t,e)}).then(i.done,i.done)},Kr.events=function(e,t,n,r){for(var i,a=this,o=He(n,r),s=function(e){e.dataflow=a;try{o.receive(e)}catch(e){a.error(e)}finally{a.run()}},l=0,c=(i="string"==typeof e&&"undefined"!=typeof document?document.querySelectorAll(e):Object(Ee.h)(e)).length;l=Ee.c&&(r=Date.now(),a.debug("-- START PROPAGATION ("+a._clock+") -----")),a._touched.forEach(function(e){a._enqueue(e,!0)}),a._touched=Se(Ee.r);try{for(;a._heap.size()>0;)(t=a._heap.pop()).rank===t.qrank?(n=t.run(a._getPulse(t,e)),s>=Ee.a&&a.debug(t.id,n===Rr?"STOP":n,t),n!==Rr&&(a._pulse=n,t._targets&&t._targets.forEach(function(e){a._enqueue(e)})),++o):a._enqueue(t,!0)}catch(e){i=e}if(a._pulses={},a._pulse=null,s>=Ee.c&&(r=Date.now()-r,a.info("> Pulse "+a._clock+": "+o+" operators; "+r+"ms")),i&&(a._postrun=[],a.error(i)),a._onrun)try{a._onrun(a,o,i)}catch(e){a.error(e)}if(a._postrun.length){var l=a._postrun;a._postrun=[],l.sort(function(e,t){return t.priority-e.priority}).forEach(function(e){zr(a,e.callback)})}return o},Kr.runAsync=function(){return this._pending||Promise.resolve(this.run())},Kr.runAfter=function(e,t,n){this._pulse||t?this._postrun.push({priority:n||0,callback:e}):zr(this,e)},Kr._enqueue=function(e,t){var n=!this._pulses[e.id];n&&(this._pulses[e.id]=this._pulse),(n||t)&&(e.qrank=e.rank,this._heap.push(e))},Kr._getPulse=function(e,t){var n,r=e.source,i=this._clock;return r&&Object(Ee.u)(r)?new Ur(this,i,n=r.map(function(e){return e.pulse}),t):(n=this._pulses[e.id],r&&((r=r.pulse)&&r!==Rr?r.stamp===i&&n.target!==e?n=r:n.source=r.source:n.source=[]),n)},Kr.error=Qr("error"),Kr.warn=Qr("warn"),Kr.info=Qr("info"),Kr.debug=Qr("debug"),Kr.logLevel=Qr("level");var Zr=Object(Ee.t)(Yr,je);Zr.run=function(e){return e.stamp<=this.stamp?e.StopPropagation:(this.skip()?this.skip(!1):t=this.evaluate(e),(t=t||e)!==e.StopPropagation&&(this.pulse=t),this.stamp=e.stamp,t);var t},Zr.evaluate=function(e){var t=this.marshall(e.stamp),n=this.transform(t,e);return t.clear(),n},Zr.transform=function(){};var Xr={};function Jr(e){var t=function(e){return e=e&&e.toLowerCase(),Xr.hasOwnProperty(e)?Xr[e]:null}(e);return t&&t.Definition||null}function ei(e){return e&&e.length?1===e.length?e[0]:(t=e,function(e){for(var n=t.length,r=1,i=String(t[0](e));r 1 ? this.dev / (this.valid-1) : 0",req:["mean"],idx:1}),variancep:ai({name:"variancep",set:"this.valid > 1 ? this.dev / this.valid : 0",req:["variance"],idx:2}),stdev:ai({name:"stdev",set:"this.valid > 1 ? Math.sqrt(this.dev / (this.valid-1)) : 0",req:["variance"],idx:2}),stdevp:ai({name:"stdevp",set:"this.valid > 1 ? Math.sqrt(this.dev / this.valid) : 0",req:["variance"],idx:2}),stderr:ai({name:"stderr",set:"this.valid > 1 ? Math.sqrt(this.dev / (this.valid * (this.valid-1))) : 0",req:["variance"],idx:2}),distinct:ai({name:"distinct",set:"cell.data.distinct(this.get)",req:["values"],idx:3}),ci0:ai({name:"ci0",set:"cell.data.ci0(this.get)",req:["values"],idx:3}),ci1:ai({name:"ci1",set:"cell.data.ci1(this.get)",req:["values"],idx:3}),median:ai({name:"median",set:"cell.data.q2(this.get)",req:["values"],idx:3}),q1:ai({name:"q1",set:"cell.data.q1(this.get)",req:["values"],idx:3}),q3:ai({name:"q3",set:"cell.data.q3(this.get)",req:["values"],idx:3}),argmin:ai({name:"argmin",init:"this.argmin = null;",add:"if (v < this.min) this.argmin = t;",rem:"if (v <= this.min) this.argmin = null;",set:"this.argmin || cell.data.argmin(this.get)",req:["min"],str:["values"],idx:3}),argmax:ai({name:"argmax",init:"this.argmax = null;",add:"if (v > this.max) this.argmax = t;",rem:"if (v >= this.max) this.argmax = null;",set:"this.argmax || cell.data.argmax(this.get)",req:["max"],str:["values"],idx:3}),min:ai({name:"min",init:"this.min = null;",add:"if (v < this.min || this.min === null) this.min = v;",rem:"if (v <= this.min) this.min = NaN;",set:"this.min = (isNaN(this.min) ? cell.data.min(this.get) : this.min)",str:["values"],idx:4}),max:ai({name:"max",init:"this.max = null;",add:"if (v > this.max || this.max === null) this.max = v;",rem:"if (v >= this.max) this.max = NaN;",set:"this.max = (isNaN(this.max) ? cell.data.max(this.get) : this.max)",str:["values"],idx:4})},ri=Object.keys(ni);function ii(e,t){return ni[e](t)}function ai(e){return function(t){var n=Object(Ee.m)({init:"",add:"",rem:"",idx:0},e);return n.out=t||e.name,n}}function oi(e,t){return e.idx-t.idx}function si(e,t){var n=t||Ee.s,r="var cell = this.cell; this.valid = 0; this.missing = 0;",i="this.cell = cell; this.init();",a="if(v==null){++this.missing; return;} if(v!==v) return; ++this.valid;",o="if(v==null){--this.missing; return;} if(v!==v) return; --this.valid;",s="var cell = this.cell;";return function(e,t){var n,r=e.reduce(function e(n,r){function i(t){n[t]||e(n,n[t]=ni[t]())}return r.req&&r.req.forEach(i),t&&r.str&&r.str.forEach(i),n},e.reduce(function(e,t){return e[t.name]=t,e},{})),i=[];for(n in r)i.push(r[n]);return i.sort(oi)}(e,!0).forEach(function(e){r+=e.init,a+=e.add,o+=e.rem}),e.slice().sort(oi).forEach(function(e){s+="t['"+e.out+"']="+e.set+";"}),s+="return t;",(i=Function("cell",i)).prototype.init=Function(r),i.prototype.add=Function("v","t",a),i.prototype.rem=Function("v","t",o),i.prototype.set=Function("t",s),i.prototype.get=n,i.fields=e.map(function(e){return e.out}),i}var li=function(e,t){var n,r=[],i=e.length,a=-1;if(null==t)for(;++at?1:e>=t?0:NaN},fi=function(e){var t;return 1===e.length&&(t=e,e=function(e,n){return di(t(e),n)}),{left:function(t,n,r,i){for(null==r&&(r=0),null==i&&(i=t.length);r>>1;e(t[a],n)<0?r=a+1:i=a}return r},right:function(t,n,r,i){for(null==r&&(r=0),null==i&&(i=t.length);r>>1;e(t[a],n)>0?i=a:r=a+1}return r}}};var pi=fi(di),mi=pi.right,gi=pi.left,hi=mi;var bi=function(e){return null===e?NaN:+e},vi=function(e,t){var n,r,i=e.length,a=0,o=-1,s=0,l=0;if(null==t)for(;++o1)return l/(a-1)},_i=function(e,t){var n,r,i,a=e.length,o=-1;if(null==t){for(;++o=n)for(r=i=n;++on&&(r=n),i=n)for(r=i=n;++on&&(r=n),i0)return[e];if((r=t0)for(e=Math.ceil(e/o),t=Math.floor(t/o),a=new Array(i=Math.ceil(t-e+1));++s=0?(a>=Ei?10:a>=Si?5:a>=wi?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(a>=Ei?10:a>=Si?5:a>=wi?2:1)}function Mi(e,t,n){var r=Math.abs(t-e)/Math.max(0,n),i=Math.pow(10,Math.floor(Math.log(r)/Math.LN10)),a=r/i;return a>=Ei?i*=10:a>=Si?i*=5:a>=wi&&(i*=2),t=1)return+n(e[r-1],r-1,e);var r,i=(r-1)*t,a=Math.floor(i),o=+n(e[a],a,e);return o+(+n(e[a+1],a+1,e)-o)*(i-a)}},Di=function(e,t){var n,r,i=e.length,a=-1;if(null==t){for(;++a=n)for(r=n;++ar&&(r=n)}else for(;++a=n)for(r=n;++ar&&(r=n);return r},Ai=function(e){for(var t,n,r,i=e.length,a=-1,o=0;++a=0;)for(t=(r=e[i]).length;--t>=0;)n[--o]=r[t];return n},ki=function(e,t){var n,r,i=e.length,a=-1;if(null==t){for(;++a=n)for(r=n;++an&&(r=n)}else for(;++a=n)for(r=n;++an&&(r=n);return r},Ri=function(e,t){for(var n=t.length,r=new Array(n);n--;)r[n]=e[t[n]];return r};var Ii=function(e,t){var n=li(e,t);return[Ti(n.sort(di),.25),Ti(n,.5),Ti(n,.75)]},Li=function(e,t){var n,r,i=NaN,a={mean:function(e){return arguments.length?(n=e||0,i=NaN,a):n},stdev:function(e){return arguments.length?(r=null==e?1:e,i=NaN,a):r},sample:function(){var e,t,a=0,o=0;if(i==i)return a=i,i=NaN,a;do{e=(a=2*ui()-1)*a+(o=2*ui()-1)*o}while(0===e||e>1);return t=Math.sqrt(-2*Math.log(e)/e),i=n+o*t*r,n+a*t*r},pdf:function(e){var t=Math.exp(Math.pow(e-n,2)/(-2*Math.pow(r,2)));return 1/(r*Math.sqrt(2*Math.PI))*t},cdf:function(e){var t,i=(e-n)/r,a=Math.abs(i);if(a>37)t=0;else{var o=Math.exp(-a*a/2);a<7.07106781186547?(t=o*((((((.0352624965998911*a+.700383064443688)*a+6.37396220353165)*a+33.912866078383)*a+112.079291497871)*a+221.213596169931)*a+220.206867912376),t/=((((((.0883883476483184*a+1.75566716318264)*a+16.064177579207)*a+86.7807322029461)*a+296.564248779674)*a+637.333633378831)*a+793.826512519948)*a+440.413735824752):t=o/(a+1/(a+2/(a+3/(a+4/(a+.65)))))/2.506628274631}return i>0?1-t:t},icdf:function(e){if(e<=0||e>=1)return NaN;var t=2*e-1,i=8*(Math.PI-3)/(3*Math.PI*(4-Math.PI)),a=2/(Math.PI*i)+Math.log(1-Math.pow(t,2))/2,o=Math.log(1-t*t)/i,s=(t>0?1:-1)*Math.sqrt(Math.sqrt(a*a-o)-a);return n+r*Math.SQRT2*s}};return a.mean(e).stdev(t)};function Pi(e){this._key=e?Object(Ee.q)(e):Me,this.reset()}var Fi=Pi.prototype;function Bi(e){Yr.call(this,null,e),this._adds=[],this._mods=[],this._alen=0,this._mlen=0,this._drop=!0,this._cross=!1,this._dims=[],this._dnames=[],this._measures=[],this._countOnly=!1,this._counts=null,this._prev=null,this._inputs=null,this._outputs=null}Fi.reset=function(){this._add=[],this._rem=[],this._ext=null,this._get=null,this._q=null},Fi.add=function(e){this._add.push(e)},Fi.rem=function(e){this._rem.push(e)},Fi.values=function(){if(this._get=null,0===this._rem.length)return this._add;var e,t,n,r=this._add,i=this._rem,a=this._key,o=r.length,s=i.length,l=Array(o-s),c={};for(e=0;e=0;)t=e(n[r])+"",i.hasOwnProperty(t)||(i[t]=1,++a);return a},Fi.extent=function(e){if(this._get!==e||!this._ext){var t=this.values(),n=Object(Ee.n)(t,e);this._ext=[t[n[0]],t[n[1]]],this._get=e}return this._ext},Fi.argmin=function(e){return this.extent(e)[0]||{}},Fi.argmax=function(e){return this.extent(e)[1]||{}},Fi.min=function(e){var t=this.extent(e)[0];return null!=t?e(t):1/0},Fi.max=function(e){var t=this.extent(e)[1];return null!=t?e(t):-1/0},Fi.quartile=function(e){return this._get===e&&this._q||(this._q=Ii(this.values(),e),this._get=e),this._q},Fi.q1=function(e){return this.quartile(e)[0]},Fi.q2=function(e){return this.quartile(e)[1]},Fi.q3=function(e){return this.quartile(e)[2]},Fi.ci=function(e){return this._get===e&&this._ci||(this._ci=function(e,t,n,r){var i,a,o,s,l=li(e,r),c=l.length,u=t;for(o=0,s=Array(u);o1&&(r._drop=!1,this.cross()),r.changes(i)},Ui.cross=function(){var e=this,t=e.value,n=e._dnames,r=n.map(function(){return{}}),i=n.length;function a(e){var t,a,o,s;for(t in e)for(o=e[t].tuple,a=0;ac;)t*=u;for(o=0,s=f.length;o=r&&g/a<=c&&(t=a)}return i=(a=Math.log(t))>=0?0:1+~~(-a/d),l=Math.pow(u,-i-1),(e.nice||void 0===e.nice)&&(p=p<(a=Math.floor(p/t+l)*t)?a-t:a,m=Math.ceil(m/t)*t),{start:p,stop:m,step:t}}(e),a=i.start,o=i.stop,s=i.step;null!=(t=e.anchor)&&(n=t-(a+s*Math.floor((t-a)/s)),a+=n,o+=n);var l=function(e){var t=r(e);return null==t?null:(t=Math.max(a,Math.min(+t,o-s)),a+s*Math.floor((t-a)/s))};return l.start=a,l.stop=o,l.step=s,this.value=Object(Ee.e)(l,Object(Ee.f)(r),e.name||"bin_"+Object(Ee.g)(r))};var qi=function(e,t,n){var r=e,i=t||[],a=n||[],o={},s=0;return{add:function(e){a.push(e)},remove:function(e){o[r(e)]=++s},size:function(){return i.length},data:function(e,t){return s&&(i=i.filter(function(e){return!o[r(e)]}),o={},s=0),t&&e&&i.sort(e),a.length&&(i=e?Object(Ee.E)(e,i,a.sort(e)):i.concat(a),a=[]),i}}};function Gi(e){Yr.call(this,[],e)}function $i(e){je.call(this,null,Hi,e)}function Hi(e){return this.value&&!e.modified()?this.value:Object(Ee.i)(e.fields,e.orders)}function Wi(e){Yr.call(this,null,e)}Gi.Definition={type:"Collect",metadata:{source:!0},params:[{name:"sort",type:"compare"}]},Object(Ee.t)(Gi,Yr).transform=function(e,t){var n=t.fork(t.ALL),r=qi(Me,this.value,n.materialize(n.ADD).add),i=e.sort,a=t.changed()||i&&(e.modified("sort")||t.modified(i.fields));return n.visit(n.REM,r.remove),this.modified(a),this.value=n.source=r.data(i,a),t.source&&t.source.root&&(this.value.root=t.source.root),n},Object(Ee.t)($i,je),Wi.Definition={type:"CountPattern",metadata:{generates:!0,changes:!0},params:[{name:"field",type:"field",required:!0},{name:"case",type:"enum",values:["upper","lower","mixed"],default:"mixed"},{name:"pattern",type:"string",default:'[\\w"]+'},{name:"stopwords",type:"string",default:""},{name:"as",type:"string",array:!0,length:2,default:["text","count"]}]};var Vi=Object(Ee.t)(Wi,Yr);function Ki(e){Yr.call(this,null,e)}Vi.transform=function(e,t){function n(t){return function(n){for(var r,i=function(e,t,n){switch(t){case"upper":e=e.toUpperCase();break;case"lower":e=e.toLowerCase()}return e.match(n)}(s(n),e.case,a)||[],l=0,c=i.length;l=n&&e<=r?1/i:0},a.cdf=function(e){return er?1:(e-n)/i},a.icdf=function(e){return e>=0&&e<=1?n+e*i:NaN},a.min(e).max(t)}},Yi="distributions",Zi="function",Xi="field";function Ji(e){Yr.call(this,null,e)}var ea=[{key:{function:"normal"},params:[{name:"mean",type:"number",default:0},{name:"stdev",type:"number",default:1}]},{key:{function:"uniform"},params:[{name:"min",type:"number",default:0},{name:"max",type:"number",default:1}]},{key:{function:"kde"},params:[{name:"field",type:"field",required:!0},{name:"from",type:"data"},{name:"bandwidth",type:"number",default:0}]}],ta={key:{function:"mixture"},params:[{name:"distributions",type:"param",array:!0,params:ea},{name:"weights",type:"number",array:!0}]};function na(e){Yr.call(this,[1/0,-1/0],e)}function ra(e,t){je.call(this,e),this.parent=t}Ji.Definition={type:"Density",metadata:{generates:!0},params:[{name:"extent",type:"number",array:!0,length:2},{name:"steps",type:"number",default:100},{name:"method",type:"string",default:"pdf",values:["pdf","cdf"]},{name:"distribution",type:"param",params:ea.concat(ta)},{name:"as",type:"string",array:!0,default:["value","density"]}]},Object(Ee.t)(Ji,Yr).transform=function(e,t){var n=t.fork(t.NO_SOURCE|t.NO_FIELDS);if(!this.value||t.changed()||e.modified()){var r=function e(t,n){var r=t[Zi];Qi.hasOwnProperty(r)||Object(Ee.l)("Unknown distribution function: "+r);var i=Qi[r]();for(var a in t)a===Xi?i.data((t.from||n()).map(t[a])):a===Yi?i[a](t[a].map(function(t){return e(t,n)})):typeof i[a]===Zi&&i[a](t[a]);return i}(e.distribution,function(e){return function(){return e.materialize(e.SOURCE).source}}(t)),i=e.method||"pdf";"pdf"!==i&&"cdf"!==i&&Object(Ee.l)("Invalid density method: "+i),e.extent||r.data||Object(Ee.l)("Missing density extent parameter."),i=r[i];var a=e.as||["value","density"],o=e.extent||_i(r.data()),s=(o[1]-o[0])/(e.steps||100),l=xi(o[0],o[1]+s/2,s).map(function(e){var t={};return t[a[0]]=e,t[a[1]]=i(e),Te(t)});this.value&&(n.rem=this.value),this.value=n.add=n.source=l}return n},na.Definition={type:"Extent",metadata:{},params:[{name:"field",type:"field",required:!0}]},Object(Ee.t)(na,Yr).transform=function(e,t){var n=this.value,r=e.field,i=n[0],a=n[1],o=t.ADD;(t.changed()||t.modified(r.fields)||e.modified("field"))&&(o=t.SOURCE,i=1/0,a=-1/0),t.visit(o,function(e){var t=r(e);null!=t&&((t=+t)a&&(a=t))}),this.value=[i,a]};var ia=Object(Ee.t)(ra,je);function aa(e){Yr.call(this,{},e),this._keys=Object(Ee.p)();var t=this._targets=[];t.active=0,t.forEach=function(e){for(var n=0,r=t.active;nn.cleanThreshold&&n.runAfter(o.clean),t},Object(Ee.t)(sa,je),ca.Definition={type:"Filter",metadata:{changes:!0},params:[{name:"expr",type:"expr",required:!0}]},Object(Ee.t)(ca,Yr).transform=function(e,t){var n=t.dataflow,r=this.value,i=t.fork(),a=i.add,o=i.rem,s=i.mod,l=e.expr,c=!0;function u(t){var n=Me(t),i=l(t,e),u=r.get(n);i&&u?(r.delete(n),a.push(t)):i||u?c&&i&&!u&&s.push(t):(r.set(n,1),o.push(t))}return t.visit(t.REM,function(e){var t=Me(e);r.has(t)?r.delete(t):o.push(e)}),t.visit(t.ADD,function(t){l(t,e)?a.push(t):r.set(Me(t),1)}),t.visit(t.MOD,u),e.modified()&&(c=!1,t.visit(t.REFLOW,u)),r.empty>n.cleanThreshold&&n.runAfter(r.clean),i},da.Definition={type:"Flatten",metadata:{generates:!0},params:[{name:"fields",type:"field",array:!0,required:!0},{name:"as",type:"string",array:!0}]},Object(Ee.t)(da,Yr).transform=function(e,t){var n=t.fork(t.NO_SOURCE),r=e.fields,i=ua(r,e.as||[]),a=i.length;return n.rem=this.value,t.visit(t.SOURCE,function(e){for(var t,o,s,l=r.map(function(t){return t(e)}),c=l.reduce(function(e,t){return Math.max(e,t.length)},0),u=0;u0){for(n=[];--s>=0;)n.push(i=Te(l(e))),a.push(i);o.add=o.add.length?o.materialize(o.ADD).add.concat(n):n}else r=a.slice(0,-s),o.rem=o.rem.length?o.materialize(o.REM).rem.concat(r):r,a=a.slice(-s);return o.source=this.value=a,o};var ga={value:"value",median:function(e,t){var n,r=e.length,i=-1,a=[];if(null==t)for(;++ia&&(a=r[1]);return[i,a]}function Ca(e){je.call(this,null,Oa,e)}function Oa(e){return this.value&&!e.modified()?this.value:e.values.reduce(function(e,t){return e.concat(t)},[])}function Ma(e){Yr.call(this,null,e)}function Na(e){Bi.call(this,e)}_a.transform=function(e,t){var n,r=this,i=e.modified();return r.value&&(i||t.modified(r._inputs))?(n=r.value=i?r.init(e):{},t.visit(t.SOURCE,function(e){r.add(e)})):(n=r.value=r.value||this.init(e),t.visit(t.REM,function(e){r.rem(e)}),t.visit(t.ADD,function(e){r.add(e)})),r.changes(),t.visit(t.SOURCE,function(e){Object(Ee.m)(e,n[r.cellkey(e)].tuple)}),t.reflow(i).modifies(this._outputs)},_a.changes=function(){var e,t,n=this._adds,r=this._mods;for(e=0,t=this._alen;e1&&!a&&Object(Ee.l)('Multi-field lookup requires explicit "as" parameter.'),a&&a.length!==f*r&&Object(Ee.l)('The "as" parameter has too few output field names.'),a=a||l.map(Ee.g),n=function(e){for(var t,n,i=0,u=0;it||null==t)&&null!=e?1:(t=t instanceof Date?+t:t,(e=e instanceof Date?+e:e)!==e&&t==t?-1:t!=t&&e==e?1:0)}),t?i.slice(0,t):i}(n,e.limit||0,t);return{key:e.key,groupby:e.groupby,ops:o.map(function(){return i}),fields:o.map(function(e){return function(e,t,n,r){return Object(Ee.e)(function(r){return t(r)===e?n(r):NaN},r,e+"")}(e,n,r,a)}),as:o.map(function(e){return e+""}),modified:e.modified.bind(e)}}(e,t),t)},Object(Ee.t)(Da,aa).transform=function(e,t){var n=this,r=e.subflow,i=e.field;return(e.modified("field")||i&&t.modified(Object(Ee.f)(i)))&&Object(Ee.l)("PreFacet does not support field modification."),this._targets.active=0,t.visit(t.MOD,function(e){var a=n.subflow(Me(e),r,t,e);i?i(e).forEach(function(e){a.mod(e)}):a.mod(e)}),t.visit(t.ADD,function(e){var a=n.subflow(Me(e),r,t,e);i?i(e).forEach(function(e){a.add(Te(e))}):a.add(e)}),t.visit(t.REM,function(e){var a=n.subflow(Me(e),r,t,e);i?i(e).forEach(function(e){a.rem(e)}):a.rem(e)}),t},Aa.Definition={type:"Project",metadata:{generates:!0,changes:!0},params:[{name:"fields",type:"field",array:!0},{name:"as",type:"string",null:!0,array:!0}]},Object(Ee.t)(Aa,Yr).transform=function(e,t){var n,r,i=e.fields,a=ua(e.fields,e.as||[]),o=i?function(e,t){return function(e,t,n,r){for(var i=0,a=n.length;i=s&&(t=a[r],l[Me(t)]&&n.rem.push(t),a[r]=e),++o}if(t.rem.length&&(t.visit(t.REM,function(e){var t=Me(e);l[t]&&(l[t]=-1,n.rem.push(e)),--o}),a=a.filter(function(e){return-1!==l[Me(e)]})),(t.rem.length||r)&&a.lengthi){for(var u=0,d=a.length-i;un.cleanThreshold&&n.runAfter(i.clean),t.fork()},Object(Ee.t)(Ba,Yr).transform=function(e,t){(!this.value||e.modified("field")||e.modified("sort")||t.changed()||e.sort&&t.modified(e.sort.fields))&&(this.value=(e.sort?t.source.slice().sort(e.sort):t.source).map(e.field))};var Ua={row_number:function(){return{next:function(e){return e.index+1}}},rank:function(){var e;return{init:function(){e=1},next:function(t){var n=t.index,r=t.data;return n&&t.compare(r[n-1],r[n])?e=n+1:e}}},dense_rank:function(){var e;return{init:function(){e=1},next:function(t){var n=t.index,r=t.data;return n&&t.compare(r[n-1],r[n])?++e:e}}},percent_rank:function(){var e=Ua.rank(),t=e.next;return{init:e.init,next:function(e){return(t(e)-1)/(e.data.length-1)}}},cume_dist:function(){var e;return{init:function(){e=0},next:function(t){var n=t.index,r=t.data,i=t.compare;if(e0||Object(Ee.l)("ntile num must be greater than zero.");var n=Ua.cume_dist(),r=n.next;return{init:n.init,next:function(e){return Math.ceil(t*r(e))}}},lag:function(e,t){return t=+t||1,{next:function(n){var r=n.index-t;return r>=0?e(n.data[r]):null}}},lead:function(e,t){return t=+t||1,{next:function(n){var r=n.index+t,i=n.data;return r0||Object(Ee.l)("nth_value nth must be greater than zero."),{next:function(n){var r=n.i0+(t-1);return r0&&!i(a[n],a[n-1])&&(e.i0=t.left(a,a[n])),rthis.x2&&(this.x2=e),t>this.y2&&(this.y2=t),this},Do.expand=function(e){return this.x1-=e,this.y1-=e,this.x2+=e,this.y2+=e,this},Do.round=function(){return this.x1=Math.floor(this.x1),this.y1=Math.floor(this.y1),this.x2=Math.ceil(this.x2),this.y2=Math.ceil(this.y2),this},Do.translate=function(e,t){return this.x1+=e,this.x2+=e,this.y1+=t,this.y2+=t,this},Do.rotate=function(e,t,n){var r=Math.cos(e),i=Math.sin(e),a=t-t*r+n*i,o=n-t*i-n*r,s=this.x1,l=this.x2,c=this.y1,u=this.y2;return this.clear().add(r*s-i*c+a,i*s+r*c+o).add(r*s-i*u+a,i*s+r*u+o).add(r*l-i*c+a,i*l+r*c+o).add(r*l-i*u+a,i*l+r*u+o)},Do.union=function(e){return e.x1this.x2&&(this.x2=e.x2),e.y2>this.y2&&(this.y2=e.y2),this},Do.intersect=function(e){return e.x1>this.x1&&(this.x1=e.x1),e.y1>this.y1&&(this.y1=e.y1),e.x2=e.x2&&this.y1<=e.y1&&this.y2>=e.y2},Do.alignsWith=function(e){return e&&(this.x1==e.x1||this.x2==e.x2||this.y1==e.y1||this.y2==e.y2)},Do.intersects=function(e){return e&&!(this.x2e.x2||this.y2e.y2)},Do.contains=function(e,t){return!(ethis.x2||tthis.y2)},Do.width=function(){return this.x2-this.x1},Do.height=function(){return this.y2-this.y1};var Ao=0,ko=function(e,t){var n,r=[];return n={id:"gradient_"+Ao++,x1:e?e[0]:0,y1:e?e[1]:0,x2:t?t[0]:1,y2:t?t[1]:0,stops:r,stop:function(e,t){return r.push({offset:e,color:t}),n}}};function Ro(e){this.mark=e,this.bounds=this.bounds||new To}function Io(e){Ro.call(this,e),this.items=this.items||[]}function Lo(e,t){if("undefined"!=typeof document&&document.createElement){var n=document.createElement("canvas");if(n&&n.getContext)return n.width=e,n.height=t,n}return null}function Po(){return"undefined"!=typeof Image?Image:null}function Fo(e){this._pending=0,this._loader=e||Qe()}Object(Ee.t)(Io,Ro);var Bo=Fo.prototype;function Uo(e){e._pending+=1}function jo(e){e._pending-=1}Bo.pending=function(){return this._pending},Bo.sanitizeURL=function(e){var t=this;return Uo(t),t._loader.sanitize(e,{context:"href"}).then(function(e){return jo(t),e}).catch(function(){return jo(t),null})},Bo.loadImage=function(e){var t=this,n=Po();return Uo(t),t._loader.sanitize(e,{context:"image"}).then(function(e){var r=e.href;if(!r||!n)throw{url:r};var i=new n;return i.onload=function(){jo(t),i.loaded=!0},i.onerror=function(){jo(t),i.loaded=!1},i.src=r,i}).catch(function(e){return jo(t),{loaded:!1,width:0,height:0,src:e&&e.url||""}})},Bo.ready=function(){var e=this;return new Promise(function(t){!function n(r){e.pending()?setTimeout(function(){n(!0)},10):t(r)}(!1)})};var zo=Math.PI,qo=2*zo,Go=qo-1e-6;function $o(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function Ho(){return new $o}$o.prototype=Ho.prototype={constructor:$o,moveTo:function(e,t){this._+="M"+(this._x0=this._x1=+e)+","+(this._y0=this._y1=+t)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(e,t){this._+="L"+(this._x1=+e)+","+(this._y1=+t)},quadraticCurveTo:function(e,t,n,r){this._+="Q"+ +e+","+ +t+","+(this._x1=+n)+","+(this._y1=+r)},bezierCurveTo:function(e,t,n,r,i,a){this._+="C"+ +e+","+ +t+","+ +n+","+ +r+","+(this._x1=+i)+","+(this._y1=+a)},arcTo:function(e,t,n,r,i){e=+e,t=+t,n=+n,r=+r,i=+i;var a=this._x1,o=this._y1,s=n-e,l=r-t,c=a-e,u=o-t,d=c*c+u*u;if(i<0)throw new Error("negative radius: "+i);if(null===this._x1)this._+="M"+(this._x1=e)+","+(this._y1=t);else if(d>1e-6)if(Math.abs(u*s-l*c)>1e-6&&i){var f=n-a,p=r-o,m=s*s+l*l,g=f*f+p*p,h=Math.sqrt(m),b=Math.sqrt(d),v=i*Math.tan((zo-Math.acos((m+d-g)/(2*h*b)))/2),_=v/b,y=v/h;Math.abs(_-1)>1e-6&&(this._+="L"+(e+_*c)+","+(t+_*u)),this._+="A"+i+","+i+",0,0,"+ +(u*f>c*p)+","+(this._x1=e+y*s)+","+(this._y1=t+y*l)}else this._+="L"+(this._x1=e)+","+(this._y1=t);else;},arc:function(e,t,n,r,i,a){e=+e,t=+t;var o=(n=+n)*Math.cos(r),s=n*Math.sin(r),l=e+o,c=t+s,u=1^a,d=a?r-i:i-r;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+l+","+c:(Math.abs(this._x1-l)>1e-6||Math.abs(this._y1-c)>1e-6)&&(this._+="L"+l+","+c),n&&(d<0&&(d=d%qo+qo),d>Go?this._+="A"+n+","+n+",0,1,"+u+","+(e-o)+","+(t-s)+"A"+n+","+n+",0,1,"+u+","+(this._x1=l)+","+(this._y1=c):d>1e-6&&(this._+="A"+n+","+n+",0,"+ +(d>=zo)+","+u+","+(this._x1=e+n*Math.cos(i))+","+(this._y1=t+n*Math.sin(i))))},rect:function(e,t,n,r){this._+="M"+(this._x0=this._x1=+e)+","+(this._y0=this._y1=+t)+"h"+ +n+"v"+ +r+"h"+-n+"Z"},toString:function(){return this._}};var Wo=Ho,Vo=function(e){return function(){return e}},Ko=Math.abs,Qo=Math.atan2,Yo=Math.cos,Zo=Math.max,Xo=Math.min,Jo=Math.sin,es=Math.sqrt,ts=1e-12,ns=Math.PI,rs=ns/2,is=2*ns;function as(e){return e>=1?rs:e<=-1?-rs:Math.asin(e)}function os(e){return e.innerRadius}function ss(e){return e.outerRadius}function ls(e){return e.startAngle}function cs(e){return e.endAngle}function us(e){return e&&e.padAngle}function ds(e,t,n,r,i,a,o){var s=e-n,l=t-r,c=(o?a:-a)/es(s*s+l*l),u=c*l,d=-c*s,f=e+u,p=t+d,m=n+u,g=r+d,h=(f+m)/2,b=(p+g)/2,v=m-f,_=g-p,y=v*v+_*_,x=i-a,E=f*g-m*p,S=(_<0?-1:1)*es(Zo(0,x*x*y-E*E)),w=(E*_-v*S)/y,C=(-E*v-_*S)/y,O=(E*_+v*S)/y,M=(-E*v+_*S)/y,N=w-h,T=C-b,D=O-h,A=M-b;return N*N+T*T>D*D+A*A&&(w=O,C=M),{cx:w,cy:C,x01:-u,y01:-d,x11:w*(i/x-1),y11:C*(i/x-1)}}function fs(e){this._context=e}fs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:this._context.lineTo(e,t)}}};var ps=function(e){return new fs(e)};function ms(e){return e[0]}function gs(e){return e[1]}var hs=function(){var e=ms,t=gs,n=Vo(!0),r=null,i=ps,a=null;function o(o){var s,l,c,u=o.length,d=!1;for(null==r&&(a=i(c=Wo())),s=0;s<=u;++s)!(s=u;--d)s.point(h[d],b[d]);s.lineEnd(),s.areaEnd()}g&&(h[c]=+e(f,c,l),b[c]=+n(f,c,l),s.point(t?+t(f,c,l):h[c],r?+r(f,c,l):b[c]))}if(p)return s=null,p+""||null}function c(){return hs().defined(i).curve(o).context(a)}return l.x=function(n){return arguments.length?(e="function"==typeof n?n:Vo(+n),t=null,l):e},l.x0=function(t){return arguments.length?(e="function"==typeof t?t:Vo(+t),l):e},l.x1=function(e){return arguments.length?(t=null==e?null:"function"==typeof e?e:Vo(+e),l):t},l.y=function(e){return arguments.length?(n="function"==typeof e?e:Vo(+e),r=null,l):n},l.y0=function(e){return arguments.length?(n="function"==typeof e?e:Vo(+e),l):n},l.y1=function(e){return arguments.length?(r=null==e?null:"function"==typeof e?e:Vo(+e),l):r},l.lineX0=l.lineY0=function(){return c().x(e).y(n)},l.lineY1=function(){return c().x(e).y(r)},l.lineX1=function(){return c().x(t).y(n)},l.defined=function(e){return arguments.length?(i="function"==typeof e?e:Vo(!!e),l):i},l.curve=function(e){return arguments.length?(o=e,null!=a&&(s=o(a)),l):o},l.context=function(e){return arguments.length?(null==e?a=s=null:s=o(a=e),l):a},l};_s(ps);function vs(e){this._curve=e}function _s(e){function t(t){return new vs(e(t))}return t._curve=e,t}vs.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(e,t){this._curve.point(t*Math.sin(e),t*-Math.cos(e))}};Array.prototype.slice;var ys={draw:function(e,t){var n=Math.sqrt(t/ns);e.moveTo(n,0),e.arc(0,0,n,0,is)}},xs=(Math.sqrt(1/3),Math.sin(ns/10)/Math.sin(7*ns/10)),Es=(Math.sin(is/10),Math.cos(is/10),Math.sqrt(3),Math.sqrt(3),Math.sqrt(12),function(){});function Ss(e,t,n){e._context.bezierCurveTo((2*e._x0+e._x1)/3,(2*e._y0+e._y1)/3,(e._x0+2*e._x1)/3,(e._y0+2*e._y1)/3,(e._x0+4*e._x1+t)/6,(e._y0+4*e._y1+n)/6)}function ws(e){this._context=e}ws.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Ss(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Ss(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function Cs(e){this._context=e}Cs.prototype={areaStart:Es,areaEnd:Es,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x2=e,this._y2=t;break;case 1:this._point=2,this._x3=e,this._y3=t;break;case 2:this._point=3,this._x4=e,this._y4=t,this._context.moveTo((this._x0+4*this._x1+e)/6,(this._y0+4*this._y1+t)/6);break;default:Ss(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function Os(e){this._context=e}Os.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+e)/6,r=(this._y0+4*this._y1+t)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:Ss(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function Ms(e,t){this._basis=new ws(e),this._beta=t}Ms.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var e=this._x,t=this._y,n=e.length-1;if(n>0)for(var r,i=e[0],a=t[0],o=e[n]-i,s=t[n]-a,l=-1;++l<=n;)r=l/n,this._basis.point(this._beta*e[l]+(1-this._beta)*(i+r*o),this._beta*t[l]+(1-this._beta)*(a+r*s));this._x=this._y=null,this._basis.lineEnd()},point:function(e,t){this._x.push(+e),this._y.push(+t)}};var Ns=function e(t){function n(e){return 1===t?new ws(e):new Ms(e,t)}return n.beta=function(t){return e(+t)},n}(.85);function Ts(e,t,n){e._context.bezierCurveTo(e._x1+e._k*(e._x2-e._x0),e._y1+e._k*(e._y2-e._y0),e._x2+e._k*(e._x1-t),e._y2+e._k*(e._y1-n),e._x2,e._y2)}function Ds(e,t){this._context=e,this._k=(1-t)/6}Ds.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Ts(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2,this._x1=e,this._y1=t;break;case 2:this._point=3;default:Ts(this,e,t)}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var As=function e(t){function n(e){return new Ds(e,t)}return n.tension=function(t){return e(+t)},n}(0);function ks(e,t){this._context=e,this._k=(1-t)/6}ks.prototype={areaStart:Es,areaEnd:Es,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x3=e,this._y3=t;break;case 1:this._point=2,this._context.moveTo(this._x4=e,this._y4=t);break;case 2:this._point=3,this._x5=e,this._y5=t;break;default:Ts(this,e,t)}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var Rs=function e(t){function n(e){return new ks(e,t)}return n.tension=function(t){return e(+t)},n}(0);function Is(e,t){this._context=e,this._k=(1-t)/6}Is.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ts(this,e,t)}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var Ls=function e(t){function n(e){return new Is(e,t)}return n.tension=function(t){return e(+t)},n}(0);function Ps(e,t,n){var r=e._x1,i=e._y1,a=e._x2,o=e._y2;if(e._l01_a>ts){var s=2*e._l01_2a+3*e._l01_a*e._l12_a+e._l12_2a,l=3*e._l01_a*(e._l01_a+e._l12_a);r=(r*s-e._x0*e._l12_2a+e._x2*e._l01_2a)/l,i=(i*s-e._y0*e._l12_2a+e._y2*e._l01_2a)/l}if(e._l23_a>ts){var c=2*e._l23_2a+3*e._l23_a*e._l12_a+e._l12_2a,u=3*e._l23_a*(e._l23_a+e._l12_a);a=(a*c+e._x1*e._l23_2a-t*e._l12_2a)/u,o=(o*c+e._y1*e._l23_2a-n*e._l12_2a)/u}e._context.bezierCurveTo(r,i,a,o,e._x2,e._y2)}function Fs(e,t){this._context=e,this._alpha=t}Fs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3;default:Ps(this,e,t)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var Bs=function e(t){function n(e){return t?new Fs(e,t):new Ds(e,0)}return n.alpha=function(t){return e(+t)},n}(.5);function Us(e,t){this._context=e,this._alpha=t}Us.prototype={areaStart:Es,areaEnd:Es,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=e,this._y3=t;break;case 1:this._point=2,this._context.moveTo(this._x4=e,this._y4=t);break;case 2:this._point=3,this._x5=e,this._y5=t;break;default:Ps(this,e,t)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var js=function e(t){function n(e){return t?new Us(e,t):new ks(e,0)}return n.alpha=function(t){return e(+t)},n}(.5);function zs(e,t){this._context=e,this._alpha=t}zs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ps(this,e,t)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var qs=function e(t){function n(e){return t?new zs(e,t):new Is(e,0)}return n.alpha=function(t){return e(+t)},n}(.5);function Gs(e){this._context=e}Gs.prototype={areaStart:Es,areaEnd:Es,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(e,t){e=+e,t=+t,this._point?this._context.lineTo(e,t):(this._point=1,this._context.moveTo(e,t))}};function $s(e){return e<0?-1:1}function Hs(e,t,n){var r=e._x1-e._x0,i=t-e._x1,a=(e._y1-e._y0)/(r||i<0&&-0),o=(n-e._y1)/(i||r<0&&-0),s=(a*i+o*r)/(r+i);return($s(a)+$s(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(s))||0}function Ws(e,t){var n=e._x1-e._x0;return n?(3*(e._y1-e._y0)/n-t)/2:t}function Vs(e,t,n){var r=e._x0,i=e._y0,a=e._x1,o=e._y1,s=(a-r)/3;e._context.bezierCurveTo(r+s,i+s*t,a-s,o-s*n,a,o)}function Ks(e){this._context=e}function Qs(e){this._context=new Ys(e)}function Ys(e){this._context=e}function Zs(e){this._context=e}function Xs(e){var t,n,r=e.length-1,i=new Array(r),a=new Array(r),o=new Array(r);for(i[0]=0,a[0]=2,o[0]=e[0]+2*e[1],t=1;t=0;--t)i[t]=(o[t]-i[t+1])/a[t];for(a[r-1]=(e[r]+i[r-1])/2,t=0;t=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,t),this._context.lineTo(e,t);else{var n=this._x*(1-this._t)+e*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,t)}}this._x=e,this._y=t}};var el={basis:{curve:function(e){return new ws(e)}},"basis-closed":{curve:function(e){return new Cs(e)}},"basis-open":{curve:function(e){return new Os(e)}},bundle:{curve:Ns,tension:"beta",value:.85},cardinal:{curve:As,tension:"tension",value:0},"cardinal-open":{curve:Ls,tension:"tension",value:0},"cardinal-closed":{curve:Rs,tension:"tension",value:0},"catmull-rom":{curve:Bs,tension:"alpha",value:.5},"catmull-rom-closed":{curve:js,tension:"alpha",value:.5},"catmull-rom-open":{curve:qs,tension:"alpha",value:.5},linear:{curve:ps},"linear-closed":{curve:function(e){return new Gs(e)}},monotone:{horizontal:function(e){return new Qs(e)},vertical:function(e){return new Ks(e)}},natural:{curve:function(e){return new Zs(e)}},step:{curve:function(e){return new Js(e,.5)}},"step-after":{curve:function(e){return new Js(e,1)}},"step-before":{curve:function(e){return new Js(e,0)}}};function tl(e,t,n){var r=el.hasOwnProperty(e)&&el[e],i=null;return r&&(i=r.curve||r[t||"vertical"],r.tension&&null!=n&&(i=i[r.tension](n))),i}var nl={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7},rl=[/([MLHVCSQTAZmlhvcsqtaz])/g,/###/,/(\d)([-+])/g,/\s|,|###/],il=function(e){var t,n,r,i,a,o,s,l,c,u,d,f=[];for(l=0,u=(t=e.slice().replace(rl[0],"###$1").split(rl[1]).slice(1)).length;ls)for(c=1,d=i.length;c1&&(n*=g=Math.sqrt(g),r*=g);var h=f/n,b=d/n,v=-d/r,_=f/r,y=h*s+b*l,x=v*s+_*l,E=h*e+b*t,S=v*e+_*t,w=1/((E-y)*(E-y)+(S-x)*(S-x))-.25;w<0&&(w=0);var C=Math.sqrt(w);a==i&&(C=-C);var O=.5*(y+E)-C*(S-x),M=.5*(x+S)+C*(E-y),N=Math.atan2(x-M,y-O),T=Math.atan2(S-M,E-O)-N;T<0&&1===a?T+=2*Math.PI:T>0&&0===a&&(T-=2*Math.PI);for(var D=Math.ceil(Math.abs(T/(.5*Math.PI+.001))),A=[],k=0;kp;if(s||(s=l=Wo()),fts)if(g>is-ts)s.moveTo(f*Yo(p),f*Jo(p)),s.arc(0,0,f,p,m,!h),d>ts&&(s.moveTo(d*Yo(m),d*Jo(m)),s.arc(0,0,d,m,p,h));else{var b,v,_=p,y=m,x=p,E=m,S=g,w=g,C=o.apply(this,arguments)/2,O=C>ts&&(r?+r.apply(this,arguments):es(d*d+f*f)),M=Xo(Ko(f-d)/2,+n.apply(this,arguments)),N=M,T=M;if(O>ts){var D=as(O/d*Jo(C)),A=as(O/f*Jo(C));(S-=2*D)>ts?(x+=D*=h?1:-1,E-=D):(S=0,x=E=(p+m)/2),(w-=2*A)>ts?(_+=A*=h?1:-1,y-=A):(w=0,_=y=(p+m)/2)}var k=f*Yo(_),R=f*Jo(_),I=d*Yo(E),L=d*Jo(E);if(M>ts){var P=f*Yo(y),F=f*Jo(y),B=d*Yo(x),U=d*Jo(x);if(gts?function(e,t,n,r,i,a,o,s){var l=n-e,c=r-t,u=o-i,d=s-a,f=(u*(t-a)-d*(e-i))/(d*l-u*c);return[e+f*l,t+f*c]}(k,R,B,U,P,F,I,L):[I,L],z=k-j[0],q=R-j[1],G=P-j[0],$=F-j[1],H=1/Jo(((u=(z*G+q*$)/(es(z*z+q*q)*es(G*G+$*$)))>1?0:u<-1?ns:Math.acos(u))/2),W=es(j[0]*j[0]+j[1]*j[1]);N=Xo(M,(d-W)/(H-1)),T=Xo(M,(f-W)/(H+1))}}w>ts?T>ts?(b=ds(B,U,k,R,f,T,h),v=ds(P,F,I,L,f,T,h),s.moveTo(b.cx+b.x01,b.cy+b.y01),Tts&&S>ts?N>ts?(b=ds(I,L,P,F,d,-N,h),v=ds(k,R,B,U,d,-N,h),s.lineTo(b.cx+b.x01,b.cy+b.y01),Njl)return Gl(e-n,t-n),void Gl(e+n,t+n);var o,s,l,c,u=1/0,d=-1/0,f=1/0,p=-1/0;function m(e){l=n*Math.cos(e),c=n*Math.sin(e),ld&&(d=l),cp&&(p=c)}if(m(r),m(i),i!==r)if((r%=Bl)<0&&(r+=Bl),(i%=Bl)<0&&(i+=Bl),ii;++s,o-=Ul)m(o);else for(o=r-r%Ul+Ul,s=0;s<4&&o0&&(e.globalAlpha=n,e.fillStyle=$l(e,t,t.fill),!0)},Wl=[],Vl=function(e,t,n){var r=null!=(r=t.strokeWidth)?r:1;return!(r<=0)&&((n*=null==t.strokeOpacity?1:t.strokeOpacity)>0&&(e.globalAlpha=n,e.strokeStyle=$l(e,t,t.stroke),e.lineWidth=r,e.lineCap=t.strokeCap||"butt",e.lineJoin=t.strokeJoin||"miter",e.miterLimit=t.strokeMiterLimit||10,e.setLineDash&&(e.setLineDash(t.strokeDash||Wl),e.lineDashOffset=t.strokeDashOffset||0),!0))};function Kl(e,t){return e.zindex-t.zindex||e.index-t.index}function Ql(e){if(!e.zdirty)return e.zitems;var t,n,r,i=e.items,a=[];for(n=0,r=i.length;n=0;)if(n=t(i[r]))return n;if(i===a)for(r=(i=e.items).length;--r>=0;)if(!i[r].zindex&&(n=t(i[r])))return n;return null}function Xl(e){return function(t,n,r){Yl(n,function(n){r&&!r.intersects(n.bounds)||Jl(e,t,n,n)})}}function Jl(e,t,n,r){var i=null==n.opacity?1:n.opacity;0!==i&&(e(t,r)||(n.fill&&Hl(t,n,i)&&t.fill(),n.stroke&&Vl(t,n,i)&&t.stroke()))}var ec=function(){return!0};function tc(e){return e||(e=ec),function(t,n,r,i,a,o){return r*=t.pixelRatio,i*=t.pixelRatio,Zl(n,function(n){var s=n.bounds;if((!s||s.contains(a,o))&&s)return e(t,n,r,i,a,o)?n:void 0})}}function nc(e,t){return function(n,r,i,a){var o,s,l=Array.isArray(r)?r[0]:r,c=null==t?l.fill:t,u=l.stroke&&n.isPointInStroke;return u&&(o=l.strokeWidth,s=l.strokeCap,n.lineWidth=null!=o?o:1,n.lineCap=null!=s?s:"butt"),!e(n,r)&&(c&&n.isPointInPath(i,a)||u&&n.isPointInStroke(i,a))}}function rc(e){return tc(nc(e))}var ic=function(e,t){return"translate("+e+","+t+")"},ac=function(e){return ic(e.x||0,e.y||0)},oc=function(e,t){function n(e,n){var r=n.x||0,i=n.y||0;e.translate(r,i),e.beginPath(),t(e,n),e.translate(-r,-i)}return{type:e,tag:"path",nested:!1,attr:function(e,n){e("transform",ac(n)),e("d",t(null,n))},bound:function(e,n){return t(zl(e),n),Fl(e,n).translate(n.x||0,n.y||0)},draw:Xl(n),pick:rc(n)}},sc=oc("arc",function(e,t){return Nl.context(e)(t)});var lc=function(e,t,n){function r(e,n){e.beginPath(),t(e,n)}var i,a=nc(r);return{type:e,tag:"path",nested:!0,attr:function(e,n){var r=n.mark.items;r.length&&e("d",t(null,r))},bound:function(e,n){var r=n.items;return 0===r.length?e:(t(zl(e),r),Fl(e,r[0]))},draw:(i=r,function(e,t,n){!t.items.length||n&&!n.intersects(t.bounds)||Jl(i,e,t.items[0],t.items)}),pick:function(e,t,n,r,i,o){var s=t.items,l=t.bounds;return!s||!s.length||l&&!l.contains(i,o)?null:(n*=e.pixelRatio,r*=e.pixelRatio,a(e,s,n,r)?s[0]:null)},tip:n}},cc=lc("area",function(e,t){var n=t[0],r=n.interpolate||"linear";return("horizontal"===n.orient?Dl:Tl).curve(tl(r,n.orient,n.tension)).context(e)(t)},function(e,t){var n="horizontal"===e[0].orient?t[1]:t[0],r="horizontal"===e[0].orient?"y":"x",i=0,a=e.length;if(1===a)return e[0];for(;i>>1;e[o][r]0&&(pc(e,t),t.fill&&Hl(e,t,i)&&e.fill(),t.stroke&&Vl(e,t,i)&&e.stroke()),t.clip&&(e.beginPath(),e.rect(0,0,s,l),e.clip()),n&&n.translate(-a,-o),Yl(t,function(t){r.draw(e,t,n)}),n&&n.translate(a,o),e.restore()})},pick:function(e,t,n,r,i,a){if(t.bounds&&!t.bounds.contains(i,a)||!t.items)return null;var o=this,s=n*e.pixelRatio,l=r*e.pixelRatio;return Zl(t,function(c){var u,d,f,p;if(!(p=c.bounds)||p.contains(i,a))return d=c.x||0,f=c.y||0,e.save(),e.translate(d,f),d=i-d,f=a-f,!(u=Zl(c,function(e){return function(e,t,n){return(!1!==e.interactive||"group"===e.marktype)&&e.bounds&&e.bounds.contains(t,n)}(e,d,f)?o.pick(e,n,r,d,f):null}))&&!1!==t.interactive&&(c.fill||c.stroke)&&mc(e,c,s,l)&&(u=c),e.restore(),u||null})},background:function(e,t){var n=t.stroke?fc:0;e("class","background"),e("d",Ll(null,t,n,n))},foreground:function(e,t,n){e("clip-path",t.clip?dc(n,t,t):null)}};function hc(e,t){var n=e.image;return n&&n.url===e.url||(n={loaded:!1,width:0,height:0},t.loadImage(e.url).then(function(t){e.image=t,e.image.url=e.url})),n}function bc(e,t){return"center"===e?t/2:"right"===e?t:0}function vc(e,t){return"middle"===e?t/2:"bottom"===e?t:0}var _c={type:"image",tag:"image",nested:!1,attr:function(e,t,n){var r=hc(t,n),i=t.x||0,a=t.y||0,o=(null!=t.width?t.width:r.width)||0,s=(null!=t.height?t.height:r.height)||0,l=!1===t.aspect?"none":"xMidYMid";i-=bc(t.align,o),a-=vc(t.baseline,s),e("href",r.src||"","http://www.w3.org/1999/xlink","xlink:href"),e("transform",ic(i,a)),e("width",o),e("height",s),e("preserveAspectRatio",l)},bound:function(e,t){var n=t.image,r=t.x||0,i=t.y||0,a=(null!=t.width?t.width:n&&n.width)||0,o=(null!=t.height?t.height:n&&n.height)||0;return r-=bc(t.align,a),i-=vc(t.baseline,o),e.set(r,i,r+a,i+o)},draw:function(e,t,n){var r=this;Yl(t,function(t){if(!n||n.intersects(t.bounds)){var i,a,o,s,l=hc(t,r),c=t.x||0,u=t.y||0,d=(null!=t.width?t.width:l.width)||0,f=(null!=t.height?t.height:l.height)||0;c-=bc(t.align,d),u-=vc(t.baseline,f),!1!==t.aspect&&(a=l.width/l.height,o=t.width/t.height,a==a&&o==o&&a!==o&&(o=0;)if(!1!==e[a].defined&&(n=e[a].x-t[0])*n+(r=e[a].y-t[1])*r0?function(e){var t,n=+e.limit,r=e.text+"";Oc?(Oc.font=jc(e),t=Lc):(Mc=Pc(e),t=Rc);if(t(r)>>1,t(r.slice(i))>n?s=i+1:l=i;return a+r.slice(s)}for(;s>>1),t(r.slice(0,i))=0;)if(!1!==e[i].defined&&(n=e[i].x-t[0])*n+(r=e[i].y-t[1])*r<(n=e[i].size||1)*n)return e[i];return null})},Wc=function(e,t,n){var r=Hc[e.mark.marktype],i=t||r.bound;return r.nested&&(e=e.mark),i(e.bounds||(e.bounds=new To),e,n)},Vc={mark:null},Kc=function(e,t,n){var r,i,a,o,s=Hc[e.marktype],l=s.bound,c=e.items,u=c&&c.length;if(s.nested)return u?a=c[0]:(Vc.mark=e,a=Vc),o=Wc(a,l,n),t=t&&t.union(o)||o;if(t=t||e.bounds&&e.bounds.clear()||new To,u)for(r=0,i=c.length;rt;)e.removeChild(n[--r]);return e}function iu(e){return"mark-"+e.marktype+(e.role?" role-"+e.role:"")+(e.name?" "+e.name:"")}Xc.toJSON=function(e){return function(e,t){return JSON.stringify(e,Qc,t)}(this.root,e||0)},Xc.mark=function(e,t,n){var r=Jc(e,t=t||this.root.items[0]);return t.items[n]=r,r.zindex&&(r.group.zdirty=!0),r};var au=function(e,t){var n=t.getBoundingClientRect();return[e.clientX-n.left-(t.clientLeft||0),e.clientY-n.top-(t.clientTop||0)]};function ou(e,t){this._active=null,this._handlers={},this._loader=e||Qe(),this._tooltip=t||su}function su(e,t,n,r){e.element().setAttribute("title",r||"")}var lu=ou.prototype;function cu(e){this._el=null,this._bgcolor=null,this._loader=new Fo(e)}lu.initialize=function(e,t,n){return this._el=e,this._obj=n||null,this.origin(t)},lu.element=function(){return this._el},lu.canvas=function(){return this._el&&this._el.firstChild},lu.origin=function(e){return arguments.length?(this._origin=e||[0,0],this):this._origin.slice()},lu.scene=function(e){return arguments.length?(this._scene=e,this):this._scene},lu.on=function(){},lu.off=function(){},lu._handlerIndex=function(e,t,n){for(var r=e?e.length:0;--r>=0;)if(e[r].type===t&&(!n||e[r].handler===n))return r;return-1},lu.handlers=function(e){var t,n=this._handlers,r=[];if(e)r.push.apply(r,n[this.eventName(e)]);else for(t in n)r.push.apply(r,n[t]);return r},lu.eventName=function(e){var t=e.indexOf(".");return t<0?e:e.slice(0,t)},lu.handleHref=function(e,t,n){this._loader.sanitize(n,{context:"href"}).then(function(t){var n=new MouseEvent(e.type,e),r=eu(null,"a");for(var i in t)r.setAttribute(i,t[i]);r.dispatchEvent(n)}).catch(function(){})},lu.handleTooltip=function(e,t,n){if(t&&null!=t.tooltip){t=function(e,t,n,r){var i,a,o=e&&e.mark;if(o&&(i=Hc[o.marktype]).tip){for((a=au(t,n))[0]-=r[0],a[1]-=r[1];e=e.mark.group;)a[0]-=e.x||0,a[1]-=e.y||0;e=i.tip(o.items,a)}return e}(t,e,this.canvas(),this._origin);var r=n&&t&&t.tooltip||null;this._tooltip.call(this._obj,this,e,t,r)}},lu.getItemBoundingClientRect=function(e){if(t=this.canvas()){for(var t,n=t.getBoundingClientRect(),r=this._origin,i=e.bounds,a=i.x1+r[0]+n.left,o=i.y1+r[1]+n.top,s=i.width(),l=i.height();e.mark&&(e=e.mark.group);)a+=e.x||0,o+=e.y||0;return{x:a,y:o,width:s,height:l,left:a,top:o,right:a+s,bottom:o+l}}};var uu=cu.prototype;uu.initialize=function(e,t,n,r,i){return this._el=e,this.resize(t,n,r,i)},uu.element=function(){return this._el},uu.canvas=function(){return this._el&&this._el.firstChild},uu.background=function(e){return 0===arguments.length?this._bgcolor:(this._bgcolor=e,this)},uu.resize=function(e,t,n,r){return this._width=e,this._height=t,this._origin=n||[0,0],this._scale=r||1,this},uu.dirty=function(){},uu.render=function(e){var t=this;return t._call=function(){t._render(e)},t._call(),t._call=null,t},uu._render=function(){},uu.renderAsync=function(e){var t=this.render(e);return this._ready?this._ready.then(function(){return t}):Promise.resolve(t)},uu._load=function(e,t){var n=this,r=n._loader[e](t);if(!n._ready){var i=n._call;n._ready=n._loader.ready().then(function(e){e&&i(),n._ready=null})}return r},uu.sanitizeURL=function(e){return this._load("sanitizeURL",e)},uu.loadImage=function(e){return this._load("loadImage",e)};var du="mouseout";function fu(e,t){ou.call(this,e,t),this._down=null,this._touch=null,this._first=!0}var pu=Object(Ee.t)(fu,ou);function mu(e,t,n){return function(r){var i=this._active,a=this.pickEvent(r);a===i?this.fire(e,r):(i&&i.exit||this.fire(n,r),this._active=a,this.fire(t,r),this.fire(e,r))}}function gu(e){return function(t){this.fire(e,t),this._active=null}}pu.initialize=function(e,t,n){var r=this._canvas=e&&tu(e,"canvas");if(r){var i=this;this.events.forEach(function(e){r.addEventListener(e,function(t){pu[e]?pu[e].call(i,t):i.fire(e,t)})})}return ou.prototype.initialize.call(this,e,t,n)},pu.canvas=function(){return this._canvas},pu.context=function(){return this._canvas.getContext("2d")},pu.events=["keydown","keypress","keyup","dragenter","dragleave","dragover","mousedown","mouseup","mousemove","mouseout","mouseover","click","dblclick","wheel","mousewheel","touchstart","touchmove","touchend"],pu.DOMMouseScroll=function(e){this.fire("mousewheel",e)},pu.mousemove=mu("mousemove","mouseover","mouseout"),pu.dragover=mu("dragover","dragenter","dragleave"),pu.mouseout=gu("mouseout"),pu.dragleave=gu("dragleave"),pu.mousedown=function(e){this._down=this._active,this.fire("mousedown",e)},pu.click=function(e){this._down===this._active&&(this.fire("click",e),this._down=null)},pu.touchstart=function(e){this._touch=this.pickEvent(e.changedTouches[0]),this._first&&(this._active=this._touch,this._first=!1),this.fire("touchstart",e,!0)},pu.touchmove=function(e){this.fire("touchmove",e,!0)},pu.touchend=function(e){this.fire("touchend",e,!0),this._touch=null},pu.fire=function(e,t,n){var r,i,a=n?this._touch:this._active,o=this._handlers[e];if(t.vegaType=e,"click"===e&&a&&a.href?this.handleHref(t,a,a.href):"mousemove"!==e&&e!==du||this.handleTooltip(t,a,e!==du),o)for(r=0,i=o.length;r=0&&r.splice(i,1),this},pu.pickEvent=function(e){var t=au(e,this._canvas),n=this._origin;return this.pick(this._scene,t[0],t[1],t[0]-n[0],t[1]-n[1])},pu.pick=function(e,t,n,r,i){var a=this.context();return Hc[e.marktype].pick.call(this,a,e,t,n,r,i)};var hu="undefined"!=typeof window&&window.devicePixelRatio||1;function bu(e){cu.call(this,e),this._redraw=!1,this._dirty=new To}var vu=Object(Ee.t)(bu,cu),_u=cu.prototype,yu=new To;function xu(e,t){ou.call(this,e,t);var n=this;n._hrefHandler=Su(n,function(e,t){t&&t.href&&n.handleHref(e,t,t.href)}),n._tooltipHandler=Su(n,function(e,t){n.handleTooltip(e,t,e.type!==du)})}vu.initialize=function(e,t,n,r,i){return this._canvas=Lo(1,1),e&&(ru(e,0).appendChild(this._canvas),this._canvas.setAttribute("class","marks")),_u.initialize.call(this,e,t,n,r,i)},vu.resize=function(e,t,n,r){return _u.resize.call(this,e,t,n,r),function(e,t,n,r,i){var a="undefined"!=typeof HTMLElement&&e instanceof HTMLElement&&null!=e.parentNode,o=e.getContext("2d"),s=a?hu:i;e.width=t*s,e.height=n*s,a&&1!==s&&(e.style.width=t+"px",e.style.height=n+"px"),o.pixelRatio=s,o.setTransform(s,0,0,s,s*r[0],s*r[1])}(this._canvas,this._width,this._height,this._origin,this._scale),this._redraw=!0,this},vu.canvas=function(){return this._canvas},vu.context=function(){return this._canvas?this._canvas.getContext("2d"):null},vu.dirty=function(e){var t=function(e,t){if(null==t)return e;for(var n=yu.clear().union(e);null!=t;t=t.mark.group)n.translate(t.x||0,t.y||0);return n}(e.bounds,e.mark.group);this._dirty.union(t)},vu._render=function(e){var t=this.context(),n=this._origin,r=this._width,i=this._height,a=this._dirty;return t.save(),this._redraw||a.empty()?(this._redraw=!1,a=null):a=function(e,t,n){return t.expand(1).round(),t.translate(-n[0]%1,-n[1]%1),e.beginPath(),e.rect(t.x1,t.y1,t.width(),t.height()),e.clip(),t}(t,a,n),this.clear(-n[0],-n[1],r,i),this.draw(t,e,a),t.restore(),this._dirty.clear(),this},vu.draw=function(e,t,n){var r=Hc[t.marktype];t.clip&&function(e,t){var n=t.clip;if(e.save(),e.beginPath(),Object(Ee.x)(n))n(e);else{var r=t.group;e.rect(0,0,r.width||0,r.height||0)}e.clip()}(e,t),r.draw.call(this,e,t,n),t.clip&&e.restore()},vu.clear=function(e,t,n,r){var i=this.context();i.clearRect(e,t,n,r),null!=this._bgcolor&&(i.fillStyle=this._bgcolor,i.fillRect(e,t,n,r))};var Eu=Object(Ee.t)(xu,ou);function Su(e,t){return function(n){var r=n.target.__data__;n.vegaType=n.type,r=Array.isArray(r)?r[0]:r,t.call(e._obj,n,r)}}function wu(e,t,n){var r,i,a="<"+e;if(t)for(r in t)null!=(i=t[r])&&(a+=" "+r+'="'+i+'"');return n&&(a+=" "+n),a+">"}function Cu(e){return""}Eu.initialize=function(e,t,n){var r=this._svg;return r&&(r.removeEventListener("click",this._hrefHandler),r.removeEventListener("mousemove",this._tooltipHandler),r.removeEventListener(du,this._tooltipHandler)),this._svg=r=e&&tu(e,"svg"),r&&(r.addEventListener("click",this._hrefHandler),r.addEventListener("mousemove",this._tooltipHandler),r.addEventListener(du,this._tooltipHandler)),ou.prototype.initialize.call(this,e,t,n)},Eu.canvas=function(){return this._svg},Eu.on=function(e,t){var n=this.eventName(e),r=this._handlers;if(this._handlerIndex(r[n],e,t)<0){var i={type:e,handler:t,listener:Su(this,t)};(r[n]||(r[n]=[])).push(i),this._svg&&this._svg.addEventListener(n,i.listener)}return this},Eu.off=function(e,t){var n=this.eventName(e),r=this._handlers[n],i=this._handlerIndex(r,e,t);return i>=0&&(this._svg&&this._svg.removeEventListener(n,r[i].listener),r.splice(i,1)),this};var Ou={version:"1.1",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"},Mu={fill:"fill",fillOpacity:"fill-opacity",stroke:"stroke",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",strokeCap:"stroke-linecap",strokeJoin:"stroke-linejoin",strokeDash:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeMiterLimit:"stroke-miterlimit",opacity:"opacity"},Nu=Object.keys(Mu),Tu=Ou.xmlns;function Du(e){cu.call(this,e),this._dirtyID=1,this._dirty=[],this._svg=null,this._root=null,this._defs=null}var Au=Object(Ee.t)(Du,cu),ku=cu.prototype;function Ru(e,t,n){var r,i,a;for((e=nu(e,n,"linearGradient",Tu)).setAttribute("id",t.id),e.setAttribute("x1",t.x1),e.setAttribute("x2",t.x2),e.setAttribute("y1",t.y1),e.setAttribute("y2",t.y2),r=0,i=t.stops.length;r1}(e)&&o.previousSibling!==n)&&t.insertBefore(o,n?n.nextSibling:t.firstChild),o}Au.initialize=function(e,t,n,r){return e&&(this._svg=nu(e,0,"svg",Tu),this._svg.setAttribute("class","marks"),ru(e,1),this._root=nu(this._svg,0,"g",Tu),ru(this._svg,1)),this._defs={gradient:{},clipping:{}},this.background(this._bgcolor),ku.initialize.call(this,e,t,n,r)},Au.background=function(e){return arguments.length&&this._svg&&this._svg.style.setProperty("background-color",e),ku.background.apply(this,arguments)},Au.resize=function(e,t,n,r){return ku.resize.call(this,e,t,n,r),this._svg&&(this._svg.setAttribute("width",this._width*this._scale),this._svg.setAttribute("height",this._height*this._scale),this._svg.setAttribute("viewBox","0 0 "+this._width+" "+this._height),this._root.setAttribute("transform","translate("+this._origin+")")),this._dirty=[],this},Au.canvas=function(){return this._svg},Au.svg=function(){if(!this._svg)return null;var e={class:"marks",width:this._width*this._scale,height:this._height*this._scale,viewBox:"0 0 "+this._width+" "+this._height};for(var t in Ou)e[t]=Ou[t];var n=this._bgcolor?wu("rect",{width:this._width,height:this._height,style:"fill: "+this._bgcolor+";"})+Cu("rect"):"";return wu("svg",e)+n+this._svg.innerHTML+Cu("svg")},Au._render=function(e){return this._dirtyCheck()&&(this._dirtyAll&&this._resetDefs(),this.draw(this._root,e),ru(this._root,1)),this.updateDefs(),this._dirty=[],++this._dirtyID,this},Au.updateDefs=function(){var e,t=this._svg,n=this._defs,r=n.el,i=0;for(e in n.gradient)r||(n.el=r=nu(t,0,"defs",Tu)),Ru(r,n.gradient[e],i++);for(e in n.clipping)r||(n.el=r=nu(t,0,"defs",Tu)),Iu(r,n.clipping[e],i++);r&&(0===i?(t.removeChild(r),n.el=null):ru(r,i))},Au._resetDefs=function(){var e=this._defs;e.gradient={},e.clipping={}},Au.dirty=function(e){e.dirty!==this._dirtyID&&(e.dirty=this._dirtyID,this._dirty.push(e))},Au.isDirty=function(e){return this._dirtyAll||!e._svg||e.dirty===this._dirtyID},Au._dirtyCheck=function(){this._dirtyAll=!0;var e=this._dirty;if(!e.length)return!0;var t,n,r,i,a,o,s,l=++this._dirtyID;for(a=0,o=e.length;a0?wu("defs")+a+Cu("defs"):""},$u.attributes=function(e,t){return Gu={},e(Wu,t,this),Gu},$u.href=function(e){var t,n=this,r=e.href;if(r){if(t=n._hrefs&&n._hrefs[r])return t;n.sanitizeURL(r).then(function(e){e["xlink:href"]=e.href,e.href=null,(n._hrefs||(n._hrefs={}))[r]=e})}return null},$u.mark=function(e){var t,n=this,r=Hc[e.marktype],i=r.tag,a=this._defs,o="";function s(s){var l=n.href(s);l&&(o+=wu("a",l)),t="g"!==i?Vu(s,e,i,a):null,o+=wu(i,n.attributes(r.attr,s),t),"text"===i?o+=Bc(s).replace(/&/g,"&").replace(//g,">"):"g"===i&&(o+=wu("path",n.attributes(r.background,s),Vu(s,e,"bgrect",a))+Cu("path"),o+=wu("g",n.attributes(r.foreground,s))+n.markGroup(s)+Cu("g")),o+=Cu(i),l&&(o+=Cu("a"))}return"g"!==i&&!1===e.interactive&&(t='style="pointer-events: none;"'),o+=wu("g",{class:iu(e),"clip-path":e.clip?dc(n,e,e.group):null},t),r.nested?e.items&&e.items.length&&s(e.items[0]):Yl(e,s),o+Cu("g")},$u.markGroup=function(e){var t=this,n="";return Yl(e,function(e){n+=t.mark(e)}),n};var Ku={Canvas:"canvas",PNG:"png",SVG:"svg",None:"none"},Qu={};function Yu(e,t){return e=String(e||"").toLowerCase(),arguments.length>1?(Qu[e]=t,this):Qu[e]}Qu.canvas=Qu.png={renderer:bu,headless:bu,handler:fu},Qu.svg={renderer:Du,headless:qu,handler:xu},Qu.none={};var Zu=new To;function Xu(e){Yr.call(this,null,e)}function Ju(e,t,n){return t(e.bounds.clear(),e,n)}Object(Ee.t)(Xu,Yr).transform=function(e,t){var n,r=t.dataflow,i=e.mark,a=i.marktype,o=Hc[a],s=o.bound,l=i.bounds;return o.nested?(i.items.length&&r.dirty(i.items[0]),l=Ju(i,s),i.items.forEach(function(e){e.bounds.clear().union(l)})):a===io||e.modified()?(t.visit(t.MOD,function(e){r.dirty(e)}),l.clear(),i.items.forEach(function(e){l.union(Ju(e,s))}),i.role===co&&t.reflow()):(n=t.changed(t.REM),t.visit(t.ADD,function(e){l.union(Ju(e,s))}),t.visit(t.MOD,function(e){n=n||l.alignsWith(e.bounds),r.dirty(e),l.union(Ju(e,s))}),n&&(l.clear(),i.items.forEach(function(e){l.union(e.bounds)}))),function(e){var t=e.clip;if(Object(Ee.x)(t))t(zl(Zu.clear()));else{if(!t)return;Zu.set(0,0,e.group.width,e.group.height)}e.bounds.intersect(Zu)}(i),t.modifies("bounds")};var ed=":vega_identifier:";function td(e){Yr.call(this,0,e)}function nd(e){Yr.call(this,null,e)}function rd(e){Yr.call(this,null,e)}td.Definition={type:"Identifier",metadata:{modifies:!0},params:[{name:"as",type:"string",required:!0}]},Object(Ee.t)(td,Yr).transform=function(e,t){var n=function(e){var t=e._signals[ed];t||(e._signals[ed]=t=e.add(0));return t}(t.dataflow),r=n.value,i=e.as;return t.visit(t.ADD,function(e){e[i]||(e[i]=++r)}),n.set(this.value=r),t},Object(Ee.t)(nd,Yr).transform=function(e,t){var n=this.value;n||((n=t.dataflow.scenegraph().mark(e.markdef,function(e){var t=e.groups,n=e.parent;return t&&1===t.size?t.get(Object.keys(t.object)[0]):t&&n?t.lookup(n):null}(e),e.index)).group.context=e.context,e.context.group||(e.context.group=n.group),n.source=this,n.clip=e.clip,n.interactive=e.interactive,this.value=n);var r=n.marktype===io?Io:Ro;return t.visit(t.ADD,function(e){r.call(e,n)}),(e.modified("clip")||e.modified("interactive"))&&(n.clip=e.clip,n.interactive=!!e.interactive,n.zdirty=!0,t.reflow()),n.items=t.source,t};var id={parity:function(e){return e.filter(function(e,t){return t%2?e.opacity=0:1})},greedy:function(e){var t;return e.filter(function(e,n){return n&&ad(t.bounds,e.bounds)?e.opacity=0:(t=e,1)})}};function ad(e,t){return!(e.x2-1t.x2||e.y2-1t.y2)}function od(e){for(var t,n=1,r=e.length,i=e[0].bounds;n1&&t.height()>1}function ld(e){Yr.call(this,null,e)}function cd(e,t){for(var n=0,r=e.length;n1&&y)for(i=0;i0&&(l.x+=c=d/2,l.bounds.translate(c,0));if(md(n.center,No)&&1!==C&&x)for(i=0;i0&&(l.y+=u=f/2,l.bounds.translate(0,u));for(i=0;ii&&(e.warn("Grid headers exceed limit: "+i),t=t.slice(0,i)),w+=a,g=0,b=t.length;g=0&&null==(y=n[h]);h-=f);s?(x=null==p?y.x:Math.round(y.bounds.x1+p*y.bounds.width()),E=w):(x=w,E=null==p?y.y:Math.round(y.bounds.y1+p*y.bounds.height())),v.union(_.bounds.translate(x-(_.x||0),E-(_.y||0))),_.x=x,_.y=E,e.dirty(_),C=o(C,v[c])}return C}function vd(e,t,n,r,i,a){if(t){e.dirty(t);var o=n,s=n;r?o=Math.round(i.x1+a*i.width()):s=Math.round(i.y1+a*i.height()),t.bounds.translate(o-(t.x||0),s-(t.y||0)),t.mark.bounds.clear().union(t.bounds),t.x=o,t.y=s,e.dirty(t)}}Object(Ee.t)(rd,Yr).transform=function(e,t){var n=id[e.method]||id.parity,r=t.materialize(t.SOURCE).source;if(r){e.sort&&(r=r.slice().sort(e.sort)),"greedy"===e.method&&(r=r.filter(sd)),r.forEach(function(e){e.opacity=1});var i,a,o,s,l,c=r;if(c.length>=3&&od(c)){t=t.reflow(e.modified()).modifies("opacity");do{c=n(c)}while(c.length>=3&&od(c));c.length<3&&!Object(Ee.K)(r).opacity&&(c.length>1&&(Object(Ee.K)(c).opacity=0),Object(Ee.K)(r).opacity=1)}if(e.boundScale){var u=(i=e.boundScale,a=e.boundOrient,o=e.boundTolerance,s=i.range(),l=new To,a===Ka||a===Za?l.set(s[0],-1/0,s[1],1/0):l.set(-1/0,s[0],1/0,s[1]),l.expand(o||1),function(e){return l.encloses(e.bounds)});r.forEach(function(e){u(e)||(e.opacity=0)})}return t}},Object(Ee.t)(ld,Yr).transform=function(e,t){var n=t.dataflow;if(t.visit(t.ALL,function(e){n.dirty(e)}),t.fields&&t.fields.zindex){var r=t.source&&t.source[0];r&&(r.mark.zdirty=!0)}};var _d=.5,yd=new To;function xd(e){Yr.call(this,null,e)}function Ed(e,t,n){return e[t]===n?0:(e[t]=n,1)}function Sd(e){var t=e.items[0].datum.orient;return t===Qa||t===Ya}function wd(e,t,n,r){var i,a,o=t.items[0],s=o.datum,l=s.orient,c=function(e){var t=+e.grid;return[e.ticks?t++:-1,e.labels?t++:-1,t+ +e.domain]}(s),u=o.range,d=o.offset,f=o.position,p=o.minExtent,m=o.maxExtent,g=s.title&&o.items[c[2]].items[0],h=o.titlePadding,b=o.bounds,v=0,_=0;switch(yd.clear().union(b),b.clear(),(i=c[0])>-1&&b.union(o.items[i].bounds),(i=c[1])>-1&&b.union(o.items[i].bounds),l){case Ka:v=f||0,_=-d,a=Math.max(p,Math.min(m,-b.y1)),g&&(a=Cd(g,a,h,0,-1,b)),b.add(0,-a).add(u,0);break;case Qa:v=-d,_=f||0,a=Math.max(p,Math.min(m,-b.x1)),g&&(a=Cd(g,a,h,1,-1,b)),b.add(-a,0).add(0,u);break;case Ya:v=n+d,_=f||0,a=Math.max(p,Math.min(m,b.x2)),g&&(a=Cd(g,a,h,1,1,b)),b.add(0,0).add(a,u);break;case Za:v=f||0,_=r+d,a=Math.max(p,Math.min(m,b.y2)),g&&(a=Cd(g,a,h,0,1,b)),b.add(0,0).add(u,a);break;default:v=o.x,_=o.y}return Fl(b.translate(v,_),o),Ed(o,"x",v+_d)|Ed(o,"y",_+_d)&&(o.bounds=yd,e.dirty(o),o.bounds=b,e.dirty(o)),o.mark.bounds.clear().union(b)}function Cd(e,t,n,r,i,a){var o=e.bounds,s=0,l=0;return e.auto?(t+=n,r?s=(e.x||0)-(e.x=i*t):l=(e.y||0)-(e.y=i*t),o.translate(-s,-l),e.mark.bounds.set(o.x1,o.y1,o.x2,o.y2),r?(a.add(0,o.y1).add(0,o.y2),t+=o.width()):(a.add(o.x1,0).add(o.x2,0),t+=o.height())):a.union(o),t}function Od(e,t,n,r,i,a,o){var s,l,c,u,d,f=t.items[0],p=f.datum,m=p.orient,g=f.offset,h=f.bounds,b=0,v=0;switch(m===Ka||m===Za?(c=i,b=n[m]):m!==Qa&&m!==Ya||(c=r,v=n[m]),yd.clear().union(h),h.clear(),f.items.forEach(function(e){h.union(e.bounds)}),s=Math.ceil(h.width()+2*f.padding-1),l=Math.ceil(h.height()+2*f.padding-1),p.type===vo&&(u=f.items[0].items[0].items[0].items,d=u.reduce(function(e,t){return e[t.column]=Math.max(t.bounds.x2-t.x,e[t.column]||0),e},{}),u.forEach(function(e){e.width=d[e.column],e.height=e.bounds.y2-e.y})),m){case Qa:b-=n.leftWidth+g-Math.floor(c.x1),n.left+=l+n.margin;break;case Ya:b+=g+Math.ceil(c.x2),n.right+=l+n.margin;break;case Ka:v-=l+g-Math.floor(c.y1),n.top+=s+n.margin;break;case Za:v+=g+Math.ceil(c.y2),n.bottom+=s+n.margin;break;case Xa:b+=g,v+=g;break;case Ja:b+=a-s-g,v+=g;break;case eo:b+=g,v+=o-l-g;break;case to:b+=a-s-g,v+=o-l-g;break;default:b=f.x,v=f.y}return Fl(h.set(b,v,b+s,v+l),f),Ed(f,"x",b)|Ed(f,"width",s)|Ed(f,"y",v)|Ed(f,"height",l)&&(f.bounds=yd,e.dirty(f),f.bounds=h,e.dirty(f)),f.mark.bounds.clear().union(h)}Object(Ee.t)(xd,Yr).transform=function(e,t){var n=t.dataflow;return e.mark.items.forEach(function(t){e.layout&&hd(n,t,e.layout),function(e,t,n){var r,i,a,o,s,l,c=t.items,u=Math.max(0,t.width||0),d=Math.max(0,t.height||0),f=(new To).set(0,0,u,d),p=f.clone(),m=f.clone(),g=[];for(s=0,l=c.length;s0?r:1:0},Ud=function(e){return function(t){var n,r=t[0],i=t[1];return i=s&&o[i]<=l&&(c<0&&(c=i),n=i);if(!(c<0))return s=e.invertExtent(o[c]),l=e.invertExtent(o[n]),[void 0===s[0]?s[1]:s[0],void 0===l[1]?l[0]:l[1]]}};function zd(){}function qd(e,t){var n=new zd;if(e instanceof zd)e.each(function(e,t){n.set(t,e)});else if(Array.isArray(e)){var r,i=-1,a=e.length;if(null==t)for(;++i=r.length)return null!=e&&n.sort(e),null!=t?t(n):n;for(var l,c,u,d=-1,f=n.length,p=r[i++],m=Gd(),g=o();++dr.length)return n;var o,s=i[a-1];return null!=t&&a>=r.length?o=n.entries():(o=[],n.each(function(t,n){o.push({key:n,values:e(t,a)})})),null!=s?o.sort(function(e,t){return s(e.key,t.key)}):o}(a(e,0,Vd,Kd),0)},key:function(e){return r.push(e),n},sortKeys:function(e){return i[r.length-1]=e,n},sortValues:function(t){return e=t,n},rollup:function(e){return t=e,n}}};function Hd(){return{}}function Wd(e,t,n){e[t]=n}function Vd(){return Gd()}function Kd(e,t,n){e.set(t,n)}function Qd(){}var Yd=Gd.prototype;function Zd(e,t){var n=new Qd;if(e instanceof Qd)e.each(function(e){n.add(e)});else if(e){var r=-1,i=e.length;if(null==t)for(;++r>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):(t=df.exec(e))?yf(parseInt(t[1],16)):(t=ff.exec(e))?new wf(t[1],t[2],t[3],1):(t=pf.exec(e))?new wf(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=mf.exec(e))?xf(t[1],t[2],t[3],t[4]):(t=gf.exec(e))?xf(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=hf.exec(e))?Of(t[1],t[2]/100,t[3]/100,1):(t=bf.exec(e))?Of(t[1],t[2]/100,t[3]/100,t[4]):vf.hasOwnProperty(e)?yf(vf[e]):"transparent"===e?new wf(NaN,NaN,NaN,0):null}function yf(e){return new wf(e>>16&255,e>>8&255,255&e,1)}function xf(e,t,n,r){return r<=0&&(e=t=n=NaN),new wf(e,t,n,r)}function Ef(e){return e instanceof of||(e=_f(e)),e?new wf((e=e.rgb()).r,e.g,e.b,e.opacity):new wf}function Sf(e,t,n,r){return 1===arguments.length?Ef(e):new wf(e,t,n,null==r?1:r)}function wf(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}function Cf(e){return((e=Math.max(0,Math.min(255,Math.round(e)||0)))<16?"0":"")+e.toString(16)}function Of(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Nf(e,t,n,r)}function Mf(e,t,n,r){return 1===arguments.length?function(e){if(e instanceof Nf)return new Nf(e.h,e.s,e.l,e.opacity);if(e instanceof of||(e=_f(e)),!e)return new Nf;if(e instanceof Nf)return e;var t=(e=e.rgb()).r/255,n=e.g/255,r=e.b/255,i=Math.min(t,n,r),a=Math.max(t,n,r),o=NaN,s=a-i,l=(a+i)/2;return s?(o=t===a?(n-r)/s+6*(n0&&l<1?0:o,new Nf(o,s,l,e.opacity)}(e):new Nf(e,t,n,null==r?1:r)}function Nf(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function Tf(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}rf(of,_f,{displayable:function(){return this.rgb().displayable()},hex:function(){return this.rgb().hex()},toString:function(){return this.rgb()+""}}),rf(wf,Sf,af(of,{brighter:function(e){return e=null==e?1/.7:Math.pow(1/.7,e),new wf(this.r*e,this.g*e,this.b*e,this.opacity)},darker:function(e){return e=null==e?.7:Math.pow(.7,e),new wf(this.r*e,this.g*e,this.b*e,this.opacity)},rgb:function(){return this},displayable:function(){return 0<=this.r&&this.r<=255&&0<=this.g&&this.g<=255&&0<=this.b&&this.b<=255&&0<=this.opacity&&this.opacity<=1},hex:function(){return"#"+Cf(this.r)+Cf(this.g)+Cf(this.b)},toString:function(){var e=this.opacity;return(1===(e=isNaN(e)?1:Math.max(0,Math.min(1,e)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===e?")":", "+e+")")}})),rf(Nf,Mf,af(of,{brighter:function(e){return e=null==e?1/.7:Math.pow(1/.7,e),new Nf(this.h,this.s,this.l*e,this.opacity)},darker:function(e){return e=null==e?.7:Math.pow(.7,e),new Nf(this.h,this.s,this.l*e,this.opacity)},rgb:function(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,i=2*n-r;return new wf(Tf(e>=240?e-240:e+120,i,r),Tf(e,i,r),Tf(e<120?e+240:e-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1}}));var Df=Math.PI/180,Af=180/Math.PI,kf=.96422,Rf=1,If=.82521,Lf=4/29,Pf=6/29,Ff=3*Pf*Pf,Bf=Pf*Pf*Pf;function Uf(e){if(e instanceof zf)return new zf(e.l,e.a,e.b,e.opacity);if(e instanceof Kf){if(isNaN(e.h))return new zf(e.l,0,0,e.opacity);var t=e.h*Df;return new zf(e.l,Math.cos(t)*e.c,Math.sin(t)*e.c,e.opacity)}e instanceof wf||(e=Ef(e));var n,r,i=Hf(e.r),a=Hf(e.g),o=Hf(e.b),s=qf((.2225045*i+.7168786*a+.0606169*o)/Rf);return i===a&&a===o?n=r=s:(n=qf((.4360747*i+.3850649*a+.1430804*o)/kf),r=qf((.0139322*i+.0971045*a+.7141733*o)/If)),new zf(116*s-16,500*(n-s),200*(s-r),e.opacity)}function jf(e,t,n,r){return 1===arguments.length?Uf(e):new zf(e,t,n,null==r?1:r)}function zf(e,t,n,r){this.l=+e,this.a=+t,this.b=+n,this.opacity=+r}function qf(e){return e>Bf?Math.pow(e,1/3):e/Ff+Lf}function Gf(e){return e>Pf?e*e*e:Ff*(e-Lf)}function $f(e){return 255*(e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055)}function Hf(e){return(e/=255)<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function Wf(e){if(e instanceof Kf)return new Kf(e.h,e.c,e.l,e.opacity);if(e instanceof zf||(e=Uf(e)),0===e.a&&0===e.b)return new Kf(NaN,0,e.l,e.opacity);var t=Math.atan2(e.b,e.a)*Af;return new Kf(t<0?t+360:t,Math.sqrt(e.a*e.a+e.b*e.b),e.l,e.opacity)}function Vf(e,t,n,r){return 1===arguments.length?Wf(e):new Kf(e,t,n,null==r?1:r)}function Kf(e,t,n,r){this.h=+e,this.c=+t,this.l=+n,this.opacity=+r}rf(zf,jf,af(of,{brighter:function(e){return new zf(this.l+18*(null==e?1:e),this.a,this.b,this.opacity)},darker:function(e){return new zf(this.l-18*(null==e?1:e),this.a,this.b,this.opacity)},rgb:function(){var e=(this.l+16)/116,t=isNaN(this.a)?e:e+this.a/500,n=isNaN(this.b)?e:e-this.b/200;return new wf($f(3.1338561*(t=kf*Gf(t))-1.6168667*(e=Rf*Gf(e))-.4906146*(n=If*Gf(n))),$f(-.9787684*t+1.9161415*e+.033454*n),$f(.0719453*t-.2289914*e+1.4052427*n),this.opacity)}})),rf(Kf,Vf,af(of,{brighter:function(e){return new Kf(this.h,this.c,this.l+18*(null==e?1:e),this.opacity)},darker:function(e){return new Kf(this.h,this.c,this.l-18*(null==e?1:e),this.opacity)},rgb:function(){return Uf(this).rgb()}}));var Qf=-.29227,Yf=-.90649,Zf=1.97294,Xf=Zf*Yf,Jf=1.78277*Zf,ep=1.78277*Qf- -.14861*Yf;function tp(e,t,n,r){return 1===arguments.length?function(e){if(e instanceof np)return new np(e.h,e.s,e.l,e.opacity);e instanceof wf||(e=Ef(e));var t=e.r/255,n=e.g/255,r=e.b/255,i=(ep*r+Xf*t-Jf*n)/(ep+Xf-Jf),a=r-i,o=(Zf*(n-i)-Qf*a)/Yf,s=Math.sqrt(o*o+a*a)/(Zf*i*(1-i)),l=s?Math.atan2(o,a)*Af-120:NaN;return new np(l<0?l+360:l,s,i,e.opacity)}(e):new np(e,t,n,null==r?1:r)}function np(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function rp(e,t,n,r,i){var a=e*e,o=a*e;return((1-3*e+3*a-o)*t+(4-6*a+3*o)*n+(1+3*e+3*a-3*o)*r+o*i)/6}rf(np,tp,af(of,{brighter:function(e){return e=null==e?1/.7:Math.pow(1/.7,e),new np(this.h,this.s,this.l*e,this.opacity)},darker:function(e){return e=null==e?.7:Math.pow(.7,e),new np(this.h,this.s,this.l*e,this.opacity)},rgb:function(){var e=isNaN(this.h)?0:(this.h+120)*Df,t=+this.l,n=isNaN(this.s)?0:this.s*t*(1-t),r=Math.cos(e),i=Math.sin(e);return new wf(255*(t+n*(-.14861*r+1.78277*i)),255*(t+n*(Qf*r+Yf*i)),255*(t+n*(Zf*r)),this.opacity)}}));var ip=function(e){var t=e.length-1;return function(n){var r=n<=0?n=0:n>=1?(n=1,t-1):Math.floor(n*t),i=e[r],a=e[r+1],o=r>0?e[r-1]:2*i-a,s=r180||n<-180?n-360*Math.round(n/360):n):op(isNaN(e)?t:e)}function cp(e){return 1==(e=+e)?up:function(t,n){return n-t?function(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}(t,n,e):op(isNaN(t)?n:t)}}function up(e,t){var n=t-e;return n?sp(e,n):op(isNaN(e)?t:e)}var dp=function e(t){var n=cp(t);function r(e,t){var r=n((e=Sf(e)).r,(t=Sf(t)).r),i=n(e.g,t.g),a=n(e.b,t.b),o=up(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=i(t),e.b=a(t),e.opacity=o(t),e+""}}return r.gamma=e,r}(1);function fp(e){return function(t){var n,r,i=t.length,a=new Array(i),o=new Array(i),s=new Array(i);for(n=0;na&&(i=t.slice(a,i),s[o]?s[o]+=i:s[++o]=i),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,l.push({i:o,x:bp(n,r)})),a=yp.lastIndex;return a180?t+=360:t-e>180&&(e+=360),a.push({i:n.push(i(n)+"rotate(",null,r)-2,x:bp(e,t)})):t&&n.push(i(n)+"rotate("+t+r)}(a.rotate,o.rotate,s,l),function(e,t,n,a){e!==t?a.push({i:n.push(i(n)+"skewX(",null,r)-2,x:bp(e,t)}):t&&n.push(i(n)+"skewX("+t+r)}(a.skewX,o.skewX,s,l),function(e,t,n,r,a,o){if(e!==n||t!==r){var s=a.push(i(a)+"scale(",null,",",null,")");o.push({i:s-4,x:bp(e,n)},{i:s-2,x:bp(t,r)})}else 1===n&&1===r||a.push(i(a)+"scale("+n+","+r+")")}(a.scaleX,a.scaleY,o.scaleX,o.scaleY,s,l),a=o=null,function(e){for(var t,n=-1,r=l.length;++n2?em:Jp,r=i=null,u}function u(t){return(r||(r=n(a,o,l?function(e){return function(t,n){var r=e(t=+t,n=+n);return function(e){return e<=t?0:e>=n?1:r(e)}}}(e):e,s)))(+t)}return u.invert=function(e){return(i||(i=n(o,a,Xp,l?function(e){return function(t,n){var r=e(t=+t,n=+n);return function(e){return e<=0?t:e>=1?n:r(e)}}}(t):t)))(+e)},u.domain=function(e){return arguments.length?(a=Jd.call(e,Yp),c()):a.slice()},u.range=function(e){return arguments.length?(o=ef.call(e),c()):o.slice()},u.rangeRound=function(e){return o=ef.call(e),s=Mp,c()},u.clamp=function(e){return arguments.length?(l=!!e,c()):l},u.interpolate=function(e){return arguments.length?(s=e,c()):s},c()}var rm=function(e,t){if((n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var n,r=e.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+e.slice(n+1)]},im=function(e){return(e=rm(Math.abs(e)))?e[1]:NaN},am=/^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function om(e){return new sm(e)}function sm(e){if(!(t=am.exec(e)))throw new Error("invalid format: "+e);var t;this.fill=t[1]||" ",this.align=t[2]||">",this.sign=t[3]||"-",this.symbol=t[4]||"",this.zero=!!t[5],this.width=t[6]&&+t[6],this.comma=!!t[7],this.precision=t[8]&&+t[8].slice(1),this.trim=!!t[9],this.type=t[10]||""}om.prototype=sm.prototype,sm.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(null==this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(null==this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};var lm,cm,um,dm,fm=function(e){e:for(var t,n=e.length,r=1,i=-1;r0){if(!+e[r])break e;i=0}}return i>0?e.slice(0,i)+e.slice(t+1):e},pm=function(e,t){var n=rm(e,t);if(!n)return e+"";var r=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")},mm={"%":function(e,t){return(100*e).toFixed(t)},b:function(e){return Math.round(e).toString(2)},c:function(e){return e+""},d:function(e){return Math.round(e).toString(10)},e:function(e,t){return e.toExponential(t)},f:function(e,t){return e.toFixed(t)},g:function(e,t){return e.toPrecision(t)},o:function(e){return Math.round(e).toString(8)},p:function(e,t){return pm(100*e,t)},r:pm,s:function(e,t){var n=rm(e,t);if(!n)return e+"";var r=n[0],i=n[1],a=i-(lm=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,o=r.length;return a===o?r:a>o?r+new Array(a-o+1).join("0"):a>0?r.slice(0,a)+"."+r.slice(a):"0."+new Array(1-a).join("0")+rm(e,Math.max(0,t+a-1))[0]},X:function(e){return Math.round(e).toString(16).toUpperCase()},x:function(e){return Math.round(e).toString(16)}},gm=function(e){return e},hm=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"],bm=function(e){var t,n,r=e.grouping&&e.thousands?(t=e.grouping,n=e.thousands,function(e,r){for(var i=e.length,a=[],o=0,s=t[0],l=0;i>0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),a.push(e.substring(i-=s,i+s)),!((l+=s+1)>r));)s=t[o=(o+1)%t.length];return a.reverse().join(n)}):gm,i=e.currency,a=e.decimal,o=e.numerals?function(e){return function(t){return t.replace(/[0-9]/g,function(t){return e[+t]})}}(e.numerals):gm,s=e.percent||"%";function l(e){var t=(e=om(e)).fill,n=e.align,l=e.sign,c=e.symbol,u=e.zero,d=e.width,f=e.comma,p=e.precision,m=e.trim,g=e.type;"n"===g?(f=!0,g="g"):mm[g]||(null==p&&(p=12),m=!0,g="g"),(u||"0"===t&&"="===n)&&(u=!0,t="0",n="=");var h="$"===c?i[0]:"#"===c&&/[boxX]/.test(g)?"0"+g.toLowerCase():"",b="$"===c?i[1]:/[%p]/.test(g)?s:"",v=mm[g],_=/[defgprs%]/.test(g);function y(e){var i,s,c,y=h,x=b;if("c"===g)x=v(e)+x,e="";else{var E=(e=+e)<0;if(e=v(Math.abs(e),p),m&&(e=fm(e)),E&&0==+e&&(E=!1),y=(E?"("===l?l:"-":"-"===l||"("===l?"":l)+y,x=("s"===g?hm[8+lm/3]:"")+x+(E&&"("===l?")":""),_)for(i=-1,s=e.length;++i(c=e.charCodeAt(i))||c>57){x=(46===c?a+e.slice(i+1):e.slice(i))+x,e=e.slice(0,i);break}}f&&!u&&(e=r(e,1/0));var S=y.length+e.length+x.length,w=S>1)+y+e+x+w.slice(S);break;default:e=w+y+e+x}return o(e)}return p=null==p?6:/[gprs]/.test(g)?Math.max(1,Math.min(21,p)):Math.max(0,Math.min(20,p)),y.toString=function(){return e+""},y}return{format:l,formatPrefix:function(e,t){var n=l(((e=om(e)).type="f",e)),r=3*Math.max(-8,Math.min(8,Math.floor(im(t)/3))),i=Math.pow(10,-r),a=hm[8+r/3];return function(e){return n(i*e)+a}}}};!function(e){cm=bm(e),um=cm.format,dm=cm.formatPrefix}({decimal:".",thousands:",",grouping:[3],currency:["$",""]});var vm=function(e){return Math.max(0,-im(Math.abs(e)))},_m=function(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(im(t)/3)))-im(Math.abs(e)))},ym=function(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,im(t)-im(e))+1},xm=function(e,t,n){var r,i=e[0],a=e[e.length-1],o=Mi(i,a,null==t?10:t);switch((n=om(null==n?",f":n)).type){case"s":var s=Math.max(Math.abs(i),Math.abs(a));return null!=n.precision||isNaN(r=_m(o,s))||(n.precision=r),dm(n,s);case"":case"e":case"g":case"p":case"r":null!=n.precision||isNaN(r=ym(o,Math.max(Math.abs(i),Math.abs(a))))||(n.precision=r-("e"===n.type));break;case"f":case"%":null!=n.precision||isNaN(r=vm(o))||(n.precision=r-2*("%"===n.type))}return um(n)};function Em(e){var t=e.domain;return e.ticks=function(e){var n=t();return Ci(n[0],n[n.length-1],null==e?10:e)},e.tickFormat=function(e,n){return xm(t(),e,n)},e.nice=function(n){null==n&&(n=10);var r,i=t(),a=0,o=i.length-1,s=i[a],l=i[o];return l0?r=Oi(s=Math.floor(s/r)*r,l=Math.ceil(l/r)*r,n):r<0&&(r=Oi(s=Math.ceil(s*r)/r,l=Math.floor(l*r)/r,n)),r>0?(i[a]=Math.floor(s/r)*r,i[o]=Math.ceil(l/r)*r,t(i)):r<0&&(i[a]=Math.ceil(s*r)/r,i[o]=Math.floor(l*r)/r,t(i)),e},e}function Sm(){var e=nm(Xp,bp);return e.copy=function(){return tm(e,Sm())},Em(e)}var wm=function(e,t){var n,r=0,i=(e=e.slice()).length-1,a=e[r],o=e[i];return oa[1-u])))return n=Math.max(0,mi(d,l)-1),o=l===c?n:mi(d,c)-1,l-d[n]>t+1e-10&&++n,u&&(s=n,n=f-o,o=f-s),n>o?void 0:r().slice(n,o+1)}},n.invert=function(e){var t=n.invertRange([e,e]);return t?t[0]:t},n.copy=function(){return Gm().domain(r()).range(a).round(o).paddingInner(s).paddingOuter(l).align(c)},u()}var $m=Array.prototype.map,Hm=Array.prototype.slice;function Wm(e){return $m.call(e,function(e){return+e})}function Vm(e,t){return arguments.length>1?(Km[e]=function(e,t){return function(){var n=t();return n.invertRange||(n.invertRange=n.invert?Ud(n):n.invertExtent?jd(n):void 0),n.type=e,n}}(e,t),this):Km.hasOwnProperty(e)?Km[e]:void 0}var Km={identity:function e(){var t=[0,1];function n(e){return+e}return n.invert=n,n.domain=n.range=function(e){return arguments.length?(t=Jd.call(e,Yp),n):t.slice()},n.copy=function(){return e().domain(t)},Em(n)},linear:Sm,log:function e(){var t=nm(Cm,Om).domain([1,10]),n=t.domain,r=10,i=Tm(10),a=Nm(10);function o(){return i=Tm(r),a=Nm(r),n()[0]<0&&(i=Dm(i),a=Dm(a)),t}return t.base=function(e){return arguments.length?(r=+e,o()):r},t.domain=function(e){return arguments.length?(n(e),o()):n()},t.ticks=function(e){var t,o=n(),s=o[0],l=o[o.length-1];(t=l0){for(;fl)break;g.push(d)}}else for(;f=1;--u)if(!((d=c*u)l)break;g.push(d)}}else g=Ci(f,p,Math.min(p-f,m)).map(a);return t?g.reverse():g},t.tickFormat=function(e,n){if(null==n&&(n=10===r?".0e":","),"function"!=typeof n&&(n=um(n)),e===1/0)return n;null==e&&(e=10);var o=Math.max(1,r*e/t.ticks().length);return function(e){var t=e/a(Math.round(i(e)));return t*r0?r[i-1]:t[0],i=r?[i[r-1],n]:[i[o-1],i[o]]},o.copy=function(){return e().domain([t,n]).range(a)},Em(o)},threshold:function e(){var t=[.5],n=[0,1],r=1;function i(e){if(e<=e)return n[hi(t,e,0,r)]}return i.domain=function(e){return arguments.length?(t=ef.call(e),r=Math.min(t.length,n.length-1),i):t.slice()},i.range=function(e){return arguments.length?(n=ef.call(e),r=Math.min(t.length,n.length-1),i):n.slice()},i.invertExtent=function(e){var r=n.indexOf(e);return[t[r-1],t[r]]},i.copy=function(){return e().domain(t).range(n)},i},time:function(){return qm(Ht,Gt,Lt,Rt,At,Tt,Mt,St,gn).domain([new Date(2e3,0,1),new Date(2e3,0,2)])},utc:function(){return qm(un,ln,Jt,Zt,Qt,Vt,Mt,St,bn).domain([Date.UTC(2e3,0,1),Date.UTC(2e3,0,2)])},band:Gm,point:function(){return function e(t){var n=t.copy;return t.padding=t.paddingOuter,delete t.paddingInner,t.copy=function(){return e(n())},t}(Gm().paddingInner(1))},sequential:function e(t){var n=Sm(),r=0,i=1,a=!1;function o(){var e=n.domain();r=e[0],i=Object(Ee.K)(e)-r}function s(e){var n=(e-r)/i;return t(a?Math.max(0,Math.min(1,n)):n)}return s.clamp=function(e){return arguments.length?(a=!!e,s):a},s.domain=function(e){return arguments.length?(n.domain(e),o(),s):n.domain()},s.interpolator=function(e){return arguments.length?(t=e,s):t},s.copy=function(){return e().domain(n.domain()).clamp(a).interpolator(t)},s.ticks=function(e){return n.ticks(e)},s.tickFormat=function(e,t){return n.tickFormat(e,t)},s.nice=function(e){return n.nice(e),o(),s},s},"bin-linear":function e(){var t=Sm(),n=[];function r(e){return t(e)}return r.domain=function(e){return arguments.length?(function(e){n=Wm(e),t.domain([n[0],Object(Ee.K)(n)])}(e),r):n.slice()},r.range=function(e){return arguments.length?(t.range(e),r):t.range()},r.rangeRound=function(e){return arguments.length?(t.rangeRound(e),r):t.rangeRound()},r.interpolate=function(e){return arguments.length?(t.interpolate(e),r):t.interpolate()},r.invert=function(e){return t.invert(e)},r.ticks=function(e){var t=n.length,i=~~(t/(e||t));return i<2?r.domain():n.filter(function(e,t){return!(t%i)})},r.tickFormat=function(){return t.tickFormat.apply(t,arguments)},r.copy=function(){return e().domain(r.domain()).range(r.range())},r},"bin-ordinal":function e(){var t=[],n=[];function r(e){return null==e||e!=e?void 0:n[(hi(t,e)-1)%n.length]}return r.domain=function(e){return arguments.length?(t=Wm(e),r):t.slice()},r.range=function(e){return arguments.length?(n=Hm.call(e),r):n.slice()},r.copy=function(){return e().domain(r.domain()).range(r.range())},r}};for(var Qm in Km)Vm(Qm,Km[Qm]);function Ym(e,t,n){var r=n-t;return r?"linear"===e.type||"sequential"===e.type?function(e){return(e-t)/r}:e.copy().domain([t,n]).range([0,1]).interpolate(Zm):Object(Ee.j)(0)}function Zm(e,t){var n=t-e;return function(t){return e+t*n}}function Xm(e){for(var t=e.length/6|0,n=new Array(t),r=0;r1)&&(e-=Math.floor(e));var t=Math.abs(e-.5);return _h.h=360*e-100,_h.s=1.5-1.5*t,_h.l=.8-.9*t,_h+""},xh=Sf(),Eh=Math.PI/3,Sh=2*Math.PI/3,wh=function(e){var t;return e=(.5-e)*Math.PI,xh.r=255*(t=Math.sin(e))*t,xh.g=255*(t=Math.sin(e+Eh))*t,xh.b=255*(t=Math.sin(e+Sh))*t,xh+""};function Ch(e){var t=e.length;return function(n){return e[Math.max(0,Math.min(t-1,Math.floor(n*t)))]}}var Oh=Ch(ag("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")),Mh=Ch(ag("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),Nh=Ch(ag("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),Th=Ch(ag("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),Dh={blueorange:ig},Ah={category10:og,accent:sg,dark2:lg,paired:cg,pastel1:ug,pastel2:dg,set1:fg,set2:pg,set3:mg,category20:Jm,category20b:eg,category20c:tg,tableau10:ng,tableau20:rg,viridis:Oh,magma:Mh,inferno:Nh,plasma:Th,rainbow:yh,sinebow:wh,blueorange:pp(Object(Ee.K)(ig))};function kh(e,t){Ah[e]=o["interpolate"+t],Dh[e]=o["scheme"+t]}function Rh(e,t){if(arguments.length>1)return Ah[e]=t,this;var n=e.split("-");return e=n[0],(n=+n[1]+1)&&Dh.hasOwnProperty(e)?Dh[e][n-1]:!n&&Ah.hasOwnProperty(e)?Ah[e]:void 0}kh("blues","Blues"),kh("greens","Greens"),kh("greys","Greys"),kh("purples","Purples"),kh("reds","Reds"),kh("oranges","Oranges"),kh("brownbluegreen","BrBG"),kh("purplegreen","PRGn"),kh("pinkyellowgreen","PiYG"),kh("purpleorange","PuOr"),kh("redblue","RdBu"),kh("redgrey","RdGy"),kh("redyellowblue","RdYlBu"),kh("redyellowgreen","RdYlGn"),kh("spectral","Spectral"),kh("bluegreen","BuGn"),kh("bluepurple","BuPu"),kh("greenblue","GnBu"),kh("orangered","OrRd"),kh("purplebluegreen","PuBuGn"),kh("purpleblue","PuBu"),kh("purplered","PuRd"),kh("redpurple","RdPu"),kh("yellowgreenblue","YlGnBu"),kh("yellowgreen","YlGn"),kh("yelloworangebrown","YlOrBr"),kh("yelloworangered","YlOrRd");var Ih={millisecond:St,second:Mt,minute:Tt,hour:At,day:Rt,week:Lt,month:Gt,year:Ht},Lh={millisecond:St,second:Mt,minute:Vt,hour:Qt,day:Zt,week:Jt,month:ln,year:un};function Ph(e,t){var n,r;return Object(Ee.z)(t)&&(n=t.step,t=t.interval),Object(Ee.B)(t)&&(t="time"===e.type?(r=t,Ih.hasOwnProperty(r)&&Ih[r]):"utc"===e.type?function(e){return Lh.hasOwnProperty(e)&&Lh[e]}(t):Object(Ee.l)("Only time and utc scales accept interval strings."),n&&(t=t.every(n))),t}function Fh(e,t,n){var r=e.range(),i=r[0],a=Object(Ee.K)(r);if(i>a&&(r=a,a=i,i=r),t=t.filter(function(t){return!((t=e(t))a)}),n>0&&t.length>1){for(var o=[t[0],Object(Ee.K)(t)];t.length>n&&t.length>=3;)t=t.filter(function(e,t){return!(t%2)});t.length<3&&(t=o)}return t}function Bh(e,t){return e.ticks?e.ticks(t):e.domain()}function Uh(e,t,n){var r,i,a=e.tickFormat?e.tickFormat(t,n):n?um(n):String;return e.type===Md?(r=a,i=function(e){var t=om(e||",");if(null==t.precision){switch(t.precision=12,t.type){case"%":t.precision-=2;break;case"e":t.precision-=1}return n=um(t),r=um(".1f")(1)[1],function(e){var t,i,a=n(e),o=a.indexOf(r);if(o<0)return a;for(t=function(e,t){var n,r=e.lastIndexOf("e");if(r>0)return r;for(r=e.length;--r>t;)if((n=e.charCodeAt(r))>=48&&n<=57)return r+1}(a,o),i=to;)if("0"!==a[t]){++t;break}return a.slice(0,t)+i}}return um(t);var n,r}(n),function(e){return r(e)?i(e):""}):a}function jh(e){Yr.call(this,null,e)}function zh(e){Yr.call(this,null,e)}function qh(){return Te({})}function Gh(e){return e.exit}function $h(e){Yr.call(this,null,e)}Object(Ee.t)(jh,Yr).transform=function(e,t){if(this.value&&!e.modified())return t.StopPropagation;var n=t.fork(t.NO_SOURCE|t.NO_FIELDS),r=this.value,i=e.scale,a=null==e.count?e.values?e.values.length:10:Ph(i,e.count),o=e.format||Uh(i,a,e.formatSpecifier),s=e.values?Fh(i,e.values,a):Bh(i,a);return r&&(n.rem=r),r=s.map(function(e,t){return Te({index:t/(s.length-1),value:e,label:o(e)})}),e.extra&&r.push(Te({index:-1,extra:{value:r[0].value},label:""})),n.source=r,n.add=r,this.value=r,n},Object(Ee.t)(zh,Yr).transform=function(e,t){var n=t.dataflow,r=t.fork(t.NO_SOURCE|t.NO_FIELDS),i=e.item||qh,a=e.key||Me,o=this.value;return Object(Ee.u)(r.encode)&&(r.encode=null),o&&(e.modified("key")||t.modified(a))&&Object(Ee.l)("DataJoin does not support modified key function or fields."),o||(t=t.addAll(),this.value=o=Object(Ee.p)().test(Gh),o.lookup=function(e){return o.get(a(e))}),t.visit(t.ADD,function(e){var t=a(e),n=o.get(t);n?n.exit?(o.empty--,r.add.push(n)):r.mod.push(n):(o.set(t,n=i(e)),r.add.push(n)),n.datum=e,n.exit=!1}),t.visit(t.MOD,function(e){var t=a(e),n=o.get(t);n&&(n.datum=e,r.mod.push(n))}),t.visit(t.REM,function(e){var t=a(e),n=o.get(t);e!==n.datum||n.exit||(r.rem.push(n),n.exit=!0,++o.empty)}),t.changed(t.ADD_MOD)&&r.modifies("datum"),e.clean&&o.empty>n.cleanThreshold&&n.runAfter(o.clean),r},Object(Ee.t)($h,Yr).transform=function(e,t){var n=t.fork(t.ADD_REM),r=e.encoders,i=t.encode;if(Object(Ee.u)(i)){if(!n.changed()&&!i.every(function(e){return r[e]}))return t.StopPropagation;i=i[0],n.encode=null}var a="enter"===i,o=r.update||Ee.o,s=r.enter||Ee.o,l=r.exit||Ee.o,c=(i&&!a?r[i]:o)||Ee.o;if(t.changed(t.ADD)&&(t.visit(t.ADD,function(t){s(t,e),o(t,e),c!==Ee.o&&c!==o&&c(t,e)}),n.modifies(s.output),n.modifies(o.output),c!==Ee.o&&c!==o&&n.modifies(c.output)),t.changed(t.REM)&&l!==Ee.o&&(t.visit(t.REM,function(t){l(t,e)}),n.modifies(l.output)),a||c!==Ee.o){var u=t.MOD|(e.modified()?t.REFLOW:0);a?(t.visit(u,function(t){var r=s(t,e);(c(t,e)||r)&&n.mod.push(t)}),n.mod.length&&n.modifies(s.output)):t.visit(u,function(t){c(t,e)&&n.mod.push(t)}),n.mod.length&&n.modifies(c.output)}return n.changed()?n:t.StopPropagation};var Hh="symbol",Wh="discrete",Vh={};function Kh(e,t,n){return n===Hh&&Vh[e.type]?function(e){return function(t,n,r){var i=r[n+1]||r.max||1/0,a=Qh(t,e),o=Qh(i,e);return a&&o?a+"–"+o:o?"< "+o:"≥ "+a}}(t):n===Wh?function(e){return function(t,n){return n?e(t):null}}(t):function(e){return function(t){return e(t)}}(t)}function Qh(e,t){return isFinite(e)?t(e):null}function Yh(e){Yr.call(this,[],e)}Vh[Rd]=function(e){var t=[-1/0].concat(e.quantiles());return t.max=1/0,t},Vh[Id]=function(e){var t=e.domain(),n=t[0],r=Object(Ee.K)(t),i=e.range().length,a=new Array(i),o=0;a[0]=-1/0;for(;++oMath.PI?n<=e:n>e;return"M"+t*i+","+t*a+"A"+t+","+t+" 0 0,"+(l?1:0)+" "+t*o+","+t*s+"L"+r*o+","+r*s},"diagonal-horizontal":function(e,t,n,r){var i=(e+n)/2;return"M"+e+","+t+"C"+i+","+t+" "+i+","+r+" "+n+","+r},"diagonal-vertical":function(e,t,n,r){var i=(t+r)/2;return"M"+e+","+t+"C"+e+","+i+" "+n+","+i+" "+n+","+r},"diagonal-radial":function(e,t,n,r){var i=Math.cos(e),a=Math.sin(e),o=Math.cos(n),s=Math.sin(n),l=(t+r)/2;return"M"+t*i+","+t*a+"C"+l*i+","+l*a+" "+l*o+","+l*s+" "+r*o+","+r*s}});function Xh(e){return e.source.x}function Jh(e){return e.source.y}function eb(e){return e.target.x}function tb(e){return e.target.y}function nb(e){Yr.call(this,{},e)}function rb(e,t,n,r){return"M"+e+","+t+"L"+n+","+r}function ib(e,t,n,r){var i=n-e,a=r-t,o=Math.sqrt(i*i+a*a)/2;return"M"+e+","+t+"A"+o+","+o+" "+180*Math.atan2(a,i)/Math.PI+" 0 1 "+n+","+r}function ab(e,t,n,r){var i=n-e,a=r-t,o=.2*(i+a),s=.2*(a-i);return"M"+e+","+t+"C"+(e+o)+","+(t+s)+" "+(n+s)+","+(r-o)+" "+n+","+r}function ob(e){Yr.call(this,null,e)}nb.Definition={type:"LinkPath",metadata:{modifies:!0},params:[{name:"sourceX",type:"field",default:"source.x"},{name:"sourceY",type:"field",default:"source.y"},{name:"targetX",type:"field",default:"target.x"},{name:"targetY",type:"field",default:"target.y"},{name:"orient",type:"enum",default:"vertical",values:["horizontal","vertical","radial"]},{name:"shape",type:"enum",default:"line",values:["line","arc","curve","diagonal","orthogonal"]},{name:"as",type:"string",default:"path"}]},Object(Ee.t)(nb,Yr).transform=function(e,t){var n=e.sourceX||Xh,r=e.sourceY||Jh,i=e.targetX||eb,a=e.targetY||tb,o=e.as||"path",s=e.orient||"vertical",l=e.shape||"line",c=Zh.get(l+"-"+s)||Zh.get(l);return c||Object(Ee.l)("LinkPath unsupported type: "+e.shape+(e.orient?"-"+e.orient:"")),t.visit(t.SOURCE,function(e){e[o]=c(n(e),r(e),i(e),a(e))}),t.reflow(e.modified()).modifies(o)},ob.Definition={type:"Pie",metadata:{modifies:!0},params:[{name:"field",type:"field"},{name:"startAngle",type:"number",default:0},{name:"endAngle",type:"number",default:6.283185307179586},{name:"sort",type:"boolean",default:!1},{name:"as",type:"string",array:!0,length:2,default:["startAngle","endAngle"]}]},Object(Ee.t)(ob,Yr).transform=function(e,t){var n,r,i,a=e.as||["startAngle","endAngle"],o=a[0],s=a[1],l=e.field||Ee.F,c=e.startAngle||0,u=null!=e.endAngle?e.endAngle:2*Math.PI,d=t.source,f=d.map(l),p=f.length,m=c,g=(u-c)/function(e,t){var n,r=e.length,i=-1,a=0;if(null==t)for(;++i-1)return r;var i,a,o=t.domain,s=e.type,l=t.zero||void 0===t.zero&&lb[s];if(!o)return 0;cb[s]&&t.padding&&o[0]!==Object(Ee.K)(o)&&(o=function(e,t,n,r,i){var a=Math.abs(Object(Ee.K)(n)-n[0]),o=a/(a-2*r),s=e===Md?Object(Ee.X)(t,null,o):e===Td?Object(Ee.Y)(t,null,o,.5):e===Nd?Object(Ee.Y)(t,null,o,i):Object(Ee.W)(t,null,o);return(t=t.slice())[0]=s[0],t[t.length-1]=s[1],t}(s,o,t.range,t.padding,t.exponent));(l||null!=t.domainMin||null!=t.domainMax||null!=t.domainMid)&&(i=(o=o.slice()).length-1||1,l&&(o[0]>0&&(o[0]=0),o[i]<0&&(o[i]=0)),null!=t.domainMin&&(o[0]=t.domainMin),null!=t.domainMax&&(o[i]=t.domainMax),null!=t.domainMid&&(((a=t.domainMid)o[i])&&n.warn("Scale domainMid exceeds domain min or max.",a),o.splice(i,0,a)));e.domain(o),s===kd&&e.unknown(t.domainImplicit?tf:void 0);t.nice&&e.nice&&e.nice(!0!==t.nice&&Ph(e,t.nice)||null);return o.length}(i,e,r)),t.fork(t.NO_SOURCE|t.NO_FIELDS)},Object(Ee.t)(mb,Yr).transform=function(e,t){var n=e.modified("sort")||t.changed(t.ADD)||t.modified(e.sort.fields)||t.modified("datum");return n&&t.source.sort(e.sort),this.modified(n),t};function gb(e){Yr.call(this,null,e)}function hb(e,t,n,r,i){for(var a,o=(t-e.sum)/2,s=e.length,l=0;lf&&(f=d),n&&u.sort(n)}return p.max=f,p}(t.source,e.groupby,e.sort,c),r=0,i=n.length,a=n.max;rr!=p>r&&n<(f-c)*(r-u)/(p-u)+c&&(i=-i)}return i}function Cb(e,t,n){var r,i,a,o;return function(e,t,n){return(t[0]-e[0])*(n[1]-e[1])==(n[0]-e[0])*(t[1]-e[1])}(e,t,n)&&(i=e[r=+(e[0]===t[0])],a=n[r],o=t[r],i<=a&&a<=o||o<=a&&a<=i)}var Ob=function(){},Mb=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]],Nb=function(){var e=1,t=1,n=Ni,r=s;function i(e){var t=n(e);if(Array.isArray(t))t=t.slice().sort(yb);else{var r=_i(e),i=r[0],o=r[1];t=Mi(i,o,t),t=xi(Math.floor(i/t)*t,Math.floor(o/t)*t,t)}return t.map(function(t){return a(e,t)})}function a(n,i){var a=[],s=[];return function(n,r,i){var a,s,l,c,u,d,f=new Array,p=new Array;a=s=-1,c=n[0]>=r,Mb[c<<1].forEach(m);for(;++a=r,Mb[l|c<<1].forEach(m);Mb[c<<0].forEach(m);for(;++s=r,u=n[s*e]>=r,Mb[c<<1|u<<2].forEach(m);++a=r,d=u,u=n[s*e+a+1]>=r,Mb[l|c<<1|u<<2|d<<3].forEach(m);Mb[c|u<<3].forEach(m)}a=-1,u=n[s*e]>=r,Mb[u<<2].forEach(m);for(;++a=r,Mb[u<<2|d<<3].forEach(m);function m(e){var t,n,r=[e[0][0]+a,e[0][1]+s],l=[e[1][0]+a,e[1][1]+s],c=o(r),u=o(l);(t=p[c])?(n=f[u])?(delete p[t.end],delete f[n.start],t===n?(t.ring.push(l),i(t.ring)):f[t.start]=p[n.end]={start:t.start,end:n.end,ring:t.ring.concat(n.ring)}):(delete p[t.end],t.ring.push(l),p[t.end=u]=t):(t=f[u])?(n=p[c])?(delete f[t.start],delete p[n.end],t===n?(t.ring.push(l),i(t.ring)):f[n.start]=p[t.end]={start:n.start,end:t.end,ring:n.ring.concat(t.ring)}):(delete f[t.start],t.ring.unshift(r),f[t.start=c]=t):f[c]=p[u]={start:c,end:u,ring:[r,l]}}Mb[u<<3].forEach(m)}(n,i,function(e){r(e,n,i),xb(e)>0?a.push([e]):s.push(e)}),s.forEach(function(e){for(var t,n=0,r=a.length;n0&&o0&&s0&&a>0))throw new Error("invalid size");return e=r,t=a,i},i.thresholds=function(e){return arguments.length?(n="function"==typeof e?e:Array.isArray(e)?Eb(_b.call(e)):Eb(e),i):n},i.smooth=function(e){return arguments.length?(r=e?s:Ob,i):r===s},i};function Tb(e,t,n){for(var r=e.width,i=e.height,a=1+(n<<1),o=0;o=n&&(s>=a&&(l-=e.data[s-a+o*r]),t.data[s-n+o*r]=l/Math.min(s+1,r-1+a-s,a))}function Db(e,t,n){for(var r=e.width,i=e.height,a=1+(n<<1),o=0;o=n&&(s>=a&&(l-=e.data[o+(s-a)*r]),t.data[o+(s-n)*r]=l/Math.min(s+1,i-1+a-s,a))}function Ab(e){return e[0]}function kb(e){return e[1]}var Rb=["size","smooth"],Ib=["x","y","size","cellSize","bandwidth"];function Lb(e){Yr.call(this,null,e)}Lb.Definition={type:"Contour",metadata:{generates:!0},params:[{name:"size",type:"number",array:!0,length:2,required:!0},{name:"values",type:"number",array:!0},{name:"x",type:"field"},{name:"y",type:"field"},{name:"cellSize",type:"number"},{name:"bandwidth",type:"number"},{name:"count",type:"number"},{name:"smooth",type:"boolean"},{name:"nice",type:"boolean",default:!1},{name:"thresholds",type:"number",array:!0}]},Object(Ee.t)(Lb,Yr).transform=function(e,t){if(this.value&&!t.changed()&&!e.modified())return t.StopPropagation;var n,r,i,a,o=t.fork(t.NO_SOURCE|t.NO_FIELDS),s=e.count||10;return e.values?(n=Nb(),r=Rb,i=e.values):(n=function(){var e=Ab,t=kb,n=960,r=500,i=20,a=2,o=3*i,s=n+2*o>>a,l=r+2*o>>a,c=Eb(20);function u(n){var r=new Float32Array(s*l),u=new Float32Array(s*l);n.forEach(function(n,i,c){var u=e(n,i,c)+o>>a,d=t(n,i,c)+o>>a;u>=0&&u=0&&d>a),Db({width:s,height:l,data:u},{width:s,height:l,data:r},i>>a),Tb({width:s,height:l,data:r},{width:s,height:l,data:u},i>>a),Db({width:s,height:l,data:u},{width:s,height:l,data:r},i>>a),Tb({width:s,height:l,data:r},{width:s,height:l,data:u},i>>a),Db({width:s,height:l,data:u},{width:s,height:l,data:r},i>>a);var f=c(r);if(!Array.isArray(f)){var p=Di(r);f=Mi(0,p,f),(f=xi(0,Math.floor(p/f)*f,f)).shift()}return Nb().thresholds(f).size([s,l])(r).map(d)}function d(e){return e.value*=Math.pow(2,-2*a),e.coordinates.forEach(f),e}function f(e){e.forEach(p)}function p(e){e.forEach(m)}function m(e){e[0]=e[0]*Math.pow(2,a)-o,e[1]=e[1]*Math.pow(2,a)-o}function g(){return s=n+2*(o=3*i)>>a,l=r+2*o>>a,u}return u.x=function(t){return arguments.length?(e="function"==typeof t?t:Eb(+t),u):e},u.y=function(e){return arguments.length?(t="function"==typeof e?e:Eb(+e),u):t},u.size=function(e){if(!arguments.length)return[n,r];var t=Math.ceil(e[0]),i=Math.ceil(e[1]);if(!(t>=0||t>=0))throw new Error("invalid size");return n=t,r=i,g()},u.cellSize=function(e){if(!arguments.length)return 1<=1))throw new Error("invalid cell size");return a=Math.floor(Math.log(e)/Math.LN2),g()},u.thresholds=function(e){return arguments.length?(c="function"==typeof e?e:Array.isArray(e)?Eb(_b.call(e)):Eb(e),u):c},u.bandwidth=function(e){if(!arguments.length)return Math.sqrt(i*(i+1));if(!((e=+e)>=0))throw new Error("invalid bandwidth");return i=Math.round((Math.sqrt(4*e*e+1)-1)/2),g()},u}(),r=Ib,i=t.materialize(t.SOURCE).source),n.thresholds(e.thresholds||(e.nice?s:(a=s,function(e){for(var t=_i(e),n=t[0],r=t[1]-n,i=[],o=1;o<=a;++o)i.push(n+r*o/(a+1));return i}))),r.forEach(function(t){null!=e[t]&&n[t](e[t])}),this.value&&(o.rem=this.value),i=i&&i.length?n(i).map(Te):[],this.value=o.source=o.add=i,o};var Pb="FeatureCollection";function Fb(e){Yr.call(this,null,e)}Fb.Definition={type:"GeoJSON",metadata:{},params:[{name:"fields",type:"field",array:!0,length:2},{name:"geojson",type:"field"}]},Object(Ee.t)(Fb,Yr).transform=function(e,t){var n,r=this._features,i=this._points,a=e.fields,o=a&&a[0],s=a&&a[1],l=e.geojson,c=t.ADD;n=e.modified()||t.changed(t.REM)||t.modified(Object(Ee.f)(l))||o&&t.modified(Object(Ee.f)(o))||s&&t.modified(Object(Ee.f)(s)),this.value&&!n||(c=t.SOURCE,this._features=r=[],this._points=i=[]),l&&t.visit(c,function(e){r.push(l(e))}),o&&s&&(t.visit(c,function(e){var t=o(e),n=s(e);null!=t&&null!=n&&(t=+t)===t&&(n=+n)===n&&i.push([t,n])}),r=r.concat({type:"Feature",geometry:{type:"MultiPoint",coordinates:i}})),this.value={type:Pb,features:r}};var Bb=function(){return new Ub};function Ub(){this.reset()}Ub.prototype={constructor:Ub,reset:function(){this.s=this.t=0},add:function(e){zb(jb,e,this.t),zb(this,jb.s,this.s),this.s?this.t+=jb.t:this.s=jb.t},valueOf:function(){return this.s}};var jb=new Ub;function zb(e,t,n){var r=e.s=t+n,i=r-t,a=r-i;e.t=t-a+(n-i)}var qb=1e-6,Gb=Math.PI,$b=Gb/2,Hb=Gb/4,Wb=2*Gb,Vb=180/Gb,Kb=Gb/180,Qb=Math.abs,Yb=Math.atan,Zb=Math.atan2,Xb=Math.cos,Jb=Math.ceil,ev=Math.exp,tv=(Math.floor,Math.log),nv=Math.pow,rv=Math.sin,iv=Math.sign||function(e){return e>0?1:e<0?-1:0},av=Math.sqrt,ov=Math.tan;function sv(e){return e>1?0:e<-1?Gb:Math.acos(e)}function lv(e){return e>1?$b:e<-1?-$b:Math.asin(e)}function cv(){}function uv(e,t){e&&fv.hasOwnProperty(e.type)&&fv[e.type](e,t)}var dv={Feature:function(e,t){uv(e.geometry,t)},FeatureCollection:function(e,t){for(var n=e.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,a=Xb(t),o=rv(t),s=_v*o,l=vv*a+s*Xb(i),c=s*r*rv(i);xv.add(Zb(c,l)),bv=e,vv=a,_v=o}var Nv=function(e){return Ev.reset(),yv(e,Sv),2*Ev};function Tv(e){return[Zb(e[1],e[0]),lv(e[2])]}function Dv(e){var t=e[0],n=e[1],r=Xb(n);return[r*Xb(t),r*rv(t),rv(n)]}function Av(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function kv(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function Rv(e,t){e[0]+=t[0],e[1]+=t[1],e[2]+=t[2]}function Iv(e,t){return[e[0]*t,e[1]*t,e[2]*t]}function Lv(e){var t=av(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]);e[0]/=t,e[1]/=t,e[2]/=t}var Pv,Fv,Bv,Uv,jv,zv,qv,Gv,$v,Hv,Wv=Bb(),Vv={point:Kv,lineStart:Yv,lineEnd:Zv,polygonStart:function(){Vv.point=Xv,Vv.lineStart=Jv,Vv.lineEnd=e_,Wv.reset(),Sv.polygonStart()},polygonEnd:function(){Sv.polygonEnd(),Vv.point=Kv,Vv.lineStart=Yv,Vv.lineEnd=Zv,xv<0?(Pv=-(Bv=180),Fv=-(Uv=90)):Wv>qb?Uv=90:Wv<-qb&&(Fv=-90),Hv[0]=Pv,Hv[1]=Bv}};function Kv(e,t){$v.push(Hv=[Pv=e,Bv=e]),tUv&&(Uv=t)}function Qv(e,t){var n=Dv([e*Kb,t*Kb]);if(Gv){var r=kv(Gv,n),i=kv([r[1],-r[0],0],r);Lv(i),i=Tv(i);var a,o=e-jv,s=o>0?1:-1,l=i[0]*Vb*s,c=Qb(o)>180;c^(s*jvUv&&(Uv=a):c^(s*jv<(l=(l+360)%360-180)&&lUv&&(Uv=t)),c?et_(Pv,Bv)&&(Bv=e):t_(e,Bv)>t_(Pv,Bv)&&(Pv=e):Bv>=Pv?(eBv&&(Bv=e)):e>jv?t_(Pv,e)>t_(Pv,Bv)&&(Bv=e):t_(e,Bv)>t_(Pv,Bv)&&(Pv=e)}else $v.push(Hv=[Pv=e,Bv=e]);tUv&&(Uv=t),Gv=n,jv=e}function Yv(){Vv.point=Qv}function Zv(){Hv[0]=Pv,Hv[1]=Bv,Vv.point=Kv,Gv=null}function Xv(e,t){if(Gv){var n=e-jv;Wv.add(Qb(n)>180?n+(n>0?360:-360):n)}else zv=e,qv=t;Sv.point(e,t),Qv(e,t)}function Jv(){Sv.lineStart()}function e_(){Xv(zv,qv),Sv.lineEnd(),Qb(Wv)>qb&&(Pv=-(Bv=180)),Hv[0]=Pv,Hv[1]=Bv,Gv=null}function t_(e,t){return(t-=e)<0?t+360:t}function n_(e,t){return e[0]-t[0]}function r_(e,t){return e[0]<=e[1]?e[0]<=t&&t<=e[1]:tt_(r[0],r[1])&&(r[1]=i[1]),t_(i[0],r[1])>t_(r[0],r[1])&&(r[0]=i[0])):a.push(r=i);for(o=-1/0,t=0,r=a[n=a.length-1];t<=n;r=i,++t)i=a[t],(s=t_(r[1],i[0]))>o&&(o=s,Pv=i[0],Bv=r[1])}return $v=Hv=null,Pv===1/0||Fv===1/0?[[NaN,NaN],[NaN,NaN]]:[[Pv,Fv],[Bv,Uv]]},x_={sphere:cv,point:E_,lineStart:w_,lineEnd:M_,polygonStart:function(){x_.lineStart=N_,x_.lineEnd=T_},polygonEnd:function(){x_.lineStart=w_,x_.lineEnd=M_}};function E_(e,t){e*=Kb;var n=Xb(t*=Kb);S_(n*Xb(e),n*rv(e),rv(t))}function S_(e,t,n){o_+=(e-o_)/++i_,s_+=(t-s_)/i_,l_+=(n-l_)/i_}function w_(){x_.point=C_}function C_(e,t){e*=Kb;var n=Xb(t*=Kb);b_=n*Xb(e),v_=n*rv(e),__=rv(t),x_.point=O_,S_(b_,v_,__)}function O_(e,t){e*=Kb;var n=Xb(t*=Kb),r=n*Xb(e),i=n*rv(e),a=rv(t),o=Zb(av((o=v_*a-__*i)*o+(o=__*r-b_*a)*o+(o=b_*i-v_*r)*o),b_*r+v_*i+__*a);a_+=o,c_+=o*(b_+(b_=r)),u_+=o*(v_+(v_=i)),d_+=o*(__+(__=a)),S_(b_,v_,__)}function M_(){x_.point=E_}function N_(){x_.point=D_}function T_(){A_(g_,h_),x_.point=E_}function D_(e,t){g_=e,h_=t,e*=Kb,t*=Kb,x_.point=A_;var n=Xb(t);b_=n*Xb(e),v_=n*rv(e),__=rv(t),S_(b_,v_,__)}function A_(e,t){e*=Kb;var n=Xb(t*=Kb),r=n*Xb(e),i=n*rv(e),a=rv(t),o=v_*a-__*i,s=__*r-b_*a,l=b_*i-v_*r,c=av(o*o+s*s+l*l),u=lv(c),d=c&&-u/c;f_+=d*o,p_+=d*s,m_+=d*l,a_+=u,c_+=u*(b_+(b_=r)),u_+=u*(v_+(v_=i)),d_+=u*(__+(__=a)),S_(b_,v_,__)}var k_=function(e){i_=a_=o_=s_=l_=c_=u_=d_=f_=p_=m_=0,yv(e,x_);var t=f_,n=p_,r=m_,i=t*t+n*n+r*r;return i<1e-12&&(t=c_,n=u_,r=d_,a_Gb?e-Wb:e<-Gb?e+Wb:e,t]}function L_(e,t,n){return(e%=Wb)?t||n?R_(F_(e),B_(t,n)):F_(e):t||n?B_(t,n):I_}function P_(e){return function(t,n){return[(t+=e)>Gb?t-Wb:t<-Gb?t+Wb:t,n]}}function F_(e){var t=P_(e);return t.invert=P_(-e),t}function B_(e,t){var n=Xb(e),r=rv(e),i=Xb(t),a=rv(t);function o(e,t){var o=Xb(t),s=Xb(e)*o,l=rv(e)*o,c=rv(t),u=c*n+s*r;return[Zb(l*i-u*a,s*n-c*r),lv(u*i+l*a)]}return o.invert=function(e,t){var o=Xb(t),s=Xb(e)*o,l=rv(e)*o,c=rv(t),u=c*i-l*a;return[Zb(l*i+c*a,s*n+u*r),lv(u*n-s*r)]},o}I_.invert=I_;var U_=function(e){function t(t){return(t=e(t[0]*Kb,t[1]*Kb))[0]*=Vb,t[1]*=Vb,t}return e=L_(e[0]*Kb,e[1]*Kb,e.length>2?e[2]*Kb:0),t.invert=function(t){return(t=e.invert(t[0]*Kb,t[1]*Kb))[0]*=Vb,t[1]*=Vb,t},t};function j_(e,t,n,r,i,a){if(n){var o=Xb(t),s=rv(t),l=r*n;null==i?(i=t+r*Wb,a=t-l/2):(i=z_(o,i),a=z_(o,a),(r>0?ia)&&(i+=r*Wb));for(var c,u=i;r>0?u>a:u1&&t.push(t.pop().concat(t.shift()))},result:function(){var n=t;return t=[],e=null,n}}},G_=function(e,t){return Qb(e[0]-t[0])=0;--a)i.point((u=c[a])[0],u[1]);else r(f.x,f.p.x,-1,i);f=f.p}c=(f=f.o).z,p=!p}while(!f.v);i.lineEnd()}}};function W_(e){if(t=e.length){for(var t,n,r=0,i=e[0];++r=0?1:-1,C=w*S,O=C>Gb,M=g*x;if(V_.add(Zb(M*w*rv(C),h*E+M*Xb(C))),o+=O?S+w*Wb:S,O^p>=n^_>=n){var N=kv(Dv(f),Dv(v));Lv(N);var T=kv(a,N);Lv(T);var D=(O^S>=0?-1:1)*lv(T[2]);(r>D||r===D&&(N[0]||N[1]))&&(s+=O^S>=0?1:-1)}}return(o<-qb||o0){for(d||(i.polygonStart(),d=!0),i.lineStart(),e=0;e1&&2&l&&f.push(f.pop().concat(f.shift())),o.push(f.filter(Y_))}return f}};function Y_(e){return e.length>1}function Z_(e,t){return((e=e.x)[0]<0?e[1]-$b-qb:$b-e[1])-((t=t.x)[0]<0?t[1]-$b-qb:$b-t[1])}var X_=Q_(function(){return!0},function(e){var t,n=NaN,r=NaN,i=NaN;return{lineStart:function(){e.lineStart(),t=1},point:function(a,o){var s=a>0?Gb:-Gb,l=Qb(a-n);Qb(l-Gb)0?$b:-$b),e.point(i,r),e.lineEnd(),e.lineStart(),e.point(s,r),e.point(a,r),t=0):i!==s&&l>=Gb&&(Qb(n-i)qb?Yb((rv(t)*(a=Xb(r))*rv(n)-rv(r)*(i=Xb(t))*rv(e))/(i*a*o)):(t+r)/2}(n,r,a,o),e.point(i,r),e.lineEnd(),e.lineStart(),e.point(s,r),t=0),e.point(n=a,r=o),i=s},lineEnd:function(){e.lineEnd(),n=r=NaN},clean:function(){return 2-t}}},function(e,t,n,r){var i;if(null==e)i=n*$b,r.point(-Gb,i),r.point(0,i),r.point(Gb,i),r.point(Gb,0),r.point(Gb,-i),r.point(0,-i),r.point(-Gb,-i),r.point(-Gb,0),r.point(-Gb,i);else if(Qb(e[0]-t[0])>qb){var a=e[0]0,i=Qb(t)>qb;function a(e,n){return Xb(e)*Xb(n)>t}function o(e,n,r){var i=[1,0,0],a=kv(Dv(e),Dv(n)),o=Av(a,a),s=a[0],l=o-s*s;if(!l)return!r&&e;var c=t*o/l,u=-t*s/l,d=kv(i,a),f=Iv(i,c);Rv(f,Iv(a,u));var p=d,m=Av(f,p),g=Av(p,p),h=m*m-g*(Av(f,f)-1);if(!(h<0)){var b=av(h),v=Iv(p,(-m-b)/g);if(Rv(v,f),v=Tv(v),!r)return v;var _,y=e[0],x=n[0],E=e[1],S=n[1];x0^v[1]<(Qb(v[0]-y)Gb^(y<=v[0]&&v[0]<=x)){var O=Iv(p,(-m+b)/g);return Rv(O,f),[v,Tv(O)]}}}function s(t,n){var i=r?e:Gb-e,a=0;return t<-i?a|=1:t>i&&(a|=2),n<-i?a|=4:n>i&&(a|=8),a}return Q_(a,function(e){var t,n,l,c,u;return{lineStart:function(){c=l=!1,u=1},point:function(d,f){var p,m=[d,f],g=a(d,f),h=r?g?0:s(d,f):g?s(d+(d<0?Gb:-Gb),f):0;if(!t&&(c=l=g)&&e.lineStart(),g!==l&&(!(p=o(t,m))||G_(t,p)||G_(m,p))&&(m[0]+=qb,m[1]+=qb,g=a(m[0],m[1])),g!==l)u=0,g?(e.lineStart(),p=o(m,t),e.point(p[0],p[1])):(p=o(t,m),e.point(p[0],p[1]),e.lineEnd()),t=p;else if(i&&t&&r^g){var b;h&n||!(b=o(m,t,!0))||(u=0,r?(e.lineStart(),e.point(b[0][0],b[0][1]),e.point(b[1][0],b[1][1]),e.lineEnd()):(e.point(b[1][0],b[1][1]),e.lineEnd(),e.lineStart(),e.point(b[0][0],b[0][1])))}!g||t&&G_(t,m)||e.point(m[0],m[1]),t=m,l=g,n=h},lineEnd:function(){l&&e.lineEnd(),t=null},clean:function(){return u|(c&&l)<<1}}},function(t,r,i,a){j_(a,e,n,i,t,r)},r?[0,-e]:[-Gb,e-Gb])},ey=function(e,t,n,r,i,a){var o,s=e[0],l=e[1],c=0,u=1,d=t[0]-s,f=t[1]-l;if(o=n-s,d||!(o>0)){if(o/=d,d<0){if(o0){if(o>u)return;o>c&&(c=o)}if(o=i-s,d||!(o<0)){if(o/=d,d<0){if(o>u)return;o>c&&(c=o)}else if(d>0){if(o0)){if(o/=f,f<0){if(o0){if(o>u)return;o>c&&(c=o)}if(o=a-l,f||!(o<0)){if(o/=f,f<0){if(o>u)return;o>c&&(c=o)}else if(f>0){if(o0&&(e[0]=s+c*d,e[1]=l+c*f),u<1&&(t[0]=s+u*d,t[1]=l+u*f),!0}}}}},ty=1e9,ny=-ty;function ry(e,t,n,r){function i(i,a){return e<=i&&i<=n&&t<=a&&a<=r}function a(i,a,s,c){var u=0,d=0;if(null==i||(u=o(i,s))!==(d=o(a,s))||l(i,a)<0^s>0)do{c.point(0===u||3===u?e:n,u>1?r:t)}while((u=(u+s+4)%4)!==d);else c.point(a[0],a[1])}function o(r,i){return Qb(r[0]-e)0?0:3:Qb(r[0]-n)0?2:1:Qb(r[1]-t)0?1:0:i>0?3:2}function s(e,t){return l(e.x,t.x)}function l(e,t){var n=o(e,1),r=o(t,1);return n!==r?n-r:0===n?t[1]-e[1]:1===n?e[0]-t[0]:2===n?e[1]-t[1]:t[0]-e[0]}return function(o){var l,c,u,d,f,p,m,g,h,b,v,_=o,y=q_(),x={point:E,lineStart:function(){x.point=S,c&&c.push(u=[]);b=!0,h=!1,m=g=NaN},lineEnd:function(){l&&(S(d,f),p&&h&&y.rejoin(),l.push(y.result()));x.point=E,h&&_.lineEnd()},polygonStart:function(){_=y,l=[],c=[],v=!0},polygonEnd:function(){var t=function(){for(var t=0,n=0,i=c.length;nr&&(f-a)*(r-o)>(p-o)*(e-a)&&++t:p<=r&&(f-a)*(r-o)<(p-o)*(e-a)&&--t;return t}(),n=v&&t,i=(l=Ai(l)).length;(n||i)&&(o.polygonStart(),n&&(o.lineStart(),a(null,null,1,o),o.lineEnd()),i&&H_(l,s,t,a,o),o.polygonEnd());_=o,l=c=u=null}};function E(e,t){i(e,t)&&_.point(e,t)}function S(a,o){var s=i(a,o);if(c&&u.push([a,o]),b)d=a,f=o,p=s,b=!1,s&&(_.lineStart(),_.point(a,o));else if(s&&h)_.point(a,o);else{var l=[m=Math.max(ny,Math.min(ty,m)),g=Math.max(ny,Math.min(ty,g))],y=[a=Math.max(ny,Math.min(ty,a)),o=Math.max(ny,Math.min(ty,o))];ey(l,y,e,t,n,r)?(h||(_.lineStart(),_.point(l[0],l[1])),_.point(y[0],y[1]),s||_.lineEnd(),v=!1):s&&(_.lineStart(),_.point(a,o),v=!1)}m=a,g=o,h=s}return x}}Bb();function iy(e,t,n){var r=xi(e,t-qb,n).concat(t);return function(e){return r.map(function(t){return[e,t]})}}function ay(e,t,n){var r=xi(e,t-qb,n).concat(t);return function(e){return r.map(function(t){return[t,e]})}}function oy(){var e,t,n,r,i,a,o,s,l,c,u,d,f=10,p=f,m=90,g=360,h=2.5;function b(){return{type:"MultiLineString",coordinates:v()}}function v(){return xi(Jb(r/m)*m,n,m).map(u).concat(xi(Jb(s/g)*g,o,g).map(d)).concat(xi(Jb(t/f)*f,e,f).filter(function(e){return Qb(e%m)>qb}).map(l)).concat(xi(Jb(a/p)*p,i,p).filter(function(e){return Qb(e%g)>qb}).map(c))}return b.lines=function(){return v().map(function(e){return{type:"LineString",coordinates:e}})},b.outline=function(){return{type:"Polygon",coordinates:[u(r).concat(d(o).slice(1),u(n).reverse().slice(1),d(s).reverse().slice(1))]}},b.extent=function(e){return arguments.length?b.extentMajor(e).extentMinor(e):b.extentMinor()},b.extentMajor=function(e){return arguments.length?(r=+e[0][0],n=+e[1][0],s=+e[0][1],o=+e[1][1],r>n&&(e=r,r=n,n=e),s>o&&(e=s,s=o,o=e),b.precision(h)):[[r,s],[n,o]]},b.extentMinor=function(n){return arguments.length?(t=+n[0][0],e=+n[1][0],a=+n[0][1],i=+n[1][1],t>e&&(n=t,t=e,e=n),a>i&&(n=a,a=i,i=n),b.precision(h)):[[t,a],[e,i]]},b.step=function(e){return arguments.length?b.stepMajor(e).stepMinor(e):b.stepMinor()},b.stepMajor=function(e){return arguments.length?(m=+e[0],g=+e[1],b):[m,g]},b.stepMinor=function(e){return arguments.length?(f=+e[0],p=+e[1],b):[f,p]},b.precision=function(f){return arguments.length?(h=+f,l=iy(a,i,90),c=ay(t,e,h),u=iy(s,o,90),d=ay(r,n,h),b):h},b.extentMajor([[-180,-90+qb],[180,90-qb]]).extentMinor([[-180,-80-qb],[180,80+qb]])}var sy,ly,cy,uy,dy=function(e){return e},fy=Bb(),py=Bb(),my={point:cv,lineStart:cv,lineEnd:cv,polygonStart:function(){my.lineStart=gy,my.lineEnd=vy},polygonEnd:function(){my.lineStart=my.lineEnd=my.point=cv,fy.add(Qb(py)),py.reset()},result:function(){var e=fy/2;return fy.reset(),e}};function gy(){my.point=hy}function hy(e,t){my.point=by,sy=cy=e,ly=uy=t}function by(e,t){py.add(uy*e-cy*t),cy=e,uy=t}function vy(){by(sy,ly)}var _y=my,yy=1/0,xy=yy,Ey=-yy,Sy=Ey;var wy,Cy,Oy,My,Ny={point:function(e,t){eEy&&(Ey=e);tSy&&(Sy=t)},lineStart:cv,lineEnd:cv,polygonStart:cv,polygonEnd:cv,result:function(){var e=[[yy,xy],[Ey,Sy]];return Ey=Sy=-(xy=yy=1/0),e}},Ty=0,Dy=0,Ay=0,ky=0,Ry=0,Iy=0,Ly=0,Py=0,Fy=0,By={point:Uy,lineStart:jy,lineEnd:Gy,polygonStart:function(){By.lineStart=$y,By.lineEnd=Hy},polygonEnd:function(){By.point=Uy,By.lineStart=jy,By.lineEnd=Gy},result:function(){var e=Fy?[Ly/Fy,Py/Fy]:Iy?[ky/Iy,Ry/Iy]:Ay?[Ty/Ay,Dy/Ay]:[NaN,NaN];return Ty=Dy=Ay=ky=Ry=Iy=Ly=Py=Fy=0,e}};function Uy(e,t){Ty+=e,Dy+=t,++Ay}function jy(){By.point=zy}function zy(e,t){By.point=qy,Uy(Oy=e,My=t)}function qy(e,t){var n=e-Oy,r=t-My,i=av(n*n+r*r);ky+=i*(Oy+e)/2,Ry+=i*(My+t)/2,Iy+=i,Uy(Oy=e,My=t)}function Gy(){By.point=Uy}function $y(){By.point=Wy}function Hy(){Vy(wy,Cy)}function Wy(e,t){By.point=Vy,Uy(wy=Oy=e,Cy=My=t)}function Vy(e,t){var n=e-Oy,r=t-My,i=av(n*n+r*r);ky+=i*(Oy+e)/2,Ry+=i*(My+t)/2,Iy+=i,Ly+=(i=My*e-Oy*t)*(Oy+e),Py+=i*(My+t),Fy+=3*i,Uy(Oy=e,My=t)}var Ky=By;function Qy(e){this._context=e}Qy.prototype={_radius:4.5,pointRadius:function(e){return this._radius=e,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(e,t){switch(this._point){case 0:this._context.moveTo(e,t),this._point=1;break;case 1:this._context.lineTo(e,t);break;default:this._context.moveTo(e+this._radius,t),this._context.arc(e,t,this._radius,0,Wb)}},result:cv};var Yy,Zy,Xy,Jy,ex,tx=Bb(),nx={point:cv,lineStart:function(){nx.point=rx},lineEnd:function(){Yy&&ix(Zy,Xy),nx.point=cv},polygonStart:function(){Yy=!0},polygonEnd:function(){Yy=null},result:function(){var e=+tx;return tx.reset(),e}};function rx(e,t){nx.point=ix,Zy=Jy=e,Xy=ex=t}function ix(e,t){Jy-=e,ex-=t,tx.add(av(Jy*Jy+ex*ex)),Jy=e,ex=t}var ax=nx;function ox(){this._string=[]}function sx(e){return"m0,"+e+"a"+e+","+e+" 0 1,1 0,"+-2*e+"a"+e+","+e+" 0 1,1 0,"+2*e+"z"}ox.prototype={_radius:4.5,_circle:sx(4.5),pointRadius:function(e){return(e=+e)!==this._radius&&(this._radius=e,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._string.push("Z"),this._point=NaN},point:function(e,t){switch(this._point){case 0:this._string.push("M",e,",",t),this._point=1;break;case 1:this._string.push("L",e,",",t);break;default:null==this._circle&&(this._circle=sx(this._radius)),this._string.push("M",e,",",t,this._circle)}},result:function(){if(this._string.length){var e=this._string.join("");return this._string=[],e}return null}};var lx=function(e,t){var n,r,i=4.5;function a(e){return e&&("function"==typeof i&&r.pointRadius(+i.apply(this,arguments)),yv(e,n(r))),r.result()}return a.area=function(e){return yv(e,n(_y)),_y.result()},a.measure=function(e){return yv(e,n(ax)),ax.result()},a.bounds=function(e){return yv(e,n(Ny)),Ny.result()},a.centroid=function(e){return yv(e,n(Ky)),Ky.result()},a.projection=function(t){return arguments.length?(n=null==t?(e=null,dy):(e=t).stream,a):e},a.context=function(e){return arguments.length?(r=null==e?(t=null,new ox):new Qy(t=e),"function"!=typeof i&&r.pointRadius(i),a):t},a.pointRadius=function(e){return arguments.length?(i="function"==typeof e?e:(r.pointRadius(+e),+e),a):i},a.projection(e).context(t)};function cx(e){return function(t){var n=new ux;for(var r in e)n[r]=e[r];return n.stream=t,n}}function ux(){}function dx(e,t,n){var r=e.clipExtent&&e.clipExtent();return e.scale(150).translate([0,0]),null!=r&&e.clipExtent(null),yv(n,e.stream(Ny)),t(Ny.result()),null!=r&&e.clipExtent(r),e}function fx(e,t,n){return dx(e,function(n){var r=t[1][0]-t[0][0],i=t[1][1]-t[0][1],a=Math.min(r/(n[1][0]-n[0][0]),i/(n[1][1]-n[0][1])),o=+t[0][0]+(r-a*(n[1][0]+n[0][0]))/2,s=+t[0][1]+(i-a*(n[1][1]+n[0][1]))/2;e.scale(150*a).translate([o,s])},n)}function px(e,t,n){return fx(e,[[0,0],t],n)}function mx(e,t,n){return dx(e,function(n){var r=+t,i=r/(n[1][0]-n[0][0]),a=(r-i*(n[1][0]+n[0][0]))/2,o=-i*n[0][1];e.scale(150*i).translate([a,o])},n)}function gx(e,t,n){return dx(e,function(n){var r=+t,i=r/(n[1][1]-n[0][1]),a=-i*n[0][0],o=(r-i*(n[1][1]+n[0][1]))/2;e.scale(150*i).translate([a,o])},n)}ux.prototype={constructor:ux,point:function(e,t){this.stream.point(e,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var hx=16,bx=Xb(30*Kb),vx=function(e,t){return+t?function(e,t){function n(r,i,a,o,s,l,c,u,d,f,p,m,g,h){var b=c-r,v=u-i,_=b*b+v*v;if(_>4*t&&g--){var y=o+f,x=s+p,E=l+m,S=av(y*y+x*x+E*E),w=lv(E/=S),C=Qb(Qb(E)-1)t||Qb((b*T+v*D)/_-.5)>.3||o*f+s*p+l*m2?e[2]%360*Kb:0,M()):[h*Vb,b*Vb,v*Vb]},C.angle=function(e){return arguments.length?(_=e%360*Kb,M()):_*Vb},C.precision=function(e){return arguments.length?(o=vx(s,w=e*e),N()):av(w)},C.fitExtent=function(e,t){return fx(C,e,t)},C.fitSize=function(e,t){return px(C,e,t)},C.fitWidth=function(e,t){return mx(C,e,t)},C.fitHeight=function(e,t){return gx(C,e,t)},function(){return t=e.apply(this,arguments),C.invert=t.invert&&O,M()}}function Sx(e){var t=0,n=Gb/3,r=Ex(e),i=r(t,n);return i.parallels=function(e){return arguments.length?r(t=e[0]*Kb,n=e[1]*Kb):[t*Vb,n*Vb]},i}function wx(e,t){var n=rv(e),r=(n+rv(t))/2;if(Qb(r)0?t<-$b+qb&&(t=-$b+qb):t>$b-qb&&(t=$b-qb);var n=i/nv(Rx(t),r);return[n*rv(r*e),i-n*Xb(r*e)]}return a.invert=function(e,t){var n=i-t,a=iv(r)*av(e*e+n*n);return[Zb(e,Qb(n))/r*iv(n),2*Yb(nv(i/a,1/r))-$b]},a}function Lx(e,t){return[e,t]}Lx.invert=Lx;function Px(e,t){var n=Xb(e),r=e===t?rv(e):(n-Xb(t))/(t-e),i=n/r+e;if(Qb(r)qb&&--i>0);return[e/(.8707+(a=r*r)*(a*(a*a*a*(.003971-.001529*a)-.013791)-.131979)),r]};function jx(e,t){return[Xb(t)*rv(e),rv(t)]}jx.invert=Nx(lv);function zx(e,t){var n=Xb(t),r=1+Xb(e)*n;return[n*rv(e)/r,rv(t)/r]}zx.invert=Nx(function(e){return 2*Yb(e)});function qx(e,t){return[tv(ov(($b+t)/2)),-e]}qx.invert=function(e,t){return[-t,2*Yb(ev(e))-$b]};var Gx=lx(),$x=["clipAngle","clipExtent","scale","translate","center","rotate","parallels","precision","reflectX","reflectY","coefficient","distance","fraction","lobes","parallel","radius","ratio","spacing","tilt"];function Hx(e,t){if(!e||"string"!=typeof e)throw new Error("Projection type must be a name string.");return e=e.toLowerCase(),arguments.length>1?(Vx[e]=function(e,t){return function n(){var r=t();return r.type=e,r.path=lx().projection(r),r.copy=r.copy||function(){var e=n();return $x.forEach(function(t){r.hasOwnProperty(t)&&e[t](r[t]())}),e.path.pointRadius(r.path.pointRadius()),e},r}}(e,t),this):Vx.hasOwnProperty(e)?Vx[e]:null}function Wx(e){return e&&e.path||Gx}var Vx={albers:Ox,albersusa:function(){var e,t,n,r,i,a,o=Ox(),s=Cx().rotate([154,0]).center([-2,58.5]).parallels([55,65]),l=Cx().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(e,t){a=[e,t]}};function u(e){var t=e[0],o=e[1];return a=null,n.point(t,o),a||(r.point(t,o),a)||(i.point(t,o),a)}function d(){return e=t=null,u}return u.invert=function(e){var t=o.scale(),n=o.translate(),r=(e[0]-n[0])/t,i=(e[1]-n[1])/t;return(i>=.12&&i<.234&&r>=-.425&&r<-.214?s:i>=.166&&i<.234&&r>=-.214&&r<-.115?l:o).invert(e)},u.stream=function(n){return e&&t===n?e:(r=[o.stream(t=n),s.stream(n),l.stream(n)],i=r.length,e={point:function(e,t){for(var n=-1;++n2?e[2]+90:90]):[(e=n())[0],e[1],e[2]-90]},n([0,0,90]).scale(159.155)}};for(var Kx in Vx)Hx(Kx,Vx[Kx]);function Qx(e){Yr.call(this,null,e)}function Yx(e){Yr.call(this,null,e)}function Zx(e){Yr.call(this,null,e)}function Xx(e){Yr.call(this,[],e),this.generator=oy()}function Jx(e){Yr.call(this,null,e),this.modified(!0)}function eE(e,t,n){Object(Ee.x)(e[t])&&e[t](n)}Qx.Definition={type:"GeoPath",metadata:{modifies:!0},params:[{name:"projection",type:"projection"},{name:"field",type:"field"},{name:"pointRadius",type:"number",expr:!0},{name:"as",type:"string",default:"path"}]},Object(Ee.t)(Qx,Yr).transform=function(e,t){var n=t.fork(t.ALL),r=this.value,i=e.field||Ee.s,a=e.as||"path",o=n.SOURCE;!r||e.modified()?(this.value=r=Wx(e.projection),n.materialize().reflow()):o=i===Ee.s||t.modified(i.fields)?n.ADD_MOD:n.ADD;var s=function(e,t){var n=e.pointRadius();e.context(null),null!=t&&e.pointRadius(t);return n}(r,e.pointRadius);return n.visit(o,function(e){e[a]=r(i(e))}),r.pointRadius(s),n.modifies(a)},Yx.Definition={type:"GeoPoint",metadata:{modifies:!0},params:[{name:"projection",type:"projection",required:!0},{name:"fields",type:"field",array:!0,required:!0,length:2},{name:"as",type:"string",array:!0,length:2,default:["x","y"]}]},Object(Ee.t)(Yx,Yr).transform=function(e,t){var n,r=e.projection,i=e.fields[0],a=e.fields[1],o=e.as||["x","y"],s=o[0],l=o[1];function c(e){var t=r([i(e),a(e)]);t?(e[s]=t[0],e[l]=t[1]):(e[s]=void 0,e[l]=void 0)}return e.modified()?t=t.materialize().reflow(!0).visit(t.SOURCE,c):(n=t.modified(i.fields)||t.modified(a.fields),t.visit(n?t.ADD_MOD:t.ADD,c)),t.modifies(o)},Zx.Definition={type:"GeoShape",metadata:{modifies:!0},params:[{name:"projection",type:"projection"},{name:"field",type:"field",default:"datum"},{name:"pointRadius",type:"number",expr:!0},{name:"as",type:"string",default:"shape"}]},Object(Ee.t)(Zx,Yr).transform=function(e,t){var n=t.fork(t.ALL),r=this.value,i=e.field||Object(Ee.q)("datum"),a=e.as||"shape",o=n.ADD_MOD;return r&&!e.modified()||(this.value=r=function(e,t,n){var r=null==n?function(n){return e(t(n))}:function(r){var i=e.pointRadius(),a=e.pointRadius(n)(t(r));return e.pointRadius(i),a};return r.context=function(t){return e.context(t),r},r}(Wx(e.projection),i,e.pointRadius),n.materialize().reflow(),o=n.SOURCE),n.visit(o,function(e){e[a]=r}),n.modifies(a)},Xx.Definition={type:"Graticule",metadata:{changes:!0},params:[{name:"extent",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"extentMajor",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"extentMinor",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"step",type:"number",array:!0,length:2},{name:"stepMajor",type:"number",array:!0,length:2,default:[90,360]},{name:"stepMinor",type:"number",array:!0,length:2,default:[10,10]},{name:"precision",type:"number",default:2.5}]},Object(Ee.t)(Xx,Yr).transform=function(e,t){var n,r=this.value,i=this.generator;if(!r.length||e.modified())for(var a in e)Object(Ee.x)(i[a])&&i[a](e[a]);return n=i(),r.length?t.mod.push(ke(r[0],n)):t.add.push(Te(n)),r[0]=n,t},Object(Ee.t)(Jx,Yr).transform=function(e,t){var n=this.value;return!n||e.modified("type")?(this.value=n=function(e){var t=Hx((e||"mercator").toLowerCase());t||Object(Ee.l)("Unrecognized projection type: "+e);return t()}(e.type),$x.forEach(function(t){null!=e[t]&&eE(n,t,e[t])})):$x.forEach(function(t){e.modified(t)&&eE(n,t,e[t])}),null!=e.pointRadius&&n.path.pointRadius(e.pointRadius),e.fit&&function(e,t){var n=(r=t.fit,1===(r=Object(Ee.h)(r)).length?r[0]:{type:Pb,features:r.reduce(function(e,t){return t&&t.type===Pb?e.push.apply(e,t.features):Object(Ee.u)(t)?e.push.apply(e,t):e.push(t),e},[])});var r;t.extent?e.fitExtent(t.extent,n):t.size&&e.fitSize(t.size,n)}(n,e),t.fork(t.NO_SOURCE|t.NO_FIELDS)};var tE=function(e){return function(){return e}},nE=function(){return 1e-6*(Math.random()-.5)};function rE(e,t,n,r){if(isNaN(t)||isNaN(n))return e;var i,a,o,s,l,c,u,d,f,p=e._root,m={data:r},g=e._x0,h=e._y0,b=e._x1,v=e._y1;if(!p)return e._root=m,e;for(;p.length;)if((c=t>=(a=(g+b)/2))?g=a:b=a,(u=n>=(o=(h+v)/2))?h=o:v=o,i=p,!(p=p[d=u<<1|c]))return i[d]=m,e;if(s=+e._x.call(null,p.data),l=+e._y.call(null,p.data),t===s&&n===l)return m.next=p,i?i[d]=m:e._root=m,e;do{i=i?i[d]=new Array(4):e._root=new Array(4),(c=t>=(a=(g+b)/2))?g=a:b=a,(u=n>=(o=(h+v)/2))?h=o:v=o}while((d=u<<1|c)==(f=(l>=o)<<1|s>=a));return i[f]=p,i[d]=m,e}var iE=function(e,t,n,r,i){this.node=e,this.x0=t,this.y0=n,this.x1=r,this.y1=i};function aE(e){return e[0]}function oE(e){return e[1]}function sE(e,t,n){var r=new lE(null==t?aE:t,null==n?oE:n,NaN,NaN,NaN,NaN);return null==e?r:r.addAll(e)}function lE(e,t,n,r,i,a){this._x=e,this._y=t,this._x0=n,this._y0=r,this._x1=i,this._y1=a,this._root=void 0}function cE(e){for(var t={data:e.data},n=t;e=e.next;)n=n.next={data:e.data};return t}var uE=sE.prototype=lE.prototype;function dE(e){return e.x+e.vx}function fE(e){return e.y+e.vy}uE.copy=function(){var e,t,n=new lE(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return n;if(!r.length)return n._root=cE(r),n;for(e=[{source:r,target:n._root=new Array(4)}];r=e.pop();)for(var i=0;i<4;++i)(t=r.source[i])&&(t.length?e.push({source:t,target:r.target[i]=new Array(4)}):r.target[i]=cE(t));return n},uE.add=function(e){var t=+this._x.call(null,e),n=+this._y.call(null,e);return rE(this.cover(t,n),t,n,e)},uE.addAll=function(e){var t,n,r,i,a=e.length,o=new Array(a),s=new Array(a),l=1/0,c=1/0,u=-1/0,d=-1/0;for(n=0;nu&&(u=r),id&&(d=i));for(ue||e>i||r>t||t>a))return this;var o,s,l=i-n,c=this._root;switch(s=(t<(r+a)/2)<<1|e<(n+i)/2){case 0:do{(o=new Array(4))[s]=c,c=o}while(a=r+(l*=2),e>(i=n+l)||t>a);break;case 1:do{(o=new Array(4))[s]=c,c=o}while(a=r+(l*=2),(n=i-l)>e||t>a);break;case 2:do{(o=new Array(4))[s]=c,c=o}while(r=a-(l*=2),e>(i=n+l)||r>t);break;case 3:do{(o=new Array(4))[s]=c,c=o}while(r=a-(l*=2),(n=i-l)>e||r>t)}this._root&&this._root.length&&(this._root=c)}return this._x0=n,this._y0=r,this._x1=i,this._y1=a,this},uE.data=function(){var e=[];return this.visit(function(t){if(!t.length)do{e.push(t.data)}while(t=t.next)}),e},uE.extent=function(e){return arguments.length?this.cover(+e[0][0],+e[0][1]).cover(+e[1][0],+e[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]},uE.find=function(e,t,n){var r,i,a,o,s,l,c,u=this._x0,d=this._y0,f=this._x1,p=this._y1,m=[],g=this._root;for(g&&m.push(new iE(g,u,d,f,p)),null==n?n=1/0:(u=e-n,d=t-n,f=e+n,p=t+n,n*=n);l=m.pop();)if(!(!(g=l.node)||(i=l.x0)>f||(a=l.y0)>p||(o=l.x1)=b)<<1|e>=h)&&(l=m[m.length-1],m[m.length-1]=m[m.length-1-c],m[m.length-1-c]=l)}else{var v=e-+this._x.call(null,g.data),_=t-+this._y.call(null,g.data),y=v*v+_*_;if(y=(s=(m+h)/2))?m=s:h=s,(u=o>=(l=(g+b)/2))?g=l:b=l,t=p,!(p=p[d=u<<1|c]))return this;if(!p.length)break;(t[d+1&3]||t[d+2&3]||t[d+3&3])&&(n=t,f=d)}for(;p.data!==e;)if(r=p,!(p=p.next))return this;return(i=p.next)&&delete p.next,r?(i?r.next=i:delete r.next,this):t?(i?t[d]=i:delete t[d],(p=t[0]||t[1]||t[2]||t[3])&&p===(t[3]||t[2]||t[1]||t[0])&&!p.length&&(n?n[f]=p:this._root=p),this):(this._root=i,this)},uE.removeAll=function(e){for(var t=0,n=e.length;t=0&&(t=e.slice(n+1),e=e.slice(0,n)),e&&!r.hasOwnProperty(e))throw new Error("unknown type: "+e);return{type:e,name:t}})),o=-1,s=a.length;if(!(arguments.length<2)){if(null!=t&&"function"!=typeof t)throw new Error("invalid callback: "+t);for(;++o0)for(var n,r,i=new Array(n),a=0;a=0&&t._call.call(null,e),t=t._next;--SE}()}finally{SE=0,function(){var e,t,n=yE,r=1/0;for(;n;)n._call?(r>n._time&&(r=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:yE=t);xE=e,BE(r)}(),NE=0}}function FE(){var e=DE.now(),t=e-ME;t>OE&&(TE-=t,ME=e)}function BE(e){SE||(wE&&(wE=clearTimeout(wE)),e-NE>24?(e<1/0&&(wE=setTimeout(PE,e-DE.now()-TE)),CE&&(CE=clearInterval(CE))):(CE||(ME=DE.now(),CE=setInterval(FE,OE)),SE=1,AE(PE)))}IE.prototype=LE.prototype={constructor:IE,restart:function(e,t,n){if("function"!=typeof e)throw new TypeError("callback is not a function");n=(null==n?kE():+n)+(null==t?0:+t),this._next||xE===this||(xE?xE._next=this:yE=this,xE=this),this._call=e,this._time=n,BE()},stop:function(){this._call&&(this._call=null,this._time=1/0,BE())}};function UE(e){return e.x}function jE(e){return e.y}var zE=10,qE=Math.PI*(3-Math.sqrt(5)),GE=function(e){var t,n=1,r=.001,i=1-Math.pow(r,1/300),a=0,o=.6,s=Gd(),l=LE(u),c=EE("tick","end");function u(){d(),c.call("tick",t),n1?(null==n?s.remove(e):s.set(e,p(n)),t):s.get(e)},find:function(t,n,r){var i,a,o,s,l,c=0,u=e.length;for(null==r?r=1/0:r*=r,c=0;c1?(c.on(e,n),t):c.on(e)}}},$E={center:function(e,t){var n;function r(){var r,i,a=n.length,o=0,s=0;for(r=0;rl+p||ic+p||as.index){var m=l-o.x-o.vx,g=c-o.y-o.vy,h=m*m+g*g;he.r&&(e.r=e[t].r)}function s(){if(t){var r,i,a=t.length;for(n=new Array(a),r=0;r=o)){(e.data!==t||e.next)&&(0===u&&(p+=(u=nE())*u),0===d&&(p+=(d=nE())*d),p=0;)i.tick();else if(i.stopped()&&i.restart(),!a)return t.StopPropagation;return this.finish(e,t)},YE.finish=function(e,t){for(var n,r=t.dataflow,i=this._argops,a=0,o=i.length;a=0;)t+=n[r].value;else t=1;e.value=t}function oS(e,t){var n,r,i,a,o,s=new uS(e),l=+e.value&&(s.value=e.value),c=[s];for(null==t&&(t=sS);n=c.pop();)if(l&&(n.value=+n.data.value),(i=t(n.data))&&(o=i.length))for(n.children=new Array(o),a=o-1;a>=0;--a)c.push(r=n.children[a]=new uS(i[a])),r.parent=n,r.depth=n.depth+1;return s.eachBefore(cS)}function sS(e){return e.children}function lS(e){e.data=e.data.data}function cS(e){var t=0;do{e.height=t}while((e=e.parent)&&e.height<++t)}function uS(e){this.data=e,this.depth=this.height=0,this.parent=null}uS.prototype=oS.prototype={constructor:uS,count:function(){return this.eachAfter(aS)},each:function(e){var t,n,r,i,a=this,o=[a];do{for(t=o.reverse(),o=[];a=t.pop();)if(e(a),n=a.children)for(r=0,i=n.length;r=0;--n)i.push(t[n]);return this},sum:function(e){return this.eachAfter(function(t){for(var n=+e(t.data)||0,r=t.children,i=r&&r.length;--i>=0;)n+=r[i].value;t.value=n})},sort:function(e){return this.eachBefore(function(t){t.children&&t.children.sort(e)})},path:function(e){for(var t=this,n=function(e,t){if(e===t)return e;var n=e.ancestors(),r=t.ancestors(),i=null;for(e=n.pop(),t=r.pop();e===t;)i=e,e=n.pop(),t=r.pop();return i}(t,e),r=[t];t!==n;)t=t.parent,r.push(t);for(var i=r.length;e!==n;)r.splice(i,0,e),e=e.parent;return r},ancestors:function(){for(var e=this,t=[e];e=e.parent;)t.push(e);return t},descendants:function(){var e=[];return this.each(function(t){e.push(t)}),e},leaves:function(){var e=[];return this.eachBefore(function(t){t.children||e.push(t)}),e},links:function(){var e=this,t=[];return e.each(function(n){n!==e&&t.push({source:n.parent,target:n})}),t},copy:function(){return oS(this).eachBefore(lS)}};var dS=Array.prototype.slice;var fS=function(e){for(var t,n,r=0,i=(e=function(e){for(var t,n,r=e.length;r;)n=Math.random()*r--|0,t=e[r],e[r]=e[n],e[n]=t;return e}(dS.call(e))).length,a=[];r0&&n*n>r*r+i*i}function hS(e,t){for(var n=0;n(o*=o)?(r=(c+o-i)/(2*c),a=Math.sqrt(Math.max(0,o/c-r*r)),n.x=e.x-r*s-a*l,n.y=e.y-r*l+a*s):(r=(c+i-o)/(2*c),a=Math.sqrt(Math.max(0,i/c-r*r)),n.x=t.x+r*s-a*l,n.y=t.y+r*l+a*s)):(n.x=t.x+n.r,n.y=t.y)}function xS(e,t){var n=e.r+t.r-1e-6,r=t.x-e.x,i=t.y-e.y;return n>0&&n*n>r*r+i*i}function ES(e){var t=e._,n=e.next._,r=t.r+n.r,i=(t.x*n.r+n.x*t.r)/r,a=(t.y*n.r+n.y*t.r)/r;return i*i+a*a}function SS(e){this._=e,this.next=null,this.previous=null}function wS(e){if(!(i=e.length))return 0;var t,n,r,i,a,o,s,l,c,u,d;if((t=e[0]).x=0,t.y=0,!(i>1))return t.r;if(n=e[1],t.x=-n.r,n.x=t.r,n.y=0,!(i>2))return t.r+n.r;yS(n,t,r=e[2]),t=new SS(t),n=new SS(n),r=new SS(r),t.next=r.previous=n,n.next=t.previous=r,r.next=n.previous=t;e:for(s=3;sf&&(f=s),h=u*u*g,(p=Math.max(f/h,h/d))>m){u-=s;break}m=p}b.push(o={value:u,dice:l1?t:1)},n}(WS),QS=function e(t){function n(e,n,r,i,a){if((o=e._squarify)&&o.ratio===t)for(var o,s,l,c,u,d=-1,f=o.length,p=e.value;++d1?t:1)},n}(WS);function YS(e){Yr.call(this,null,e)}function ZS(e){return e.values}function XS(e){Yr.call(this,null,e)}YS.Definition={type:"Nest",metadata:{treesource:!0,changes:!0},params:[{name:"keys",type:"field",array:!0},{name:"generate",type:"boolean"}]},Object(Ee.t)(YS,Yr).transform=function(e,t){t.source||Object(Ee.l)("Nest transform requires an upstream data source.");var n=e.generate,r=e.modified(),i=t.clone(),a=this.value;return(!a||r||t.changed())&&(a&&a.each(function(e){e.children&&Oe(e.data)&&i.rem.push(e.data)}),this.value=a=oS({values:Object(Ee.h)(e.keys).reduce(function(e,t){return e.key(t),e},$d()).entries(i.source)},ZS),n&&a.each(function(e){e.children&&(e=Te(e.data),i.add.push(e),i.source.push(e))}),tS(a,Me,Me)),i.source.root=a,i},Object(Ee.t)(XS,Yr).transform=function(e,t){t.source&&t.source.root||Object(Ee.l)(this.constructor.name+" transform requires a backing tree data source.");var n=this.layout(e.method),r=this.fields,i=t.source.root,a=e.as||r;e.field&&i.sum(e.field),e.sort&&i.sort(e.sort),function(e,t,n){for(var r,i=0,a=t.length;i0)throw new Error("cycle");return a}return n.id=function(t){return arguments.length?(e=CS(t),n):e},n.parentId=function(e){return arguments.length?(t=CS(e),n):t},n}().id(e.key).parentId(e.parentKey)(r.source),e.key,Ee.T)),r.source.root=this.value,r};var ow={tidy:function(){var e=US,t=1,n=1,r=null;function i(i){var l=function(e){for(var t,n,r,i,a,o=new $S(e,0),s=[o];t=s.pop();)if(r=t._.children)for(t.children=new Array(a=r.length),i=a-1;i>=0;--i)s.push(n=t.children[i]=new $S(r[i],i)),n.parent=t;return(o.parent=new $S(null,0)).children=[o],o}(i);if(l.eachAfter(a),l.parent.m=-l.z,l.eachBefore(o),r)i.eachBefore(s);else{var c=i,u=i,d=i;i.eachBefore(function(e){e.xu.x&&(u=e),e.depth>d.depth&&(d=e)});var f=c===u?1:e(c,u)/2,p=f-c.x,m=t/(u.x+f+p),g=n/(d.depth||1);i.eachBefore(function(e){e.x=(e.x+p)*m,e.y=e.depth*g})}return i}function a(t){var n=t.children,r=t.parent.children,i=t.i?r[t.i-1]:null;if(n){!function(e){for(var t,n=0,r=0,i=e.children,a=i.length;--a>=0;)(t=i[a]).z+=n,t.m+=n,n+=t.s+(r+=t.c)}(t);var a=(n[0].z+n[n.length-1].z)/2;i?(t.z=i.z+e(t._,i._),t.m=t.z-a):t.z=a}else i&&(t.z=i.z+e(t._,i._));t.parent.A=function(t,n,r){if(n){for(var i,a=t,o=t,s=n,l=a.parent.children[0],c=a.m,u=o.m,d=s.m,f=l.m;s=zS(s),a=jS(a),s&&a;)l=jS(l),(o=zS(o)).a=t,(i=s.z+d-a.z-c+e(s._,a._))>0&&(qS(GS(s,t,r),t,i),c+=i,u+=i),d+=s.m,c+=a.m,f+=l.m,u+=o.m;s&&!zS(o)&&(o.t=s,o.m+=d-u),a&&!jS(l)&&(l.t=a,l.m+=c-f,r=t)}return r}(t,i,t.parent.A||r[0])}function o(e){e._.x=e.z+e.parent.m,e.m+=e.parent.m}function s(e){e.x*=t,e.y=e.depth*n}return i.separation=function(t){return arguments.length?(e=t,i):e},i.size=function(e){return arguments.length?(r=!1,t=+e[0],n=+e[1],i):r?null:[t,n]},i.nodeSize=function(e){return arguments.length?(r=!0,t=+e[0],n=+e[1],i):r?[t,n]:null},i},cluster:function(){var e=nS,t=1,n=1,r=!1;function i(i){var a,o=0;i.eachAfter(function(t){var n=t.children;n?(t.x=function(e){return e.reduce(rS,0)/e.length}(n),t.y=function(e){return 1+e.reduce(iS,0)}(n)):(t.x=a?o+=e(t,a):0,t.y=0,a=t)});var s=function(e){for(var t;t=e.children;)e=t[0];return e}(i),l=function(e){for(var t;t=e.children;)e=t[t.length-1];return e}(i),c=s.x-e(s,l)/2,u=l.x+e(l,s)/2;return i.eachAfter(r?function(e){e.x=(e.x-i.x)*t,e.y=(i.y-e.y)*n}:function(e){e.x=(e.x-c)/(u-c)*t,e.y=(1-(i.y?e.y/i.y:1))*n})}return i.separation=function(t){return arguments.length?(e=t,i):e},i.size=function(e){return arguments.length?(r=!1,t=+e[0],n=+e[1],i):r?null:[t,n]},i.nodeSize=function(e){return arguments.length?(r=!0,t=+e[0],n=+e[1],i):r?[t,n]:null},i}},sw=["x","y","depth","children"];function lw(e){XS.call(this,e)}lw.Definition={type:"Tree",metadata:{tree:!0,modifies:!0},params:[{name:"field",type:"field"},{name:"sort",type:"compare"},{name:"method",type:"enum",default:"tidy",values:["tidy","cluster"]},{name:"size",type:"number",array:!0,length:2},{name:"nodeSize",type:"number",array:!0,length:2},{name:"as",type:"string",array:!0,length:4,default:sw}]};var cw=Object(Ee.t)(lw,XS);function uw(e){Yr.call(this,[],e)}cw.layout=function(e){var t=e||"tidy";if(ow.hasOwnProperty(t))return ow[t]();Object(Ee.l)("Unrecognized Tree layout method: "+t)},cw.params=["size","nodeSize","separation"],cw.fields=sw,uw.Definition={type:"TreeLinks",metadata:{tree:!0,generates:!0,changes:!0},params:[]},Object(Ee.t)(uw,Yr).transform=function(e,t){var n=this.value,r=t.source&&t.source.root,i=t.fork(t.NO_SOURCE),a={};return r||Object(Ee.l)("TreeLinks transform requires a tree data source."),t.changed(t.ADD_REM)?(i.rem=n,t.visit(t.SOURCE,function(e){a[Me(e)]=1}),r.each(function(e){var t=e.data,n=e.parent&&e.parent.data;n&&a[Me(t)]&&a[Me(n)]&&i.add.push(Te({source:n,target:t}))}),this.value=i.add):t.changed(t.MOD)&&(t.visit(t.MOD,function(e){a[Me(e)]=1}),n.forEach(function(e){(a[Me(e.source)]||a[Me(e.target)])&&i.mod.push(e)})),i};var dw={binary:function(e,t,n,r,i){var a,o,s=e.children,l=s.length,c=new Array(l+1);for(c[0]=o=a=0;a=n-1){var u=s[t];return u.x0=i,u.y0=a,u.x1=o,void(u.y1=l)}for(var d=c[t],f=r/2+d,p=t+1,m=n-1;p>>1;c[g]l-a){var v=(i*b+o*h)/r;e(t,p,h,i,a,v,l),e(p,n,b,v,a,o,l)}else{var _=(a*b+l*h)/r;e(t,p,h,i,a,o,_),e(p,n,b,i,_,o,l)}}(0,l,e.value,t,n,r,i)},dice:RS,slice:HS,slicedice:function(e,t,n,r,i){(1&e.depth?HS:RS)(e,t,n,r,i)},squarify:KS,resquarify:QS},fw=["x0","y0","x1","y1","depth","children"];function pw(e){XS.call(this,e)}pw.Definition={type:"Treemap",metadata:{tree:!0,modifies:!0},params:[{name:"field",type:"field"},{name:"sort",type:"compare"},{name:"method",type:"enum",default:"squarify",values:["squarify","resquarify","binary","dice","slice","slicedice"]},{name:"padding",type:"number",default:0},{name:"paddingInner",type:"number",default:0},{name:"paddingOuter",type:"number",default:0},{name:"paddingTop",type:"number",default:0},{name:"paddingRight",type:"number",default:0},{name:"paddingBottom",type:"number",default:0},{name:"paddingLeft",type:"number",default:0},{name:"ratio",type:"number",default:1.618033988749895},{name:"round",type:"boolean",default:!1},{name:"size",type:"number",array:!0,length:2},{name:"as",type:"string",array:!0,length:4,default:fw}]};var mw=Object(Ee.t)(pw,XS);mw.layout=function(){var e=function(){var e=KS,t=!1,n=1,r=1,i=[0],a=OS,o=OS,s=OS,l=OS,c=OS;function u(e){return e.x0=e.y0=0,e.x1=n,e.y1=r,e.eachBefore(d),i=[0],t&&e.eachBefore(kS),e}function d(t){var n=i[t.depth],r=t.x0+n,u=t.y0+n,d=t.x1-n,f=t.y1-n;d0)){if(a/=f,f<0){if(a0){if(a>d)return;a>u&&(u=a)}if(a=r-l,f||!(a<0)){if(a/=f,f<0){if(a>d)return;a>u&&(u=a)}else if(f>0){if(a0)){if(a/=p,p<0){if(a0){if(a>d)return;a>u&&(u=a)}if(a=i-c,p||!(a<0)){if(a/=p,p<0){if(a>d)return;a>u&&(u=a)}else if(p>0){if(a0||d<1)||(u>0&&(e[0]=[l+u*f,c+u*p]),d<1&&(e[1]=[l+d*f,c+d*p]),!0)}}}}}function Nw(e,t,n,r,i){var a=e[1];if(a)return!0;var o,s,l=e[0],c=e.left,u=e.right,d=c[0],f=c[1],p=u[0],m=u[1],g=(d+p)/2,h=(f+m)/2;if(m===f){if(g=r)return;if(d>p){if(l){if(l[1]>=i)return}else l=[g,n];a=[g,i]}else{if(l){if(l[1]1)if(d>p){if(l){if(l[1]>=i)return}else l=[(n-s)/o,n];a=[(i-s)/o,i]}else{if(l){if(l[1]=r)return}else l=[t,o*t+s];a=[r,o*r+s]}else{if(l){if(l[0]=-Kw)){var p=l*l+c*c,m=u*u+d*d,g=(d*p-c*m)/f,h=(l*m-u*p)/f,b=Rw.pop()||new function(){_w(this),this.x=this.y=this.arc=this.site=this.cy=null};b.arc=e,b.site=i,b.x=g+o,b.y=(b.cy=h+s)+Math.sqrt(g*g+h*h),e.circle=b;for(var v=null,_=Hw._;_;)if(b.y<_.y||b.y===_.y&&b.x<=_.x){if(!_.L){v=_.P;break}_=_.L}else{if(!_.R){v=_;break}_=_.R}Hw.insert(v,b),v||(kw=b)}}}}function Lw(e){var t=e.circle;t&&(t.P||(kw=t.N),Hw.remove(t),Rw.push(t),_w(t),e.circle=null)}var Pw=[];function Fw(e){var t=Pw.pop()||new function(){_w(this),this.edge=this.site=this.circle=null};return t.site=e,t}function Bw(e){Lw(e),Gw.remove(e),Pw.push(e),_w(e)}function Uw(e){var t=e.circle,n=t.x,r=t.cy,i=[n,r],a=e.P,o=e.N,s=[e];Bw(e);for(var l=a;l.circle&&Math.abs(n-l.circle.x)Vw)s=s.L;else{if(!((i=a-qw(s,o))>Vw)){r>-Vw?(t=s.P,n=s):i>-Vw?(t=s,n=s.N):t=n=s;break}if(!s.R){t=s;break}s=s.R}!function(e){$w[e.index]={site:e,halfedges:[]}}(e);var l=Fw(e);if(Gw.insert(t,l),t||n){if(t===n)return Lw(t),n=Fw(t.site),Gw.insert(l,n),l.edge=n.edge=ww(t.site,l.site),Iw(t),void Iw(n);if(n){Lw(t),Lw(n);var c=t.site,u=c[0],d=c[1],f=e[0]-u,p=e[1]-d,m=n.site,g=m[0]-u,h=m[1]-d,b=2*(f*h-p*g),v=f*f+p*p,_=g*g+h*h,y=[(h*v-p*_)/b+u,(f*_-g*v)/b+d];Ow(n.edge,c,m,y),l.edge=ww(c,e,null,y),n.edge=ww(e,m,null,y),Iw(t),Iw(n)}else l.edge=ww(t.site,l.site)}}function zw(e,t){var n=e.site,r=n[0],i=n[1],a=i-t;if(!a)return r;var o=e.P;if(!o)return-1/0;var s=(n=o.site)[0],l=n[1],c=l-t;if(!c)return s;var u=s-r,d=1/a-1/c,f=u/c;return d?(-f+Math.sqrt(f*f-2*d*(u*u/(-2*c)-l+c/2+i-a/2)))/d+r:(r+s)/2}function qw(e,t){var n=e.N;if(n)return zw(n,t);var r=e.site;return r[1]===t?r[0]:1/0}var Gw,$w,Hw,Ww,Vw=1e-6,Kw=1e-12;function Qw(e,t){return t[1]-e[1]||t[0]-e[0]}function Yw(e,t){var n,r,i,a=e.sort(Qw).pop();for(Ww=[],$w=new Array(e.length),Gw=new Sw,Hw=new Sw;;)if(i=kw,a&&(!i||a[1]Vw||Math.abs(i[0][1]-i[1][1])>Vw)||delete Ww[a]}(o,s,l,c),function(e,t,n,r){var i,a,o,s,l,c,u,d,f,p,m,g,h=$w.length,b=!0;for(i=0;iVw||Math.abs(g-f)>Vw)&&(l.splice(s,0,Ww.push(Cw(o,p,Math.abs(m-e)Vw?[e,Math.abs(d-e)Vw?[Math.abs(f-r)Vw?[n,Math.abs(d-n)Vw?[Math.abs(f-t)=s)return null;var l=e-i.site[0],c=t-i.site[1],u=l*l+c*c;do{i=a.cells[r=o],o=null,i.halfedges.forEach(function(n){var r=a.edges[n],s=r.left;if(s!==i.site&&s||(s=r.right)){var l=e-s[0],c=t-s[1],d=l*l+c*c;d=p));)if(t.x=d+i,t.y=f+a,!(t.x+t.x0<0||t.y+t.y0<0||t.x+t.x1>s[0]||t.y+t.y1>s[1]||n&&iC(t,e,s[0])||n&&(c=n,!((o=t).x+o.x1>c[0].x&&o.x+o.x0c[0].y&&o.y+o.y0>5,y=s[0]>>5,x=t.x-(_<<4),E=127&x,S=32-E,w=t.y1-t.y0,C=(t.y+t.y0)*y+(x>>5),O=0;O>>E:0);C+=y}return t.sprite=null,!0}return!1}return d.layout=function(){for(var l=function(e){e.width=e.height=1;var t=Math.sqrt(e.getContext("2d").getImageData(0,0,1,1).data.length>>2);e.width=(eC<<5)/t,e.height=tC/t;var n=e.getContext("2d");return n.fillStyle=n.strokeStyle="red",n.textAlign="center",{context:n,ratio:t}}(Lo()),d=function(e){var t=[],n=-1;for(;++n>5)*s[1]),p=null,m=c.length,g=-1,h=[],b=c.map(function(s){return{text:e(s),font:t(s),style:r(s),weight:i(s),rotate:a(s),size:~~n(s),padding:o(s),xoff:0,yoff:0,x1:0,y1:0,x0:0,y0:0,hasText:!1,sprite:null,datum:s}}).sort(function(e,t){return t.size-e.size});++g>1,v.y=s[1]*(u()+.5)>>1,rC(l,v,b,g),v.hasText&&f(d,v,p)&&(h.push(v),p?aC(p,v):p=[{x:v.x+v.x0,y:v.y+v.y0},{x:v.x+v.x1,y:v.y+v.y1}],v.x-=s[0]>>1,v.y-=s[1]>>1)}return h},d.words=function(e){return arguments.length?(c=e,d):c},d.size=function(e){return arguments.length?(s=[+e[0],+e[1]],d):s},d.font=function(e){return arguments.length?(t=sC(e),d):t},d.fontStyle=function(e){return arguments.length?(r=sC(e),d):r},d.fontWeight=function(e){return arguments.length?(i=sC(e),d):i},d.rotate=function(e){return arguments.length?(a=sC(e),d):a},d.text=function(t){return arguments.length?(e=sC(t),d):e},d.spiral=function(e){return arguments.length?(l=lC[e]||e,d):l},d.fontSize=function(e){return arguments.length?(n=sC(e),d):n},d.padding=function(e){return arguments.length?(o=sC(e),d):o},d.random=function(e){return arguments.length?(u=e,d):u},d};function rC(e,t,n,r){if(!t.sprite){var i=e.context,a=e.ratio;i.clearRect(0,0,(eC<<5)/a,tC/a);var o,s,l,c,u,d=0,f=0,p=0,m=n.length;for(--r;++r>5<<5,l=~~Math.max(Math.abs(v+_),Math.abs(v-_))}else o=o+31>>5<<5;if(l>p&&(p=l),d+o>=eC<<5&&(d=0,f+=p,p=0),f+l>=tC)break;i.translate((d+(o>>1))/a,(f+(l>>1))/a),t.rotate&&i.rotate(t.rotate*Jw),i.fillText(t.text,0,0),t.padding&&(i.lineWidth=2*t.padding,i.strokeText(t.text,0,0)),i.restore(),t.width=o,t.height=l,t.xoff=d,t.yoff=f,t.x1=o>>1,t.y1=l>>1,t.x0=-t.x1,t.y0=-t.y1,t.hasText=!0,d+=o}for(var x=i.getImageData(0,0,(eC<<5)/a,tC/a).data,E=[];--r>=0;)if((t=n[r]).hasText){for(s=(o=t.width)>>5,l=t.y1-t.y0,c=0;c>5),O=x[(f+u)*(eC<<5)+(d+c)<<2]?1<<31-c%32:0;E[C]|=O,S|=O}S?w=u:(t.y0++,l--,u--,f++)}t.y1=t.y0+w,t.sprite=E.slice(0,(t.y1-t.y0)*s)}}}function iC(e,t,n){n>>=5;for(var r,i=e.sprite,a=e.width>>5,o=e.x-(a<<4),s=127&o,l=32-s,c=e.y1-e.y0,u=(e.y+e.y0)*n+(o>>5),d=0;d>>s:0))&t[u+f])return!0;u+=n}return!1}function aC(e,t){var n=e[0],r=e[1];t.x+t.x0r.x&&(r.x=t.x+t.x1),t.y+t.y1>r.y&&(r.y=t.y+t.y1)}function oC(e){var t=e[0]/e[1];return function(e){return[t*(e*=.1)*Math.cos(e),e*Math.sin(e)]}}function sC(e){return"function"==typeof e?e:function(){return e}}var lC={archimedean:oC,rectangular:function(e){var t=4*e[0]/e[1],n=0,r=0;return function(e){var i=e<0?-1:1;switch(Math.sqrt(1+4*i*e)-i&3){case 0:n+=t;break;case 1:r+=4;break;case 2:n-=t;break;default:r-=4}return[n,r]}}},cC=function(e,t,n){var r=e-t+2*n;return e?r>0?r:1:0},uC=function(e){return function(t){var n,r=t[0],i=t[1];return i=s&&o[i]<=l&&(c<0&&(c=i),n=i);if(!(c<0))return s=e.invertExtent(o[c]),l=e.invertExtent(o[n]),[void 0===s[0]?s[1]:s[0],void 0===l[1]?l[0]:l[1]]}},fC=Array.prototype,pC=fC.map,mC=fC.slice,gC={name:"implicit"};function hC(e){var t=Gd(),n=[],r=gC;function i(i){var a=i+"",o=t.get(a);if(!o){if(r!==gC)return r;t.set(a,o=n.push(i))}return e[(o-1)%e.length]}return e=null==e?[]:mC.call(e),i.domain=function(e){if(!arguments.length)return n.slice();n=[],t=Gd();for(var r,a,o=-1,s=e.length;++o2?EC:xC,r=i=null,u}function u(t){return(r||(r=n(a,o,l?function(e){return function(t,n){var r=e(t=+t,n=+n);return function(e){return e<=t?0:e>=n?1:r(e)}}}(e):e,s)))(+t)}return u.invert=function(e){return(i||(i=n(o,a,yC,l?function(e){return function(t,n){var r=e(t=+t,n=+n);return function(e){return e<=0?t:e>=1?n:r(e)}}}(t):t)))(+e)},u.domain=function(e){return arguments.length?(a=pC.call(e,vC),c()):a.slice()},u.range=function(e){return arguments.length?(o=mC.call(e),c()):o.slice()},u.rangeRound=function(e){return o=mC.call(e),s=Mp,c()},u.clamp=function(e){return arguments.length?(l=!!e,c()):l},u.interpolate=function(e){return arguments.length?(s=e,c()):s},c()}var CC=function(e,t,n){var r,i=e[0],a=e[e.length-1],o=Mi(i,a,null==t?10:t);switch((n=om(null==n?",f":n)).type){case"s":var s=Math.max(Math.abs(i),Math.abs(a));return null!=n.precision||isNaN(r=_m(o,s))||(n.precision=r),dm(n,s);case"":case"e":case"g":case"p":case"r":null!=n.precision||isNaN(r=ym(o,Math.max(Math.abs(i),Math.abs(a))))||(n.precision=r-("e"===n.type));break;case"f":case"%":null!=n.precision||isNaN(r=vm(o))||(n.precision=r-2*("%"===n.type))}return um(n)};function OC(e){var t=e.domain;return e.ticks=function(e){var n=t();return Ci(n[0],n[n.length-1],null==e?10:e)},e.tickFormat=function(e,n){return CC(t(),e,n)},e.nice=function(n){null==n&&(n=10);var r,i=t(),a=0,o=i.length-1,s=i[a],l=i[o];return l0?r=Oi(s=Math.floor(s/r)*r,l=Math.ceil(l/r)*r,n):r<0&&(r=Oi(s=Math.ceil(s*r)/r,l=Math.floor(l*r)/r,n)),r>0?(i[a]=Math.floor(s/r)*r,i[o]=Math.ceil(l/r)*r,t(i)):r<0&&(i[a]=Math.ceil(s*r)/r,i[o]=Math.floor(l*r)/r,t(i)),e},e}function MC(){var e=wC(yC,bp);return e.copy=function(){return SC(e,MC())},OC(e)}function NC(){var e=[0,1];function t(e){return+e}return t.invert=t,t.domain=t.range=function(n){return arguments.length?(e=pC.call(n,vC),t):e.slice()},t.copy=function(){return NC().domain(e)},OC(t)}var TC=function(e,t){var n,r=0,i=(e=e.slice()).length-1,a=e[r],o=e[i];return o0){for(;fl)break;g.push(d)}}else for(;f=1;--u)if(!((d=c*u)l)break;g.push(d)}}else g=Ci(f,p,Math.min(p-f,m)).map(i);return a?g.reverse():g},e.tickFormat=function(t,a){if(null==a&&(a=10===n?".0e":","),"function"!=typeof a&&(a=um(a)),t===1/0)return a;null==t&&(t=10);var o=Math.max(1,n*t/e.ticks().length);return function(e){var t=e/i(Math.round(r(e)));return t*n0?n[i-1]:e[0],i=n?[r[n-1],t]:[r[o-1],r[o]]},a.copy=function(){return zC().domain([e,t]).range(i)},OC(a)}function qC(){var e=[.5],t=[0,1],n=1;function r(r){if(r<=r)return t[hi(e,r,0,n)]}return r.domain=function(i){return arguments.length?(e=mC.call(i),n=Math.min(e.length,t.length-1),r):e.slice()},r.range=function(i){return arguments.length?(t=mC.call(i),n=Math.min(e.length,t.length-1),r):t.slice()},r.invertExtent=function(n){var r=t.indexOf(n);return[e[r-1],e[r]]},r.copy=function(){return qC().domain(e).range(t)},r}var GC=1e3,$C=60*GC,HC=60*$C,WC=24*HC,VC=7*WC,KC=30*WC,QC=365*WC;function YC(e){return new Date(e)}function ZC(e){return e instanceof Date?+e:+new Date(+e)}function XC(e,t,n,r,i,a,o,s,l){var c=wC(yC,bp),u=c.invert,d=c.domain,f=l(".%L"),p=l(":%S"),m=l("%I:%M"),g=l("%I %p"),h=l("%a %d"),b=l("%b %d"),v=l("%B"),_=l("%Y"),y=[[o,1,GC],[o,5,5*GC],[o,15,15*GC],[o,30,30*GC],[a,1,$C],[a,5,5*$C],[a,15,15*$C],[a,30,30*$C],[i,1,HC],[i,3,3*HC],[i,6,6*HC],[i,12,12*HC],[r,1,WC],[r,2,2*WC],[n,1,VC],[t,1,KC],[t,3,3*KC],[e,1,QC]];function x(s){return(o(s)a[1-u])))return n=Math.max(0,mi(d,l)-1),o=l===c?n:mi(d,c)-1,l-d[n]>t+1e-10&&++n,u&&(s=n,n=f-o,o=f-s),n>o?void 0:r().slice(n,o+1)}},n.invert=function(e){var t=n.invertRange([e,e]);return t?t[0]:t},n.copy=function(){return tO().domain(r()).range(a).round(o).paddingInner(s).paddingOuter(l).align(c)},u()}var nO=Array.prototype.map,rO=Array.prototype.slice;function iO(e){return nO.call(e,function(e){return+e})}function aO(e,t){return arguments.length>1?(oO[e]=function(e,t){return function(){var n=t();return n.invertRange||(n.invertRange=n.invert?uC(n):n.invertExtent?dC(n):void 0),n.type=e,n}}(e,t),this):oO.hasOwnProperty(e)?oO[e]:void 0}var oO={identity:NC,linear:MC,log:PC,ordinal:hC,pow:BC,sqrt:UC,quantile:jC,quantize:zC,threshold:qC,time:JC,utc:eO,band:tO,point:function(){return function e(t){var n=t.copy;return t.padding=t.paddingOuter,delete t.paddingInner,t.copy=function(){return e(n())},t}(tO().paddingInner(1))},sequential:function e(t){var n=MC(),r=0,i=1,a=!1;function o(){var e=n.domain();r=e[0],i=Object(Ee.K)(e)-r}function s(e){var n=(e-r)/i;return t(a?Math.max(0,Math.min(1,n)):n)}return s.clamp=function(e){return arguments.length?(a=!!e,s):a},s.domain=function(e){return arguments.length?(n.domain(e),o(),s):n.domain()},s.interpolator=function(e){return arguments.length?(t=e,s):t},s.copy=function(){return e().domain(n.domain()).clamp(a).interpolator(t)},s.ticks=function(e){return n.ticks(e)},s.tickFormat=function(e,t){return n.tickFormat(e,t)},s.nice=function(e){return n.nice(e),o(),s},s},"bin-linear":function e(){var t=MC(),n=[];function r(e){return t(e)}return r.domain=function(e){return arguments.length?(function(e){n=iO(e),t.domain([n[0],Object(Ee.K)(n)])}(e),r):n.slice()},r.range=function(e){return arguments.length?(t.range(e),r):t.range()},r.rangeRound=function(e){return arguments.length?(t.rangeRound(e),r):t.rangeRound()},r.interpolate=function(e){return arguments.length?(t.interpolate(e),r):t.interpolate()},r.invert=function(e){return t.invert(e)},r.ticks=function(e){var t=n.length,i=~~(t/(e||t));return i<2?r.domain():n.filter(function(e,t){return!(t%i)})},r.tickFormat=function(){return t.tickFormat.apply(t,arguments)},r.copy=function(){return e().domain(r.domain()).range(r.range())},r},"bin-ordinal":function e(){var t=[],n=[];function r(e){return null==e||e!=e?void 0:n[(hi(t,e)-1)%n.length]}return r.domain=function(e){return arguments.length?(t=iO(e),r):t.slice()},r.range=function(e){return arguments.length?(n=rO.call(e),r):n.slice()},r.copy=function(){return e().domain(r.domain()).range(r.range())},r}};for(var sO in oO)aO(sO,oO[sO]);function lO(e){for(var t=e.length/6|0,n=new Array(t),r=0;ri&&(i=n);return[r,i]}(l,i)).range(r);s=function(e){return c(l(e))}}i.forEach(function(e){e[o[0]]=NaN,e[o[1]]=NaN,e[o[3]]=0});for(var u,d,f=a.words(i).text(e.text).size(e.size||[500,500]).padding(e.padding||1).spiral(e.spiral||"archimedean").rotate(e.rotate||0).font(e.font||"sans-serif").fontStyle(e.fontStyle||"normal").fontWeight(e.fontWeight||"normal").fontSize(s).random(ui).layout(),p=a.size(),m=p[0]>>1,g=p[1]>>1,h=0,b=f.length;hi?1:0}),Ri(e,t)}(d,f),c)o=t,s=e,t=Array(c+u),e=xO(c+u),function(e,t,n,r,i,a,o,s,l){var c,u=0,d=0;for(c=0;u0)for(l=0;l=t?e:((i=i||new e.constructor(t)).set(e),i);var e,t,i},add:function(e){for(var t,r=0,i=n.length,a=e.length;ri.length||n>t)&&(t=Math.max(n,t),i=EO(e,t,i),a=EO(e,t))}}),e),this._indices=null,this._dims=null}CO.Definition={type:"CrossFilter",metadata:{},params:[{name:"fields",type:"field",array:!0,required:!0},{name:"query",type:"array",array:!0,required:!0,content:{type:"number",array:!0,length:2}}]};var OO=Object(Ee.t)(CO,Yr);function MO(e){Yr.call(this,null,e)}OO.transform=function(e,t){return this._dims?e.modified("fields")||e.fields.some(function(e){return t.modified(e.fields)})?this.reinit(e,t):this.eval(e,t):this.init(e,t)},OO.init=function(e,t){for(var n,r,i=e.fields,a=e.query,o=this._indices={},s=this._dims=[],l=a.length,c=0;ch)for(i=h,a=Math.min(m,b);ib)for(i=Math.max(m,b),a=g;ip)for(i=p,a=Math.min(d,m);im)for(i=Math.max(d,m),a=f;i",iM[fM]="Identifier",iM[pM]="Keyword",iM[mM]="Null",iM[gM]="Numeric",iM[hM]="Punctuator",iM[bM]="String",iM[9]="RegularExpression";var vM="ArrayExpression",_M="BinaryExpression",yM="CallExpression",xM="ConditionalExpression",EM="Identifier",SM="Literal",wM="LogicalExpression",CM="MemberExpression",OM="ObjectExpression",MM="Property",NM="UnaryExpression",TM="Unexpected token %0",DM="Unexpected number",AM="Unexpected string",kM="Unexpected identifier",RM="Unexpected reserved word",IM="Unexpected end of input",LM="Invalid regular expression",PM="Invalid regular expression: missing /",FM="Octal literals are not allowed in strict mode.",BM="Duplicate data property in object literal not allowed in strict mode",UM="ILLEGAL",jM="Disabled.",zM=new RegExp("[ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々-〇〡-〩〱-〵〸-〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]"),qM=new RegExp("[ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮ̀-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁ҃-҇Ҋ-ԯԱ-Ֆՙա-և֑-ׇֽֿׁׂׅׄא-תװ-ײؐ-ؚؠ-٩ٮ-ۓە-ۜ۟-۪ۨ-ۼۿܐ-݊ݍ-ޱ߀-ߵߺࠀ-࠭ࡀ-࡛ࢠ-ࢲࣤ-ॣ०-९ॱ-ঃঅ-ঌএঐও-নপ-রলশ-হ়-ৄেৈো-ৎৗড়ঢ়য়-ৣ০-ৱਁ-ਃਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹ਼ਾ-ੂੇੈੋ-੍ੑਖ਼-ੜਫ਼੦-ੵઁ-ઃઅ-ઍએ-ઑઓ-નપ-રલળવ-હ઼-ૅે-ૉો-્ૐૠ-ૣ૦-૯ଁ-ଃଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହ଼-ୄେୈୋ-୍ୖୗଡ଼ଢ଼ୟ-ୣ୦-୯ୱஂஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹா-ூெ-ைொ-்ௐௗ௦-௯ఀ-ఃఅ-ఌఎ-ఐఒ-నప-హఽ-ౄె-ైొ-్ౕౖౘౙౠ-ౣ౦-౯ಁ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹ಼-ೄೆ-ೈೊ-್ೕೖೞೠ-ೣ೦-೯ೱೲഁ-ഃഅ-ഌഎ-ഐഒ-ഺഽ-ൄെ-ൈൊ-ൎൗൠ-ൣ൦-൯ൺ-ൿංඃඅ-ඖක-නඳ-රලව-ෆ්ා-ුූෘ-ෟ෦-෯ෲෳก-ฺเ-๎๐-๙ກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ູົ-ຽເ-ໄໆ່-ໍ໐-໙ໜ-ໟༀ༘༙༠-༩༹༵༷༾-ཇཉ-ཬཱ-྄྆-ྗྙ-ྼ࿆က-၉ၐ-ႝႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ፝-፟ᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-᜔ᜠ-᜴ᝀ-ᝓᝠ-ᝬᝮ-ᝰᝲᝳក-៓ៗៜ៝០-៩᠋-᠍᠐-᠙ᠠ-ᡷᢀ-ᢪᢰ-ᣵᤀ-ᤞᤠ-ᤫᤰ-᤻᥆-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉ᧐-᧙ᨀ-ᨛᨠ-ᩞ᩠-᩿᩼-᪉᪐-᪙ᪧ᪰-᪽ᬀ-ᭋ᭐-᭙᭫-᭳ᮀ-᯳ᰀ-᰷᱀-᱉ᱍ-ᱽ᳐-᳔᳒-ᳶ᳸᳹ᴀ-᷵᷼-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼ‌‍‿⁀⁔ⁱⁿₐ-ₜ⃐-⃥⃜⃡-⃰ℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯ⵿-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⷠ-ⷿⸯ々-〇〡-〯〱-〵〸-〼ぁ-ゖ゙゚ゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘫꙀ-꙯ꙴ-꙽ꙿ-ꚝꚟ-꛱ꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠧꡀ-ꡳꢀ-꣄꣐-꣙꣠-ꣷꣻ꤀-꤭ꤰ-꥓ꥠ-ꥼꦀ-꧀ꧏ-꧙ꧠ-ꧾꨀ-ꨶꩀ-ꩍ꩐-꩙ꩠ-ꩶꩺ-ꫂꫛ-ꫝꫠ-ꫯꫲ-꫶ꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯪ꯬꯭꯰-꯹가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻ︀-️︠-︭︳︴﹍-﹏ﹰ-ﹴﹶ-ﻼ0-9A-Z_a-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]");function GM(e,t){if(!e)throw new Error("ASSERT: "+t)}function $M(e){return e>=48&&e<=57}function HM(e){return"0123456789abcdefABCDEF".indexOf(e)>=0}function WM(e){return"01234567".indexOf(e)>=0}function VM(e){return 32===e||9===e||11===e||12===e||160===e||e>=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0}function KM(e){return 10===e||13===e||8232===e||8233===e}function QM(e){return 36===e||95===e||e>=65&&e<=90||e>=97&&e<=122||92===e||e>=128&&zM.test(String.fromCharCode(e))}function YM(e){return 36===e||95===e||e>=65&&e<=90||e>=97&&e<=122||e>=48&&e<=57||92===e||e>=128&&qM.test(String.fromCharCode(e))}var ZM={if:1,in:1,do:1,var:1,for:1,new:1,try:1,let:1,this:1,else:1,case:1,void:1,with:1,enum:1,while:1,break:1,catch:1,throw:1,const:1,yield:1,class:1,super:1,return:1,typeof:1,delete:1,switch:1,export:1,import:1,public:1,static:1,default:1,finally:1,extends:1,package:1,private:1,function:1,continue:1,debugger:1,interface:1,protected:1,instanceof:1,implements:1};function XM(){for(var e;oM1114111||"}"!==e)&&gN({},TM,UM),t<=65535?String.fromCharCode(t):(n=55296+(t-65536>>10),r=56320+(t-65536&1023),String.fromCharCode(n,r))}function tN(){var e,t;for(e=aM.charCodeAt(oM++),t=String.fromCharCode(e),92===e&&(117!==aM.charCodeAt(oM)&&gN({},TM,UM),++oM,(e=JM("u"))&&"\\"!==e&&QM(e.charCodeAt(0))||gN({},TM,UM),t=e);oM>>="===(r=aM.substr(oM,4))?{type:hM,value:r,start:i,end:oM+=4}:">>>"===(n=r.substr(0,3))||"<<="===n||">>="===n?{type:hM,value:n,start:i,end:oM+=3}:o===(t=n.substr(0,2))[1]&&"+-<>&|".indexOf(o)>=0||"=>"===t?{type:hM,value:t,start:i,end:oM+=2}:"<>=!+-*%&|^/".indexOf(o)>=0?{type:hM,value:o,start:i,end:++oM}:void gN({},TM,UM)}function iN(){var e,t,n;if(GM($M((n=aM[oM]).charCodeAt(0))||"."===n,"Numeric literal must start with a decimal digit or a decimal point"),t=oM,e="","."!==n){if(e=aM[oM++],n=aM[oM],"0"===e){if("x"===n||"X"===n)return++oM,function(e){for(var t="";oM=0&&gN({},LM,n),{value:n,literal:t}}(),r=function(e,t){var n=e;t.indexOf("u")>=0&&(n=n.replace(/\\u\{([0-9a-fA-F]+)\}/g,function(e,t){if(parseInt(t,16)<=1114111)return"x";gN({},LM)}).replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x"));try{new RegExp(n)}catch(e){gN({},LM)}try{return new RegExp(e,t)}catch(e){return null}}(t.value,n.value),{literal:t.literal+n.literal,value:r,regex:{pattern:t.value,flags:n.value},start:e,end:oM}}function oN(){var e;return XM(),oM>=sM?{type:dM,start:oM,end:oM}:QM(e=aM.charCodeAt(oM))?nN():40===e||41===e||59===e?rN():39===e||34===e?function(){var e,t,n,r,i="",a=!1;for(GM("'"===(e=aM[oM])||'"'===e,"String literal must starts with a quote"),t=oM,++oM;oM=0&&oM":case"<=":case">=":case"instanceof":case"in":t=7;break;case"<<":case">>":case">>>":t=8;break;case"+":case"-":t=9;break;case"*":case"/":case"%":t=11}return t}function kN(){var e,t;return e=function(){var e,t,n,r,i,a,o,s,l,c;if(e=lM,l=DN(),0===(i=AN(r=lM)))return l;for(r.prec=i,sN(),t=[e,lM],a=[l,r,o=DN()];(i=AN(lM))>0;){for(;a.length>2&&i<=a[a.length-2].prec;)o=a.pop(),s=a.pop().value,l=a.pop(),t.pop(),n=cN(s,l,o),a.push(n);(r=sN()).prec=i,a.push(r),t.push(lM),n=DN(),a.push(n)}for(n=a[c=a.length-1],t.pop();c>1;)t.pop(),n=cN(a[c-1].value,a[c-2],n),c-=2;return n}(),vN("?")&&(sN(),t=kN(),bN(":"),e=function(e,t,n){var r=new cM(xM);return r.test=e,r.consequent=t,r.alternate=n,r}(e,t,kN())),e}function RN(){var e=kN();if(vN(","))throw new Error(jM);return e}var IN=function(e){oM=0,sM=(aM=e).length,lM=null,lN();var t=RN();if(lM.type!==dM)throw new Error("Unexpect token after expression.");return t},LN={NaN:"NaN",E:"Math.E",LN2:"Math.LN2",LN10:"Math.LN10",LOG2E:"Math.LOG2E",LOG10E:"Math.LOG10E",PI:"Math.PI",SQRT1_2:"Math.SQRT1_2",SQRT2:"Math.SQRT2",MIN_VALUE:"Number.MIN_VALUE",MAX_VALUE:"Number.MAX_VALUE"},PN=function(e){function t(t,n,r){return function(i){return function(t,n,r,i){var a=e(n[0]);return r&&(a=r+"("+a+")",0===r.lastIndexOf("new ",0)&&(a="("+a+")")),a+"."+t+(i<0?"":0===i?"()":"("+n.slice(1).map(e).join(",")+")")}(t,i,n,r)}}var n="new Date";return{isNaN:"isNaN",isFinite:"isFinite",abs:"Math.abs",acos:"Math.acos",asin:"Math.asin",atan:"Math.atan",atan2:"Math.atan2",ceil:"Math.ceil",cos:"Math.cos",exp:"Math.exp",floor:"Math.floor",log:"Math.log",max:"Math.max",min:"Math.min",pow:"Math.pow",random:"Math.random",round:"Math.round",sin:"Math.sin",sqrt:"Math.sqrt",tan:"Math.tan",clamp:function(t){t.length<3&&Object(Ee.l)("Missing arguments to clamp function."),t.length>3&&Object(Ee.l)("Too many arguments to clamp function.");var n=t.map(e);return"Math.max("+n[1]+", Math.min("+n[2]+","+n[0]+"))"},now:"Date.now",utc:"Date.UTC",datetime:n,date:t("getDate",n,0),day:t("getDay",n,0),year:t("getFullYear",n,0),month:t("getMonth",n,0),hours:t("getHours",n,0),minutes:t("getMinutes",n,0),seconds:t("getSeconds",n,0),milliseconds:t("getMilliseconds",n,0),time:t("getTime",n,0),timezoneoffset:t("getTimezoneOffset",n,0),utcdate:t("getUTCDate",n,0),utcday:t("getUTCDay",n,0),utcyear:t("getUTCFullYear",n,0),utcmonth:t("getUTCMonth",n,0),utchours:t("getUTCHours",n,0),utcminutes:t("getUTCMinutes",n,0),utcseconds:t("getUTCSeconds",n,0),utcmilliseconds:t("getUTCMilliseconds",n,0),length:t("length",null,-1),indexof:t("indexOf",null),lastindexof:t("lastIndexOf",null),slice:t("slice",null),parseFloat:"parseFloat",parseInt:"parseInt",upper:t("toUpperCase","String",0),lower:t("toLowerCase","String",0),substring:t("substring","String"),replace:t("replace","String"),regexp:"RegExp",test:t("test","RegExp"),if:function(t){t.length<3&&Object(Ee.l)("Missing arguments to if function."),t.length>3&&Object(Ee.l)("Too many arguments to if function.");var n=t.map(e);return"("+n[0]+"?"+n[1]+":"+n[2]+")"}}},FN=function(e){var t=(e=e||{}).whitelist?Object(Ee.Q)(e.whitelist):{},n=e.blacklist?Object(Ee.Q)(e.blacklist):{},r=e.constants||LN,i=(e.functions||PN)(d),a=e.globalvar,o=e.fieldvar,s={},l={},c=0,u=Object(Ee.x)(a)?a:function(e){return a+'["'+e+'"]'};function d(e){if(Object(Ee.B)(e))return e;var t=f[e.type];return null==t&&Object(Ee.l)("Unsupported type: "+e.type),t(e)}var f={Literal:function(e){return e.raw},Identifier:function(e){var i=e.name;return c>0?i:n.hasOwnProperty(i)?Object(Ee.l)("Illegal identifier: "+i):r.hasOwnProperty(i)?r[i]:t.hasOwnProperty(i)?i:(s[i]=1,u(i))},MemberExpression:function(e){var t=!e.computed,n=d(e.object);t&&(c+=1);var r=d(e.property);return n===o&&(l[r]=1),t&&(c-=1),n+(t?"."+r:"["+r+"]")},CallExpression:function(e){"Identifier"!==e.callee.type&&Object(Ee.l)("Illegal callee type: "+e.callee.type);var t=e.callee.name,n=e.arguments,r=i.hasOwnProperty(t)&&i[t];return r||Object(Ee.l)("Unrecognized function: "+t),Object(Ee.x)(r)?r(n):r+"("+n.map(d).join(",")+")"},ArrayExpression:function(e){return"["+e.elements.map(d).join(",")+"]"},BinaryExpression:function(e){return"("+d(e.left)+e.operator+d(e.right)+")"},UnaryExpression:function(e){return"("+e.operator+d(e.argument)+")"},ConditionalExpression:function(e){return"("+d(e.test)+"?"+d(e.consequent)+":"+d(e.alternate)+")"},LogicalExpression:function(e){return"("+d(e.left)+e.operator+d(e.right)+")"},ObjectExpression:function(e){return"{"+e.properties.map(d).join(",")+"}"},Property:function(e){c+=1;var t=d(e.key);return c-=1,t+":"+d(e.value)}};function p(e){var t={code:d(e),globals:Object.keys(s),fields:Object.keys(l)};return s={},l={},t}return p.functions=i,p.constants=r,p},BN={};function UN(e,t,n){var r=e+":"+n,i=BN[r];return i&&i[0]===t||(BN[r]=i=[t,t(n)]),i[1]}function jN(e,t){return UN("timeFormat",gn,t)(e)}var zN=new Date(2e3,0,1);function qN(e,t,n){return zN.setMonth(e),zN.setDate(t),jN(zN,n)}function GN(e,t,n){try{e[t].apply(e,["EXPRESSION"].concat([].slice.call(n)))}catch(t){e.warn(t)}return n[n.length-1]}var $N="undefined"!=typeof window&&window||null;var HN="Literal",WN="Identifier",VN="@",KN="%",QN=":";function YN(e,t){var n;return Object(Ee.x)(e)?e:Object(Ee.B)(e)?(n=t.scales[e])&&n.value:void 0}function ZN(e,t,n){var r=KN+n;if(!t.hasOwnProperty(r))try{t[r]=e.scaleRef(n)}catch(e){}}function XN(e,t,n,r){if(t[0].type===HN)ZN(n,r,t[0].value);else if(t[0].type===WN)for(e in n.scales)ZN(n,r,e)}function JN(e,t){return function(n,r,i){if(n){var a=YN(n,(i||this).context);return a&&a.path[e](r)}return t(r)}}var eT=JN("area",Nv),tT=JN("bounds",y_),nT=JN("centroid",k_);function rT(e){var t=this.context.data[e];return t?t.values.value:[]}function iT(e,t,n,r){t[0].type!==HN&&Object(Ee.l)("First argument to data functions must be a string literal.");var i=t[0].value,a=QN+i;r.hasOwnProperty(a)||(r[a]=n.getData(i).tuplesRef())}var aT={};function oT(e){return e.data}function sT(e,t){var n=rT.call(t,e);return n.root&&n.root.lookup||aT}var lT=function(e,t,n,r){var i,a=t[0],o=t[t.length-1];return a>o&&(i=a,a=o,o=i),n=void 0===n||n,r=void 0===r||r,(n?a<=e:a=2&&t[t.length-1].value,o=VN+"unit";a!==fT||r.hasOwnProperty(o)||(r[o]=n.getData(i).indataRef(n,"unit")),iT(0,t,n,r)}function yT(e,t,n,r){var i,a,o,s,l,c=this.context.data[e],u=c?c.values.value:[],d=c?c[mT]&&c[mT].value:void 0,f=u[0],p=0;if(f){for(i=t?f.encodings.length:f.fields.length;p(a=n[1])&&(a=n[0],i=n[1]),r=r?o(r,i,a):[i,a];return r&&r.length&&+r[0]!=+r[1]?r:void 0}function ST(e,t,n){return e[0]>t&&(e[0]=t),e[1]n&&(e[1]=n),e)}var CT={random:function(){return ui()},isArray:Ee.u,isBoolean:Ee.v,isDate:Ee.w,isNumber:Ee.y,isObject:Ee.z,isRegExp:Ee.A,isString:Ee.B,isTuple:Oe,toBoolean:Ee.N,toDate:Ee.O,toNumber:Ee.P,toString:Ee.R,pad:Ee.G,peek:Ee.K,truncate:Ee.S,rgb:Sf,lab:jf,hcl:Vf,hsl:Mf,sequence:xi,format:function(e,t){return UN("format",um,t)(e)},utcFormat:function(e,t){return UN("utcFormat",bn,t)(e)},utcParse:function(e,t){return UN("utcParse",vn,t)(e)},timeFormat:jN,timeParse:function(e,t){return UN("timeParse",hn,t)(e)},monthFormat:function(e){return qN(e,1,"%B")},monthAbbrevFormat:function(e){return qN(e,1,"%b")},dayFormat:function(e){return qN(0,2+e,"%A")},dayAbbrevFormat:function(e){return qN(0,2+e,"%a")},quarter:function(e){return 1+~~(new Date(e).getMonth()/3)},utcquarter:function(e){return 1+~~(new Date(e).getUTCMonth()/3)},warn:function(){return GN(this.context.dataflow,"warn",arguments)},info:function(){return GN(this.context.dataflow,"info",arguments)},debug:function(){return GN(this.context.dataflow,"debug",arguments)},inScope:function(e){var t=this.context.group,n=!1;if(t)for(;e;){if(e===t){n=!0;break}e=e.mark.group}return n},clampRange:function(e,t,n){var r,i=e[0],a=e[1];return a=n-t?[t,n]:[Math.min(Math.max(i,t),n-r),Math.min(Math.max(a,r),n)]},pinchDistance:function(e){var t=e.touches,n=t[0].clientX-t[1].clientX,r=t[0].clientY-t[1].clientY;return Math.sqrt(n*n+r*r)},pinchAngle:function(e){var t=e.touches;return Math.atan2(t[0].clientY-t[1].clientY,t[0].clientX-t[1].clientX)},screen:function(){return $N?$N.screen:{}},containerSize:function(){var e=this.context.dataflow,t=e.container&&e.container();return t?[t.clientWidth,t.clientHeight]:[void 0,void 0]},windowSize:function(){return $N?[$N.innerWidth,$N.innerHeight]:[void 0,void 0]},span:function(e){return e[e.length-1]-e[0]||0},merge:function(){var e=[].slice.call(arguments);return e.unshift({}),Ee.m.apply(null,e)},flush:function(e,t,n,r,i,a){var o,s,l=e[0],c=Object(Ee.K)(e);return c2;break}return s=u.reduce(function(e,t){var n=t.intervals[o].extent,r=l?n.map(function(e){return{unit:t.unit,value:e}}):{unit:t.unit,value:n};return l?e.push.apply(e,r):e.push(r),e},[]),l?xT(s,r):ET(s,r)}},iT),DT("treePath",function(e,t,n){var r=sT(e,this),i=r[t],a=r[n];return i&&a?i.path(a).map(oT):void 0},iT),DT("treeAncestors",function(e,t){var n=sT(e,this)[t];return n?n.ancestors().map(oT):void 0},iT);var AT={blacklist:["_"],whitelist:["datum","event","item"],fieldvar:"datum",globalvar:function(e){return"_["+Object(Ee.M)("$"+e)+"]"},functions:function(e){var t=PN(e);for(var n in OT.forEach(function(e){t[e]=MT+e}),CT)t[n]=NT+n;return t},constants:LN,visitors:TT},kT=FN(AT),RT=function(e,t,n){var r,i,a={};try{e=Object(Ee.B)(e)?e:Object(Ee.M)(e)+"",r=IN(e)}catch(t){Object(Ee.l)("Expression parse error: "+e)}return r.visit(function(e){if("CallExpression"===e.type){var n=e.callee.name,r=AT.visitors[n];r&&r(n,e.arguments,t,a)}}),(i=kT(r)).globals.forEach(function(e){var n="$"+e;!a.hasOwnProperty(n)&&t.getSignal(e)&&(a[n]=t.signalRef(e))}),{$expr:n?n+"return("+i.code+");":i.code,$fields:i.fields,$params:a}};function IT(e,t,n,r){this.id=-1,this.type=e,this.value=t,this.params=n,r&&(this.parent=r)}function LT(e,t,n,r){return new IT(e,t,n,r)}function PT(e,t){return LT("operator",e,t)}function FT(e){var t={$ref:e.id};return e.id<0&&(e.refs=e.refs||[]).push(t),t}var BT={$tupleid:1,toString:function(){return":_tupleid_:"}};function UT(e,t){return t?{$field:e,$name:t}:{$field:e}}var jT=UT("key");function zT(e,t){return{$compare:e,$order:t}}var qT="descending";function GT(e,t){return(e&&e.signal?"$"+e.signal:e||"")+(e&&t?"_":"")+(t&&t.signal?"$"+t.signal:t||"")}function $T(e){return e&&e.signal}var HT,WT,VT=function(e,t,n){return HT=t||KT,WT=n||iD,oD(e.trim()).map(sD)},KT="view",QT="[",YT="]",ZT="{",XT="}",JT=":",eD=",",tD="@",nD=">",rD=/[[\]{}]/,iD={"*":1,arc:1,area:1,group:1,image:1,line:1,path:1,rect:1,rule:1,shape:1,symbol:1,text:1,trail:1};function aD(e,t,n,r,i){for(var a,o=0,s=e.length;t=0?--o:r&&r.indexOf(a)>=0&&++o}return t}function oD(e){for(var t=[],n=0,r=e.length,i=0;i' after between selector: "+e;if(t=t.map(sD),(n=sD(e.slice(1).trim())).between)return{between:t,stream:n};n.between=t;return n}(e):function(e){var t,n,r={source:HT},i=[],a=[0,0],o=0,s=0,l=e.length,c=0;if(e[l-1]===XT){if(!((c=e.lastIndexOf(ZT))>=0))throw"Unmatched right brace: "+e;try{a=function(e){var t=e.split(eD);if(!e.length||t.length>2)throw e;return t.map(function(t){var n=+t;if(n!=n)throw e;return n})}(e.substring(c+1,l-1))}catch(t){throw"Invalid throttle specification: "+e}e=e.slice(0,c).trim(),l=e.length,c=0}if(!l)throw e;e[0]===tD&&(o=++c);(t=aD(e,c,JT))1?(r.type=i[1],o?r.markname=i[0].slice(1):(u=i[0],WT.hasOwnProperty(u)?r.marktype=i[0]:r.source=i[0])):r.type=i[0];var u;"!"===r.type.slice(-1)&&(r.consume=!0,r.type=r.type.slice(0,-1));null!=n&&(r.filter=n);a[0]&&(r.throttle=a[0]);a[1]&&(r.debounce=a[1]);return r}(e)}function lD(e){return function(t,n,r){return LT(e,n,t||void 0,r)}}var cD=lD("aggregate"),uD=(lD("axisticks"),lD("bound"),lD("collect")),dD=lD("compare"),fD=(lD("datajoin"),lD("encode"),lD("expression")),pD=(lD("extent"),lD("facet"),lD("field")),mD=lD("key"),gD=(lD("legendentries"),lD("mark"),lD("multiextent"),lD("multivalues"),lD("overlap"),lD("params"),lD("prefacet"),lD("projection")),hD=lD("proxy"),bD=(lD("relay"),lD("render"),lD("scale")),vD=lD("sieve"),_D=(lD("sortitems"),lD("viewlayout"),lD("values"),["identity","ordinal","band","point","bin-linear","bin-ordinal","quantize","quantile","threshold","linear","pow","sqrt","log","sequential","time","utc"]);Object(Ee.Q)(_D),Object(Ee.Q)(_D.slice(4,9)),Object(Ee.Q)(_D.slice(9)),Object(Ee.Q)(_D.slice(1,6));var yD="left",xD="start",ED="end";Object(Ee.Q)(["rule"]),Object(Ee.Q)(["group","image","rect"]);function SD(e,t,n,r,i){this.scope=e,this.input=t,this.output=n,this.values=r,this.aggregate=i,this.index={}}SD.fromEntries=function(e,t){var n=t.length,r=1,i=t[0],a=t[n-1],o=t[n-2],s=null;for(e.add(t[0]);r0?",":"")+(Object(Ee.z)(t)?t.signal||kD(t):Object(Ee.M)(t));return n+"]"}:function(e){var t,n,r="{",i=0;for(t in e)n=e[t],r+=(++i>1?",":"")+Object(Ee.M)(t)+":"+(Object(Ee.z)(n)?n.signal||kD(n):Object(Ee.M)(n));return r+"}"})(e)}AD.fork=function(){return new DD(this)},AD.isSubscope=function(){return this._subid>0},AD.toRuntime=function(){return this.finish(),{background:this.background,operators:this.operators,streams:this.streams,updates:this.updates,bindings:this.bindings,eventConfig:this.eventConfig}},AD.id=function(){return(this._subid?this._subid+":":0)+this._id++},AD.add=function(e){return this.operators.push(e),e.id=this.id(),e.refs&&(e.refs.forEach(function(t){t.$ref=e.id}),e.refs=null),e},AD.proxy=function(e){var t=e instanceof IT?FT(e):e;return this.add(hD({value:t}))},AD.addStream=function(e){return this.streams.push(e),e.id=this.id(),e},AD.addUpdate=function(e){return this.updates.push(e),e},AD.finish=function(){var e,t;for(e in this.root&&(this.root.root=!0),this.signals)this.signals[e].signal=e;for(e in this.scales)this.scales[e].scale=e;function n(e,t,n){var r;e&&((r=e.data||(e.data={}))[t]||(r[t]=[])).push(n)}for(e in this.data)for(var r in n((t=this.data[e]).input,e,"input"),n(t.output,e,"output"),n(t.values,e,"values"),t.index)n(t.index[r],e,"index:"+r);return this},AD.pushState=function(e,t,n){this._encode.push(FT(this.add(vD({pulse:e})))),this._parent.push(t),this._lookup.push(n?FT(this.proxy(n)):null),this._markpath.push(-1)},AD.popState=function(){this._encode.pop(),this._parent.pop(),this._lookup.pop(),this._markpath.pop()},AD.parent=function(){return Object(Ee.K)(this._parent)},AD.encode=function(){return Object(Ee.K)(this._encode)},AD.lookup=function(){return Object(Ee.K)(this._lookup)},AD.markpath=function(){var e=this._markpath;return++e[e.length-1]},AD.fieldRef=function(e,t){if(Object(Ee.B)(e))return UT(e,t);e.signal||Object(Ee.l)("Unsupported field reference: "+Object(Ee.M)(e));var n,r=e.signal,i=this.field[r];return i||(n={name:this.signalRef(r)},t&&(n.as=t),this.field[r]=i=FT(this.add(pD(n)))),i},AD.compareRef=function(e,t){function n(e){return $T(e)?(i=!0,FT(r[e.signal])):e}var r=this.signals,i=!1,a=Object(Ee.h)(e.field).map(n),o=Object(Ee.h)(e.order).map(n);return t&&a.push(BT),i?FT(this.add(dD({fields:a,orders:o}))):zT(a,o)},AD.keyRef=function(e,t){var n=this.signals,r=!1;return e=Object(Ee.h)(e).map(function(e){return $T(e)?(r=!0,FT(n[e.signal])):e}),r?FT(this.add(mD({fields:e,flat:t}))):function(e,t){var n={$key:e};return t&&(n.$flat=!0),n}(e,t)},AD.sortRef=function(e){if(!e)return e;var t=[GT(e.op,e.field),BT],n=e.order||"ascending";return n.signal?FT(this.add(dD({fields:t,orders:[n=this.signalRef(n.signal),n]}))):zT(t,[n,n])},AD.event=function(e,t){var n=e+":"+t;if(!this.events[n]){var r=this.id();this.streams.push({id:r,source:e,type:t}),this.events[n]=r}return this.events[n]},AD.addSignal=function(e,t){this.signals.hasOwnProperty(e)&&Object(Ee.l)("Duplicate signal name: "+Object(Ee.M)(e));var n=t instanceof IT?t:this.add(PT(t));return this.signals[e]=n},AD.getSignal=function(e){return this.signals[e]||Object(Ee.l)("Unrecognized signal name: "+Object(Ee.M)(e)),this.signals[e]},AD.signalRef=function(e){return this.signals[e]?FT(this.signals[e]):(this.lambdas.hasOwnProperty(e)||(this.lambdas[e]=this.add(PT(null))),FT(this.lambdas[e]))},AD.parseLambdas=function(){for(var e=Object.keys(this.lambdas),t=0,n=e.length;t=0;)if(r=i[a].type,n=i[a].handler,e===r&&(t===n||t===n.raw)){this._handler.off(r,n);break}return this},aA.addResizeListener=function(e){var t=this._resizeListeners;return t.indexOf(e)<0&&t.push(e),this},aA.removeResizeListener=function(e){var t=this._resizeListeners,n=t.indexOf(e);return n>=0&&t.splice(n,1),this},aA.addSignalListener=function(e,t){var n=oA(this,e),r=sA(n,t);return r||((r=tM(this,function(){t(e,n.value)})).handler=t,this.on(n,null,r)),this},aA.removeSignalListener=function(e,t){var n=oA(this,e),r=sA(n,t);return r&&n._targets.remove(r),this},aA.preventDefault=function(e){return arguments.length?(this._preventDefault=e,this):this._preventDefault},aA.timer=function(e,t){this._timers.push(function(e,t,n){var r=new IE,i=t;return null==t?(r.restart(e,t,n),r):(t=+t,n=null==n?kE():+n,r.restart(function a(o){o+=i,r.restart(a,i+=t,n),e(o)},t,n),r)}(function(t){e({timestamp:Date.now(),elapsed:t})},t))},aA.events=function(e,t,n){var r,i=this,a=new $e(n),o=function(n,r){e===LO&&function(e,t){var n=e._eventConfig.defaults,r=n&&n.prevent,i=n&&n.allow;return!1!==r&&!0!==i&&(!0===r||!1===i||(r?r[t]:i?!i[t]:e.preventDefault()))}(i,t)&&n.preventDefault();try{a.receive(IO(i,n,r))}catch(e){i.error(e)}finally{i.run()}};if(e===PO)i.timer(o,t);else if(e===LO)i.addEventListener(t,o,BO);else if(e===FO?"undefined"!=typeof window&&(r=[window]):"undefined"!=typeof document&&(r=document.querySelectorAll(e)),r){for(var s=0,l=r.length;s=0;)i[e].stop();for(e=a.length;--e>=0;)for(t=(n=a[e]).sources.length;--t>=0;)n.sources[t].removeEventListener(n.type,n.handler);return r&&r.call(this,this._handler,null,null,null),this},aA.hover=function(e,t){return e=[e||"hover"],t=[t||"update",e[0]],this.on(this.events("view","mouseover",UO),jO,zO(e)),this.on(this.events("view","mouseout",UO),jO,zO(t)),this},aA.data=function(e){return TO(this,e).values.value},aA.change=DO,aA.insert=function(e,t){return DO.call(this,e,Ie().insert(t))},aA.remove=function(e,t){return DO.call(this,e,Ie().remove(t))},aA.scale=function(e){var t=this._runtime.scales;return t.hasOwnProperty(e)||Object(Ee.l)("Unrecognized scale or projection: "+e),t[e].value},aA.initialize=function(e,t){var n,r,i=this,a=i._renderType,o=Yu(a);return e=i._el=e?nM(i,e):null,o||i.error("Unrecognized renderer type: "+a),n=o.handler||fu,r=e?o.renderer:o.headless,i._renderer=r?eM(i,i._renderer,e,r):null,i._handler=function(e,t,n,r){var i=new r(e.loader(),tM(e,e.tooltip())).scene(e.scenegraph().root).initialize(n,RO(e),e);return t&&t.handlers().forEach(function(e){i.on(e.type,e.handler)}),i}(i,i._handler,e,n),i._redraw=!0,e&&(t=t?nM(i,t):e.appendChild(qO("div",{class:"vega-bindings"})),i._bind.forEach(function(e){e.param.element&&(e.element=nM(i,e.param.element))}),i._bind.forEach(function(e){VO(i,e.element||t,e)})),i},aA.toImageURL=function(e,t){return e!==Ku.Canvas&&e!==Ku.SVG&&e!==Ku.PNG?Promise.reject("Unrecognized image type: "+e):rM(this,e,t).then(function(t){return e===Ku.SVG?(n=t.svg(),r=new Blob([n],{type:"image/svg+xml"}),window.URL.createObjectURL(r)):t.canvas().toDataURL("image/png");var n,r})},aA.toCanvas=function(e){return rM(this,Ku.Canvas,e).then(function(e){return e.canvas()})},aA.toSVG=function(e){return rM(this,Ku.SVG,e).then(function(e){return e.svg()})},aA.getState=function(e){return this._runtime.getState(e||{data:JD,signals:eA,recurse:!0})},aA.setState=function(e){var t=this;return t.runAfter(function(){t._trigger=!1,t._runtime.setState(e),t.run().runAfter(function(){t._trigger=!0})}),this};var lA=function(e,t){return e=e||t.autosize,Object(Ee.z)(e)?e:{type:e=e||"pad"}},cA=function(e,t){return e=e||t.padding,Object(Ee.z)(e)?{top:uA(e.top),bottom:uA(e.bottom),left:uA(e.left),right:uA(e.right)}:{top:n=uA(e),bottom:n,left:n,right:n};var n};function uA(e){return+e||0}var dA=["value","update","react","bind"];function fA(e,t){Object(Ee.l)(e+' for "outer" push: '+Object(Ee.M)(t))}var pA=function(e,t){var n=e.name;if("outer"===e.push)t.signals[n]||fA("No prior signal definition",n),dA.forEach(function(t){void 0!==e[t]&&fA("Invalid property ",t)});else{var r=t.addSignal(n,e.value);!1===e.react&&(r.react=!1),e.bind&&t.addBinding(n,e.bind)}},mA={};function gA(e,t,n){var r=e+":"+n,i=mA[r];return i&&i[0]===t||(mA[r]=i=[t,t(n)]),i[1]}function hA(e,t){return gA("timeFormat",gn,t)(e)}var bA=new Date(2e3,0,1);function vA(e,t,n){return bA.setMonth(e),bA.setDate(t),hA(bA,n)}function _A(e,t,n){try{e[t].apply(e,["EXPRESSION"].concat([].slice.call(n)))}catch(t){e.warn(t)}return n[n.length-1]}var yA="undefined"!=typeof window&&window||null;var xA="Literal",EA="Identifier",SA="@",wA="%",CA=":",OA=function(e,t,n){var r=e-t+2*n;return e?r>0?r:1:0},MA=function(e){return function(t){var n,r=t[0],i=t[1];return i=s&&o[i]<=l&&(c<0&&(c=i),n=i);if(!(c<0))return s=e.invertExtent(o[c]),l=e.invertExtent(o[n]),[void 0===s[0]?s[1]:s[0],void 0===l[1]?l[0]:l[1]]}};function TA(){var e,t,n=hC().unknown(void 0),r=n.domain,i=n.range,a=[0,1],o=!1,s=0,l=0,c=.5;function u(){var n=r().length,u=a[1]a[1-u])))return n=Math.max(0,mi(d,l)-1),o=l===c?n:mi(d,c)-1,l-d[n]>t+1e-10&&++n,u&&(s=n,n=f-o,o=f-s),n>o?void 0:r().slice(n,o+1)}},n.invert=function(e){var t=n.invertRange([e,e]);return t?t[0]:t},n.copy=function(){return TA().domain(r()).range(a).round(o).paddingInner(s).paddingOuter(l).align(c)},u()}var DA=Array.prototype.map,AA=Array.prototype.slice;function kA(e){return DA.call(e,function(e){return+e})}function RA(e,t){return arguments.length>1?(IA[e]=function(e,t){return function(){var n=t();return n.invertRange||(n.invertRange=n.invert?MA(n):n.invertExtent?NA(n):void 0),n.type=e,n}}(e,t),this):IA.hasOwnProperty(e)?IA[e]:void 0}var IA={identity:NC,linear:MC,log:PC,ordinal:hC,pow:BC,sqrt:UC,quantile:jC,quantize:zC,threshold:qC,time:JC,utc:eO,band:TA,point:function(){return function e(t){var n=t.copy;return t.padding=t.paddingOuter,delete t.paddingInner,t.copy=function(){return e(n())},t}(TA().paddingInner(1))},sequential:function e(t){var n=MC(),r=0,i=1,a=!1;function o(){var e=n.domain();r=e[0],i=Object(Ee.K)(e)-r}function s(e){var n=(e-r)/i;return t(a?Math.max(0,Math.min(1,n)):n)}return s.clamp=function(e){return arguments.length?(a=!!e,s):a},s.domain=function(e){return arguments.length?(n.domain(e),o(),s):n.domain()},s.interpolator=function(e){return arguments.length?(t=e,s):t},s.copy=function(){return e().domain(n.domain()).clamp(a).interpolator(t)},s.ticks=function(e){return n.ticks(e)},s.tickFormat=function(e,t){return n.tickFormat(e,t)},s.nice=function(e){return n.nice(e),o(),s},s},"bin-linear":function e(){var t=MC(),n=[];function r(e){return t(e)}return r.domain=function(e){return arguments.length?(function(e){n=kA(e),t.domain([n[0],Object(Ee.K)(n)])}(e),r):n.slice()},r.range=function(e){return arguments.length?(t.range(e),r):t.range()},r.rangeRound=function(e){return arguments.length?(t.rangeRound(e),r):t.rangeRound()},r.interpolate=function(e){return arguments.length?(t.interpolate(e),r):t.interpolate()},r.invert=function(e){return t.invert(e)},r.ticks=function(e){var t=n.length,i=~~(t/(e||t));return i<2?r.domain():n.filter(function(e,t){return!(t%i)})},r.tickFormat=function(){return t.tickFormat.apply(t,arguments)},r.copy=function(){return e().domain(r.domain()).range(r.range())},r},"bin-ordinal":function e(){var t=[],n=[];function r(e){return null==e||e!=e?void 0:n[(hi(t,e)-1)%n.length]}return r.domain=function(e){return arguments.length?(t=kA(e),r):t.slice()},r.range=function(e){return arguments.length?(n=AA.call(e),r):n.slice()},r.copy=function(){return e().domain(r.domain()).range(r.range())},r}};for(var LA in IA)RA(LA,IA[LA]);function PA(e,t){var n=t-e;return function(t){return e+t*n}}function FA(e){for(var t=e.length/6|0,n=new Array(t),r=0;ro&&(i=a,a=o,o=i),n=void 0===n||n,r=void 0===r||r,(n?a<=e:a=2&&t[t.length-1].value,o=SA+"unit";a!==ck||r.hasOwnProperty(o)||(r[o]=n.getData(i).indataRef(n,"unit")),tk(0,t,n,r)}function bk(e,t,n,r){var i,a,o,s,l,c=this.context.data[e],u=c?c.values.value:[],d=c?c[dk]&&c[dk].value:void 0,f=u[0],p=0;if(f){for(i=t?f.encodings.length:f.fields.length;p(a=n[1])&&(a=n[0],i=n[1]),r=r?o(r,i,a):[i,a];return r&&r.length&&+r[0]!=+r[1]?r:void 0}function yk(e,t,n){return e[0]>t&&(e[0]=t),e[1]n&&(e[1]=n),e)}var Ek={random:function(){return ui()},isArray:Ee.u,isBoolean:Ee.v,isDate:Ee.w,isNumber:Ee.y,isObject:Ee.z,isRegExp:Ee.A,isString:Ee.B,isTuple:Oe,toBoolean:Ee.N,toDate:Ee.O,toNumber:Ee.P,toString:Ee.R,pad:Ee.G,peek:Ee.K,truncate:Ee.S,rgb:Sf,lab:jf,hcl:Vf,hsl:Mf,sequence:xi,format:function(e,t){return gA("format",um,t)(e)},utcFormat:function(e,t){return gA("utcFormat",bn,t)(e)},utcParse:function(e,t){return gA("utcParse",vn,t)(e)},timeFormat:hA,timeParse:function(e,t){return gA("timeParse",hn,t)(e)},monthFormat:function(e){return vA(e,1,"%B")},monthAbbrevFormat:function(e){return vA(e,1,"%b")},dayFormat:function(e){return vA(0,2+e,"%A")},dayAbbrevFormat:function(e){return vA(0,2+e,"%a")},quarter:function(e){return 1+~~(new Date(e).getMonth()/3)},utcquarter:function(e){return 1+~~(new Date(e).getUTCMonth()/3)},warn:function(){return _A(this.context.dataflow,"warn",arguments)},info:function(){return _A(this.context.dataflow,"info",arguments)},debug:function(){return _A(this.context.dataflow,"debug",arguments)},inScope:function(e){var t=this.context.group,n=!1;if(t)for(;e;){if(e===t){n=!0;break}e=e.mark.group}return n},clampRange:function(e,t,n){var r,i=e[0],a=e[1];return a=n-t?[t,n]:[Math.min(Math.max(i,t),n-r),Math.min(Math.max(a,r),n)]},pinchDistance:function(e){var t=e.touches,n=t[0].clientX-t[1].clientX,r=t[0].clientY-t[1].clientY;return Math.sqrt(n*n+r*r)},pinchAngle:function(e){var t=e.touches;return Math.atan2(t[0].clientY-t[1].clientY,t[0].clientX-t[1].clientX)},screen:function(){return yA?yA.screen:{}},containerSize:function(){var e=this.context.dataflow,t=e.container&&e.container();return t?[t.clientWidth,t.clientHeight]:[void 0,void 0]},windowSize:function(){return yA?[yA.innerWidth,yA.innerHeight]:[void 0,void 0]},span:function(e){return e[e.length-1]-e[0]||0},merge:function(){var e=[].slice.call(arguments);return e.unshift({}),Ee.m.apply(null,e)},flush:function(e,t,n,r,i,a){var o,s,l=e[0],c=Object(Ee.K)(e);return c2;break}return s=u.reduce(function(e,t){var n=t.intervals[o].extent,r=l?n.map(function(e){return{unit:t.unit,value:e}}):{unit:t.unit,value:n};return l?e.push.apply(e,r):e.push(r),e},[]),l?vk(s,r):_k(s,r)}},tk),Mk("treePath",function(e,t,n){var r=ik(e,this),i=r[t],a=r[n];return i&&a?i.path(a).map(rk):void 0},tk),Mk("treeAncestors",function(e,t){var n=ik(e,this)[t];return n?n.ancestors().map(rk):void 0},tk);var Nk={blacklist:["_"],whitelist:["datum","event","item"],fieldvar:"datum",globalvar:function(e){return"_["+Object(Ee.M)("$"+e)+"]"},functions:function(e){var t=PN(e);for(var n in Sk.forEach(function(e){t[e]=wk+e}),Ek)t[n]=Ck+n;return t},constants:LN,visitors:Ok},Tk=FN(Nk),Dk=function(e,t,n){var r,i,a={};try{e=Object(Ee.B)(e)?e:Object(Ee.M)(e)+"",r=IN(e)}catch(t){Object(Ee.l)("Expression parse error: "+e)}return r.visit(function(e){if("CallExpression"===e.type){var n=e.callee.name,r=Nk.visitors[n];r&&r(n,e.arguments,t,a)}}),(i=Tk(r)).globals.forEach(function(e){var n="$"+e;!a.hasOwnProperty(n)&&t.getSignal(e)&&(a[n]=t.signalRef(e))}),{$expr:n?n+"return("+i.code+");":i.code,$fields:i.fields,$params:a}};function Ak(e,t,n,r){this.id=-1,this.type=e,this.value=t,this.params=n,r&&(this.parent=r)}function kk(e,t,n,r){return new Ak(e,t,n,r)}function Rk(e,t){return kk("operator",e,t)}function Ik(e){var t={$ref:e.id};return e.id<0&&(e.refs=e.refs||[]).push(t),t}var Lk={$tupleid:1,toString:function(){return":_tupleid_:"}};function Pk(e,t){return t?{$field:e,$name:t}:{$field:e}}var Fk=Pk("key");function Bk(e,t){return{$compare:e,$order:t}}var Uk="descending";function jk(e,t){return(e&&e.signal?"$"+e.signal:e||"")+(e&&t?"_":"")+(t&&t.signal?"$"+t.signal:t||"")}var zk="scope",qk="view";function Gk(e){return e&&e.signal}function $k(e,t){return null!=e?e:t}function Hk(e){return e&&e.signal||e}var Wk="timer";function Vk(e,t){return(e.merge?Kk:e.stream?Qk:e.type?Yk:Object(Ee.l)("Invalid stream specification: "+Object(Ee.M)(e)))(e,t)}function Kk(e,t){var n=Zk({merge:e.merge.map(function(e){return Vk(e,t)})},e,t);return t.addStream(n).id}function Qk(e,t){var n=Zk({stream:Vk(e.stream,t)},e,t);return t.addStream(n).id}function Yk(e,t){var n,r,i;return e.type===Wk?(n=t.event(Wk,e.throttle),e={between:e.between,filter:e.filter}):n=t.event((i=e.source)===zk?qk:i||qk,e.type),r=Zk({stream:n},e,t),1===Object.keys(r).length?n:t.addStream(r).id}function Zk(e,t,n){var r,i,a,o,s=t.between;return s&&(2!==s.length&&Object(Ee.l)('Stream "between" parameter must have 2 entries: '+Object(Ee.M)(t)),e.between=[Vk(s[0],n),Vk(s[1],n)]),s=t.filter?Object(Ee.h)(t.filter):[],(t.marktype||t.markname||t.markrole)&&s.push((r=t.marktype,i=t.markname,a=t.markrole,(o="event.item")+(r&&"*"!==r?"&&"+o+".mark.marktype==='"+r+"'":"")+(a?"&&"+o+".mark.role==='"+a+"'":"")+(i?"&&"+o+".mark.name==='"+i+"'":""))),t.source===zk&&s.push("inScope(event.item)"),s.length&&(e.filter=Dk("("+s.join(")&&(")+")").$expr),null!=(s=t.throttle)&&(e.throttle=+s),null!=(s=t.debounce)&&(e.debounce=+s),t.consume&&(e.consume=!0),e}var Xk=function(e,t,n){var r,i,a=e.events,o=e.update,s=e.encode,l=[];a||Object(Ee.l)("Signal update missing events specification."),Object(Ee.B)(a)&&(a=VT(a,t.isSubscope()?zk:qk)),(a=Object(Ee.h)(a).filter(function(e){return e.signal||e.scale?(l.push(e),0):1})).length&&l.push(a.length>1?{merge:a}:a[0]),null!=s&&(o&&Object(Ee.l)("Signal encode and update are mutually exclusive."),o="encode(item(),"+Object(Ee.M)(s)+")"),r=Object(Ee.B)(o)?Dk(o,t,"var datum=event.item&&event.item.datum;"):null!=o.expr?Dk(o.expr,t,"var datum=event.item&&event.item.datum;"):null!=o.value?o.value:null!=o.signal?{$expr:"_.value",$params:{value:t.signalRef(o.signal)}}:Object(Ee.l)("Invalid signal update specification."),i={target:n,update:r},e.force&&(i.options={force:!0}),l.forEach(function(e){t.addUpdate(Object(Ee.m)(function(e,t){return{source:e.signal?t.signalRef(e.signal):e.scale?t.scaleRef(e.scale):Vk(e,t)}}(e,t),i))})};function Jk(e){return function(t,n,r){return kk(e,n,t||void 0,r)}}var eR=Jk("aggregate"),tR=Jk("axisticks"),nR=Jk("bound"),rR=Jk("collect"),iR=Jk("compare"),aR=Jk("datajoin"),oR=Jk("encode"),sR=(Jk("extent"),Jk("facet")),lR=Jk("field"),cR=Jk("key"),uR=Jk("legendentries"),dR=Jk("mark"),fR=Jk("multiextent"),pR=Jk("multivalues"),mR=Jk("overlap"),gR=Jk("params"),hR=Jk("prefacet"),bR=Jk("projection"),vR=Jk("proxy"),_R=Jk("relay"),yR=Jk("render"),xR=Jk("scale"),ER=Jk("sieve"),SR=Jk("sortitems"),wR=Jk("viewlayout"),CR=Jk("values"),OR=0,MR=["identity","ordinal","band","point","bin-linear","bin-ordinal","quantize","quantile","threshold","linear","pow","sqrt","log","sequential","time","utc"],NR=Object(Ee.Q)(MR),TR=Object(Ee.Q)(MR.slice(4,9)),DR=Object(Ee.Q)(MR.slice(9)),AR=Object(Ee.Q)(MR.slice(1,6));function kR(e){return AR.hasOwnProperty(e)}function RR(e){return TR.hasOwnProperty(e)}function IR(e){return"quantile"===e}function LR(e,t){var n,r=t.getScale(e.name).params;for(n in r.domain=BR(e.domain,e,t),null!=e.range&&(r.range=function e(t,n,r){var i=t.range,a=n.config.range;if(i.signal)return n.signalRef(i.signal);if(Object(Ee.B)(i)){if(a&&a.hasOwnProperty(i))return t=Object(Ee.m)({},t,{range:a[i]}),e(t,n,r);"width"===i?i=[0,{signal:"width"}]:"height"===i?i=kR(t.type)?[0,{signal:"height"}]:[{signal:"height"},0]:Object(Ee.l)("Unrecognized scale range value: "+Object(Ee.M)(i))}else{if(i.scheme)return r.scheme=PR(i.scheme,n),i.extent&&(r.schemeExtent=function(e,t){return e.signal?t.signalRef(e.signal):e.map(function(e){return PR(e,t)})}(i.extent,n)),void(i.count&&(r.schemeCount=PR(i.count,n)));if(i.step)return void(r.rangeStep=PR(i.step,n));if(kR(t.type)&&!Object(Ee.u)(i))return BR(i,t,n);Object(Ee.u)(i)||Object(Ee.l)("Unsupported range type: "+Object(Ee.M)(i))}return i.map(function(e){return PR(e,n)})}(e,t,r)),null!=e.interpolate&&function(e,t){t.interpolate=PR(e.type||e),null!=e.gamma&&(t.interpolateGamma=PR(e.gamma))}(e.interpolate,r),null!=e.nice&&function(e,t){t.nice=Object(Ee.z)(e)?{interval:PR(e.interval),step:PR(e.step)}:PR(e)}(e.nice,r),e)r.hasOwnProperty(n)||"name"===n||(r[n]=PR(e[n],t))}function PR(e,t){return Object(Ee.z)(e)?e.signal?t.signalRef(e.signal):Object(Ee.l)("Unsupported object: "+Object(Ee.M)(e)):e}function FR(e){Object(Ee.l)("Can not find data set: "+Object(Ee.M)(e))}function BR(e,t,n){if(e)return e.signal?n.signalRef(e.signal):(Object(Ee.u)(e)?function(e,t,n){return e.map(function(e){return PR(e,n)})}:e.fields?function(e,t,n){var r=e.data,i=e.fields.reduce(function(e,t){return t=Object(Ee.B)(t)?{data:r,field:t}:Object(Ee.u)(t)||t.signal?function(e,t){var n="_:vega:_"+OR++,r=rR({});if(Object(Ee.u)(e))r.value={$ingest:e};else if(e.signal){var i="setdata("+Object(Ee.M)(n)+","+e.signal+")";r.params.input=t.signalRef(i)}return t.addDataPipeline(n,[r,ER({})]),{data:n,field:"data"}}(t,n):t,e.push(t),e},[]);return(kR(t.type)?function(e,t,n){var r,i,a;return r=n.map(function(e){var n=t.getData(e.data);return n||FR(e.data),n.countsRef(t,e.field)}),i=t.add(eR({groupby:Fk,ops:["sum"],fields:[t.fieldRef("count")],as:["count"],pulse:r})),a=t.add(rR({pulse:Ik(i)})),Ik(t.add(CR({field:Fk,sort:t.sortRef(UR(e.sort,!0)),pulse:Ik(a)})))}:IR(t.type)?function(e,t,n){var r=n.map(function(e){var n=t.getData(e.data);return n||FR(e.data),n.domainRef(t,e.field)});return Ik(t.add(pR({values:r})))}:function(e,t,n){var r=n.map(function(e){var n=t.getData(e.data);return n||FR(e.data),n.extentRef(t,e.field)});return Ik(t.add(fR({extents:r})))})(e,n,i)}:function(e,t,n){var r=n.getData(e.data);r||FR(e.data);return kR(t.type)?r.valuesRef(n,e.field,UR(e.sort,!1)):IR(t.type)?r.domainRef(n,e.field):r.extentRef(n,e.field)})(e,t,n);null==t.domainMin&&null==t.domainMax||Object(Ee.l)("No scale domain defined for domainMin/domainMax to override.")}function UR(e,t){return e&&(e.field||e.op?e.field||"count"===e.op?t&&e.field?Object(Ee.l)("Multiple domain scales can not sort by field."):t&&e.op&&"count"!==e.op&&Object(Ee.l)("Multiple domain scales support op count only."):Object(Ee.l)("No field provided for sort aggregate op: "+e.op):Object(Ee.z)(e)?e.field="key":e={field:"key"}),e}function jR(e,t,n){return Object(Ee.u)(e)?e.map(function(e){return jR(e,t,n)}):Object(Ee.z)(e)?e.signal?n.signalRef(e.signal):"fit"===t?e:Object(Ee.l)("Unsupported parameter object: "+Object(Ee.M)(e)):e}var zR="top",qR="left",GR="bottom",$R="vertical",HR="start",WR="end",VR="guide-label",KR="group-title",QR="symbol",YR="gradient",ZR="discrete",XR=["size","shape","fill","stroke","strokeDash","opacity"],JR={name:1,interactive:1},eI=Object(Ee.Q)(["rule"]),tI=Object(Ee.Q)(["group","image","rect"]),nI=function(e,t){var n="";return eI[t]?n:(e.x2&&(e.x?(tI[t]&&(n+="if(o.x>o.x2)$=o.x,o.x=o.x2,o.x2=$;"),n+="o.width=o.x2-o.x;"):n+="o.x=o.x2-(o.width||0);"),e.xc&&(n+="o.x=o.xc-(o.width||0)/2;"),e.y2&&(e.y?(tI[t]&&(n+="if(o.y>o.y2)$=o.y,o.y=o.y2,o.y2=$;"),n+="o.height=o.y2-o.y;"):n+="o.y=o.y2-(o.height||0);"),e.yc&&(n+="o.y=o.yc-(o.height||0)/2;"),n)},rI=function(e,t,n,r){var i=Dk(e,t);return i.$fields.forEach(function(e){r[e]=1}),Object(Ee.m)(n,i.$params),i.$expr},iI=function(e,t,n,r){return function e(t,n,r,i){var a,o,s;if(t.signal)a="datum",s=rI(t.signal,n,r,i);else if(t.group||t.parent){for(o=Math.max(1,t.level||1),a="item";o-- >0;)a+=".mark.group";t.parent?(s=t.parent,a+=".datum"):s=t.group}else t.datum?(a="datum",s=t.datum):Object(Ee.l)("Invalid field reference: "+Object(Ee.M)(t));t.signal||(Object(Ee.B)(s)?(i[s]=1,s=Object(Ee.L)(s).map(Ee.M).join("][")):s=e(s,n,r,i));return a+"["+s+"]"}(Object(Ee.z)(e)?e:{datum:e},t,n,r)};var aI=function(e,t,n,r,i){var a,o,s,l=oI(e.scale,n,r,i);return null!=e.range?(o=l+".range()",t=0===(a=+e.range)?o+"[0]":"($="+o+","+(1===a?"$[$.length-1]":"$[0]+"+a+"*($[$.length-1]-$[0])")+")"):(void 0!==t&&(t=l+"("+t+")"),e.band&&(s=function(e,t){if(!Object(Ee.B)(e))return-1;var n=t.scaleType(e);return"band"===n||"point"===n?1:0}(e.scale,n))&&(a=(o=l+".bandwidth")+"()"+(1===(a=+e.band)?"":"*"+a),s<0&&(a="("+o+"?"+a+":0)"),t=(t?t+"+":"")+a,e.extra&&(t="(datum.extra?"+l+"(datum.extra.value):"+t+")")),null==t&&(t="0")),t};function oI(e,t,n,r){var i;if(Object(Ee.B)(e))i=wA+e,n.hasOwnProperty(i)||(n[i]=t.scaleRef(e)),i=Object(Ee.M)(i);else{for(i in t.scales)n[wA+i]=t.scaleRef(i);i=Object(Ee.M)(wA)+"+"+(e.signal?"("+rI(e.signal,t,n,r)+")":iI(e,t,n,r))}return"_["+i+"]"}var sI=function(e,t,n,r){return Object(Ee.z)(e)?"("+lI(null,e,t,n,r)+")":e},lI=function(e,t,n,r,i){if(null!=t.gradient)return function(e,t,n,r){return"this.gradient("+oI(e.gradient,t,n,r)+","+Object(Ee.M)(e.start)+","+Object(Ee.M)(e.stop)+","+Object(Ee.M)(e.count)+")"}(t,n,r,i);var a=t.signal?rI(t.signal,n,r,i):t.color?function(e,t,n,r){function i(e,i,a,o){return"this."+e+"("+[lI(null,i,t,n,r),lI(null,a,t,n,r),lI(null,o,t,n,r)].join(",")+").toString()"}return e.c?i("hcl",e.h,e.c,e.l):e.h||e.s?i("hsl",e.h,e.s,e.l):e.l||e.a?i("lab",e.l,e.a,e.b):e.r||e.g||e.b?i("rgb",e.r,e.g,e.b):null}(t.color,n,r,i):null!=t.field?iI(t.field,n,r,i):void 0!==t.value?Object(Ee.M)(t.value):void 0;return null!=t.scale&&(a=aI(t,a,n,r,i)),void 0===a&&(a=null),null!=t.exponent&&(a="Math.pow("+a+","+sI(t.exponent,n,r,i)+")"),null!=t.mult&&(a+="*"+sI(t.mult,n,r,i)),null!=t.offset&&(a+="+"+sI(t.offset,n,r,i)),t.round&&(a="Math.round("+a+")"),a},cI=function(e,t,n){return e+"["+Object(Ee.M)(t)+"]="+n+";"},uI=function(e,t,n,r,i){var a="";return t.forEach(function(t){var o=lI(e,t,n,r,i);a+=t.test?rI(t.test,n,r,i)+"?"+o+":":o}),cI("o",e,a)};function dI(e,t,n,r){var i,a,o,s={},l="var o=item,datum=o.datum,$;";for(i in e)a=e[i],Object(Ee.u)(a)?l+=uI(i,a,r,n,s):(o=lI(i,a,r,n,s),l+=cI("o",i,o));return l+=nI(e,t),{$expr:l+="return 1;",$fields:Object.keys(s),$output:Object.keys(e)}}var fI="mark",pI="frame",mI="title";function gI(e){return Object(Ee.z)(e)?Object(Ee.m)({},e):{value:e}}function hI(e,t,n){return null!=n?(e[t]=Object(Ee.z)(n)&&!Object(Ee.u)(n)?n:{value:n},1):0}function bI(e,t,n){for(var r in t)n&&n.hasOwnProperty(r)||(e[r]=Object(Ee.m)(e[r]||{},t[r]));return e}function vI(e,t,n,r,i,a){var o,s;for(s in(a=a||{}).encoders={$encode:o={}},e=function(e,t,n,r,i){var a,o,s={};"legend"!=n&&0!==String(n).indexOf("axis")||(n=null);for(a in o=n===pI?i.group:n===fI?Object(Ee.m)({},i.mark,i[t]):null)yI(a,e)||("fill"===a||"stroke"===a)&&(yI("fill",e)||yI("stroke",e))||(s[a]=_I(o[a]));return Object(Ee.h)(r).forEach(function(t){var n=i.style&&i.style[t];for(var r in n)yI(r,e)||(s[r]=_I(n[r]))}),(e=Object(Ee.m)({},e)).enter=Object(Ee.m)(s,e.enter),e}(e,t,n,r,i.config))o[s]=dI(e[s],t,a,i);return a}function _I(e){return e&&e.signal?{signal:e.signal}:{value:e}}function yI(e,t){return t&&(t.enter&&t.enter[e]||t.update&&t.update[e])}var xI=function(e,t,n,r,i,a,o){return{type:e,name:o?o.name:void 0,role:t,style:o&&o.style||n,key:r,from:i,interactive:!(!o||!o.interactive),encode:bI(a,o,JR)}};function EI(e,t,n){return $k(t[e],n[e])}function SI(e,t){return $k(e.direction,t)===$R}function wI(e,t){return $k(e.gradientLength,t.gradientLength||t.gradientWidth)}function CI(e,t){return $k(e.gradientThickness,t.gradientThickness||t.gradientHeight)}function OI(e,t){var n=t&&(t.update&&t.update[e]||t.enter&&t.enter[e]);return n&&n.signal?n:n?n.value:null}var MI="group",NI="text",TI=function(e,t,n,r){var i,a,o,s,l={value:0},c=SI(e,t.gradientDirection),u=gI(CI(e,t)),d=wI(e,t),f=EI("labelOverlap",e,t),p={},m="";return p.enter=i={opacity:l},hI(i,"fill",EI("labelColor",e,t)),hI(i,"font",EI("labelFont",e,t)),hI(i,"fontSize",EI("labelFontSize",e,t)),hI(i,"fontWeight",EI("labelFontWeight",e,t)),hI(i,"limit",$k(e.labelLimit,t.gradientLabelLimit)),p.exit={opacity:l},p.update=a={opacity:{value:1},text:{field:"label"}},c?(i.align={value:"left"},i.baseline=a.baseline={signal:'datum.perc<=0?"bottom":datum.perc>=1?"top":"middle"'},o="y",s="x",m="1-"):(i.align=a.align={signal:'datum.perc<=0?"left":datum.perc>=1?"right":"center"'},i.baseline={value:"top"},o="x",s="y"),i[o]=a[o]={signal:m+"datum.perc",mult:d},i[s]=a[s]=u,u.offset=$k(e.labelOffset,t.gradientLabelOffset)||0,e=xI(NI,"legend-label",VR,"value",r,p,n),f&&(e.overlap={method:f,order:"datum.index"}),e},DI=function(e,t,n,r,i,a,o,s){return{type:MI,name:n,role:e,style:t,from:r,interactive:i||!1,encode:a,marks:o,layout:s}},AI={value:0};function kI(e,t){return{align:EI("gridAlign",e,t),center:{row:!0,column:!1},columns:function(e,t){return $k(e.columns,$k(t.columns,+SI(e,t.symbolDirection)))}(e,t),padding:{row:EI("rowPadding",e,t),column:EI("columnPadding",e,t)}}}function RI(e){return Object(Ee.z)(e)&&e.signal?e.signal:Object(Ee.M)(e)}var II=function(e){var t=e.role||"";return t.indexOf("axis")&&t.indexOf("legend")?e.type===MI?"scope":t||fI:t},LI=function(e,t){var n=Jr(e.type);n||Object(Ee.l)("Unrecognized transform type: "+Object(Ee.M)(e.type));var r=kk(n.type.toLowerCase(),null,PI(n,e,t));return e.signal&&t.addSignal(e.signal,t.proxy(r)),r.metadata=n.metadata||{},r};function PI(e,t,n){var r,i,a,o={};for(i=0,a=e.params.length;i0?",":"")+(Object(Ee.z)(t)?t.signal||fL(t):Object(Ee.M)(t));return n+"]"}:function(e){var t,n,r="{",i=0;for(t in e)n=e[t],r+=(++i>1?",":"")+Object(Ee.M)(t)+":"+(Object(Ee.z)(n)?n.signal||fL(n):Object(Ee.M)(n));return r+"}"})(e)}dL.fork=function(){return new uL(this)},dL.isSubscope=function(){return this._subid>0},dL.toRuntime=function(){return this.finish(),{background:this.background,operators:this.operators,streams:this.streams,updates:this.updates,bindings:this.bindings,eventConfig:this.eventConfig}},dL.id=function(){return(this._subid?this._subid+":":0)+this._id++},dL.add=function(e){return this.operators.push(e),e.id=this.id(),e.refs&&(e.refs.forEach(function(t){t.$ref=e.id}),e.refs=null),e},dL.proxy=function(e){var t=e instanceof Ak?Ik(e):e;return this.add(vR({value:t}))},dL.addStream=function(e){return this.streams.push(e),e.id=this.id(),e},dL.addUpdate=function(e){return this.updates.push(e),e},dL.finish=function(){var e,t;for(e in this.root&&(this.root.root=!0),this.signals)this.signals[e].signal=e;for(e in this.scales)this.scales[e].scale=e;function n(e,t,n){var r;e&&((r=e.data||(e.data={}))[t]||(r[t]=[])).push(n)}for(e in this.data)for(var r in n((t=this.data[e]).input,e,"input"),n(t.output,e,"output"),n(t.values,e,"values"),t.index)n(t.index[r],e,"index:"+r);return this},dL.pushState=function(e,t,n){this._encode.push(Ik(this.add(ER({pulse:e})))),this._parent.push(t),this._lookup.push(n?Ik(this.proxy(n)):null),this._markpath.push(-1)},dL.popState=function(){this._encode.pop(),this._parent.pop(),this._lookup.pop(),this._markpath.pop()},dL.parent=function(){return Object(Ee.K)(this._parent)},dL.encode=function(){return Object(Ee.K)(this._encode)},dL.lookup=function(){return Object(Ee.K)(this._lookup)},dL.markpath=function(){var e=this._markpath;return++e[e.length-1]},dL.fieldRef=function(e,t){if(Object(Ee.B)(e))return Pk(e,t);e.signal||Object(Ee.l)("Unsupported field reference: "+Object(Ee.M)(e));var n,r=e.signal,i=this.field[r];return i||(n={name:this.signalRef(r)},t&&(n.as=t),this.field[r]=i=Ik(this.add(lR(n)))),i},dL.compareRef=function(e,t){function n(e){return Gk(e)?(i=!0,Ik(r[e.signal])):e}var r=this.signals,i=!1,a=Object(Ee.h)(e.field).map(n),o=Object(Ee.h)(e.order).map(n);return t&&a.push(Lk),i?Ik(this.add(iR({fields:a,orders:o}))):Bk(a,o)},dL.keyRef=function(e,t){var n=this.signals,r=!1;return e=Object(Ee.h)(e).map(function(e){return Gk(e)?(r=!0,Ik(n[e.signal])):e}),r?Ik(this.add(cR({fields:e,flat:t}))):function(e,t){var n={$key:e};return t&&(n.$flat=!0),n}(e,t)},dL.sortRef=function(e){if(!e)return e;var t=[jk(e.op,e.field),Lk],n=e.order||"ascending";return n.signal?Ik(this.add(iR({fields:t,orders:[n=this.signalRef(n.signal),n]}))):Bk(t,[n,n])},dL.event=function(e,t){var n=e+":"+t;if(!this.events[n]){var r=this.id();this.streams.push({id:r,source:e,type:t}),this.events[n]=r}return this.events[n]},dL.addSignal=function(e,t){this.signals.hasOwnProperty(e)&&Object(Ee.l)("Duplicate signal name: "+Object(Ee.M)(e));var n=t instanceof Ak?t:this.add(Rk(t));return this.signals[e]=n},dL.getSignal=function(e){return this.signals[e]||Object(Ee.l)("Unrecognized signal name: "+Object(Ee.M)(e)),this.signals[e]},dL.signalRef=function(e){return this.signals[e]?Ik(this.signals[e]):(this.lambdas.hasOwnProperty(e)||(this.lambdas[e]=this.add(Rk(null))),Ik(this.lambdas[e]))},dL.parseLambdas=function(){for(var e=Object.keys(this.lambdas),t=0,n=e.length;te?"[Object]":t.indexOf(r)>=0?"[Circular]":(t.push(r),r)}}(t))}var LL=function(){function e(e){this.options=NL({},kL,e);var t=this.options.id;if(this.call=this.tooltip_handler.bind(this),!this.options.disableDefaultStyle&&!document.getElementById(this.options.styleId)){var n=document.createElement("style");n.setAttribute("id",this.options.styleId),n.innerHTML=function(e){if(!/^[A-Za-z]+[-:.\w]*$/.test(e))throw new Error("Invalid HTML ID");return DL.toString().replace(AL,e)}(t),document.head.childNodes.length>0?document.head.insertBefore(n,document.head.childNodes[0]):document.head.appendChild(n)}this.el=document.getElementById(t),this.el||(this.el=document.createElement("div"),this.el.setAttribute("id",t),this.el.classList.add("vg-tooltip"),document.body.appendChild(this.el))}return e.prototype.tooltip_handler=function(e,t,n,r){if(null!=r&&""!==r){this.el.innerHTML=function(e,t,n){if(Object(Ee.u)(e))return"["+e.map(function(e){return t(Object(Ee.B)(e)?e:IL(e,n))}).join(", ")+"]";if(Object(Ee.z)(e)){var r="",i=e,a=i.title,o=TL(i,["title"]);a&&(r+="

"+t(a)+"

");var s=Object.keys(o);if(s.length>0){r+="";for(var l=0,c=s;l"}r+="
'+t(u)+':'+t(d)+"
"}return r||"{}"}return t(e)}(r,RL,this.options.maxDepth),this.el.classList.add("visible",this.options.theme+"-theme");var i=function(e,t,n,r){var i=e.clientX+n;i+t.width>window.innerWidth&&(i=+e.clientX-n-t.width);var a=e.clientY+r;return a+t.height>window.innerHeight&&(a=+e.clientY-r-t.height),{x:i,y:a}}(t,this.el.getBoundingClientRect(),this.options.offsetX,this.options.offsetY),a=i.x,o=i.y;this.el.setAttribute("style","top: "+o+"px; left: "+a+"px")}else this.el.classList.remove("visible",this.options.theme+"-theme")},e}(),PL=n(2),FL=n.n(PL);function BL(e){return!!e.or}function UL(e){return!!e.and}function jL(e){return!!e.not}function zL(e,t){for(var n={},r=0,i=t;r-1}function HL(e,t){for(var n=0,r=0;r1&&(kF(OF.droppedDay(e)),delete(e=eP(e)).day),void 0!==e.year?n.push(e.year):void 0!==e.day?n.push(RF):n.push(0),void 0!==e.month){var r=t?function(e){if(Object(Ee.y)(e))return e-1+"";var t=e.toLowerCase(),n=PF.indexOf(t);if(-1!==n)return n+"";var r=t.substr(0,3),i=FF.indexOf(r);if(-1!==i)return i+"";throw new Error(OF.invalidTimeUnit("month",e))}(e.month):e.month;n.push(r)}else if(void 0!==e.quarter){var i=t?function(e){if(Object(Ee.y)(e))return e>4&&kF(OF.invalidTimeUnit("quarter",e)),e-1+"";throw new Error(OF.invalidTimeUnit("quarter",e))}(e.quarter):e.quarter;n.push(i+"*3")}else n.push(0);if(void 0!==e.date)n.push(e.date);else if(void 0!==e.day){var a=t?function(e){if(Object(Ee.y)(e))return e%7+"";var t=e.toLowerCase(),n=BF.indexOf(t);if(-1!==n)return n+"";var r=t.substr(0,3),i=UF.indexOf(r);if(-1!==i)return i+"";throw new Error(OF.invalidTimeUnit("day",e))}(e.day):e.day;n.push(a+"+1")}else n.push(1);for(var o=0,s=["hours","minutes","seconds","milliseconds"];o-1&&(t!==LF.SECONDS||0===n||"i"!==e.charAt(n-1))}function YF(e,t){var n=aP(t),r=WF(e)?"utc":"";return jF(qF.reduce(function(t,i){var a;return QF(e,i)&&(t[i]=(a=i)===LF.QUARTER?"("+r+"quarter("+n+")-1)":""+r+a+"("+n+")"),t},{}))}function ZF(e){return"day"!==e&&e.indexOf("day")>=0?(kF(OF.dayReplacedWithDate(e)),e.replace("day","date")):e}!function(e){e.QUANTITATIVE="quantitative",e.ORDINAL="ordinal",e.TEMPORAL="temporal",e.NOMINAL="nominal",e.LATITUDE="latitude",e.LONGITUDE="longitude",e.GEOJSON="geojson"}(KF||(KF={}));var XF={quantitative:1,ordinal:1,temporal:1,nominal:1,latitude:1,longitude:1,geojson:1};var JF=KF.QUANTITATIVE,eB=KF.ORDINAL,tB=KF.TEMPORAL,nB=KF.NOMINAL,rB=KF.GEOJSON;function iB(e){var t=e.field,n=e.timeUnit,r=e.bin,i=e.aggregate;return NL({},n?{timeUnit:n}:{},r?{bin:r}:{},i?{aggregate:i}:{},{field:t})}function aB(e){return!!e&&!!e.condition}function oB(e){return!!e&&!!e.condition&&!Object(Ee.u)(e.condition)&&sB(e.condition)}function sB(e){return!(!e||!e.field&&"count"!==e.aggregate)}function lB(e){return sB(e)&&Object(Ee.B)(e.field)}function cB(e){return e&&"value"in e&&void 0!==e.value}function uB(e){return!(!e||!e.scale&&!e.sort)}function dB(e,t){void 0===t&&(t={});var n,r,i=e.field,a=t.prefix,o=t.suffix;if(function(e){return"count"===e.aggregate}(e))i="count_*";else{var s=void 0;t.nofn||(!function(e){return!!e.op}(e)?e.bin?(s=oF(e.bin),o=t.binSuffix||""):e.aggregate?s=String(e.aggregate):e.timeUnit&&(s=String(e.timeUnit)):s=e.op),s&&(i=i?s+"_"+i:s)}return o&&(i=i+"_"+o),a&&(i=a+"_"+i),t.expr?(n=i,void 0===(r=t.expr)&&(r="datum"),r+"["+Object(Ee.M)(Object(Ee.L)(n).join("."))+"]"):oP(i)}function fB(e){return!function(e){switch(e.type){case"nominal":case"ordinal":case"geojson":return!0;case"quantitative":return!!e.bin;case"latitude":case"longitude":case"temporal":return!1}throw new Error(OF.invalidFieldType(e.type))}(e)}function pB(e,t){var n,r=e.field,i=e.bin,a=e.timeUnit,o=e.aggregate;return"count"===o?t.countTitle:i?r+" (binned)":a?r+" ("+function(e){return qF.reduce(function(t,n){return QF(e,n)?t.concat(n):t},[])}(a).join("-")+")":o?(n=o).charAt(0).toUpperCase()+n.substr(1)+" of "+r:r}var mB=function(e,t){switch(t.fieldTitle){case"plain":return e.field;case"functional":return function(e,t){var n=e.aggregate||e.timeUnit||e.bin&&"bin";return n?n.toUpperCase()+"("+e.field+")":e.field}(e);default:return pB(e,t)}},gB=mB;function hB(e){gB=e}function bB(e,t){return gB(e,t)}function vB(e){return sB(e)?e:oB(e)?e.condition:void 0}function _B(e,t){if(Object(Ee.B)(e)||Object(Ee.y)(e)||Object(Ee.v)(e)){var n=Object(Ee.B)(e)?"string":Object(Ee.y)(e)?"number":"boolean";return kF(OF.primitiveChannelDef(t,n,e)),{value:e}}return sB(e)?yB(e,t):oB(e)?NL({},e,{condition:yB(e.condition,t)}):e}function yB(e,t){if(e.aggregate&&(r=e.aggregate,!lP[r])){e.aggregate;var n=TL(e,["aggregate"]);kF(OF.invalidAggregate(e.aggregate)),e=n}var r;if(e.timeUnit&&(e=NL({},e,{timeUnit:ZF(e.timeUnit)})),e.bin&&(e=NL({},e,{bin:xB(e.bin,t)})),e.type){var i=function(e){if(e)switch(e=e.toLowerCase()){case"q":case JF:return"quantitative";case"t":case tB:return"temporal";case"o":case eB:return"ordinal";case"n":case nB:return"nominal";case KF.LATITUDE:return"latitude";case KF.LONGITUDE:return"longitude";case rB:return"geojson"}}(e.type);e.type!==i&&(e=NL({},e,{type:i})),"quantitative"!==e.type&&uP(e.aggregate)&&(kF(OF.invalidFieldTypeForCountAggregate(e.type,e.aggregate)),e=NL({},e,{type:"quantitative"}))}else{var a=function(e,t){if(e.timeUnit)return"temporal";if(e.bin)return"quantitative";switch(aF(t)){case"continuous":return"quantitative";case"discrete":case"flexible":return"nominal";default:return"quantitative"}}(e,t);kF(OF.emptyOrInvalidFieldType(e.type,t,a)),e=NL({},e,{type:a})}var o=function(e,t){var n=e.type;switch(t){case"row":case"column":return fB(e)?{compatible:!1,warning:OF.facetChannelShouldBeDiscrete(t)}:EB;case"x":case"y":case"color":case"fill":case"stroke":case"text":case"detail":case"key":case"tooltip":case"href":return EB;case"longitude":case"longitude2":case"latitude":case"latitude2":return n!==JF?{compatible:!1,warning:"Channel "+t+" should be used with a quantitative field only, not "+e.type+" field."}:EB;case"opacity":case"size":case"x2":case"y2":return"nominal"===n&&!e.sort||"geojson"===n?{compatible:!1,warning:"Channel "+t+" should not be used with an unsorted discrete field."}:EB;case"shape":return"nominal"!==e.type&&"geojson"!==e.type?{compatible:!1,warning:"Shape channel should be used with only either nominal or geojson data"}:EB;case"order":return"nominal"!==e.type||"sort"in e?EB:{compatible:!1,warning:"Channel order is inappropriate for nominal field, which has no inherent order."}}throw new Error("channelCompatability not implemented for channel "+t)}(e,t),s=o.compatible,l=o.warning;return s||kF(l),e}function xB(e,t){return Object(Ee.v)(e)?{maxbins:sF(t)}:e.maxbins||e.step?e:NL({},e,{maxbins:sF(t)})}var EB={compatible:!0};function SB(e){return"temporal"===e.type||!!e.timeUnit}function wB(e,t){var n,r,i=t.timeUnit,a=t.type,o=t.time,s=t.undefinedIfExprNotRequired,l=void 0;return IF(e)?l=jF(e,!0):(Object(Ee.B)(e)||Object(Ee.y)(e))&&(i||"temporal"===a)&&(l=function(e){return!!zF[e]}(i)?jF(((n={})[i]=e,n),!0):function(e){return!!GF[e]}(i)?wB(e,{timeUnit:(r=i,r.substr(3))}):"datetime("+JSON.stringify(e)+")"),l?o?"time("+l+")":l:s?void 0:JSON.stringify(e)}function CB(e,t){var n=e.timeUnit,r=e.type;return t.map(function(e){var t=wB(e,{timeUnit:n,type:r,undefinedIfExprNotRequired:!0});return void 0!==t?{signal:t}:e})}function OB(e,t){var n=e&&e[t];return!!n&&(Object(Ee.u)(n)?HL(n,function(e){return!!e.field}):sB(n)||oB(n))}function MB(e){return HL(WP,function(t){if(OB(e,t)){var n=e[t];if(Object(Ee.u)(n))return HL(n,function(e){return!!e.aggregate});var r=vB(n);return r&&!!r.aggregate}return!1})}function NB(e,t,n){if(e)for(var r=function(r){Object(Ee.u)(e[r])?e[r].forEach(function(e){t.call(n,e,r)}):t.call(n,e[r],r)},i=0,a=ZL(e);i-1?e[n]=t:kF(OF.incompatibleChannel(n,AB)),e},{})})}(e)).mark,s=(e.encoding,e.selection),l=(e.projection,TL(e,["mark","encoding","selection","projection"])),c=void 0;Object(Ee.y)(t.box.extent)&&(c=t.box.extent),kB(o)&&o.extent&&"min-max"===o.extent&&(c=void 0);var u=function(e,t,n){var r=function(e,t){e.mark;var n,r,i=e.encoding;if(e.projection,TL(e,["mark","encoding","projection"]),"vertical"===t?(r="y",n=i.y):(r="x",n=i.x),n&&n.aggregate){var a=n.aggregate,o=TL(n,["aggregate"]);a!==AB&&kF("Continuous axis should not have customized aggregation function "+a),n=o}return{continuousAxisChannelDef:n,continuousAxis:r}}(e,t),i=r.continuousAxisChannelDef,a=r.continuousAxis,o=e.encoding,s=void 0===n,l=[{op:"q1",field:i.field,as:"lower_box_"+i.field},{op:"q3",field:i.field,as:"upper_box_"+i.field},{op:"median",field:i.field,as:"mid_box_"+i.field}],c=[];l.push({op:"min",field:i.field,as:(s?"lower_whisker_":"min_")+i.field}),l.push({op:"max",field:i.field,as:(s?"upper_whisker_":"max_")+i.field}),s||(c=[{calculate:"datum.upper_box_"+i.field+" - datum.lower_box_"+i.field,as:"iqr_"+i.field},{calculate:"min(datum.upper_box_"+i.field+" + datum.iqr_"+i.field+" * "+n+", datum.max_"+i.field+")",as:"upper_whisker_"+i.field},{calculate:"max(datum.lower_box_"+i.field+" - datum.iqr_"+i.field+" * "+n+", datum.min_"+i.field+")",as:"lower_whisker_"+i.field}]);var u=[],d=[],f=[],p={};return NB(o,function(e,t){if(t!==a)if(sB(e)){if(e.aggregate&&e.aggregate!==AB)l.push({op:e.aggregate,field:e.field,as:dB(e)});else if(void 0===e.aggregate){var n=dB(e),r=e.bin;if(r){var i=e.field;d.push({bin:r,field:i,as:n})}else if(e.timeUnit){var s=e.timeUnit;i=e.field,f.push({timeUnit:s,field:i,as:n})}u.push(n)}p[t]={field:dB(e),type:e.type}}else p[t]=o[t]}),{transform:[].concat(d,f,[{aggregate:l,groupby:u}],c),continuousAxisChannelDef:i,continuousAxis:a,encodingWithoutContinuousAxis:p}}(e,function(e){var t=e.mark,n=e.encoding;if(e.projection,TL(e,["mark","encoding","projection"]),sB(n.x)&&fB(n.x)){if(sB(n.y)&&fB(n.y)){if(void 0===n.x.aggregate&&n.y.aggregate===AB)return"vertical";if(void 0===n.y.aggregate&&n.x.aggregate===AB)return"horizontal";if(n.x.aggregate===AB&&n.y.aggregate===AB)throw new Error("Both x and y cannot have aggregate");return kB(t)&&t.orient?t.orient:"vertical"}return"horizontal"}if(sB(n.y)&&fB(n.y))return"vertical";throw new Error("Need a valid continuous axis for boxplots")}(e),c),d=u.transform,f=u.continuousAxisChannelDef,p=u.continuousAxis,m=u.encodingWithoutContinuousAxis,g=(m.color,m.size),h=TL(m,["color","size"]),b=g?{size:g}:DB(t.box,"size"),v={};return f.scale&&(v.scale=f.scale),f.axis&&(v.axis=f.axis),NL({},l,{transform:d,layer:[{mark:{type:"rule",style:"boxWhisker"},encoding:NL((n={},n[p]=NL({field:"lower_whisker_"+f.field,type:f.type},v),n[p+"2"]={field:"lower_box_"+f.field,type:f.type},n),h,DB(t.boxWhisker,"color"))},{mark:{type:"rule",style:"boxWhisker"},encoding:NL((r={},r[p]={field:"upper_box_"+f.field,type:f.type},r[p+"2"]={field:"upper_whisker_"+f.field,type:f.type},r),h,DB(t.boxWhisker,"color"))},NL({},s?{selection:s}:{},{mark:{type:"bar",style:"box"},encoding:NL((i={},i[p]={field:"lower_box_"+f.field,type:f.type},i[p+"2"]={field:"upper_box_"+f.field,type:f.type},i),m,m.color?{}:DB(t.box,"color"),b)}),{mark:{type:"tick",style:"boxMid"},encoding:NL((a={},a[p]={field:"mid_box_"+f.field,type:f.type},a),h,DB(t.boxMid,"color"),b)}]})}),LB("error-bar",function(e){e.mark,e.selection,e.projection;var t=e.encoding,n=TL(e,["mark","selection","projection","encoding"]),r=(t.size,TL(t,["size"])),i=(t.x2,t.y2,TL(t,["x2","y2"])),a=(i.x,i.y,TL(i,["x","y"]));if(!t.x2&&!t.y2)throw new Error("Neither x2 or y2 provided");return NL({},n,{layer:[{mark:"rule",encoding:r},{mark:"tick",encoding:i},{mark:"tick",encoding:t.x2?NL({x:t.x2,y:t.y},a):NL({x:t.x,y:t.y2},a)}]})});var BB,UB=["shortTimeLabels"],jB={entryPadding:1,format:1,offset:1,orient:1,padding:1,tickCount:1,title:1,type:1,values:1,zindex:1},zB=NL({},jB,{opacity:1,shape:1,stroke:1,fill:1,size:1,encode:1}),qB=JL(jB),GB=JL(zB);!function(e){e.LINEAR="linear",e.BIN_LINEAR="bin-linear",e.LOG="log",e.POW="pow",e.SQRT="sqrt",e.TIME="time",e.UTC="utc",e.SEQUENTIAL="sequential",e.QUANTILE="quantile",e.QUANTIZE="quantize",e.THRESHOLD="threshold",e.ORDINAL="ordinal",e.BIN_ORDINAL="bin-ordinal",e.POINT="point",e.BAND="band"}(BB||(BB={}));var $B={linear:"numeric",log:"numeric",pow:"numeric",sqrt:"numeric","bin-linear":"bin-linear",time:"time",utc:"time",sequential:"sequential",ordinal:"ordinal","bin-ordinal":"bin-ordinal",point:"ordinal-position",band:"ordinal-position"},HB=ZL($B);var WB={linear:0,log:1,pow:1,sqrt:1,time:0,utc:0,point:10,band:11,"bin-linear":0,sequential:0,ordinal:0,"bin-ordinal":0};function VB(e){return WB[e]}var KB=["linear","bin-linear","log","pow","sqrt","time","utc"],QB=Object(Ee.Q)(KB),YB=KB.concat(["sequential"]),ZB=Object(Ee.Q)(YB),XB=Object(Ee.Q)(["ordinal","bin-ordinal","point","band"]),JB=Object(Ee.Q)(["bin-linear","bin-ordinal"]);function eU(e){return e in XB}function tU(e){return e in JB}function nU(e){return e in ZB}function rU(e){return e in QB}var iU={textXRangeStep:90,rangeStep:21,pointPadding:.5,bandPaddingInner:.1,facetSpacing:16,minBandSize:2,minFontSize:8,maxFontSize:40,minOpacity:.3,maxOpacity:.8,minSize:9,minStrokeWidth:1,maxStrokeWidth:4};function aU(e){return e&&e.selection}var oU={type:1,domain:1,range:1,rangeStep:1,scheme:1,reverse:1,round:1,clamp:1,nice:1,base:1,exponent:1,interpolate:1,zero:1,padding:1,paddingInner:1,paddingOuter:1},sU=(JL(oU),JL(TL(oU,["type","domain","range","rangeStep","scheme"])));!function(){for(var e={},t=0,n=WP;t window:mousemove!",encodings:["x","y"],translate:"[mousedown, window:mouseup] > window:mousemove!",zoom:"wheel!",mark:{fill:"#333",fillOpacity:.125,stroke:"white"},resolve:"global"}},style:{},title:{}};var hU=["view"].concat(EF,PB),bU=["padding","numberFormat","timeFormat","countTitle","stack","scale","selection","invalidValues","overlay"],vU=NL({view:["width","height"]},{area:["line","point"],bar:["binSpacing","continuousBandSize","discreteBandSize"],line:["point"],text:["shortTimeLabels"],tick:["bandSize","thickness"]},FB);function _U(e,t,n){var r="title"===t?mU(e.title).mark:e[t];"view"===t&&(n="cell");var i=NL({},r,e.style[t]);ZL(i).length>0&&(e.style[n||t]=i),delete e[t]}var yU={zero:1,center:1,normalize:1};var xU=[cF,lF,hF,dF,vF,_F,uF,fF,pF],EU=[cF,lF];function SU(e,t,n){var r=SF(e)?e.type:e;if(!$L(xU,r))return null;var i=function(e){var t=e.x,n=e.y;if(sB(t)&&sB(n))if("quantitative"===t.type&&"quantitative"===n.type){if(t.stack)return"x";if(n.stack)return"y";if(!!t.aggregate!=!!n.aggregate)return t.aggregate?"x":"y"}else{if("quantitative"===t.type)return"x";if("quantitative"===n.type)return"y"}else{if(sB(t)&&"quantitative"===t.type)return"x";if(sB(n)&&"quantitative"===n.type)return"y"}}(t);if(!i)return null;var a=t[i],o=lB(a)?dB(a,{}):void 0,s="x"===i?"y":"x",l=t[s],c=lB(l)?dB(l,{}):void 0,u=YP.reduce(function(e,n){if(OB(t,n)){var r=t[n];(Object(Ee.u)(r)?r:[r]).forEach(function(t){var r=vB(t);if(!r.aggregate){var i=lB(r)?dB(r,{}):void 0;(!i||i!==c&&i!==o)&&e.push({channel:n,fieldDef:r})}})}return e},[]);if(0===u.length)return null;var d=void 0;return(d=void 0!==a.stack?a.stack:$L(EU,r)&&void 0===n?"zero":n)&&yU[d]?(a.scale&&a.scale.type&&a.scale.type!==BB.LINEAR&&kF(OF.cannotStackNonLinearScale(a.scale.type)),OB(t,i===_P?xP:EP)?(void 0!==a.stack&&kF(OF.cannotStackRangedMark(i)),null):(a.aggregate&&!$L(dP,a.aggregate)&&kF(OF.stackNonSummativeAggregate(a.aggregate)),{groupbyChannel:l?s:void 0,fieldChannel:i,impute:xF(r),stackBy:u,offset:d})):null}function wU(e){return void 0!==e.facet}function CU(e){return!!e.mark}function OU(e){return void 0!==e.layer}function MU(e){return void 0!==e.repeat}function NU(e){return TU(e)||DU(e)}function TU(e){return void 0!==e.vconcat}function DU(e){return void 0!==e.hconcat}function AU(e,t){if(wU(e))return function(e,t){var n=e.spec,r=TL(e,["spec"]);return NL({},r,{spec:AU(n,t)})}(e,t);if(OU(e))return function e(t,n,r,i){var a=t.layer,o=t.encoding,s=t.projection,l=TL(t,["layer","encoding","projection"]);var c=kU({parentEncoding:r,encoding:o});var u=RU({parentProjection:i,projection:s});return NL({},l,{layer:a.map(function(t){return OU(t)?e(t,n,c,u):IU(t,n,c,u)})})}(e,t);if(MU(e))return function(e,t){var n=e.spec,r=TL(e,["spec"]);return NL({},r,{spec:AU(n,t)})}(e,t);if(TU(e))return function(e,t){var n=e.vconcat,r=TL(e,["vconcat"]);return NL({},r,{vconcat:n.map(function(e){return AU(e,t)})})}(e,t);if(DU(e))return function(e,t){var n=e.hconcat,r=TL(e,["hconcat"]);return NL({},r,{hconcat:n.map(function(e){return AU(e,t)})})}(e,t);if(CU(e)){var n=OB(e.encoding,MP),r=OB(e.encoding,NP);return n||r?function(e,t){var n=e.encoding,r=n.row,i=n.column,a=TL(n,["row","column"]),o=e.mark,s=e.width,l=e.projection,c=e.height,u=e.selection,d=(e.encoding,TL(e,["mark","width","projection","height","selection","encoding"]));return NL({},d,{facet:NL({},r?{row:r}:{},i?{column:i}:{}),spec:IU(NL({},l?{projection:l}:{},{mark:o},s?{width:s}:{},c?{height:c}:{},{encoding:a},u?{selection:u}:{}),t)})}(e,t):IU(e,t)}throw new Error(OF.INVALID_SPEC)}function kU(e){var t=e.parentEncoding,n=e.encoding;if(t&&n){var r=ZL(t).reduce(function(e,t){return n[t]&&e.push(t),e},[]);r.length>0&&kF(OF.encodingOverridden(r))}var i=NL({},t||{},n||{});return ZL(i).length>0?i:void 0}function RU(e){var t=e.parentProjection,n=e.projection;return t&&n&&kF(OF.projectionOverridden({parentProjection:t,projection:n})),n||t}function IU(e,t,n,r){var i=e.encoding,a=e.projection,o=SF(e.mark)?e.mark.type:e.mark;if(n||r){var s=RU({parentProjection:r,projection:a}),l=kU({parentEncoding:n,encoding:i});return IU(NL({},e,s?{projection:s}:{},l?{encoding:l}:{}),t)}return function(e){return CF(e.mark)}(e)?function(e){return e&&(!!e.x&&!!e.x2||!!e.y&&!!e.y2)}(i)?function(e){var t=OB(e.encoding,_P),n=OB(e.encoding,yP),r=OB(e.encoding,xP),i=OB(e.encoding,EP);if(r&&!t||i&&!n){var a=eP(e);return r&&!t&&(a.encoding.x=a.encoding.x2,delete a.encoding.x2),i&&!n&&(a.encoding.y=a.encoding.y2,delete a.encoding.y2),a}return e}(e):"line"===o&&(i.x2||i.y2)?(kF(OF.lineWithRange(!!i.x2,!!i.y2)),IU(NL({mark:"rule"},e),t,n,r)):xF(o)?function(e,t){void 0===t&&(t={});var n,r=e.selection,i=e.projection,a=e.encoding,o=e.mark,s=TL(e,["selection","projection","encoding","mark"]),l=SF(o)?o:{type:o},c=function(e,t,n){return"transparent"===e.point?{opacity:0}:e.point?Object(Ee.z)(e.point)?e.point:{}:void 0!==e.point?null:t.point||n.shape?Object(Ee.z)(t.point)?t.point:{}:null}(l,t[l.type],a),u="area"===l.type&&function(e,t){return e.line?!0===e.line?{}:e.line:void 0!==e.line?null:t.line?!0===t.line?{}:t.line:null}(l,t[l.type]);if(!c&&!u)return NL({},e,{mark:LU(l)});var d=[NL({},r?{selection:r}:{},{mark:LU(NL({},l,"area"===l.type?{opacity:.7}:{})),encoding:function(e,t){for(var n=NL({},e),r=0,i=t;r1?t:t.type}function PU(e){return Object(Ee.B)(e)?{type:e}:e||{}}var FU=["background","padding","datasets"];function BU(e){return FU.reduce(function(t,n){return e&&void 0!==e[n]&&(t[n]=e[n]),t},{})}function UU(e){return!!e.url}function jU(e){return!!e.values}var zU="main",qU="raw";function GU(e){return!!e.signal}function $U(e){return!!e.step}function HU(e){return!Object(Ee.u)(e)&&("field"in e&&"data"in e)}var WU=JL({opacity:1,fill:1,fillOpacity:1,stroke:1,strokeCap:1,strokeWidth:1,strokeOpacity:1,strokeDash:1,strokeDashOffset:1,strokeJoin:1,strokeMiterLimit:1,size:1,shape:1,interpolate:1,tension:1,orient:1,align:1,baseline:1,text:1,dir:1,dx:1,dy:1,ellipsis:1,limit:1,radius:1,theta:1,angle:1,font:1,fontSize:1,fontWeight:1,fontStyle:1,cursor:1,href:1,tooltip:1,cornerRadius:1});function VU(e,t,n,r){void 0===r&&(r={header:!1});var i=e.combine(),a=i.orient,o=i.scale,s=i.title,l=i.zindex,c=TL(i,["orient","scale","title","zindex"]);if(ZL(c).forEach(function(e){var n=mP[e];n&&n!==t&&"both"!==n&&delete c[e]}),"grid"===t){if(!c.grid)return;if(c.encode){var u=c.encode.grid;c.encode=NL({},u?{grid:u}:{}),0===ZL(c.encode).length&&delete c.encode}return NL({scale:o,orient:a},c,{domain:!1,labels:!1,maxExtent:0,minExtent:0,ticks:!1,zindex:void 0!==l?l:0})}if(r.header||!e.mainExtracted){if(c.encode){for(var d=0,f=pP;d=0})}(r))return{scale:n,value:0};"bar"!==i&&"area"!==i||kF(OF.nonZeroScaleUsedWithLengthMark(i,t,{zeroFalse:!1===r.explicit.zero}))}}return"zeroOrMin"===e?"x"===t?{value:0}:{field:{group:"height"}}:"x"===t?{field:{group:"width"}}:{value:0}}return e}}function lj(e,t){var n,r;void 0===t&&(t={valueOnly:!1});var i=e.markDef,a=e.encoding,o=e.config,s=i.filled,l=i.type,c={fill:Ej("fill",i,o),stroke:Ej("stroke",i,o),color:Ej("color",i,o)},u=$L(["bar","point","circle","square","geoshape"],l)?"transparent":void 0,d={fill:i.fill||c.fill||u,stroke:i.stroke||c.stroke},f=s?"fill":"stroke",p=NL({},d.fill?{fill:{value:d.fill}}:{},d.stroke?{stroke:{value:d.stroke}}:{});return a.fill||a.stroke?(i.color&&kF(OF.droppingColor("property",{fill:"fill"in a,stroke:"stroke"in a})),NL({},fj("fill",e,{defaultValue:d.fill||u}),fj("stroke",e,{defaultValue:d.stroke}))):a.color?NL({},p,fj("color",e,{vgChannel:f,defaultValue:i[f]||i.color||c[f]||c.color||(s?u:void 0)})):i.fill||i.stroke?(i.color&&kF(OF.droppingColor("property",{fill:"fill"in i,stroke:"stroke"in i})),p):i.color?NL({},p,((n={})[f]={value:i.color},n)):c.fill||c.stroke?p:c.color?NL({},u?{fill:{value:"transparent"}}:{},((r={})[f]={value:c.color},r)):{}}function cj(e,t){return NL({},function(e,t){return WU.reduce(function(n,r){return void 0!==e[r]&&"ignore"!==t[r]&&(n[r]={value:e[r]}),n},{})}(e.markDef,t),lj(e),fj("opacity",e),function(e){var t=e.encoding.tooltip;if(Object(Ee.u)(t)){var n=t.map(function(t){var n=void 0!==t.title?t.title:dB(t,{binSuffix:"range"}),r=aj(t,e.config).signal;return'"'+n+'": '+r});return{tooltip:{signal:"{"+n.join(", ")+"}"}}}return gj(e,"tooltip",t)}(e),mj(e,"href"))}function uj(e){return e+" !== null && !isNaN("+e+")"}function dj(e){if("filter"===e.config.invalidValues){var t=["x","y"].map(function(t){var n=e.getScaleComponent(t);if(n&&nU(n.get("type")))return e.vgField(t,{expr:"datum"})}).filter(function(e){return!!e}).map(uj);if(t.length>0)return{defined:{signal:t.join(" && ")}}}return{}}function fj(e,t,n){void 0===n&&(n={});var r=n.defaultValue,i=n.vgChannel,a=n.defaultRef||(void 0!==r?{value:r}:void 0),o=t.encoding[e];return pj(t,o,i||e,function(n){return ij(e,n,t.scaleName(e),t.getScaleComponent(e),null,a)})}function pj(e,t,n,r){var i,a,o=t&&t.condition,s=r(t);if(o){var l=(Object(Ee.u)(o)?o:[o]).map(function(t){var n=r(t),i=function(e){return e.selection}(t)?Cq(e,t.selection):zq(e,t.test);return NL({test:i},n)});return(i={})[n]=l.concat(void 0!==s?[s]:[]),i}return void 0!==s?((a={})[n]=s,a):{}}function mj(e,t){return void 0===t&&(t="text"),gj(e,t,e.encoding[t])}function gj(e,t,n){return pj(e,n,t,function(t){return aj(t,e.config)})}function hj(e,t,n){var r,i,a,o=n.scaleName(t),s="x"===t?"width":"height";if(n.encoding.size||void 0!==n.markDef.size)if(n.markDef.orient){var l=((r={})[t+"c"]=nj(e,o,{},{band:.5}),r);if(vB(n.encoding.size))return NL({},l,fj("size",n,{vgChannel:s}));if(cB(n.encoding.size))return NL({},l,fj("size",n,{vgChannel:s}));if(void 0!==n.markDef.size)return NL({},l,((i={})[s]={value:n.markDef.size},i))}else kF(OF.cannotApplySizeToNonOrientedMark(n.markDef.type));return(a={})[t]=nj(e,o,{binSuffix:"range"}),a[s]=rj(o),a}function bj(e,t,n,r){var i="x"===e?"width":"height";return NL({},_j(e,t,n,"x"===e?"xc":"yc"),fj("size",t,{defaultRef:r,vgChannel:i}))}function vj(e,t,n,r,i){return"x"===t?{x2:tj(e,n,"start",i?0:r),x:tj(e,n,"end",i?r:0)}:{y2:tj(e,n,"start",i?r:0),y:tj(e,n,"end",i?0:r)}}function _j(e,t,n,r){var i,a=t.encoding,o=t.mark,s=t.stack,l=a[e],c=t.scaleName(e),u=t.getScaleComponent(e),d=ej(e,t.markDef),f=l||!a.latitude&&!a.longitude?NL({},function(e,t,n,r,i,a){return sB(t)&&i&&e===i.fieldChannel?nj(t,n,{suffix:"end"}):ij(e,t,n,r,i,a)}(e,a[e],c,u,s,sj(n,e,c,u,o)),d?{offset:d}:{}):{field:t.getName(e)};return(i={})[r||e]=f,i}function yj(e,t,n){var r,i=e.encoding,a=e.mark,o=e.stack,s="x2"===n?"x":"y",l=i[s],c=e.scaleName(s),u=e.getScaleComponent(s),d=ej(n,e.markDef),f=l||!i.latitude&&!i.longitude?NL({},function(e,t,n,r,i,a,o){return sB(t)&&a&&e.charAt(0)===a.fieldChannel.charAt(0)?nj(t,r,{suffix:"start"}):ij(e,n,r,i,a,o)}(n,l,i[n],c,u,o,sj(t,s,c,u,a)),d?{offset:d}:{}):{field:e.getName(n)};return(r={})[n]=f,r}function xj(e){return[].concat(e.type,e.style||[])}function Ej(e,t,n){var r=n.mark[e],i=n[t.type];void 0!==i[e]&&(r=i[e]);for(var a=0,o=xj(t);a0&&l.push(i.join(" ")),s.length>0&&l.push(s.join(":")),l.length>0&&(a&&(a+=" + ' ' + "),a+=r?"utcFormat("+t+", '"+l.join(" ")+"')":"timeFormat("+t+", '"+l.join(" ")+"')"),a||void 0}}(t,e,r,a)}function Dj(e,t){return(Object(Ee.u)(e)?e:[e]).reduce(function(e,n){return e.field.push(dB(n,t)),e.order.push(n.sort||"ascending"),e},{field:[],order:[]})}function Aj(e,t){var n=e.slice();return t.forEach(function(e){for(var t=0,r=n;t0?{encode:{update:m}}:{})}var g=i.axes,h=g&&g.length>0;if(s||h){var b="row"===t?"height":"width";return NL({name:e.getName(t+"_"+n),type:"group",role:t+"-"+n},r.facetFieldDef?{from:{data:e.getName(t+"_domain")},sort:function(e,t){var n=e.sort;return XU(n)?{field:dB(n,{expr:"datum"}),order:n.order||"ascending"}:Object(Ee.u)(n)?{field:Uj(e,t,"datum"),order:"ascending"}:{field:dB(e,{expr:"datum"}),order:n||"ascending"}}(l,t)}:{},s?{title:s}:{},i.sizeSignal?{encode:{update:(a={},a[b]=i.sizeSignal,a)}}:{},h?{axes:g}:{})}}return null}function Hj(e,t,n,r){for(var i={},a=0,o=n;a0?t:a<0?n:tz(t,n,r,i)}}function tz(e,t,n,r){return e.explicit&&t.explicit&&kF(OF.mergeConflictingProperty(n,r,e.value,t.value)),e}function nz(e,t,n,r,i){return void 0===i&&(i=tz),void 0===e||void 0===e.value?t:e.explicit&&!t.explicit?e:t.explicit&&!e.explicit?t:qL(e.value)===qL(t.value)?e:i(e,t,n,r)}var rz=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return ML(t,e),t}(Zj);function iz(e,t,n,r,i){if("gradient"!==i){var a=NL({},function(e,t,n){for(var r=0,i=n;r0?a:void 0}}function az(e,t,n,r,i){var a={};if("gradient"===i){var o=sz(n.encoding.opacity)||n.markDef.opacity;o&&(a.opacity={value:o})}return a=NL({},a,t),ZL(a).length>0?a:void 0}function oz(e,t,n,r,i){var a=n.legend(r),o=n.config,s={};if(SB(e)){var l=n.getScaleComponent(r).get("type")===BB.UTC,c=Tj("datum.value",e.timeUnit,a.format,o.legend.shortTimeLabels,o.timeFormat,l);t=NL({},c?{text:{signal:c}}:{},t)}return s=NL({},s,t),ZL(s).length>0?s:void 0}function sz(e){return cz(e,function(e,t){return Math.max(e,t.value)})}function lz(e){return cz(e,function(e,t){return void 0!==e?e:t.value})}function cz(e,t){return function(e){return!!e&&!!e.condition&&(Object(Ee.u)(e.condition)||cB(e.condition))}(e)?(Object(Ee.u)(e.condition)?e.condition:[e.condition]).reduce(t,e.value):cB(e)?e.value:void 0}function uz(e){Yz(e)?e.component.legends=function(e){var t=e.encoding;return[AP,kP,RP,DP,TP,BP].reduce(function(n,r){var i=t[r];return!e.legend(r)||!e.getScaleComponent(r)||sB(i)&&r===TP&&i.type===rB||(n[r]=function(e,t){var n=e.fieldDef(t),r=e.legend(t),i=new rz({},function(e,t){var n;switch(t){case AP:var r=e.scaleName(AP);return e.markDef.filled?{fill:r}:{stroke:r};case kP:case RP:case DP:case TP:case BP:return(n={})[t]=e.scaleName(t),n}}(e,t));qB.forEach(function(n){var a=function(e,t,n,r){var i=r.fieldDef(n);switch(e){case"format":return Cj(i,t.format,r.config);case"title":var a=void 0!==i.title?i.title:t.title||(void 0===t.title?void 0:null);return wj(a,bB(i,r.config))||void 0;case"values":return function(e,t){var n=e.values;if(n)return CB(t,n)}(t,i);case"type":return wj(t.type,function(e,t,n){if($P(t)&&("quantitative"===e&&!tU(n)||"temporal"===e&&$L(["time","utc"],n)))return"gradient"}(i.type,n,r.getScaleComponent(n).get("type")))}return t[e]}(n,r,t,e);if(void 0!==a){var o="values"===n?!!r.values:"title"===n&&a===e.fieldDef(t).title||a===r[n];(o||void 0===e.config.legend[n])&&i.set(n,a,o)}});var a=r.encoding||{},o=["labels","legend","title","symbols","gradient"].reduce(function(r,o){var s=Lj(a[o]||{},e),l=m[o]?m[o](n,s,e,t,i.get("type")):s;return void 0!==l&&ZL(l).length>0&&(r[o]={update:l}),r},{});ZL(o).length>0&&i.set("encode",o,!!r.encoding);return i}(e,r)),n},{})}(e):e.component.legends=function(e){for(var t=e.component,n=t.legends,r=t.resolve,i=function(t){uz(t),ZL(t.component.legends).forEach(function(i){r.legend[i]=Yj(e.component.resolve,i),"shared"===r.legend[i]&&(n[i]=dz(n[i],t.component.legends[i]),n[i]||(r.legend[i]="independent",delete n[i]))})},a=0,o=e.children;a1?"["+o.join(", ")+"]":o[0]}},i)]}var gz=["type","clipAngle","clipExtent","center","rotate","precision","coefficient","distance","fraction","lobes","parallel","radius","ratio","spacing","tilt"],hz=function(e){function t(t,n,r,i){var a=e.call(this,NL({},n),{name:t})||this;return a.specifiedProjection=n,a.size=r,a.data=i,a.merged=!1,a}return ML(t,e),t}(Zj);function bz(e){Yz(e)?e.component.projection=function(e){var t=e.specifiedProjection,n=e.config;if(e.hasProjection){var r=[];return[[CP,SP],[OP,wP]].forEach(function(t){(e.channelHasField(t[0])||e.channelHasField(t[1]))&&r.push({signal:e.getName("geojson_"+r.length)})}),e.channelHasField(TP)&&e.fieldDef(TP).type===rB&&r.push({signal:e.getName("geojson_"+r.length)}),0===r.length&&r.push(e.requestDataName(zU)),new hz(e.projectionName(!0),NL({},n.projection||{},t||{}),[e.getSizeSignalRef("width"),e.getSizeSignalRef("height")],r)}return}(e):e.component.projection=function(e){if(0===e.children.length)return;var t,n=WL(e.children,function(e){bz(e);var n=e.component.projection;if(n){if(t){var r=function(e,t){var n=WL(gz,function(n){return!e.explicit.hasOwnProperty(n)&&!t.explicit.hasOwnProperty(n)||!(!e.explicit.hasOwnProperty(n)||!t.explicit.hasOwnProperty(n)||qL(e.get(n))!==qL(t.get(n)))});if(qL(e.size)===qL(t.size)){if(n)return e;if(qL(e.explicit)===qL({}))return t;if(qL(t.explicit)===qL({}))return e}return null}(t,n);return r&&(t=r),!!r}return t=n,!0}return!0});if(t&&n){var r=e.projectionName(!0),i=new hz(r,t.specifiedProjection,t.size,eP(t.data));return e.children.forEach(function(e){e.component.projection&&(i.data=i.data.concat(e.component.projection.data),e.renameProjection(e.component.projection.get("name"),r),e.component.projection.merged=!0)}),i}return}(e)}var vz=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.dimensions=n,i.measures=r,i}return ML(t,e),t.prototype.clone=function(){return new t(null,NL({},this.dimensions),eP(this.measures))},t.makeFromEncoding=function(e,n){var r=!1;n.forEachFieldDef(function(e){e.aggregate&&(r=!0)});var i={},a={};return r?(n.forEachFieldDef(function(e,t){var r=e.aggregate,o=e.field;r?"count"===r?(i["*"]=i["*"]||{},i["*"].count=dB(e)):(i[o]=i[o]||{},i[o][r]=dB(e),rF(t)&&"unaggregated"===n.scaleDomain(t)&&(i[o].min=dB({field:o,aggregate:"min"}),i[o].max=dB({field:o,aggregate:"max"}))):function(e,t,n){n.bin?(e[dB(n,{})]=!0,e[dB(n,{binSuffix:"end"})]=!0,Ij(n,t)&&(e[dB(n,{binSuffix:"range"})]=!0)):e[dB(n)]=!0}(a,t,e)}),ZL(a).length+ZL(i).length===0?null:new t(e,a,i)):null},t.makeFromTransform=function(e,n){for(var r={},i={},a=0,o=n.aggregate;a0?{type:"filter",expr:t.join(" && ")}:null},t}(Pj);var xz=function(e){function t(t,n){var r=e.call(this,t)||this;return r._parse=n,r}return ML(t,e),t.prototype.clone=function(){return new t(null,eP(this._parse))},t.makeExplicit=function(e,t,n){var r={},i=t.data;return i&&i.format&&i.format.parse&&(r=i.format.parse),this.makeWithAncestors(e,r,{},n)},t.makeImplicitFromFilterTransform=function(e,t,n){var r={};return function e(t,n){if(jL(t))e(t.not,n);else if(UL(t))for(var r=0,i=t.and;r1?e.field in r||(r[e.field]="flatten"):uB(e)&&XU(e.sort)&&sP(e.sort.field)>1&&(e.sort.field in r||(r[e.sort.field]="flatten")):uP(e.aggregate)||(r[e.field]="number")}),this.makeWithAncestors(e,{},r,n)},t.makeWithAncestors=function(e,n,r,i){for(var a=0,o=ZL(r);a1}).map(function(e){var n,r=function(e,t){var n=aP(e);return"number"===t?"toNumber("+n+")":"boolean"===t?"toBoolean("+n+")":"string"===t?"toString("+n+")":"date"===t?"toDate("+n+")":"flatten"===t?n:0===t.indexOf("date:")?"timeParse("+n+","+t.slice(5,t.length)+")":0===t.indexOf("utc:")?"utcParse("+n+","+t.slice(4,t.length)+")":(kF(OF.unrecognizedParse(t)),null)}(e,t._parse[e]);return r?{type:"formula",expr:r,as:(n=e,""+Object(Ee.L)(n).join("."))}:null}).filter(function(e){return null!==e})},t}(Pj),Ez=function(e){function t(t){var n=e.call(this,null)||this;if(jU(t=t||{name:"source"}))n._data={values:t.values};else if(UU(t)){if(n._data={url:t.url},t.format||(t.format={}),!t.format||!t.format.type){var r=/(?:\.([^.]+))?$/.exec(t.url)[1];$L(["json","csv","tsv","dsv","topojson"],r)||(r="json"),t.format.type=r}}else(function(e){return!!e.name&&!UU(e)&&!jU(e)})(t)&&(n._data={});if(t.name&&(n._name=t.name),t.format){var i=t.format,a=(i.parse,TL(i,["parse"]));n._data.format=a}return n}return ML(t,e),Object.defineProperty(t.prototype,"data",{get:function(){return this._data},enumerable:!0,configurable:!0}),t.prototype.hasName=function(){return!!this._name},Object.defineProperty(t.prototype,"dataName",{get:function(){return this._name},set:function(e){this._name=e},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"parent",{set:function(e){throw new Error("Source nodes have to be roots.")},enumerable:!0,configurable:!0}),t.prototype.remove=function(){throw new Error("Source nodes are roots and cannot be removed.")},t.prototype.hash=function(){return jU(this._data)?(this._hash||(this._hash=GL(this._data)),this._hash):UU(this._data)?GL([this._data.url,this._data.format]):this._name},t.prototype.assemble=function(){return NL({name:this._name},this._data,{transform:[]})},t}(Pj),Sz=function(e){function t(t,n){var r=e.call(this,t)||this;return r.formula=n,r}return ML(t,e),t.prototype.clone=function(){return new t(null,eP(this.formula))},t.makeFromEncoding=function(e,n){var r=n.reduceFieldDef(function(e,t){if(t.timeUnit){var n=dB(t);e[n]={as:n,timeUnit:t.timeUnit,field:t.field}}return e},{});return 0===ZL(r).length?null:new t(e,r)},t.makeFromTransform=function(e,n){var r;return new t(e,((r={})[n.field]={as:n.as,timeUnit:n.timeUnit,field:n.field},r))},t.prototype.merge=function(e){this.formula=NL({},this.formula,e.formula),e.remove()},t.prototype.producedFields=function(){var e={};return XL(this.formula).forEach(function(t){e[t.as]=!0}),e},t.prototype.dependentFields=function(){var e={};return XL(this.formula).forEach(function(t){e[t.field]=!0}),e},t.prototype.assemble=function(){return XL(this.formula).map(function(e){return{type:"formula",as:e.as,expr:YF(e.timeUnit,e.field)}})},t}(Pj);function wz(e){return function t(n){if(!(n instanceof Ez)){var r=n.parent;e(n)&&t(r)}}}function Cz(e){var t=e.parent;if(e instanceof xz){if(t instanceof Ez)return!1;if(t.numChildren()>1)return!0;if(t instanceof xz)t.merge(e);else{if(function(e,t){for(var n in e)if(n in t)return!0;return!1}(t.producedFields(),e.dependentFields()))return!0;e.swapWithParent()}}return!0}function Oz(e){return!(e instanceof Fj||e.numChildren()>0||e instanceof _z)&&(e.remove(),!0)}function Mz(e){var t={};return wz(function(e){if(e instanceof Sz){var n=e.producedFields();ZL(n).every(function(e){return!!t[e]})?e.remove():t=NL({},t,n)}return!0})(e)}var Nz=function(e){function t(t,n){var r=e.call(this,t)||this;return r._stack=n,r}return ML(t,e),t.prototype.clone=function(){return new t(null,eP(this._stack))},t.makeFromTransform=function(e,n){var r=n.stack,i=n.groupby,a=n.as,o=n.offset,s=void 0===o?"zero":o,l=[],c=[];if(void 0!==n.sort)for(var u=0,d=n.sort;u1}(a)?a:Object(Ee.B)(a)?[a,a+"_end"]:[n.stack+"_start",n.stack+"_end"]})},t.makeFromEncoding=function(e,n){var r,i=n.stack;if(!i)return null;i.groupbyChannel&&(r=n.fieldDef(i.groupbyChannel));var a,o=function(e){return e.stack.stackBy.reduce(function(e,t){var n=dB(t.fieldDef);return n&&e.push(n),e},[])}(n),s=n.encoding.order;a=Object(Ee.u)(s)||sB(s)?Dj(s):o.reduce(function(e,t){return e.field.push(t),e.order.push("descending"),e},{field:[],order:[]});var l=n.vgField(i.fieldChannel);return new t(e,{dimensionFieldDef:r,stackField:l,facetby:[],stackby:o,sort:a,offset:i.offset,impute:i.impute,as:[l+"_start",l+"_end"]})},Object.defineProperty(t.prototype,"stack",{get:function(){return this._stack},enumerable:!0,configurable:!0}),t.prototype.addDimensions=function(e){this._stack.facetby=this._stack.facetby.concat(e)},t.prototype.dependentFields=function(){var e={};e[this._stack.stackField]=!0,this.getGroupbyFields().forEach(function(t){return e[t]=!0}),this._stack.facetby.forEach(function(t){return e[t]=!0});var t=this._stack.sort.field;return Object(Ee.u)(t)?t.forEach(function(t){return e[t]=!0}):e[t]=!0,e},t.prototype.producedFields=function(){return this._stack.as.reduce(function(e,t){return e[t]=!0,e},{})},t.prototype.getGroupbyFields=function(){var e=this._stack,t=e.dimensionFieldDef,n=e.impute,r=e.groupby;return t?t.bin?n?[dB(t,{binSuffix:"mid"})]:[dB(t,{}),dB(t,{binSuffix:"end"})]:[dB(t)]:r||[]},t.prototype.assemble=function(){var e=[],t=this._stack,n=t.facetby,r=t.dimensionFieldDef,i=t.stackField,a=t.stackby,o=t.sort,s=t.offset,l=t.impute,c=t.as;if(l&&r){var u=r?dB(r,{binSuffix:"mid"}):void 0;r.bin&&e.push({type:"formula",expr:"("+dB(r,{expr:"datum"})+"+"+dB(r,{expr:"datum",binSuffix:"end"})+")/2",as:u}),e.push({type:"impute",field:i,groupby:a,key:u,method:"value",value:0})}return e.push({type:"stack",groupby:this.getGroupbyFields().concat(n),field:i,sort:o,as:c,offset:s}),e},t}(Pj),Tz="scale_";function Dz(e){if(e instanceof _z)if(1!==e.numChildren()||e.children[0]instanceof Fj){!function e(t){if(t instanceof Fj&&t.type===zU&&1===t.numChildren()){var n=t.children[0];n instanceof _z||(n.swapWithParent(),e(t))}}(e.model.component.data.main),VL(e.children.map((n=e,function e(t){if(!(t instanceof _z)){var r=t.clone();if(r instanceof Fj){var i=Tz+r.getSource();r.setSource(i),n.model.component.data.outputNodes[i]=r}else(r instanceof vz||r instanceof Nz)&&r.addDimensions(n.fields);return VL(t.children.map(e)).forEach(function(e){return e.parent=r}),[r]}return VL(t.children.map(e))}))).forEach(function(t){return t.parent=e.model.component.data.main})}else{var t=e.children[0];(t instanceof vz||t instanceof Nz)&&t.addDimensions(e.fields),t.swapWithParent(),Dz(e)}else e.children.forEach(Dz);var n}function Az(e){e instanceof yz&&WL(XL(e.filter),function(e){return null===e})&&e.remove(),e instanceof Fj&&!e.isRequired()&&e.remove(),e.children.forEach(Az)}function kz(e){var t=[];return e.forEach(function e(n){0===n.numChildren()?t.push(n):n.children.forEach(e)}),t}function Rz(e){Yz(e)?function(e){var t=e.specifiedScales,n=e.component.scales;ZL(n).forEach(function(r){var i=t[r],a=i?i.domain:void 0,o=function(e,t){var n=e.getScaleComponent(t).get("type"),r=function(e,t,n,r){if("unaggregated"===e){var i=Lz(t,n),a=i.valid,o=i.reason;if(!a)return void kF(o)}else if(void 0===e&&r.useUnaggregatedDomain){var a=Lz(t,n).valid;if(a)return"unaggregated"}return e}(e.scaleDomain(t),e.fieldDef(t),n,e.config.scale);r!==e.scaleDomain(t)&&(e.specifiedScales[t]=NL({},e.specifiedScales[t],{domain:r}));if("x"===t&&e.channelHasField("x2"))return e.channelHasField("x")?Iz(n,r,e,"x").concat(Iz(n,r,e,"x2")):Iz(n,r,e,"x2");if("y"===t&&e.channelHasField("y2"))return e.channelHasField("y")?Iz(n,r,e,"y").concat(Iz(n,r,e,"y2")):Iz(n,r,e,"y2");return Iz(n,r,e,t)}(e,r),s=n[r];if(s.domains=o,aU(a)&&s.set("domainRaw",{signal:Sq+GL(a)},!0),e.component.data.isFaceted){for(var l=e;!Zz(l)&&l.parent;)l=l.parent;var c=l.component.resolve.scale[r];if("shared"===c)for(var u=0,d=o;u0){var r=n[0];return n.length>1&&(kF(OF.MORE_THAN_ONE_SORT),r=!0),NL({},o,{sort:r})}return o}var i=YL(n.map(function(e){return!0===e?e:"count"===e.op?e:(kF(OF.domainSortDropped(e)),!0)}),GL),a=void 0;1===i.length?a=i[0]:i.length>1&&(kF(OF.MORE_THAN_ONE_SORT),a=!0);var o,s=YL(e.map(function(e){return HU(e)?e.data:null}),function(e){return e});return 1===s.length&&null!==s[0]?o=NL({data:s[0],fields:t.map(function(e){return e.field})},a?{sort:a}:{}):NL({fields:t},a?{sort:a}:{})}(e.component.scales[t].domains.map(function(t){return HU(t)&&(t.data=e.lookupDataSource(t.data)),t}))}function Bz(e){return ZL(e.component.scales).reduce(function(t,n){var r=e.component.scales[n];if(r.merged)return t;var i=r.combine(),a=i.domainRaw,o=i.range,s=i.name,l=i.type,c=(i.domainRaw,i.range,TL(i,["name","type","domainRaw","range"]));return o=function(e,t,n,r){if("x"===r||"y"===r){if($U(e))return{step:{signal:t+"_step"}};if(Object(Ee.u)(e)&&2===e.length){var i=e[0],a=e[1];if(0===i&&GU(a))return[0,{signal:n.getSizeName(a.signal)}];if(GU(i)&&0===a)return[{signal:n.getSizeName(i.signal)},0]}}return e}(o,s,e,n),a&&function(e){return e.signal.indexOf(Sq)>=0}(a)&&(a=function(e,t){var n=JSON.parse(t.signal.replace(Sq,"")),r=nP(n.selection),i=e.component.selection&&e.component.selection[r];if(!i)return i=e.getSelectionComponent(r,n.selection),n.encoding||n.field||(n.field=i.project[0].field,i.project.length>1&&kF('A "field" or "encoding" must be specified when using a selection as a scale domain. Using "field": '+Object(Ee.M)(n.field)+".")),{signal:Mq(i.type).scaleDomain+"("+Object(Ee.M)(r+yq)+", "+Object(Ee.M)(n.encoding||null)+", "+Object(Ee.M)(n.field||null)+("global"===i.resolve?")":", "+Object(Ee.M)(i.resolve)+")")};kF('Use "bind": "scales" to setup a binding for scales and selections within the same view.');return{signal:"null"}}(e,a)),t.push(NL({name:s,type:l,domain:Fz(e,n)},a?{domainRaw:a}:{},{range:o},c)),t},[])}var Uz=function(e){function t(t,n){var r=e.call(this,{},{name:t})||this;return r.merged=!1,r.domains=[],r.setWithExplicit("type",n),r}return ML(t,e),t}(Zj),jz=["range","rangeStep","scheme"];function zz(e){Yz(e)?function(e){var t=e.component.scales;nF.forEach(function(n){var r=t[n];if(r){var i=e.getScaleComponent(n),a=e.specifiedScales[n],o=e.fieldDef(n),s="x"===n?"width":"y"===n?"height":void 0,l=s?!!e.component.layoutSize.get(s):void 0,c=i.get("type"),u=$L(["point","band"],c)||!!a.rangeStep;s&&e.fit&&!l&&u&&(kF(OF.CANNOT_FIX_RANGE_STEP_WITH_FIT),l=!0);var d=function(e){var t=[],n=e.getScaleComponent("x"),r=n&&n.get("range");r&&$U(r)&&Object(Ee.y)(r.step)&&t.push(r.step);var i=e.getScaleComponent("y"),a=i&&i.get("range");a&&$U(a)&&Object(Ee.y)(a.step)&&t.push(a.step);return t}(e),f=function(e,t,n,r,i,a,o,s,l,c){for(var u=s||null===r.rangeStep,d=0,f=jz;d0?Math.min.apply(null,e):t.rangeStep?t.rangeStep:21}function $z(e,t){Yz(e)?function(e,t){var n=e.component.scales;ZL(n).forEach(function(r){var i=e.specifiedScales[r],a=n[r],o=e.getScaleComponent(r),s=e.fieldDef(r),l=e.config,c=i[t],u=o.get("type"),d=lU(u,t),f=cU(r,t);if(void 0!==c&&(d?f&&kF(f):kF(OF.scalePropertyNotWorkWithScaleType(u,t,r))),d&&void 0===f)if(void 0!==c)a.copyKeyFromObject(t,i);else{var p=function(e,t,n,r,i,a,o,s,l){var c=l.scale;switch(e){case"nice":return function(e,t,n){if(n.bin||$L([BB.TIME,BB.UTC],e))return;return $L([_P,yP],t)}(r,t,n);case"padding":return function(e,t,n,r,i,a){if($L([_P,yP],e)){if(rU(t)){if(void 0!==n.continuousPadding)return n.continuousPadding;var o=i.type,s=i.orient;if("bar"===o&&!r.bin&&("vertical"===s&&"x"===e||"horizontal"===s&&"y"===e))return a.continuousBandSize}if(t===BB.POINT)return n.pointPadding}return}(t,r,c,n,s,l.bar);case"paddingInner":return function(e,t,n){if(void 0!==e)return;if($L([_P,yP],t))return n.bandPaddingInner;return}(i,t,c);case"paddingOuter":return function(e,t,n,r,i){if(void 0!==e)return;if($L([_P,yP],t)&&n===BB.BAND)return void 0!==i.bandPaddingOuter?i.bandPaddingOuter:r/2;return}(i,t,r,a,c);case"reverse":return function(e,t){if(nU(e)&&"descending"===t)return!0;return}(r,n.sort);case"zero":return function(e,t,n,r){if(n&&"unaggregated"!==n)return!1;if("size"===e&&"quantitative"===t.type)return!0;if(!t.bin&&$L([_P,yP],e)){var i=r.orient,a=r.type;return!$L(["bar","area","line","trail"],a)||!("horizontal"===i&&"y"===e||"vertical"===i&&"x"===e)}return!1}(t,n,o,s)}return c[e]}(t,r,s,o.get("type"),o.get("padding"),o.get("paddingInner"),i.domain,e.markDef,l);void 0!==p&&a.set(t,p,!1)}})}(e,t):Hz(e,t)}function Hz(e,t){for(var n=e.component.scales,r=0,i=e.children;r0?e:void 0},e.prototype.assembleGroup=function(e){void 0===e&&(e=[]);var t={};(e=e.concat(this.assembleSelectionSignals())).length>0&&(t.signals=e);var n=this.assembleLayout();n&&(t.layout=n),t.marks=[].concat(this.assembleHeaderMarks(),this.assembleMarks());var r=!this.parent||Zz(this.parent)?function e(t){return eq(t)||Jz(t)||Xz(t)?t.children.reduce(function(t,n){return t.concat(e(n))},Bz(t)):Bz(t)}(this):[];r.length>0&&(t.scales=r);var i=this.assembleAxes();i.length>0&&(t.axes=i);var a=this.assembleLegends();return a.length>0&&(t.legends=a),t},e.prototype.hasDescendantWithFieldOnChannel=function(e){for(var t=0,n=this.children;t=0&&(c=!0)}),c||n.splice(l+1,0,s),n}};function cq(e,t){var n=t.project,r=lq.has(t)?"(item().isVoronoi ? datum.datum : datum)":"datum",i=[],a=n.map(function(e){return Object(Ee.M)(e.channel)}).filter(function(e){return e}).join(", "),o=n.map(function(e){return Object(Ee.M)(e.field)}).join(", "),s=n.map(function(t){var n=t.channel,a=e.fieldDef(n);return a&&a.bin?(i.push(t.field),"["+aP(e.vgField(n,{}),r)+", "+aP(e.vgField(n,{binSuffix:"end"}),r)+"]"):""+aP(t.field,r)}).join(", ");return[{name:t.name+xq,value:{},on:[{events:t.events,update:"datum && item().mark.marktype !== 'group' ? {unit: "+Tq(e)+", encodings: ["+a+"], fields: ["+o+"], values: ["+s+"]"+(i.length?", "+i.map(function(e){return Object(Ee.M)("bin_"+e)+": 1"}).join(", "):"")+"} : null",force:!0}]}]}var uq={predicate:"vlMulti",scaleDomain:"vlMultiDomain",signals:cq,modifyExpr:function(e,t){return t.name+xq+", "+("global"===t.resolve?"null":"{unit: "+Tq(e)+"}")}},dq={predicate:"vlSingle",scaleDomain:"vlSingleDomain",signals:cq,topLevelSignals:function(e,t,n){var r=n.filter(function(e){return e.name===t.name}),i="data("+Object(Ee.M)(t.name+yq)+")",a=i+"[0].values";return r.length?n:n.concat({name:t.name,update:i+".length && {"+t.project.map(function(e,t){return e.field+": "+a+"["+t+"]"}).join(", ")+"}"})},modifyExpr:function(e,t){return t.name+xq+", "+("global"===t.resolve?"true":"{unit: "+Tq(e)+"}")}},fq="_translate_anchor",pq="_translate_delta";function mq(e,t,n,r,i){var a=t.name,o=rq.has(t),s=i.filter(function(e){return e.name===Aq(t,n,o?"data":"visual")})[0],l=a+fq,c=a+pq,u=e.getSizeSignalRef(r).signal,d=e.getScaleComponent(n),f=d.get("type"),p=l+".extent_"+n,m=(o?"log"===f?"panLog":"pow"===f?"panPow":"panLinear":"panLinear")+"("+p+", "+(""+(o&&n===_P?"-":"")+c+"."+n+" / "+(o?""+u:"span("+p+")"))+(o&&"pow"===f?", "+(d.get("exponent")||1):"")+")";s.on.push({events:{signal:c},update:o?m:"clampRange("+m+", 0, "+u+")"})}var gq="_zoom_anchor",hq="_zoom_delta";function bq(e,t,n,r,i){var a=t.name,o=rq.has(t),s=i.filter(function(e){return e.name===Aq(t,n,o?"data":"visual")})[0],l=e.getSizeSignalRef(r).signal,c=e.getScaleComponent(n),u=c.get("type"),d=o?iq(e,n):s.name,f=a+hq,p=(o?"log"===u?"zoomLog":"pow"===u?"zoomPow":"zoomLinear":"zoomLinear")+"("+d+", "+(""+a+gq+"."+n)+", "+f+(o&&"pow"===u?", "+(c.get("exponent")||1):"")+")";s.on.push({events:{signal:f},update:o?p:"clampRange("+p+", 0, "+l+")"})}var vq={project:{has:function(e){var t=e;return void 0!==t.fields||void 0!==t.encodings},parse:function(e,t,n){var r={},i={};(t.fields||[]).forEach(function(e){return r[e]=null}),(t.encodings||[]).forEach(function(t){var n=e.fieldDef(t);if(n)if(n.timeUnit){var a=e.vgField(t);r[a]=t,i[a]={as:a,field:n.field,timeUnit:n.timeUnit}}else r[n.field]=t;else kF(OF.cannotProjectOnChannelWithoutField(t))});var a=n.project||(n.project=[]);for(var o in r)r.hasOwnProperty(o)&&a.push({field:o,channel:r[o]});var s=n.fields||(n.fields={});a.filter(function(e){return e.channel}).forEach(function(e){return s[e.channel]=e.field}),ZL(i).length&&(n.timeUnit=new Sz(null,i))}},toggle:{has:function(e){return"multi"===e.type&&e.toggle},signals:function(e,t,n){return n.concat({name:t.name+"_toggle",value:!1,on:[{events:t.events,update:t.toggle}]})},modifyExpr:function(e,t,n){var r=t.name+xq,i=t.name+"_toggle";return i+" ? null : "+r+", "+("global"===t.resolve?i+" ? null : true, ":i+" ? null : {unit: "+Tq(e)+"}, ")+i+" ? "+r+" : null"}},scales:rq,translate:{has:function(e){return"interval"===e.type&&e.translate},signals:function(e,t,n){var r=t.name,i=rq.has(t),a=r+fq,o=kq(t),s=o.x,l=o.y,c=VT(t.translate,"scope");return i||(c=c.map(function(e){return e.between[0].markname=r+"_brush",e})),n.push({name:a,value:{},on:[{events:c.map(function(e){return e.between[0]}),update:"{x: x(unit), y: y(unit)"+(null!==s?", extent_x: "+(i?iq(e,_P):"slice("+Aq(t,"x","visual")+")"):"")+(null!==l?", extent_y: "+(i?iq(e,yP):"slice("+Aq(t,"y","visual")+")"):"")+"}"}]},{name:r+pq,value:{},on:[{events:c,update:"{x: "+a+".x - x(unit), y: "+a+".y - y(unit)}"}]}),null!==s&&mq(e,t,_P,"width",n),null!==l&&mq(e,t,yP,"height",n),n}},zoom:{has:function(e){return"interval"===e.type&&e.zoom},signals:function(e,t,n){var r=t.name,i=rq.has(t),a=r+hq,o=kq(t),s=o.x,l=o.y,c=Object(Ee.M)(e.scaleName(_P)),u=Object(Ee.M)(e.scaleName(yP)),d=VT(t.zoom,"scope");return i||(d=d.map(function(e){return e.markname=r+"_brush",e})),n.push({name:r+gq,on:[{events:d,update:i?"{"+[c?"x: invert("+c+", x(unit))":"",u?"y: invert("+u+", y(unit))":""].filter(function(e){return!!e}).join(", ")+"}":"{x: x(unit), y: y(unit)}"}]},{name:a,on:[{events:d,force:!0,update:"pow(1.001, event.deltaY * pow(16, event.deltaMode))"}]}),null!==s&&bq(e,t,"x","width",n),null!==l&&bq(e,t,"y","height",n),n}},inputs:{has:function(e){return"single"===e.type&&"global"===e.resolve&&e.bind&&"scales"!==e.bind},topLevelSignals:function(e,t,n){var r=t.name,i=t.project,a=t.bind,o=lq.has(t)?"(item().isVoronoi ? datum.datum : datum)":"datum";return i.forEach(function(e){var i=nP(r+"_"+e.field);n.filter(function(e){return e.name===i}).length||n.unshift({name:i,value:"",on:[{events:t.events,update:"datum && item().mark.marktype !== 'group' ? "+aP(e.field,o)+" : null"}],bind:a[e.field]||a[e.channel]||a})}),n},signals:function(e,t,n){var r=t.name,i=t.project,a=n.filter(function(e){return e.name===r+xq})[0],o=i.map(function(e){return Object(Ee.M)(e.field)}).join(", "),s=i.map(function(e){return nP(r+"_"+e.field)});return s.length&&(a.update=s.join(" && ")+" ? {fields: ["+o+"], values: ["+s.join(", ")+"]} : null"),delete a.value,delete a.on,n}},nearest:lq};function _q(e,t){for(var n in vq)vq[n].has(e)&&t(vq[n])}var yq="_store",xq="_tuple",Eq="_modify",Sq="_selection_domain_";function wq(e,t){return Oq(e,function(n,r){t=r.marks?r.marks(e,n,t):t,_q(n,function(r){r.marks&&(t=r.marks(e,n,t))})}),t}function Cq(e,t,n){var r=[];var i=rP(t,function(t){var i=nP(t),a=e.getSelectionComponent(i,t),o=Object(Ee.M)(i+yq);if(a.timeUnit){var s=n||e.component.data.raw,l=a.timeUnit.clone();s.parent?l.insertAsParentOf(s):s.parent=l}return"none"!==a.empty&&r.push(o),Mq(a.type).predicate+"("+o+", datum"+("global"===a.resolve?")":", "+Object(Ee.M)(a.resolve)+")")});return(r.length?"!("+r.map(function(e){return"length(data("+e+"))"}).join(" || ")+") || ":"")+"("+i+")"}function Oq(e,t){var n=e.component.selection;for(var r in n)if(n.hasOwnProperty(r)){var i=n[r];t(i,Mq(i.type))}}function Mq(e){switch(e){case"single":return dq;case"multi":return uq;case"interval":return oq}return null}function Nq(e){for(var t=e.parent;t&&!Zz(t);)t=t.parent;return t}function Tq(e){var t=Object(Ee.M)(e.name),n=Nq(e);return n&&(t+=(n.facet.row?" + '_' + ("+aP(n.vgField("row"),"facet")+")":"")+(n.facet.column?" + '_' + ("+aP(n.vgField("column"),"facet")+")":"")),t}function Dq(e){var t=!1;return Oq(e,function(e){t=t||e.project.some(function(e){return e.field===pU})}),t}function Aq(e,t,n){var r=e._signalNames||(e._signalNames={});if(r[t]&&r[t][n])return r[t][n];r[t]=r[t]||{};for(var i=nP(e.name+"_"+("visual"===n?t:e.fields[t])),a=i,o=1;r[a];)a=i+"_"+o++;return r[a]=r[t][n]=a}function kq(e){var t=null,n=null,r=null,i=null;return e.project.forEach(function(e,a){e.channel===_P?(t=e,n=a):e.channel===yP&&(r=e,i=a)}),{x:t,xi:n,y:r,yi:i}}function Rq(e){return e&&!!e.field&&void 0!==e.equal}function Iq(e){return e&&!!e.field&&void 0!==e.lt}function Lq(e){return e&&!!e.field&&void 0!==e.lte}function Pq(e){return e&&!!e.field&&void 0!==e.gt}function Fq(e){return e&&!!e.field&&void 0!==e.gte}function Bq(e){return!!(e&&e.field&&Object(Ee.u)(e.range)&&2===e.range.length)}function Uq(e){return e&&!!e.field&&(Object(Ee.u)(e.oneOf)||Object(Ee.u)(e.in))}function jq(e){return Uq(e)||Rq(e)||Bq(e)||Iq(e)||Pq(e)||Lq(e)||Fq(e)}function zq(e,t,n){return rP(t,function(t){return Object(Ee.B)(t)?t:function(e){return e&&e.selection}(t)?Cq(e,t.selection,n):Gq(t)})}function qq(e,t){return wB(e,{timeUnit:t,time:!0})}function Gq(e,t){void 0===t&&(t=!0);var n=e.field,r=e.timeUnit,i=r?"time("+YF(r,n)+")":dB(e,{expr:"datum"});if(Rq(e))return i+"==="+qq(e.equal,r);if(Iq(e))return i+"<"+qq(s=e.lt,r);if(Pq(e))return i+">"+qq(o=e.gt,r);if(Lq(e))return i+"<="+qq(s=e.lte,r);if(Fq(e))return i+">="+qq(o=e.gte,r);if(Uq(e)){var a=e.oneOf;return"indexof(["+function(e,t){return e.map(function(e){return qq(e,t)})}(a=a||e.in,r).join(",")+"], "+i+") !== -1"}if(Bq(e)){var o=e.range[0],s=e.range[1];if(null!==o&&null!==s&&t)return"inrange("+i+", ["+qq(o,r)+", "+qq(s,r)+"])";var l=[];return null!==o&&l.push(i+" >= "+qq(o,r)),null!==s&&l.push(i+" <= "+qq(s,r)),l.length>0?l.join(" && "):"true"}throw new Error("Invalid field predicate: "+JSON.stringify(e))}function $q(e){return jq(e)&&e.timeUnit?NL({},e,{timeUnit:ZF(e.timeUnit)}):e}function Hq(e){return void 0!==e.filter}function Wq(e,t){var n;n=function(e){return"as"in e}(e)?Object(Ee.B)(e.as)?[e.as,e.as+"_end"]:[e.as[0],e.as[1]]:[dB(e,{}),dB(e,{binSuffix:"end"})];var r=xB(e.bin,void 0)||{},i=function(e,t){return oF(e)+"_"+t}(r,e.field),a=function(e,t){return{signal:e.getName(t+"_bins"),extentSignal:e.getName(t+"_extent")}}(t,i),o=a.signal,s=a.extentSignal;return{key:i,binComponent:NL({bin:r,field:e.field,as:n},o?{signal:o}:{},s?{extentSignal:s}:{})}}var Vq=function(e){function t(t,n){var r=e.call(this,t)||this;return r.bins=n,r}return ML(t,e),t.prototype.clone=function(){return new t(null,eP(this.bins))},t.makeFromEncoding=function(e,n){var r=n.reduceFieldDef(function(e,t,r){if(t.bin){var i=Wq(t,n),a=i.key,o=i.binComponent;e[a]=NL({},o,e[a],function(e,t,n,r){if(Ij(t,n)){var i=Yz(e)&&(e.axis(n)||e.legend(n))||{},a=dB(t,{expr:"datum"}),o=dB(t,{expr:"datum",binSuffix:"end"});return{formulaAs:dB(t,{binSuffix:"range"}),formula:Nj(a,o,i.format,r)}}return{}}(n,t,r,n.config))}return e},{});return 0===ZL(r).length?null:new t(e,r)},t.makeFromTransform=function(e,n,r){var i,a=Wq(n,r),o=a.key,s=a.binComponent;return new t(e,((i={})[o]=s,i))},t.prototype.merge=function(e){this.bins=NL({},this.bins,e.bins),e.remove()},t.prototype.producedFields=function(){var e={};return XL(this.bins).forEach(function(t){t.as.forEach(function(t){return e[t]=!0})}),e},t.prototype.dependentFields=function(){var e={};return XL(this.bins).forEach(function(t){e[t.field]=!0}),e},t.prototype.assemble=function(){return VL(XL(this.bins).map(function(e){var t=[],n=NL({type:"bin",field:e.field,as:e.as,signal:e.signal},e.bin);return!e.bin.extent&&e.extentSignal&&(t.push({type:"extent",field:e.field,signal:e.extentSignal}),n.extent={signal:e.extentSignal}),t.push(n),e.formula&&t.push({type:"formula",expr:e.formula,as:e.formulaAs}),t}))},t}(Pj),Kq=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.model=n,i.filter=r,i.expr=zq(i.model,i.filter,i),i}return ML(t,e),t.prototype.clone=function(){return new t(null,this.model,eP(this.filter))},t.prototype.assemble=function(){return{type:"filter",expr:this.expr}},t}(Pj),Qq=function(e){function t(t,n,r,i){var a=e.call(this,t)||this;return a.fields=n,a.geojson=r,a.signal=i,a}return ML(t,e),t.prototype.clone=function(){return new t(null,eP(this.fields),this.geojson,this.signal)},t.parseAll=function(e,n){var r=0;if([[CP,SP],[OP,wP]].forEach(function(i){var a=i.map(function(e){return n.channelHasField(e)?n.fieldDef(e).field:void 0});(a[0]||a[1])&&(e=new t(e,a,null,n.getName("geojson_"+r++)))}),n.channelHasField(TP)){var i=n.fieldDef(TP);i.type===rB&&(e=new t(e,null,i.field,n.getName("geojson_"+r++)))}return e},t.prototype.assemble=function(){return NL({type:"geojson"},this.fields?{fields:this.fields}:{},this.geojson?{geojson:this.geojson}:{},{signal:this.signal})},t}(Pj),Yq=function(e){function t(t,n,r,i){var a=e.call(this,t)||this;return a.projection=n,a.fields=r,a.as=i,a}return ML(t,e),t.prototype.clone=function(){return new t(null,this.projection,eP(this.fields),eP(this.as))},t.parseAll=function(e,n){return n.projectionName()?([[CP,SP],[OP,wP]].forEach(function(r){var i=r.map(function(e){return n.channelHasField(e)?n.fieldDef(e).field:void 0}),a=r[0]===OP?"2":"";(i[0]||i[1])&&(e=new t(e,n.projectionName(),i,[n.getName("x"+a),n.getName("y"+a)]))}),e):e},t.prototype.assemble=function(){return{type:"geopoint",projection:this.projection,fields:this.fields,as:this.as}},t}(Pj),Zq=function(e){function t(t){return e.call(this,t)||this}return ML(t,e),t.prototype.clone=function(){return new t(null)},t.prototype.producedFields=function(){var e;return(e={})[pU]=!0,e},t.prototype.assemble=function(){return{type:"identifier",as:pU}},t}(Pj),Xq=function(e){function t(t,n,r){void 0===t&&(t={}),void 0===n&&(n={}),void 0===r&&(r=!1);var i=e.call(this,t,n)||this;return i.explicit=t,i.implicit=n,i.parseNothing=r,i}return ML(t,e),t.prototype.clone=function(){var t=e.prototype.clone.call(this);return t.parseNothing=this.parseNothing,t},t}(Zj),Jq=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.transform=n,i.secondary=r,i}return ML(t,e),t.make=function(e,n,r,i){var a=n.component.data.sources,o=new Ez(r.from.data),s=a[o.hash()];s||(a[o.hash()]=o,s=o);var l=n.getName("lookup_"+i),c=new Fj(s,l,"lookup",n.component.data.outputNodeRefCounts);return n.component.data.outputNodes[l]=c,new t(e,r,c.getSource())},t.prototype.producedFields=function(){return Object(Ee.Q)(this.transform.from.fields||(this.transform.as instanceof Array?this.transform.as:[this.transform.as]))},t.prototype.assemble=function(){var e;if(this.transform.from.fields)e=NL({values:this.transform.from.fields},this.transform.as?{as:this.transform.as instanceof Array?this.transform.as:[this.transform.as]}:{});else{var t=this.transform.as;Object(Ee.B)(t)||(kF(OF.NO_FIELDS_NEEDS_AS),t="_lookup"),e={as:[t]}}return NL({type:"lookup",from:this.secondary,key:this.transform.from.key,fields:[this.transform.lookup]},e,this.transform.default?{default:this.transform.default}:{})},t}(Pj);function eG(e){var t=0;return function n(r,i){r instanceof Ez&&(UU(r.data)||(e.push(i),i={name:null,source:i.name,transform:[]}));if(r instanceof xz&&(r.parent instanceof Ez&&!i.source?(i.format=NL({},i.format||{},{parse:r.assembleFormatParse()}),i.transform=i.transform.concat(r.assembleTransforms(!0))):i.transform=i.transform.concat(r.assembleTransforms())),r instanceof _z)return i.name||(i.name="data_"+t++),!i.source||i.transform.length>0?(e.push(i),r.data=i.name):r.data=i.source,void r.assemble().forEach(function(t){return e.push(t)});(r instanceof Kq||r instanceof Bj||r instanceof Yq||r instanceof Qq||r instanceof vz||r instanceof Jq||r instanceof fG||r instanceof Zq)&&i.transform.push(r.assemble()),(r instanceof yz||r instanceof Vq||r instanceof Sz||r instanceof Nz)&&(i.transform=i.transform.concat(r.assemble())),r instanceof vz&&(i.name||(i.name="data_"+t++)),r instanceof Fj&&(i.source&&0===i.transform.length?r.setSource(i.source):r.parent instanceof Fj?r.setSource(i.name):(i.name||(i.name="data_"+t++),r.setSource(i.name),1===r.numChildren()&&(e.push(i),i={name:null,source:i.name,transform:[]})));switch(r.numChildren()){case 0:r instanceof Fj&&(!i.source||i.transform.length>0)&&e.push(i);break;case 1:n(r.children[0],i);break;default:i.name||(i.name="data_"+t++);var a=i.name;!i.source||i.transform.length>0?e.push(i):a=i.source,r.children.forEach(function(e){n(e,{name:null,source:a,transform:[]})})}}}function tG(e){rG(e);var t=e.component.layoutSize;t.setWithExplicit("width",iG(e,"width")),t.setWithExplicit("height",iG(e,"height"))}var nG=tG;function rG(e){for(var t=0,n=e.children;t0?{data:t}:{},n?{encode:{update:n}}:{},e.assembleGroup())]},t.prototype.getMapping=function(){return this.facet},t}(nq),fG=function(e){function t(t,n){var r=e.call(this,t)||this;return r.transform=n,r}return ML(t,e),t.makeFromFacet=function(e,n){var r=n.row,i=n.column;if(r&&i){for(var a=null,o=0,s=[r,i];o0&&(t=function(e,t,n){var r=0;return t.transforms.forEach(function(i){if(function(e){return void 0!==e.calculate}(i))e=new Bj(e,i),n.set(i.as,"derived",!1);else if(Hq(i))e=xz.makeImplicitFromFilterTransform(e,i,n)||e,e=new Kq(e,t,i.filter);else if(function(e){return!!e.bin}(i))for(var a=e=Vq.makeFromTransform(e,i,t),o=0,s=ZL(a.producedFields());o0&&(n[a]={update:s}),n},{});ZL(a).length>0&&r.set("encode",a,!!n.encoding||void 0!==n.labelAngle);return r}(n,e)]),t},{})}var yG={bottom:"top",top:"bottom",left:"right",right:"left"};function xG(e,t){if(!e)return t.map(function(e){return e.clone()});if(e.length===t.length){for(var n=e.length,r=0;r0?TG:""});var r,i;return t.length>0?[{name:e.getName("pathgroup"),type:"group",from:{facet:{name:TG+e.requestDataName(zU),data:e.requestDataName(zU),groupby:t}},encode:{update:{width:{field:{group:"width"}},height:{field:{group:"height"}}}},marks:n}]:n}(e):DG(e)}var TG="faceted_path_";function DG(e,t){void 0===t&&(t={fromPrefix:""});var n=e.mark,r=void 0!==e.markDef.clip?!!e.markDef.clip:function(e){var t=e.getScaleComponent("x"),n=e.getScaleComponent("y");return!!(t&&t.get("domainRaw")||n&&n.get("domainRaw"))}(e),i=xj(e.markDef),a=e.encoding.key,o=function(e){var t=e.encoding,n=e.stack,r=e.mark,i=e.markDef,a=t.order;if(Object(Ee.u)(a)||!cB(a)){if((Object(Ee.u)(a)||sB(a))&&!n)return Dj(a,{expr:"datum"});if(xF(r)){var o=t["horizontal"===i.orient?"y":"x"];if(sB(o)){var s=o.sort;return{field:XU(s)?dB({aggregate:MB(e.encoding)?s.op:void 0,field:s.field},{expr:"datum"}):dB(o,{binSuffix:e.stack&&e.stack.impute?"mid":void 0,expr:"datum"}),order:"descending"}}}}}(e),s=MG[n].postEncodingTransform?MG[n].postEncodingTransform(e):null;return[NL({name:e.getName("marks"),type:MG[n].vgMark},r?{clip:!0}:{},i?{style:i}:{},a?{key:{field:a.field}}:{},o?{sort:o}:{},{from:{data:t.fromPrefix+e.requestDataName(zU)},encode:{update:MG[n].encodeEntry(e)}},s?{transform:s}:{})]}var AG=function(e){function t(t,n,r,i,a,o,s){void 0===i&&(i={});var l=e.call(this,t,n,r,o,a,void 0)||this;l.fit=s,l.type="unit",l.specifiedScales={},l.specifiedAxes={},l.specifiedLegends={},l.specifiedProjection={},l.selection={},l.children=[],l.initSize(NL({},i,t.width?{width:t.width}:{},t.height?{height:t.height}:{}));var c=SF(t.mark)?t.mark.type:t.mark,u=l.encoding=function(e,t){return ZL(e).reduce(function(n,r){var i;if(!VP(r))return kF(OF.invalidEncodingChannel(r)),n;if(!iF(r,t))return kF(OF.incompatibleChannel(r,t)),n;if("size"===r&&"line"===t&&(o=vB(e[r]))&&o.aggregate)return kF(OF.LINE_WITH_VARYING_SIZE),n;if("color"===r&&("fill"in e||"stroke"in e))return kF(OF.droppingColor("encoding",{fill:"fill"in e,stroke:"stroke"in e})),n;var a=e[r];if("detail"===r||"order"===r&&!Object(Ee.u)(a)&&!cB(a)||"tooltip"===r&&Object(Ee.u)(a))a&&(n[r]=(Object(Ee.u)(a)?a:[a]).reduce(function(e,t){return sB(t)?e.push(yB(t,r)):kF(OF.emptyFieldDef(t,r)),e},[]));else{var o;if((o=vB(e[r]))&&$L([KF.LATITUDE,KF.LONGITUDE],o.type)){var s=r,l=(n[s],TL(n,["symbol"==typeof s?s:s+""])),c="x"===r?"longitude":"y"===r?"latitude":"x2"===r?"longitude2":"y2"===r?"latitude2":void 0;return kF(OF.latLongDeprecated(r,o.type,c)),NL({},l,((i={})[c]=NL({},_B(o,r),{type:"quantitative"}),i))}if(!sB(a)&&!cB(a)&&!aB(a))return kF(OF.emptyFieldDef(a,r)),n;n[r]=_B(a,r)}return n},{})}(function(e,t){return cG(e,t)}(t.encoding||{},a),c);return l.markDef=wG(t.mark,u,o),l.stack=SU(c,u,l.config.stack),l.specifiedScales=l.initScales(c,u),l.specifiedAxes=l.initAxes(u),l.specifiedLegends=l.initLegend(u),l.specifiedProjection=t.projection,l.selection=t.selection,l}return ML(t,e),Object.defineProperty(t.prototype,"hasProjection",{get:function(){var e=this.encoding,t=this.mark===bF,n=e&&qP.some(function(t){return sB(e[t])});return t||n},enumerable:!0,configurable:!0}),t.prototype.scaleDomain=function(e){var t=this.specifiedScales[e];return t?t.domain:void 0},t.prototype.axis=function(e){return this.specifiedAxes[e]},t.prototype.legend=function(e){return this.specifiedLegends[e]},t.prototype.initScales=function(e,t){return nF.reduce(function(e,n){var r,i,a=t[n];return sB(a)?(r=a,i=a.scale):oB(a)?(r=a.condition,i=a.condition.scale):"x"===n?r=vB(t.x2):"y"===n&&(r=vB(t.y2)),r&&(e[n]=i||{}),e},{})},t.prototype.initAxes=function(e){return[_P,yP].reduce(function(t,n){var r=e[n];if(sB(r)||n===_P&&sB(e.x2)||n===yP&&sB(e.y2)){var i=sB(r)?r.axis:null;null!==i&&!1!==i&&(t[n]=NL({},i))}return t},{})},t.prototype.initLegend=function(e){return eF.reduce(function(t,n){var r=e[n];if(r){var i=sB(r)?r.legend:oB(r)?r.condition.legend:null;null!==i&&!1!==i&&(t[n]=NL({},i))}return t},{})},t.prototype.parseData=function(){this.component.data=pG(this)},t.prototype.parseLayoutSize=function(){!function(e){var t=e.component.layoutSize;if(!t.explicit.width){var n=aG(e,"width");t.set("width",n,!1)}if(!t.explicit.height){var r=aG(e,"height");t.set("height",r,!1)}}(this)},t.prototype.parseSelection=function(){this.component.selection=function(e,t){var n={},r=e.config.selection,i=function(i){if(!t.hasOwnProperty(i))return"continue";var a=t[i],o=r[a.type];for(var s in o)"encodings"===s&&a.fields||"fields"===s&&a.encodings||("mark"===s&&(a[s]=NL({},o[s],a[s])),void 0!==a[s]&&!0!==a[s]||(a[s]=o[s]||a[s]));i=nP(i);var l=n[i]=NL({},a,{name:i,events:Object(Ee.B)(a.on)?VT(a.on,"scope"):a.on});_q(l,function(t){t.parse&&t.parse(e,a,l)})};for(var a in t)i(a);return n}(this,this.selection)},t.prototype.parseMarkGroup=function(){this.component.mark=NG(this)},t.prototype.parseAxisAndHeader=function(){this.component.axes=_G(this)},t.prototype.assembleSelectionTopLevelSignals=function(e){return function(e,t){var n=!1;return Oq(e,function(r,i){i.topLevelSignals&&(t=i.topLevelSignals(e,r,t)),_q(r,function(n){n.topLevelSignals&&(t=n.topLevelSignals(e,r,t))}),n=!0}),n&&(t.filter(function(e){return"unit"===e.name}).length||t.unshift({name:"unit",value:{},on:[{events:"mousemove",update:"isTuple(group()) ? group() : unit"}]})),t}(this,e)},t.prototype.assembleSelectionSignals=function(){return function(e,t){Oq(e,function(n,r){var i=n.name,a=r.modifyExpr(e,n);t.push.apply(t,r.signals(e,n)),_q(n,function(r){r.signals&&(t=r.signals(e,n,t)),r.modifyExpr&&(a=r.modifyExpr(e,n,a))}),t.push({name:i+Eq,on:[{events:{signal:i+xq},update:"modify("+Object(Ee.M)(n.name+yq)+", "+a+")"}]})});var n=Nq(e);if(t.length&&n){var r=Object(Ee.M)(n.getName("cell"));t.unshift({name:"facet",value:{},on:[{events:VT("mousemove","scope"),update:"isTuple(facet) ? facet : group("+r+").datum"}]})}return t}(this,[])},t.prototype.assembleSelectionData=function(e){return function(e,t){return Oq(e,function(e){t.filter(function(t){return t.name===e.name+yq}).length||t.push({name:e.name+yq})}),t}(this,e)},t.prototype.assembleLayout=function(){return null},t.prototype.assembleLayoutSignals=function(){return Wj(this)},t.prototype.assembleMarks=function(){var e=this.component.mark||[];return this.parent&&eq(this.parent)||(e=wq(this,e)),e.map(this.correctDataNames)},t.prototype.assembleLayoutSize=function(){return{width:this.getSizeSignalRef("width"),height:this.getSizeSignalRef("height")}},t.prototype.getMapping=function(){return this.encoding},t.prototype.toSpec=function(e,t){var n,r=eP(this.encoding);return n={mark:this.markDef,encoding:r},e||(n.config=eP(this.config)),t||(n.data=eP(this.data)),n},Object.defineProperty(t.prototype,"mark",{get:function(){return this.markDef.type},enumerable:!0,configurable:!0}),t.prototype.channelHasField=function(e){return OB(this.encoding,e)},t.prototype.fieldDef=function(e){return vB(this.encoding[e])},t}(nq),kG=function(e){function t(n,r,i,a,o,s,l){var c=e.call(this,n,r,i,s,o,n.resolve)||this;c.type="layer";var u=NL({},a,n.width?{width:n.width}:{},n.height?{height:n.height}:{});return c.initSize(u),c.children=n.layer.map(function(e,n){if(OU(e))return new t(e,c,c.getName("layer_"+n),u,o,s,l);if(CU(e))return new AG(e,c,c.getName("layer_"+n),u,o,s,l);throw new Error(OF.INVALID_SPEC)}),c}return ML(t,e),t.prototype.parseData=function(){this.component.data=pG(this);for(var e=0,t=this.children;e0&&!y){var x=yG[_];i[_]>i[x]&&b.set("orient",x,!1)}i[_]++}}delete m.component.axes[c]}}}}(this)},t.prototype.assembleSelectionTopLevelSignals=function(e){return this.children.reduce(function(e,t){return t.assembleSelectionTopLevelSignals(e)},e)},t.prototype.assembleSelectionSignals=function(){return this.children.reduce(function(e,t){return e.concat(t.assembleSelectionSignals())},[])},t.prototype.assembleLayoutSignals=function(){return this.children.reduce(function(e,t){return e.concat(t.assembleLayoutSignals())},Wj(this))},t.prototype.assembleSelectionData=function(e){return this.children.reduce(function(e,t){return t.assembleSelectionData(e)},e)},t.prototype.assembleTitle=function(){var t=e.prototype.assembleTitle.call(this);if(t)return t;for(var n=0,r=this.children;n0})).forEach(wz(Oz)),kz(i=i.filter(function(e){return e.numChildren()>0})).forEach(wz(Cz)),kz(i).forEach(Mz),i.forEach(Dz),ZL(r.sources).forEach(function(e){0===r.sources[e].numChildren()&&delete r.sources[e]}),function(e,t){var n=e.config?function(e){e=eP(e);for(var t=0,n=bU;t0?e:void 0}(e.config):void 0,r=[].concat(e.assembleSelectionData([]),function(e,t){var n=XL(e.sources),r=[],i=eG(r),a=0;n.forEach(function(e){e.hasName()||(e.dataName="source_"+a++);var t=e.assemble();i(e,t)}),r.forEach(function(e){0===e.transform.length&&delete e.transform});for(var o=0,s=0;s0?{projections:i}:{},e.assembleGroup(s.concat(e.assembleSelectionTopLevelSignals([]))),n?{config:n}:{})}}(l,function(e,t,n){return NL({autosize:1===ZL(n).length&&n.type?n.type:n},BU(t),BU(e))}(e,a,s))}finally{t.logger&&AF(),t.fieldTitle&&hB(mB)}}n(3),Object(Ee.Q)(["row","column","x","y","size","color","fill","stroke","detail"]),Object(Ee.Q)(["row","column","x","y","color","fill","stroke","color","detail"]),Object(Ee.Q)(["row","column","x","y","color","fill","stroke","color","detail","size"]),Object(Ee.Q)(["row","column","x","y","color","fill","stroke","detail"]),Object(Ee.Q)(["row","column","x","y","color","fill","stroke","detail"]),Object(Ee.Q)(["row","column","x","y","color","fill","stroke","size","detail"]),Object(Ee.Q)(["row","column","x","y","color","fill","stroke","size","detail"]),Object(Ee.Q)(["row","column","x","y","color","fill","stroke","size","detail","shape"]),Object(Ee.Q)(["row","column","color","fill","stroke","detail","shape"]),Object(Ee.Q)(["row","column","size","color","fill","stroke","text"]);n(5).version;n.d(t,"embedExample",function(){return BG}),window.runStreamingExample=function(e){var t,n,r=BG(e,{$schema:"https://vega.github.io/schema/vega-lite/v2.json",data:{name:"table"},autosize:{resize:!0},width:400,mark:"line",encoding:{x:{field:"x",type:"quantitative",scale:{zero:!1}},y:{field:"y",type:"quantitative"},color:{field:"category",type:"nominal"}}},!1,!1),i=(t=-1,n=[5,5,5,5],function(){t++;var e=n.map(function(e,n){return{x:t,y:e+Math.round(10*Math.random()-3*n),category:n}});return n=e.map(function(e){return e.y}),e}),a=-100;window.setInterval(function(){a++;var e=r.changeset().insert(i()).remove(function(e){return e.x'+n.replace(/^\s+|\s+$/g,""))}),window.changeSpec=function(e,t){var n=document.getElementById(e);be(n).attr("data-name",t),UG(n)},window.buildSpecOpts=function(e,t){var n=be("#"+e).attr("data-name"),r=be("select[name="+e+"]"),i=ye("input[name="+e+"]:checked"),a=r.empty()?e:r.property("value"),o=i.nodes().map(function(e){return e.value}).sort().join("_"),s=t+a+(o?"_"+o:"");n!==s&&window.changeSpec(e,s)},ye(".vl-example").each(function(){UG(this)});var jG=document.getElementById("carousel");function zG(e,t,n,r){t[r].setAttribute("data-state",""),n[r].setAttribute("data-state",""),e[r].setAttribute("data-state",""),e[r].style.display="none";var i=e[r].querySelector("video");i&&i.pause()}function qG(e,t,n,r){return function(){for(var i=0;i="0"&&r<="9";)t+=r,l();if("."===r)for(t+=".";l()&&r>="0"&&r<="9";)t+=r;if("e"===r||"E"===r)for(t+=r,l(),"-"!==r&&"+"!==r||(t+=r,l());r>="0"&&r<="9";)t+=r,l();if(e=+t,isFinite(e))return e;s("Bad number")},u=function(){var e,t,n,i="";if('"'===r)for(;l();){if('"'===r)return l(),i;if("\\"===r)if(l(),"u"===r){for(n=0,t=0;t<4&&(e=parseInt(l(),16),isFinite(e));t+=1)n=16*n+e;i+=String.fromCharCode(n)}else{if("string"!=typeof o[r])break;i+=o[r]}else i+=r}s("Bad string")},d=function(){for(;r&&r<=" ";)l()};a=function(){switch(d(),r){case"{":return function(){var e,t={};if("{"===r){if(l("{"),d(),"}"===r)return l("}"),t;for(;r;){if(e=u(),d(),l(":"),Object.hasOwnProperty.call(t,e)&&s('Duplicate key "'+e+'"'),t[e]=a(),d(),"}"===r)return l("}"),t;l(","),d()}}s("Bad object")}();case"[":return function(){var e=[];if("["===r){if(l("["),d(),"]"===r)return l("]"),e;for(;r;){if(e.push(a()),d(),"]"===r)return l("]"),e;l(","),d()}}s("Bad array")}();case'"':return u();case"-":return c();default:return r>="0"&&r<="9"?c():function(){switch(r){case"t":return l("t"),l("r"),l("u"),l("e"),!0;case"f":return l("f"),l("a"),l("l"),l("s"),l("e"),!1;case"n":return l("n"),l("u"),l("l"),l("l"),null}s("Unexpected '"+r+"'")}()}},e.exports=function(e,t){var o;return i=e,n=0,r=" ",o=a(),d(),r&&s("Syntax error"),"function"==typeof t?function e(n,r){var i,a,o=n[r];if(o&&"object"==typeof o)for(i in o)Object.prototype.hasOwnProperty.call(o,i)&&(void 0!==(a=e(o,i))?o[i]=a:delete o[i]);return t.call(n,r,o)}({"":o},""):o}},function(e,t,n){t.parse=n(9),t.stringify=n(8)},function(e,t){var n={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},function(e,t){t.read=function(e,t,n,r,i){var a,o,s=8*i-r-1,l=(1<>1,u=-7,d=n?i-1:0,f=n?-1:1,p=e[t+d];for(d+=f,a=p&(1<<-u)-1,p>>=-u,u+=s;u>0;a=256*a+e[t+d],d+=f,u-=8);for(o=a&(1<<-u)-1,a>>=-u,u+=r;u>0;o=256*o+e[t+d],d+=f,u-=8);if(0===a)a=1-c;else{if(a===l)return o?NaN:1/0*(p?-1:1);o+=Math.pow(2,r),a-=c}return(p?-1:1)*o*Math.pow(2,a-r)},t.write=function(e,t,n,r,i,a){var o,s,l,c=8*a-i-1,u=(1<>1,f=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:a-1,m=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,o=u):(o=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-o))<1&&(o--,l*=2),(t+=o+d>=1?f/l:f*Math.pow(2,1-d))*l>=2&&(o++,l/=2),o+d>=u?(s=0,o=u):o+d>=1?(s=(t*l-1)*Math.pow(2,i),o+=d):(s=t*Math.pow(2,d-1)*Math.pow(2,i),o=0));i>=8;e[n+p]=255&s,p+=m,s/=256,i-=8);for(o=o<0;e[n+p]=255&o,p+=m,o/=256,c-=8);e[n+p-m]|=128*g}},function(e,t,n){"use strict";t.byteLength=function(e){var t=c(e),n=t[0],r=t[1];return 3*(n+r)/4-r},t.toByteArray=function(e){for(var t,n=c(e),r=n[0],o=n[1],s=new a(function(e,t,n){return 3*(t+n)/4-n}(0,r,o)),l=0,u=o>0?r-4:r,d=0;d>16&255,s[l++]=t>>8&255,s[l++]=255&t;2===o&&(t=i[e.charCodeAt(d)]<<2|i[e.charCodeAt(d+1)]>>4,s[l++]=255&t);1===o&&(t=i[e.charCodeAt(d)]<<10|i[e.charCodeAt(d+1)]<<4|i[e.charCodeAt(d+2)]>>2,s[l++]=t>>8&255,s[l++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,i=n%3,a=[],o=0,s=n-i;os?s:o+16383));1===i?(t=e[n-1],a.push(r[t>>2]+r[t<<4&63]+"==")):2===i&&(t=(e[n-2]<<8)+e[n-1],a.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return a.join("")};for(var r=[],i=[],a="undefined"!=typeof Uint8Array?Uint8Array:Array,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,l=o.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function u(e,t,n){for(var i,a,o=[],s=t;s>18&63]+r[a>>12&63]+r[a>>6&63]+r[63&a]);return o.join("")}i["-".charCodeAt(0)]=62,i["_".charCodeAt(0)]=63},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";(function(e){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +var r=n(13),i=n(12),a=n(11);function o(){return l.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(o()=o())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+o().toString(16)+" bytes");return 0|e}function m(e,t){if(l.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return j(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return z(e).length;default:if(r)return j(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function h(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=i?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=l.from(t,r)),l.isBuffer(t))return 0===t.length?-1:b(e,t,n,r,i);if("number"==typeof t)return t&=255,l.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):b(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function b(e,t,n,r,i){var a,o=1,s=e.length,l=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;o=2,s/=2,l/=2,n/=2}function c(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}if(i){var u=-1;for(a=n;as&&(n=s-l),a=n;a>=0;a--){for(var d=!0,f=0;fi&&(r=i):r=i;var a=t.length;if(a%2!=0)throw new TypeError("Invalid hex string");r>a/2&&(r=a/2);for(var o=0;o>8,i=n%256,a.push(i),a.push(r);return a}(t,e.length-n),e,n,r)}function w(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function C(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i239?4:c>223?3:c>191?2:1;if(i+d<=n)switch(d){case 1:c<128&&(u=c);break;case 2:128==(192&(a=e[i+1]))&&(l=(31&c)<<6|63&a)>127&&(u=l);break;case 3:a=e[i+1],o=e[i+2],128==(192&a)&&128==(192&o)&&(l=(15&c)<<12|(63&a)<<6|63&o)>2047&&(l<55296||l>57343)&&(u=l);break;case 4:a=e[i+1],o=e[i+2],s=e[i+3],128==(192&a)&&128==(192&o)&&128==(192&s)&&(l=(15&c)<<18|(63&a)<<12|(63&o)<<6|63&s)>65535&&l<1114112&&(u=l)}null===u?(u=65533,d=1):u>65535&&(u-=65536,r.push(u>>>10&1023|55296),u=56320|1023&u),r.push(u),i+=d}return function(e){var t=e.length;if(t<=O)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return T(this,t,n);case"utf8":case"utf-8":return C(this,t,n);case"ascii":return M(this,t,n);case"latin1":case"binary":return N(this,t,n);case"base64":return w(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return D(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},l.prototype.equals=function(e){if(!l.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===l.compare(this,e)},l.prototype.inspect=function(){var e="",n=t.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},l.prototype.compare=function(e,t,n,r,i){if(!l.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(r>=i&&t>=n)return 0;if(r>=i)return-1;if(t>=n)return 1;if(t>>>=0,n>>>=0,r>>>=0,i>>>=0,this===e)return 0;for(var a=i-r,o=n-t,s=Math.min(a,o),c=this.slice(r,i),u=e.slice(t,n),d=0;di)&&(n=i),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var a=!1;;)switch(r){case"hex":return v(this,e,t,n);case"utf8":case"utf-8":return _(this,e,t,n);case"ascii":return y(this,e,t,n);case"latin1":case"binary":return x(this,e,t,n);case"base64":return E(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},l.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var O=4096;function M(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;ir)&&(n=r);for(var i="",a=t;an)throw new RangeError("Trying to access beyond buffer length")}function k(e,t,n,r,i,a){if(!l.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||te.length)throw new RangeError("Index out of range")}function R(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,a=Math.min(e.length-n,2);i>>8*(r?i:1-i)}function I(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,a=Math.min(e.length-n,4);i>>8*(r?i:3-i)&255}function L(e,t,n,r,i,a){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function P(e,t,n,r,a){return a||L(e,0,n,4),i.write(e,t,n,r,23,4),n+4}function F(e,t,n,r,a){return a||L(e,0,n,8),i.write(e,t,n,r,52,8),n+8}l.prototype.slice=function(e,t){var n,r=this.length;if(e=~~e,t=void 0===t?r:~~t,e<0?(e+=r)<0&&(e=0):e>r&&(e=r),t<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(i*=256);)r+=this[e+--t]*i;return r},l.prototype.readUInt8=function(e,t){return t||A(e,1,this.length),this[e]},l.prototype.readUInt16LE=function(e,t){return t||A(e,2,this.length),this[e]|this[e+1]<<8},l.prototype.readUInt16BE=function(e,t){return t||A(e,2,this.length),this[e]<<8|this[e+1]},l.prototype.readUInt32LE=function(e,t){return t||A(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},l.prototype.readUInt32BE=function(e,t){return t||A(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},l.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||A(e,t,this.length);for(var r=this[e],i=1,a=0;++a=(i*=128)&&(r-=Math.pow(2,8*t)),r},l.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||A(e,t,this.length);for(var r=t,i=1,a=this[e+--r];r>0&&(i*=256);)a+=this[e+--r]*i;return a>=(i*=128)&&(a-=Math.pow(2,8*t)),a},l.prototype.readInt8=function(e,t){return t||A(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},l.prototype.readInt16LE=function(e,t){t||A(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},l.prototype.readInt16BE=function(e,t){t||A(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},l.prototype.readInt32LE=function(e,t){return t||A(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},l.prototype.readInt32BE=function(e,t){return t||A(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},l.prototype.readFloatLE=function(e,t){return t||A(e,4,this.length),i.read(this,e,!0,23,4)},l.prototype.readFloatBE=function(e,t){return t||A(e,4,this.length),i.read(this,e,!1,23,4)},l.prototype.readDoubleLE=function(e,t){return t||A(e,8,this.length),i.read(this,e,!0,52,8)},l.prototype.readDoubleBE=function(e,t){return t||A(e,8,this.length),i.read(this,e,!1,52,8)},l.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||k(this,e,t,n,Math.pow(2,8*n)-1,0);var i=1,a=0;for(this[t]=255&e;++a=0&&(a*=256);)this[t+i]=e/a&255;return t+n},l.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,1,255,0),l.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},l.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,2,65535,0),l.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):R(this,e,t,!0),t+2},l.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,2,65535,0),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):R(this,e,t,!1),t+2},l.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,4,4294967295,0),l.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):I(this,e,t,!0),t+4},l.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,4,4294967295,0),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):I(this,e,t,!1),t+4},l.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);k(this,e,t,n,i-1,-i)}var a=0,o=1,s=0;for(this[t]=255&e;++a>0)-s&255;return t+n},l.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);k(this,e,t,n,i-1,-i)}var a=n-1,o=1,s=0;for(this[t+a]=255&e;--a>=0&&(o*=256);)e<0&&0===s&&0!==this[t+a+1]&&(s=1),this[t+a]=(e/o>>0)-s&255;return t+n},l.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,1,127,-128),l.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},l.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,2,32767,-32768),l.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):R(this,e,t,!0),t+2},l.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,2,32767,-32768),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):R(this,e,t,!1),t+2},l.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,4,2147483647,-2147483648),l.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):I(this,e,t,!0),t+4},l.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):I(this,e,t,!1),t+4},l.prototype.writeFloatLE=function(e,t,n){return P(this,e,t,!0,n)},l.prototype.writeFloatBE=function(e,t,n){return P(this,e,t,!1,n)},l.prototype.writeDoubleLE=function(e,t,n){return F(this,e,t,!0,n)},l.prototype.writeDoubleBE=function(e,t,n){return F(this,e,t,!1,n)},l.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--i)e[i+t]=this[i+n];else if(a<1e3||!l.TYPED_ARRAY_SUPPORT)for(i=0;i>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(a=t;a55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(o+1===r){(t-=3)>-1&&a.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&a.push(239,191,189),i=n;continue}n=65536+(i-55296<<10|n-56320)}else i&&(t-=3)>-1&&a.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;a.push(n)}else if(n<2048){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function z(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(B,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function q(e,t,n,r){for(var i=0;i=t.length||i>=e.length);++i)t[i+n]=e[i];return i}}).call(this,n(14))},function(e,t){},function(e,t){},function(e,t){e.exports=function(e){var t={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:'b"',end:'"'},{begin:"b'",end:"'"},e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null})]},n={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]};return{aliases:["zep"],case_insensitive:!0,keywords:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var let while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally int uint long ulong char uchar double float bool boolean stringlikely unlikely",contains:[e.C_LINE_COMMENT_MODE,e.HASH_COMMENT_MODE,e.COMMENT("/\\*","\\*/",{contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.COMMENT("__halt_compiler.+?;",!1,{endsWithParent:!0,keywords:"__halt_compiler",lexemes:e.UNDERSCORE_IDENT_RE}),{className:"string",begin:"<<<['\"]?\\w+['\"]?$",end:"^\\w+;",contains:[e.BACKSLASH_ESCAPE]},{begin:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{className:"function",beginKeywords:"function",end:/[;{]/,excludeEnd:!0,illegal:"\\$|\\[|%",contains:[e.UNDERSCORE_TITLE_MODE,{className:"params",begin:"\\(",end:"\\)",contains:["self",e.C_BLOCK_COMMENT_MODE,t,n]}]},{className:"class",beginKeywords:"class interface",end:"{",excludeEnd:!0,illegal:/[:\(\$"]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"namespace",end:";",illegal:/[\.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"use",end:";",contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"=>"},t,n]}}},function(e,t){e.exports=function(e){var t={begin:"{",end:"}"},n=[{begin:/\$[a-zA-Z0-9\-]+/},{className:"string",variants:[{begin:/"/,end:/"/,contains:[{begin:/""/,relevance:0}]},{begin:/'/,end:/'/,contains:[{begin:/''/,relevance:0}]}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{className:"comment",begin:"\\(:",end:":\\)",relevance:10,contains:[{className:"doctag",begin:"@\\w+"}]},{className:"meta",begin:"%\\w+"},t];return t.contains=n,{aliases:["xpath","xq"],case_insensitive:!1,lexemes:/[a-zA-Z\$][a-zA-Z0-9_:\-]*/,illegal:/(proc)|(abstract)|(extends)|(until)|(#)/,keywords:{keyword:"for let if while then else return where group by xquery encoding versionmodule namespace boundary-space preserve strip default collation base-uri orderingcopy-namespaces order declare import schema namespace function option in allowing emptyat tumbling window sliding window start when only end when previous next stable ascendingdescending empty greatest least some every satisfies switch case typeswitch try catch andor to union intersect instance of treat as castable cast map array delete insert intoreplace value rename copy modify update",literal:"false true xs:string xs:integer element item xs:date xs:datetime xs:float xs:double xs:decimal QName xs:anyURI xs:long xs:int xs:short xs:byte attribute"},contains:n}}},function(e,t){e.exports=function(e){var t={keyword:"if then else do while until for loop import with is as where when by data constant integer real text name boolean symbol infix prefix postfix block tree",literal:"true false nil",built_in:"in mod rem and or xor not abs sign floor ceil sqrt sin cos tan asin acos atan exp expm1 log log2 log10 log1p pi at text_length text_range text_find text_replace contains page slide basic_slide title_slide title subtitle fade_in fade_out fade_at clear_color color line_color line_width texture_wrap texture_transform texture scale_?x scale_?y scale_?z? translate_?x translate_?y translate_?z? rotate_?x rotate_?y rotate_?z? rectangle circle ellipse sphere path line_to move_to quad_to curve_to theme background contents locally time mouse_?x mouse_?y mouse_buttons ObjectLoader Animate MovieCredits Slides Filters Shading Materials LensFlare Mapping VLCAudioVideo StereoDecoder PointCloud NetworkAccess RemoteControl RegExp ChromaKey Snowfall NodeJS Speech Charts"},n={className:"string",begin:'"',end:'"',illegal:"\\n"},r={beginKeywords:"import",end:"$",keywords:t,contains:[n]},i={className:"function",begin:/[a-z][^\n]*->/,returnBegin:!0,end:/->/,contains:[e.inherit(e.TITLE_MODE,{starts:{endsWithParent:!0,keywords:t}})]};return{aliases:["tao"],lexemes:/[a-zA-Z][a-zA-Z0-9_?]*/,keywords:t,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,{className:"string",begin:"'",end:"'",illegal:"\\n"},{className:"string",begin:"<<",end:">>"},i,r,{className:"number",begin:"[0-9]+#[0-9A-Z_]+(\\.[0-9-A-Z_]+)?#?([Ee][+-]?[0-9]+)?"},e.NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,lexemes:"[.%]?"+e.IDENT_RE,keywords:{keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",built_in:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr",meta:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},contains:[e.COMMENT(";","$",{relevance:0}),{className:"number",variants:[{begin:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",relevance:0},{begin:"\\$[0-9][0-9A-Fa-f]*",relevance:0},{begin:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{begin:"\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"}]},e.QUOTE_STRING_MODE,{className:"string",variants:[{begin:"'",end:"[^\\\\]'"},{begin:"`",end:"[^\\\\]`"}],relevance:0},{className:"symbol",variants:[{begin:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)"},{begin:"^\\s*%%[A-Za-z0-9_$#@~.?]*:"}],relevance:0},{className:"subst",begin:"%[0-9]+",relevance:0},{className:"subst",begin:"%!S+",relevance:0},{className:"meta",begin:/^\s*\.[\w_-]+/}]}}},function(e,t){e.exports=function(e){return{lexemes:/[!#@\w]+/,keywords:{keyword:"N|0 P|0 X|0 a|0 ab abc abo al am an|0 ar arga argd arge argdo argg argl argu as au aug aun b|0 bN ba bad bd be bel bf bl bm bn bo bp br brea breaka breakd breakl bro bufdo buffers bun bw c|0 cN cNf ca cabc caddb cad caddf cal cat cb cc ccl cd ce cex cf cfir cgetb cgete cg changes chd che checkt cl cla clo cm cmapc cme cn cnew cnf cno cnorea cnoreme co col colo com comc comp con conf cope cp cpf cq cr cs cst cu cuna cunme cw delm deb debugg delc delf dif diffg diffo diffp diffpu diffs diffthis dig di dl dell dj dli do doautoa dp dr ds dsp e|0 ea ec echoe echoh echom echon el elsei em en endfo endf endt endw ene ex exe exi exu f|0 files filet fin fina fini fir fix fo foldc foldd folddoc foldo for fu go gr grepa gu gv ha helpf helpg helpt hi hid his ia iabc if ij il im imapc ime ino inorea inoreme int is isp iu iuna iunme j|0 ju k|0 keepa kee keepj lN lNf l|0 lad laddb laddf la lan lat lb lc lch lcl lcs le lefta let lex lf lfir lgetb lgete lg lgr lgrepa lh ll lla lli lmak lm lmapc lne lnew lnf ln loadk lo loc lockv lol lope lp lpf lr ls lt lu lua luad luaf lv lvimgrepa lw m|0 ma mak map mapc marks mat me menut mes mk mks mksp mkv mkvie mod mz mzf nbc nb nbs new nm nmapc nme nn nnoreme noa no noh norea noreme norm nu nun nunme ol o|0 om omapc ome on ono onoreme opt ou ounme ow p|0 profd prof pro promptr pc ped pe perld po popu pp pre prev ps pt ptN ptf ptj ptl ptn ptp ptr pts pu pw py3 python3 py3d py3f py pyd pyf quita qa rec red redi redr redraws reg res ret retu rew ri rightb rub rubyd rubyf rund ru rv sN san sa sal sav sb sbN sba sbf sbl sbm sbn sbp sbr scrip scripte scs se setf setg setl sf sfir sh sim sig sil sl sla sm smap smapc sme sn sni sno snor snoreme sor so spelld spe spelli spellr spellu spellw sp spr sre st sta startg startr star stopi stj sts sun sunm sunme sus sv sw sy synti sync tN tabN tabc tabdo tabe tabf tabfir tabl tabm tabnew tabn tabo tabp tabr tabs tab ta tags tc tcld tclf te tf th tj tl tm tn to tp tr try ts tu u|0 undoj undol una unh unl unlo unm unme uns up ve verb vert vim vimgrepa vi viu vie vm vmapc vme vne vn vnoreme vs vu vunme windo w|0 wN wa wh wi winc winp wn wp wq wqa ws wu wv x|0 xa xmapc xm xme xn xnoreme xu xunme y|0 z|0 ~ Next Print append abbreviate abclear aboveleft all amenu anoremenu args argadd argdelete argedit argglobal arglocal argument ascii autocmd augroup aunmenu buffer bNext ball badd bdelete behave belowright bfirst blast bmodified bnext botright bprevious brewind break breakadd breakdel breaklist browse bunload bwipeout change cNext cNfile cabbrev cabclear caddbuffer caddexpr caddfile call catch cbuffer cclose center cexpr cfile cfirst cgetbuffer cgetexpr cgetfile chdir checkpath checktime clist clast close cmap cmapclear cmenu cnext cnewer cnfile cnoremap cnoreabbrev cnoremenu copy colder colorscheme command comclear compiler continue confirm copen cprevious cpfile cquit crewind cscope cstag cunmap cunabbrev cunmenu cwindow delete delmarks debug debuggreedy delcommand delfunction diffupdate diffget diffoff diffpatch diffput diffsplit digraphs display deletel djump dlist doautocmd doautoall deletep drop dsearch dsplit edit earlier echo echoerr echohl echomsg else elseif emenu endif endfor endfunction endtry endwhile enew execute exit exusage file filetype find finally finish first fixdel fold foldclose folddoopen folddoclosed foldopen function global goto grep grepadd gui gvim hardcopy help helpfind helpgrep helptags highlight hide history insert iabbrev iabclear ijump ilist imap imapclear imenu inoremap inoreabbrev inoremenu intro isearch isplit iunmap iunabbrev iunmenu join jumps keepalt keepmarks keepjumps lNext lNfile list laddexpr laddbuffer laddfile last language later lbuffer lcd lchdir lclose lcscope left leftabove lexpr lfile lfirst lgetbuffer lgetexpr lgetfile lgrep lgrepadd lhelpgrep llast llist lmake lmap lmapclear lnext lnewer lnfile lnoremap loadkeymap loadview lockmarks lockvar lolder lopen lprevious lpfile lrewind ltag lunmap luado luafile lvimgrep lvimgrepadd lwindow move mark make mapclear match menu menutranslate messages mkexrc mksession mkspell mkvimrc mkview mode mzscheme mzfile nbclose nbkey nbsart next nmap nmapclear nmenu nnoremap nnoremenu noautocmd noremap nohlsearch noreabbrev noremenu normal number nunmap nunmenu oldfiles open omap omapclear omenu only onoremap onoremenu options ounmap ounmenu ownsyntax print profdel profile promptfind promptrepl pclose pedit perl perldo pop popup ppop preserve previous psearch ptag ptNext ptfirst ptjump ptlast ptnext ptprevious ptrewind ptselect put pwd py3do py3file python pydo pyfile quit quitall qall read recover redo redir redraw redrawstatus registers resize retab return rewind right rightbelow ruby rubydo rubyfile rundo runtime rviminfo substitute sNext sandbox sargument sall saveas sbuffer sbNext sball sbfirst sblast sbmodified sbnext sbprevious sbrewind scriptnames scriptencoding scscope set setfiletype setglobal setlocal sfind sfirst shell simalt sign silent sleep slast smagic smapclear smenu snext sniff snomagic snoremap snoremenu sort source spelldump spellgood spellinfo spellrepall spellundo spellwrong split sprevious srewind stop stag startgreplace startreplace startinsert stopinsert stjump stselect sunhide sunmap sunmenu suspend sview swapname syntax syntime syncbind tNext tabNext tabclose tabedit tabfind tabfirst tablast tabmove tabnext tabonly tabprevious tabrewind tag tcl tcldo tclfile tearoff tfirst throw tjump tlast tmenu tnext topleft tprevious trewind tselect tunmenu undo undojoin undolist unabbreviate unhide unlet unlockvar unmap unmenu unsilent update vglobal version verbose vertical vimgrep vimgrepadd visual viusage view vmap vmapclear vmenu vnew vnoremap vnoremenu vsplit vunmap vunmenu write wNext wall while winsize wincmd winpos wnext wprevious wqall wsverb wundo wviminfo xit xall xmapclear xmap xmenu xnoremap xnoremenu xunmap xunmenu yank",built_in:"synIDtrans atan2 range matcharg did_filetype asin feedkeys xor argv complete_check add getwinposx getqflist getwinposy screencol clearmatches empty extend getcmdpos mzeval garbagecollect setreg ceil sqrt diff_hlID inputsecret get getfperm getpid filewritable shiftwidth max sinh isdirectory synID system inputrestore winline atan visualmode inputlist tabpagewinnr round getregtype mapcheck hasmapto histdel argidx findfile sha256 exists toupper getcmdline taglist string getmatches bufnr strftime winwidth bufexists strtrans tabpagebuflist setcmdpos remote_read printf setloclist getpos getline bufwinnr float2nr len getcmdtype diff_filler luaeval resolve libcallnr foldclosedend reverse filter has_key bufname str2float strlen setline getcharmod setbufvar index searchpos shellescape undofile foldclosed setqflist buflisted strchars str2nr virtcol floor remove undotree remote_expr winheight gettabwinvar reltime cursor tabpagenr finddir localtime acos getloclist search tanh matchend rename gettabvar strdisplaywidth type abs py3eval setwinvar tolower wildmenumode log10 spellsuggest bufloaded synconcealed nextnonblank server2client complete settabwinvar executable input wincol setmatches getftype hlID inputsave searchpair or screenrow line settabvar histadd deepcopy strpart remote_peek and eval getftime submatch screenchar winsaveview matchadd mkdir screenattr getfontname libcall reltimestr getfsize winnr invert pow getbufline byte2line soundfold repeat fnameescape tagfiles sin strwidth spellbadword trunc maparg log lispindent hostname setpos globpath remote_foreground getchar synIDattr fnamemodify cscope_connection stridx winbufnr indent min complete_add nr2char searchpairpos inputdialog values matchlist items hlexists strridx browsedir expand fmod pathshorten line2byte argc count getwinvar glob foldtextresult getreg foreground cosh matchdelete has char2nr simplify histget searchdecl iconv winrestcmd pumvisible writefile foldlevel haslocaldir keys cos matchstr foldtext histnr tan tempname getcwd byteidx getbufvar islocked escape eventhandler remote_send serverlist winrestview synstack pyeval prevnonblank readfile cindent filereadable changenr exp"},illegal:/;/,contains:[e.NUMBER_MODE,e.APOS_STRING_MODE,{className:"string",begin:/"(\\"|\n\\|[^"\n])*"/},e.COMMENT('"',"$"),{className:"variable",begin:/[bwtglsav]:[\w\d_]*/},{className:"function",beginKeywords:"function function!",end:"$",relevance:0,contains:[e.TITLE_MODE,{className:"params",begin:"\\(",end:"\\)"}]},{className:"symbol",begin:/<[\w-]+>/}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,keywords:{keyword:"abs access after alias all and architecture array assert assume assume_guarantee attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",built_in:"boolean bit character integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_logic std_logic_vector unsigned signed boolean_vector integer_vector std_ulogic std_ulogic_vector unresolved_unsigned u_unsigned unresolved_signed u_signedreal_vector time_vector",literal:"false true note warning error failure line text side width"},illegal:"{",contains:[e.C_BLOCK_COMMENT_MODE,e.COMMENT("--","$"),e.QUOTE_STRING_MODE,{className:"number",begin:"\\b(\\d(_|\\d)*#\\w+(\\.\\w+)?#([eE][-+]?\\d(_|\\d)*)?|\\d(_|\\d)*(\\.\\d(_|\\d)*)?([eE][-+]?\\d(_|\\d)*)?)",relevance:0},{className:"string",begin:"'(U|X|0|1|Z|W|L|H|-)'",contains:[e.BACKSLASH_ESCAPE]},{className:"symbol",begin:"'[A-Za-z](_?[A-Za-z0-9])*",contains:[e.BACKSLASH_ESCAPE]}]}}},function(e,t){e.exports=function(e){return{aliases:["v","sv","svh"],case_insensitive:!1,keywords:{keyword:"accept_on alias always always_comb always_ff always_latch and assert assign assume automatic before begin bind bins binsof bit break buf|0 bufif0 bufif1 byte case casex casez cell chandle checker class clocking cmos config const constraint context continue cover covergroup coverpoint cross deassign default defparam design disable dist do edge else end endcase endchecker endclass endclocking endconfig endfunction endgenerate endgroup endinterface endmodule endpackage endprimitive endprogram endproperty endspecify endsequence endtable endtask enum event eventually expect export extends extern final first_match for force foreach forever fork forkjoin function generate|5 genvar global highz0 highz1 if iff ifnone ignore_bins illegal_bins implements implies import incdir include initial inout input inside instance int integer interconnect interface intersect join join_any join_none large let liblist library local localparam logic longint macromodule matches medium modport module nand negedge nettype new nexttime nmos nor noshowcancelled not notif0 notif1 or output package packed parameter pmos posedge primitive priority program property protected pull0 pull1 pulldown pullup pulsestyle_ondetect pulsestyle_onevent pure rand randc randcase randsequence rcmos real realtime ref reg reject_on release repeat restrict return rnmos rpmos rtran rtranif0 rtranif1 s_always s_eventually s_nexttime s_until s_until_with scalared sequence shortint shortreal showcancelled signed small soft solve specify specparam static string strong strong0 strong1 struct super supply0 supply1 sync_accept_on sync_reject_on table tagged task this throughout time timeprecision timeunit tran tranif0 tranif1 tri tri0 tri1 triand trior trireg type typedef union unique unique0 unsigned until until_with untyped use uwire var vectored virtual void wait wait_order wand weak weak0 weak1 while wildcard wire with within wor xnor xor",literal:"null",built_in:"$finish $stop $exit $fatal $error $warning $info $realtime $time $printtimescale $bitstoreal $bitstoshortreal $itor $signed $cast $bits $stime $timeformat $realtobits $shortrealtobits $rtoi $unsigned $asserton $assertkill $assertpasson $assertfailon $assertnonvacuouson $assertoff $assertcontrol $assertpassoff $assertfailoff $assertvacuousoff $isunbounded $sampled $fell $changed $past_gclk $fell_gclk $changed_gclk $rising_gclk $steady_gclk $coverage_control $coverage_get $coverage_save $set_coverage_db_name $rose $stable $past $rose_gclk $stable_gclk $future_gclk $falling_gclk $changing_gclk $display $coverage_get_max $coverage_merge $get_coverage $load_coverage_db $typename $unpacked_dimensions $left $low $increment $clog2 $ln $log10 $exp $sqrt $pow $floor $ceil $sin $cos $tan $countbits $onehot $isunknown $fatal $warning $dimensions $right $high $size $asin $acos $atan $atan2 $hypot $sinh $cosh $tanh $asinh $acosh $atanh $countones $onehot0 $error $info $random $dist_chi_square $dist_erlang $dist_exponential $dist_normal $dist_poisson $dist_t $dist_uniform $q_initialize $q_remove $q_exam $async$and$array $async$nand$array $async$or$array $async$nor$array $sync$and$array $sync$nand$array $sync$or$array $sync$nor$array $q_add $q_full $psprintf $async$and$plane $async$nand$plane $async$or$plane $async$nor$plane $sync$and$plane $sync$nand$plane $sync$or$plane $sync$nor$plane $system $display $displayb $displayh $displayo $strobe $strobeb $strobeh $strobeo $write $readmemb $readmemh $writememh $value$plusargs $dumpvars $dumpon $dumplimit $dumpports $dumpportson $dumpportslimit $writeb $writeh $writeo $monitor $monitorb $monitorh $monitoro $writememb $dumpfile $dumpoff $dumpall $dumpflush $dumpportsoff $dumpportsall $dumpportsflush $fclose $fdisplay $fdisplayb $fdisplayh $fdisplayo $fstrobe $fstrobeb $fstrobeh $fstrobeo $swrite $swriteb $swriteh $swriteo $fscanf $fread $fseek $fflush $feof $fopen $fwrite $fwriteb $fwriteh $fwriteo $fmonitor $fmonitorb $fmonitorh $fmonitoro $sformat $sformatf $fgetc $ungetc $fgets $sscanf $rewind $ftell $ferror"},lexemes:/[\w\$]+/,contains:[e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE,e.QUOTE_STRING_MODE,{className:"number",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"\\b((\\d+'(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)"},{begin:"\\B(('(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)"},{begin:"\\b([0-9_])+",relevance:0}]},{className:"variable",variants:[{begin:"#\\((?!parameter).+\\)"},{begin:"\\.\\w+",relevance:0}]},{className:"meta",begin:"`",end:"$",keywords:{"meta-keyword":"define __FILE__ __LINE__ begin_keywords celldefine default_nettype define else elsif end_keywords endcelldefine endif ifdef ifndef include line nounconnected_drive pragma resetall timescale unconnected_drive undef undefineall"},relevance:0}]}}},function(e,t){e.exports=function(e){return{subLanguage:"xml",contains:[{begin:"<%",end:"%>",subLanguage:"vbscript"}]}}},function(e,t){e.exports=function(e){return{aliases:["vbs"],case_insensitive:!0,keywords:{keyword:"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto",built_in:"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err",literal:"true false null nothing empty"},illegal:"//",contains:[e.inherit(e.QUOTE_STRING_MODE,{contains:[{begin:'""'}]}),e.COMMENT(/'/,/$/,{relevance:0}),e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{aliases:["vb"],case_insensitive:!0,keywords:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},illegal:"//|{|}|endif|gosub|variant|wend",contains:[e.inherit(e.QUOTE_STRING_MODE,{contains:[{begin:'""'}]}),e.COMMENT("'","$",{returnBegin:!0,contains:[{className:"doctag",begin:"'''|\x3c!--|--\x3e",contains:[e.PHRASAL_WORDS_MODE]},{className:"doctag",begin:"",contains:[e.PHRASAL_WORDS_MODE]}]}),e.C_NUMBER_MODE,{className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"if else elseif end region externalsource"}}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override virtual delegate if while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object Gtk Posix",literal:"false true null"},contains:[{className:"class",beginKeywords:"class interface namespace",end:"{",excludeEnd:!0,illegal:"[^,:\\n\\s\\.]",contains:[e.UNDERSCORE_TITLE_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"string",begin:'"""',end:'"""',relevance:5},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,{className:"meta",begin:"^#",end:"$",relevance:2}]}}},function(e,t){e.exports=function(e){var t={keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super static implements enum export import declare type namespace abstract as from extends async await",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void Promise"};return{aliases:["ts"],keywords:t,contains:[{className:"meta",begin:/^\s*['"]use strict['"]/},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE,{className:"subst",begin:"\\$\\{",end:"\\}"}]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"number",variants:[{begin:"\\b(0[bB][01]+)"},{begin:"\\b(0[oO][0-7]+)"},{begin:e.C_NUMBER_RE}],relevance:0},{begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.REGEXP_MODE,{className:"function",begin:"(\\(.*?\\)|"+e.IDENT_RE+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:e.IDENT_RE},{begin:/\(\s*\)/},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:["self",e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}]}]}],relevance:0},{className:"function",begin:"function",end:/[\{;]/,excludeEnd:!0,keywords:t,contains:["self",e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/}),{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],illegal:/["'\(]/}],illegal:/%/,relevance:0},{beginKeywords:"constructor",end:/\{/,excludeEnd:!0,contains:["self",{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],illegal:/["'\(]/}]},{begin:/module\./,keywords:{built_in:"module"},relevance:0},{beginKeywords:"module",end:/\{/,excludeEnd:!0},{beginKeywords:"interface",end:/\{/,excludeEnd:!0,keywords:"interface extends"},{begin:/\$[(.]/},{begin:"\\."+e.IDENT_RE,relevance:0},{className:"meta",begin:"@[A-Za-z]+"}]}}},function(e,t){e.exports=function(e){var t="attribute block constant cycle date dump include max min parent random range source template_from_string",n={beginKeywords:t,keywords:{name:t},relevance:0,contains:[{className:"params",begin:"\\(",end:"\\)"}]},r={begin:/\|[A-Za-z_]+:?/,keywords:"abs batch capitalize convert_encoding date date_modify default escape first format join json_encode keys last length lower merge nl2br number_format raw replace reverse round slice sort split striptags title trim upper url_encode",contains:[n]},i="autoescape block do embed extends filter flush for if import include macro sandbox set spaceless use verbatim";return i=i+" "+i.split(" ").map(function(e){return"end"+e}).join(" "),{aliases:["craftcms"],case_insensitive:!0,subLanguage:"xml",contains:[e.COMMENT(/\{#/,/#}/),{className:"template-tag",begin:/\{%/,end:/%}/,contains:[{className:"name",begin:/\w+/,keywords:i,starts:{endsWithParent:!0,contains:[r,n],relevance:0}}]},{className:"template-variable",begin:/\{\{/,end:/}}/,contains:["self",r,n]}]}}},function(e,t){e.exports=function(e){var t={className:"number",begin:"[1-9][0-9]*",relevance:0},n={className:"symbol",begin:":[^\\]]+"};return{keywords:{keyword:"ABORT ACC ADJUST AND AP_LD BREAK CALL CNT COL CONDITION CONFIG DA DB DIV DETECT ELSE END ENDFOR ERR_NUM ERROR_PROG FINE FOR GP GUARD INC IF JMP LINEAR_MAX_SPEED LOCK MOD MONITOR OFFSET Offset OR OVERRIDE PAUSE PREG PTH RT_LD RUN SELECT SKIP Skip TA TB TO TOOL_OFFSET Tool_Offset UF UT UFRAME_NUM UTOOL_NUM UNLOCK WAIT X Y Z W P R STRLEN SUBSTR FINDSTR VOFFSET PROG ATTR MN POS",literal:"ON OFF max_speed LPOS JPOS ENABLE DISABLE START STOP RESET"},contains:[{className:"built_in",begin:"(AR|P|PAYLOAD|PR|R|SR|RSR|LBL|VR|UALM|MESSAGE|UTOOL|UFRAME|TIMER| TIMER_OVERFLOW|JOINT_MAX_SPEED|RESUME_PROG|DIAG_REC)\\[",end:"\\]",contains:["self",t,n]},{className:"built_in",begin:"(AI|AO|DI|DO|F|RI|RO|UI|UO|GI|GO|SI|SO)\\[",end:"\\]",contains:["self",t,e.QUOTE_STRING_MODE,n]},{className:"keyword",begin:"/(PROG|ATTR|MN|POS|END)\\b"},{className:"keyword",begin:"(CALL|RUN|POINT_LOGIC|LBL)\\b"},{className:"keyword",begin:"\\b(ACC|CNT|Skip|Offset|PSPD|RT_LD|AP_LD|Tool_Offset)"},{className:"number",begin:"\\d+(sec|msec|mm/sec|cm/min|inch/min|deg/sec|mm|in|cm)?\\b",relevance:0},e.COMMENT("//","[;$]"),e.COMMENT("!","[;$]"),e.COMMENT("--eg:","$"),e.QUOTE_STRING_MODE,{className:"string",begin:"'",end:"'"},e.C_NUMBER_MODE,{className:"variable",begin:"\\$[A-Za-z0-9_]+"}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:"namespace const typedef struct enum service exception void oneway set list map required optional",built_in:"bool byte i16 i32 i64 double string binary",literal:"true false"},contains:[e.QUOTE_STRING_MODE,e.NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"class",beginKeywords:"struct enum service exception",end:/\{/,illegal:/\n/,contains:[e.inherit(e.TITLE_MODE,{starts:{endsWithParent:!0,excludeEnd:!0}})]},{begin:"\\b(set|list|map)\\s*<",end:">",keywords:"bool byte i16 i32 i64 double string binary",contains:["self"]}]}}},function(e,t){e.exports=function(e){var t={className:"tag",begin:/\\/,relevance:0,contains:[{className:"name",variants:[{begin:/[a-zA-Zа-яА-я]+[*]?/},{begin:/[^a-zA-Zа-яА-я0-9]/}],starts:{endsWithParent:!0,relevance:0,contains:[{className:"string",variants:[{begin:/\[/,end:/\]/},{begin:/\{/,end:/\}/}]},{begin:/\s*=\s*/,endsWithParent:!0,relevance:0,contains:[{className:"number",begin:/-?\d*\.?\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?/}]}]}}]};return{contains:[t,{className:"formula",contains:[t],relevance:0,variants:[{begin:/\$\$/,end:/\$\$/},{begin:/\$/,end:/\$/}]},e.COMMENT("%","$",{relevance:0})]}}},function(e,t){e.exports=function(e){return{aliases:["tk"],keywords:"after append apply array auto_execok auto_import auto_load auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror binary break catch cd chan clock close concat continue dde dict encoding eof error eval exec exit expr fblocked fconfigure fcopy file fileevent filename flush for foreach format gets glob global history http if incr info interp join lappend|10 lassign|10 lindex|10 linsert|10 list llength|10 load lrange|10 lrepeat|10 lreplace|10 lreverse|10 lsearch|10 lset|10 lsort|10 mathfunc mathop memory msgcat namespace open package parray pid pkg::create pkg_mkIndex platform platform::shell proc puts pwd read refchan regexp registry regsub|10 rename return safe scan seek set socket source split string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord tcl_wordBreakAfter tcl_wordBreakBefore tcltest tclvars tell time tm trace unknown unload unset update uplevel upvar variable vwait while",contains:[e.COMMENT(";[ \\t]*#","$"),e.COMMENT("^[ \\t]*#","$"),{beginKeywords:"proc",end:"[\\{]",excludeEnd:!0,contains:[{className:"title",begin:"[ \\t\\n\\r]+(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",end:"[ \\t\\n\\r]",endsWithParent:!0,excludeEnd:!0}]},{excludeEnd:!0,variants:[{begin:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\\(([a-zA-Z0-9_])*\\)",end:"[^a-zA-Z0-9_\\}\\$]"},{begin:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",end:"(\\))?[^a-zA-Z0-9_\\}\\$]"}]},{className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null})]},{className:"number",variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,contains:[e.HASH_COMMENT_MODE,{className:"meta",variants:[{begin:"^TAP version (\\d+)$"},{begin:"^1\\.\\.(\\d+)$"}]},{begin:"(s+)?---$",end:"\\.\\.\\.$",subLanguage:"yaml",relevance:0},{className:"number",begin:" (\\d+) "},{className:"symbol",variants:[{begin:"^ok"},{begin:"^not ok"}]}]}}},function(e,t){e.exports=function(e){var t="[a-zA-Z_][\\w\\-]*",n={className:"attr",variants:[{begin:"^[ \\-]*"+t+":"},{begin:'^[ \\-]*"'+t+'":'},{begin:"^[ \\-]*'"+t+"':"}]},r={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:"{{",end:"}}"},{begin:"%{",end:"}"}]}]};return{case_insensitive:!0,aliases:["yml","YAML","yaml"],contains:[n,{className:"meta",begin:"^---s*$",relevance:10},{className:"string",begin:"[\\|>] *$",returnEnd:!0,contains:r.contains,end:n.variants[0].begin},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!!"+e.UNDERSCORE_IDENT_RE},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"^ *-",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:"true false yes no null",keywords:{literal:"true false yes no null"}},e.C_NUMBER_MODE,r]}}},function(e,t){e.exports=function(e){return{contains:[{className:"comment",begin:/\$noop\(/,end:/\)/,contains:[{begin:/\(/,end:/\)/,contains:["self",{begin:/\\./}]}],relevance:10},{className:"keyword",begin:/\$(?!noop)[a-zA-Z][_a-zA-Z0-9]*/,end:/\(/,excludeEnd:!0},{className:"variable",begin:/%[_a-zA-Z0-9:]*/,end:"%"},{className:"symbol",begin:/\\./}]}}},function(e,t){e.exports=function(e){var t={keyword:"__COLUMN__ __FILE__ __FUNCTION__ __LINE__ as as! as? associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},n=e.COMMENT("/\\*","\\*/",{contains:["self"]}),r={className:"subst",begin:/\\\(/,end:"\\)",keywords:t,contains:[]},i={className:"number",begin:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",relevance:0},a=e.inherit(e.QUOTE_STRING_MODE,{contains:[r,e.BACKSLASH_ESCAPE]});return r.contains=[i],{keywords:t,contains:[a,e.C_LINE_COMMENT_MODE,n,{className:"type",begin:"\\b[A-Z][\\wÀ-ʸ']*",relevance:0},i,{className:"function",beginKeywords:"func",end:"{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/}),{begin://},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:t,contains:["self",i,a,e.C_BLOCK_COMMENT_MODE,{begin:":"}],illegal:/["']/}],illegal:/\[|%/},{className:"class",beginKeywords:"struct protocol class extension enum",keywords:t,end:"\\{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/})]},{className:"meta",begin:"(@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain)"},{beginKeywords:"import",end:/$/,contains:[e.C_LINE_COMMENT_MODE,n]}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,contains:[{className:"string",begin:"\\[\n(multipart)?",end:"\\]\n"},{className:"string",begin:"\\d{4}-\\d{2}-\\d{2}(\\s+)\\d{2}:\\d{2}:\\d{2}.\\d+Z"},{className:"string",begin:"(\\+|-)\\d+"},{className:"keyword",relevance:10,variants:[{begin:"^(test|testing|success|successful|failure|error|skip|xfail|uxsuccess)(:?)\\s+(test)?"},{begin:"^progress(:?)(\\s+)?(pop|push)?"},{begin:"^tags:"},{begin:"^time:"}]}]}}},function(e,t){e.exports=function(e){var t={className:"variable",begin:"\\$"+e.IDENT_RE},n={className:"number",begin:"#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})"},r="[\\.\\s\\n\\[\\:,]";return{aliases:["styl"],case_insensitive:!1,keywords:"if else for in",illegal:"("+["\\?","(\\bReturn\\b)","(\\bEnd\\b)","(\\bend\\b)","(\\bdef\\b)",";","#\\s","\\*\\s","===\\s","\\|","%"].join("|")+")",contains:[e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,{begin:"\\.[a-zA-Z][a-zA-Z0-9_-]*"+r,returnBegin:!0,contains:[{className:"selector-class",begin:"\\.[a-zA-Z][a-zA-Z0-9_-]*"}]},{begin:"\\#[a-zA-Z][a-zA-Z0-9_-]*"+r,returnBegin:!0,contains:[{className:"selector-id",begin:"\\#[a-zA-Z][a-zA-Z0-9_-]*"}]},{begin:"\\b("+["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"].join("|")+")"+r,returnBegin:!0,contains:[{className:"selector-tag",begin:"\\b[a-zA-Z][a-zA-Z0-9_-]*"}]},{begin:"&?:?:\\b("+["after","before","first-letter","first-line","active","first-child","focus","hover","lang","link","visited"].join("|")+")"+r},{begin:"@("+["charset","css","debug","extend","font-face","for","import","include","media","mixin","page","warn","while"].join("|")+")\\b"},t,e.CSS_NUMBER_MODE,e.NUMBER_MODE,{className:"function",begin:"^[a-zA-Z][a-zA-Z0-9_-]*\\(.*\\)",illegal:"[\\n]",returnBegin:!0,contains:[{className:"title",begin:"\\b[a-zA-Z][a-zA-Z0-9_-]*"},{className:"params",begin:/\(/,end:/\)/,contains:[n,t,e.APOS_STRING_MODE,e.CSS_NUMBER_MODE,e.NUMBER_MODE,e.QUOTE_STRING_MODE]}]},{className:"attribute",begin:"\\b("+["align-content","align-items","align-self","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","auto","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","clip-path","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","font","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-variant-ligatures","font-weight","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inherit","initial","justify-content","left","letter-spacing","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marks","mask","max-height","max-width","min-height","min-width","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","perspective","perspective-origin","pointer-events","position","quotes","resize","right","tab-size","table-layout","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-indent","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","white-space","widows","width","word-break","word-spacing","word-wrap","z-index"].reverse().join("|")+")\\b",starts:{end:/;|$/,contains:[n,t,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE,e.NUMBER_MODE,e.C_BLOCK_COMMENT_MODE],illegal:/\./,relevance:0}}]}}},function(e,t){e.exports=function(e){return{aliases:["p21","step","stp"],case_insensitive:!0,lexemes:"[A-Z_][A-Z0-9_.]*",keywords:{keyword:"HEADER ENDSEC DATA"},contains:[{className:"meta",begin:"ISO-10303-21;",relevance:10},{className:"meta",begin:"END-ISO-10303-21;",relevance:10},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.COMMENT("/\\*\\*!","\\*/"),e.C_NUMBER_MODE,e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),{className:"string",begin:"'",end:"'"},{className:"symbol",variants:[{begin:"#",end:"\\d+",illegal:"\\W"}]}]}}},function(e,t){e.exports=function(e){return{aliases:["do","ado"],case_insensitive:!0,keywords:"if else in foreach for forv forva forval forvalu forvalue forvalues by bys bysort xi quietly qui capture about ac ac_7 acprplot acprplot_7 adjust ado adopath adoupdate alpha ameans an ano anov anova anova_estat anova_terms anovadef aorder ap app appe appen append arch arch_dr arch_estat arch_p archlm areg areg_p args arima arima_dr arima_estat arima_p as asmprobit asmprobit_estat asmprobit_lf asmprobit_mfx__dlg asmprobit_p ass asse asser assert avplot avplot_7 avplots avplots_7 bcskew0 bgodfrey binreg bip0_lf biplot bipp_lf bipr_lf bipr_p biprobit bitest bitesti bitowt blogit bmemsize boot bootsamp bootstrap bootstrap_8 boxco_l boxco_p boxcox boxcox_6 boxcox_p bprobit br break brier bro brow brows browse brr brrstat bs bs_7 bsampl_w bsample bsample_7 bsqreg bstat bstat_7 bstat_8 bstrap bstrap_7 ca ca_estat ca_p cabiplot camat canon canon_8 canon_8_p canon_estat canon_p cap caprojection capt captu captur capture cat cc cchart cchart_7 cci cd censobs_table centile cf char chdir checkdlgfiles checkestimationsample checkhlpfiles checksum chelp ci cii cl class classutil clear cli clis clist clo clog clog_lf clog_p clogi clogi_sw clogit clogit_lf clogit_p clogitp clogl_sw cloglog clonevar clslistarray cluster cluster_measures cluster_stop cluster_tree cluster_tree_8 clustermat cmdlog cnr cnre cnreg cnreg_p cnreg_sw cnsreg codebook collaps4 collapse colormult_nb colormult_nw compare compress conf confi confir confirm conren cons const constr constra constrai constrain constraint continue contract copy copyright copysource cor corc corr corr2data corr_anti corr_kmo corr_smc corre correl correla correlat correlate corrgram cou coun count cox cox_p cox_sw coxbase coxhaz coxvar cprplot cprplot_7 crc cret cretu cretur creturn cross cs cscript cscript_log csi ct ct_is ctset ctst_5 ctst_st cttost cumsp cumsp_7 cumul cusum cusum_7 cutil d|0 datasig datasign datasigna datasignat datasignatu datasignatur datasignature datetof db dbeta de dec deco decod decode deff des desc descr descri describ describe destring dfbeta dfgls dfuller di di_g dir dirstats dis discard disp disp_res disp_s displ displa display distinct do doe doed doedi doedit dotplot dotplot_7 dprobit drawnorm drop ds ds_util dstdize duplicates durbina dwstat dydx e|0 ed edi edit egen eivreg emdef en enc enco encod encode eq erase ereg ereg_lf ereg_p ereg_sw ereghet ereghet_glf ereghet_glf_sh ereghet_gp ereghet_ilf ereghet_ilf_sh ereghet_ip eret eretu eretur ereturn err erro error est est_cfexist est_cfname est_clickable est_expand est_hold est_table est_unhold est_unholdok estat estat_default estat_summ estat_vce_only esti estimates etodow etof etomdy ex exi exit expand expandcl fac fact facto factor factor_estat factor_p factor_pca_rotated factor_rotate factormat fcast fcast_compute fcast_graph fdades fdadesc fdadescr fdadescri fdadescrib fdadescribe fdasav fdasave fdause fh_st file open file read file close file filefilter fillin find_hlp_file findfile findit findit_7 fit fl fli flis flist for5_0 form forma format fpredict frac_154 frac_adj frac_chk frac_cox frac_ddp frac_dis frac_dv frac_in frac_mun frac_pp frac_pq frac_pv frac_wgt frac_xo fracgen fracplot fracplot_7 fracpoly fracpred fron_ex fron_hn fron_p fron_tn fron_tn2 frontier ftodate ftoe ftomdy ftowdate g|0 gamhet_glf gamhet_gp gamhet_ilf gamhet_ip gamma gamma_d2 gamma_p gamma_sw gammahet gdi_hexagon gdi_spokes ge gen gene gener genera generat generate genrank genstd genvmean gettoken gl gladder gladder_7 glim_l01 glim_l02 glim_l03 glim_l04 glim_l05 glim_l06 glim_l07 glim_l08 glim_l09 glim_l10 glim_l11 glim_l12 glim_lf glim_mu glim_nw1 glim_nw2 glim_nw3 glim_p glim_v1 glim_v2 glim_v3 glim_v4 glim_v5 glim_v6 glim_v7 glm glm_6 glm_p glm_sw glmpred glo glob globa global glogit glogit_8 glogit_p gmeans gnbre_lf gnbreg gnbreg_5 gnbreg_p gomp_lf gompe_sw gomper_p gompertz gompertzhet gomphet_glf gomphet_glf_sh gomphet_gp gomphet_ilf gomphet_ilf_sh gomphet_ip gphdot gphpen gphprint gprefs gprobi_p gprobit gprobit_8 gr gr7 gr_copy gr_current gr_db gr_describe gr_dir gr_draw gr_draw_replay gr_drop gr_edit gr_editviewopts gr_example gr_example2 gr_export gr_print gr_qscheme gr_query gr_read gr_rename gr_replay gr_save gr_set gr_setscheme gr_table gr_undo gr_use graph graph7 grebar greigen greigen_7 greigen_8 grmeanby grmeanby_7 gs_fileinfo gs_filetype gs_graphinfo gs_stat gsort gwood h|0 hadimvo hareg hausman haver he heck_d2 heckma_p heckman heckp_lf heckpr_p heckprob hel help hereg hetpr_lf hetpr_p hetprob hettest hexdump hilite hist hist_7 histogram hlogit hlu hmeans hotel hotelling hprobit hreg hsearch icd9 icd9_ff icd9p iis impute imtest inbase include inf infi infil infile infix inp inpu input ins insheet insp inspe inspec inspect integ inten intreg intreg_7 intreg_p intrg2_ll intrg_ll intrg_ll2 ipolate iqreg ir irf irf_create irfm iri is_svy is_svysum isid istdize ivprob_1_lf ivprob_lf ivprobit ivprobit_p ivreg ivreg_footnote ivtob_1_lf ivtob_lf ivtobit ivtobit_p jackknife jacknife jknife jknife_6 jknife_8 jkstat joinby kalarma1 kap kap_3 kapmeier kappa kapwgt kdensity kdensity_7 keep ksm ksmirnov ktau kwallis l|0 la lab labe label labelbook ladder levels levelsof leverage lfit lfit_p li lincom line linktest lis list lloghet_glf lloghet_glf_sh lloghet_gp lloghet_ilf lloghet_ilf_sh lloghet_ip llogi_sw llogis_p llogist llogistic llogistichet lnorm_lf lnorm_sw lnorma_p lnormal lnormalhet lnormhet_glf lnormhet_glf_sh lnormhet_gp lnormhet_ilf lnormhet_ilf_sh lnormhet_ip lnskew0 loadingplot loc loca local log logi logis_lf logistic logistic_p logit logit_estat logit_p loglogs logrank loneway lookfor lookup lowess lowess_7 lpredict lrecomp lroc lroc_7 lrtest ls lsens lsens_7 lsens_x lstat ltable ltable_7 ltriang lv lvr2plot lvr2plot_7 m|0 ma mac macr macro makecns man manova manova_estat manova_p manovatest mantel mark markin markout marksample mat mat_capp mat_order mat_put_rr mat_rapp mata mata_clear mata_describe mata_drop mata_matdescribe mata_matsave mata_matuse mata_memory mata_mlib mata_mosave mata_rename mata_which matalabel matcproc matlist matname matr matri matrix matrix_input__dlg matstrik mcc mcci md0_ md1_ md1debug_ md2_ md2debug_ mds mds_estat mds_p mdsconfig mdslong mdsmat mdsshepard mdytoe mdytof me_derd mean means median memory memsize meqparse mer merg merge mfp mfx mhelp mhodds minbound mixed_ll mixed_ll_reparm mkassert mkdir mkmat mkspline ml ml_5 ml_adjs ml_bhhhs ml_c_d ml_check ml_clear ml_cnt ml_debug ml_defd ml_e0 ml_e0_bfgs ml_e0_cycle ml_e0_dfp ml_e0i ml_e1 ml_e1_bfgs ml_e1_bhhh ml_e1_cycle ml_e1_dfp ml_e2 ml_e2_cycle ml_ebfg0 ml_ebfr0 ml_ebfr1 ml_ebh0q ml_ebhh0 ml_ebhr0 ml_ebr0i ml_ecr0i ml_edfp0 ml_edfr0 ml_edfr1 ml_edr0i ml_eds ml_eer0i ml_egr0i ml_elf ml_elf_bfgs ml_elf_bhhh ml_elf_cycle ml_elf_dfp ml_elfi ml_elfs ml_enr0i ml_enrr0 ml_erdu0 ml_erdu0_bfgs ml_erdu0_bhhh ml_erdu0_bhhhq ml_erdu0_cycle ml_erdu0_dfp ml_erdu0_nrbfgs ml_exde ml_footnote ml_geqnr ml_grad0 ml_graph ml_hbhhh ml_hd0 ml_hold ml_init ml_inv ml_log ml_max ml_mlout ml_mlout_8 ml_model ml_nb0 ml_opt ml_p ml_plot ml_query ml_rdgrd ml_repor ml_s_e ml_score ml_searc ml_technique ml_unhold mleval mlf_ mlmatbysum mlmatsum mlog mlogi mlogit mlogit_footnote mlogit_p mlopts mlsum mlvecsum mnl0_ mor more mov move mprobit mprobit_lf mprobit_p mrdu0_ mrdu1_ mvdecode mvencode mvreg mvreg_estat n|0 nbreg nbreg_al nbreg_lf nbreg_p nbreg_sw nestreg net newey newey_7 newey_p news nl nl_7 nl_9 nl_9_p nl_p nl_p_7 nlcom nlcom_p nlexp2 nlexp2_7 nlexp2a nlexp2a_7 nlexp3 nlexp3_7 nlgom3 nlgom3_7 nlgom4 nlgom4_7 nlinit nllog3 nllog3_7 nllog4 nllog4_7 nlog_rd nlogit nlogit_p nlogitgen nlogittree nlpred no nobreak noi nois noisi noisil noisily note notes notes_dlg nptrend numlabel numlist odbc old_ver olo olog ologi ologi_sw ologit ologit_p ologitp on one onew onewa oneway op_colnm op_comp op_diff op_inv op_str opr opro oprob oprob_sw oprobi oprobi_p oprobit oprobitp opts_exclusive order orthog orthpoly ou out outf outfi outfil outfile outs outsh outshe outshee outsheet ovtest pac pac_7 palette parse parse_dissim pause pca pca_8 pca_display pca_estat pca_p pca_rotate pcamat pchart pchart_7 pchi pchi_7 pcorr pctile pentium pergram pergram_7 permute permute_8 personal peto_st pkcollapse pkcross pkequiv pkexamine pkexamine_7 pkshape pksumm pksumm_7 pl plo plot plugin pnorm pnorm_7 poisgof poiss_lf poiss_sw poisso_p poisson poisson_estat post postclose postfile postutil pperron pr prais prais_e prais_e2 prais_p predict predictnl preserve print pro prob probi probit probit_estat probit_p proc_time procoverlay procrustes procrustes_estat procrustes_p profiler prog progr progra program prop proportion prtest prtesti pwcorr pwd q\\s qby qbys qchi qchi_7 qladder qladder_7 qnorm qnorm_7 qqplot qqplot_7 qreg qreg_c qreg_p qreg_sw qu quadchk quantile quantile_7 que quer query range ranksum ratio rchart rchart_7 rcof recast reclink recode reg reg3 reg3_p regdw regr regre regre_p2 regres regres_p regress regress_estat regriv_p remap ren rena renam rename renpfix repeat replace report reshape restore ret retu retur return rm rmdir robvar roccomp roccomp_7 roccomp_8 rocf_lf rocfit rocfit_8 rocgold rocplot rocplot_7 roctab roctab_7 rolling rologit rologit_p rot rota rotat rotate rotatemat rreg rreg_p ru run runtest rvfplot rvfplot_7 rvpplot rvpplot_7 sa safesum sample sampsi sav save savedresults saveold sc sca scal scala scalar scatter scm_mine sco scob_lf scob_p scobi_sw scobit scor score scoreplot scoreplot_help scree screeplot screeplot_help sdtest sdtesti se search separate seperate serrbar serrbar_7 serset set set_defaults sfrancia sh she shel shell shewhart shewhart_7 signestimationsample signrank signtest simul simul_7 simulate simulate_8 sktest sleep slogit slogit_d2 slogit_p smooth snapspan so sor sort spearman spikeplot spikeplot_7 spikeplt spline_x split sqreg sqreg_p sret sretu sretur sreturn ssc st st_ct st_hc st_hcd st_hcd_sh st_is st_issys st_note st_promo st_set st_show st_smpl st_subid stack statsby statsby_8 stbase stci stci_7 stcox stcox_estat stcox_fr stcox_fr_ll stcox_p stcox_sw stcoxkm stcoxkm_7 stcstat stcurv stcurve stcurve_7 stdes stem stepwise stereg stfill stgen stir stjoin stmc stmh stphplot stphplot_7 stphtest stphtest_7 stptime strate strate_7 streg streg_sw streset sts sts_7 stset stsplit stsum sttocc sttoct stvary stweib su suest suest_8 sum summ summa summar summari summariz summarize sunflower sureg survcurv survsum svar svar_p svmat svy svy_disp svy_dreg svy_est svy_est_7 svy_estat svy_get svy_gnbreg_p svy_head svy_header svy_heckman_p svy_heckprob_p svy_intreg_p svy_ivreg_p svy_logistic_p svy_logit_p svy_mlogit_p svy_nbreg_p svy_ologit_p svy_oprobit_p svy_poisson_p svy_probit_p svy_regress_p svy_sub svy_sub_7 svy_x svy_x_7 svy_x_p svydes svydes_8 svygen svygnbreg svyheckman svyheckprob svyintreg svyintreg_7 svyintrg svyivreg svylc svylog_p svylogit svymarkout svymarkout_8 svymean svymlog svymlogit svynbreg svyolog svyologit svyoprob svyoprobit svyopts svypois svypois_7 svypoisson svyprobit svyprobt svyprop svyprop_7 svyratio svyreg svyreg_p svyregress svyset svyset_7 svyset_8 svytab svytab_7 svytest svytotal sw sw_8 swcnreg swcox swereg swilk swlogis swlogit swologit swoprbt swpois swprobit swqreg swtobit swweib symmetry symmi symplot symplot_7 syntax sysdescribe sysdir sysuse szroeter ta tab tab1 tab2 tab_or tabd tabdi tabdis tabdisp tabi table tabodds tabodds_7 tabstat tabu tabul tabula tabulat tabulate te tempfile tempname tempvar tes test testnl testparm teststd tetrachoric time_it timer tis tob tobi tobit tobit_p tobit_sw token tokeni tokeniz tokenize tostring total translate translator transmap treat_ll treatr_p treatreg trim trnb_cons trnb_mean trpoiss_d2 trunc_ll truncr_p truncreg tsappend tset tsfill tsline tsline_ex tsreport tsrevar tsrline tsset tssmooth tsunab ttest ttesti tut_chk tut_wait tutorial tw tware_st two twoway twoway__fpfit_serset twoway__function_gen twoway__histogram_gen twoway__ipoint_serset twoway__ipoints_serset twoway__kdensity_gen twoway__lfit_serset twoway__normgen_gen twoway__pci_serset twoway__qfit_serset twoway__scatteri_serset twoway__sunflower_gen twoway_ksm_serset ty typ type typeof u|0 unab unabbrev unabcmd update us use uselabel var var_mkcompanion var_p varbasic varfcast vargranger varirf varirf_add varirf_cgraph varirf_create varirf_ctable varirf_describe varirf_dir varirf_drop varirf_erase varirf_graph varirf_ograph varirf_rename varirf_set varirf_table varlist varlmar varnorm varsoc varstable varstable_w varstable_w2 varwle vce vec vec_fevd vec_mkphi vec_p vec_p_w vecirf_create veclmar veclmar_w vecnorm vecnorm_w vecrank vecstable verinst vers versi versio version view viewsource vif vwls wdatetof webdescribe webseek webuse weib1_lf weib2_lf weib_lf weib_lf0 weibhet_glf weibhet_glf_sh weibhet_glfa weibhet_glfa_sh weibhet_gp weibhet_ilf weibhet_ilf_sh weibhet_ilfa weibhet_ilfa_sh weibhet_ip weibu_sw weibul_p weibull weibull_c weibull_s weibullhet wh whelp whi which whil while wilc_st wilcoxon win wind windo window winexec wntestb wntestb_7 wntestq xchart xchart_7 xcorr xcorr_7 xi xi_6 xmlsav xmlsave xmluse xpose xsh xshe xshel xshell xt_iis xt_tis xtab_p xtabond xtbin_p xtclog xtcloglog xtcloglog_8 xtcloglog_d2 xtcloglog_pa_p xtcloglog_re_p xtcnt_p xtcorr xtdata xtdes xtfront_p xtfrontier xtgee xtgee_elink xtgee_estat xtgee_makeivar xtgee_p xtgee_plink xtgls xtgls_p xthaus xthausman xtht_p xthtaylor xtile xtint_p xtintreg xtintreg_8 xtintreg_d2 xtintreg_p xtivp_1 xtivp_2 xtivreg xtline xtline_ex xtlogit xtlogit_8 xtlogit_d2 xtlogit_fe_p xtlogit_pa_p xtlogit_re_p xtmixed xtmixed_estat xtmixed_p xtnb_fe xtnb_lf xtnbreg xtnbreg_pa_p xtnbreg_refe_p xtpcse xtpcse_p xtpois xtpoisson xtpoisson_d2 xtpoisson_pa_p xtpoisson_refe_p xtpred xtprobit xtprobit_8 xtprobit_d2 xtprobit_re_p xtps_fe xtps_lf xtps_ren xtps_ren_8 xtrar_p xtrc xtrc_p xtrchh xtrefe_p xtreg xtreg_be xtreg_fe xtreg_ml xtreg_pa_p xtreg_re xtregar xtrere_p xtset xtsf_ll xtsf_llti xtsum xttab xttest0 xttobit xttobit_8 xttobit_p xttrans yx yxview__barlike_draw yxview_area_draw yxview_bar_draw yxview_dot_draw yxview_dropline_draw yxview_function_draw yxview_iarrow_draw yxview_ilabels_draw yxview_normal_draw yxview_pcarrow_draw yxview_pcbarrow_draw yxview_pccapsym_draw yxview_pcscatter_draw yxview_pcspike_draw yxview_rarea_draw yxview_rbar_draw yxview_rbarm_draw yxview_rcap_draw yxview_rcapsym_draw yxview_rconnected_draw yxview_rline_draw yxview_rscatter_draw yxview_rspike_draw yxview_spike_draw yxview_sunflower_draw zap_s zinb zinb_llf zinb_plf zip zip_llf zip_p zip_plf zt_ct_5 zt_hc_5 zt_hcd_5 zt_is_5 zt_iss_5 zt_sho_5 zt_smp_5 ztbase_5 ztcox_5 ztdes_5 ztereg_5 ztfill_5 ztgen_5 ztir_5 ztjoin_5 ztnb ztnb_p ztp ztp_p zts_5 ztset_5 ztspli_5 ztsum_5 zttoct_5 ztvary_5 ztweib_5",contains:[{className:"symbol",begin:/`[a-zA-Z0-9_]+'/},{className:"variable",begin:/\$\{?[a-zA-Z0-9_]+\}?/},{className:"string",variants:[{begin:'`"[^\r\n]*?"\''},{begin:'"[^\r\n"]*"'}]},{className:"built_in",variants:[{begin:"\\b(abs|acos|asin|atan|atan2|atanh|ceil|cloglog|comb|cos|digamma|exp|floor|invcloglog|invlogit|ln|lnfact|lnfactorial|lngamma|log|log10|max|min|mod|reldif|round|sign|sin|sqrt|sum|tan|tanh|trigamma|trunc|betaden|Binomial|binorm|binormal|chi2|chi2tail|dgammapda|dgammapdada|dgammapdadx|dgammapdx|dgammapdxdx|F|Fden|Ftail|gammaden|gammap|ibeta|invbinomial|invchi2|invchi2tail|invF|invFtail|invgammap|invibeta|invnchi2|invnFtail|invnibeta|invnorm|invnormal|invttail|nbetaden|nchi2|nFden|nFtail|nibeta|norm|normal|normalden|normd|npnchi2|tden|ttail|uniform|abbrev|char|index|indexnot|length|lower|ltrim|match|plural|proper|real|regexm|regexr|regexs|reverse|rtrim|string|strlen|strlower|strltrim|strmatch|strofreal|strpos|strproper|strreverse|strrtrim|strtrim|strupper|subinstr|subinword|substr|trim|upper|word|wordcount|_caller|autocode|byteorder|chop|clip|cond|e|epsdouble|epsfloat|group|inlist|inrange|irecode|matrix|maxbyte|maxdouble|maxfloat|maxint|maxlong|mi|minbyte|mindouble|minfloat|minint|minlong|missing|r|recode|replay|return|s|scalar|d|date|day|dow|doy|halfyear|mdy|month|quarter|week|year|d|daily|dofd|dofh|dofm|dofq|dofw|dofy|h|halfyearly|hofd|m|mofd|monthly|q|qofd|quarterly|tin|twithin|w|weekly|wofd|y|yearly|yh|ym|yofd|yq|yw|cholesky|colnumb|colsof|corr|det|diag|diag0cnt|el|get|hadamard|I|inv|invsym|issym|issymmetric|J|matmissing|matuniform|mreldif|nullmat|rownumb|rowsof|sweep|syminv|trace|vec|vecdiag)(?=\\(|$)"}]},e.COMMENT("^[ \t]*\\*.*$",!1),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}}},function(e,t){e.exports=function(e){return{contains:[e.HASH_COMMENT_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:e.UNDERSCORE_IDENT_RE,lexemes:e.UNDERSCORE_IDENT_RE,keywords:{name:"for in while repeat until if then else",symbol:"bernoulli bernoulli_logit binomial binomial_logit beta_binomial hypergeometric categorical categorical_logit ordered_logistic neg_binomial neg_binomial_2 neg_binomial_2_log poisson poisson_log multinomial normal exp_mod_normal skew_normal student_t cauchy double_exponential logistic gumbel lognormal chi_square inv_chi_square scaled_inv_chi_square exponential inv_gamma weibull frechet rayleigh wiener pareto pareto_type_2 von_mises uniform multi_normal multi_normal_prec multi_normal_cholesky multi_gp multi_gp_cholesky multi_student_t gaussian_dlm_obs dirichlet lkj_corr lkj_corr_cholesky wishart inv_wishart","selector-tag":"int real vector simplex unit_vector ordered positive_ordered row_vector matrix cholesky_factor_corr cholesky_factor_cov corr_matrix cov_matrix",title:"functions model data parameters quantities transformed generated",literal:"true false"},relevance:0},{className:"number",begin:"0[xX][0-9a-fA-F]+[Li]?\\b",relevance:0},{className:"number",begin:"0[xX][0-9a-fA-F]+[Li]?\\b",relevance:0},{className:"number",begin:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",relevance:0},{className:"number",begin:"\\d+\\.(?!\\d)(?:i\\b)?",relevance:0},{className:"number",begin:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0},{className:"number",begin:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0}]}}},function(e,t){e.exports=function(e){var t=e.COMMENT("--","$");return{case_insensitive:!0,illegal:/[<>{}*#]/,contains:[{beginKeywords:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment",end:/;/,endsWithParent:!0,lexemes:/[\w\.]+/,keywords:{keyword:"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void"},contains:[{className:"string",begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE,{begin:"''"}]},{className:"string",begin:'"',end:'"',contains:[e.BACKSLASH_ESCAPE,{begin:'""'}]},{className:"string",begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t]},e.C_BLOCK_COMMENT_MODE,t]}}},function(e,t){e.exports=function(e){var t=e.getLanguage("cpp").exports;return{aliases:["sqf"],case_insensitive:!0,keywords:{keyword:"case catch default do else exit exitWith for forEach from if switch then throw to try waitUntil while with",built_in:"abs accTime acos action actionIDs actionKeys actionKeysImages actionKeysNames actionKeysNamesArray actionName actionParams activateAddons activatedAddons activateKey add3DENConnection add3DENEventHandler add3DENLayer addAction addBackpack addBackpackCargo addBackpackCargoGlobal addBackpackGlobal addCamShake addCuratorAddons addCuratorCameraArea addCuratorEditableObjects addCuratorEditingArea addCuratorPoints addEditorObject addEventHandler addGoggles addGroupIcon addHandgunItem addHeadgear addItem addItemCargo addItemCargoGlobal addItemPool addItemToBackpack addItemToUniform addItemToVest addLiveStats addMagazine addMagazineAmmoCargo addMagazineCargo addMagazineCargoGlobal addMagazineGlobal addMagazinePool addMagazines addMagazineTurret addMenu addMenuItem addMissionEventHandler addMPEventHandler addMusicEventHandler addOwnedMine addPlayerScores addPrimaryWeaponItem addPublicVariableEventHandler addRating addResources addScore addScoreSide addSecondaryWeaponItem addSwitchableUnit addTeamMember addToRemainsCollector addUniform addVehicle addVest addWaypoint addWeapon addWeaponCargo addWeaponCargoGlobal addWeaponGlobal addWeaponItem addWeaponPool addWeaponTurret agent agents AGLToASL aimedAtTarget aimPos airDensityRTD airportSide AISFinishHeal alive all3DENEntities allControls allCurators allCutLayers allDead allDeadMen allDisplays allGroups allMapMarkers allMines allMissionObjects allow3DMode allowCrewInImmobile allowCuratorLogicIgnoreAreas allowDamage allowDammage allowFileOperations allowFleeing allowGetIn allowSprint allPlayers allSites allTurrets allUnits allUnitsUAV allVariables ammo and animate animateDoor animateSource animationNames animationPhase animationSourcePhase animationState append apply armoryPoints arrayIntersect asin ASLToAGL ASLToATL assert assignAsCargo assignAsCargoIndex assignAsCommander assignAsDriver assignAsGunner assignAsTurret assignCurator assignedCargo assignedCommander assignedDriver assignedGunner assignedItems assignedTarget assignedTeam assignedVehicle assignedVehicleRole assignItem assignTeam assignToAirport atan atan2 atg ATLToASL attachedObject attachedObjects attachedTo attachObject attachTo attackEnabled backpack backpackCargo backpackContainer backpackItems backpackMagazines backpackSpaceFor behaviour benchmark binocular blufor boundingBox boundingBoxReal boundingCenter breakOut breakTo briefingName buildingExit buildingPos buttonAction buttonSetAction cadetMode call callExtension camCommand camCommit camCommitPrepared camCommitted camConstuctionSetParams camCreate camDestroy cameraEffect cameraEffectEnableHUD cameraInterest cameraOn cameraView campaignConfigFile camPreload camPreloaded camPrepareBank camPrepareDir camPrepareDive camPrepareFocus camPrepareFov camPrepareFovRange camPreparePos camPrepareRelPos camPrepareTarget camSetBank camSetDir camSetDive camSetFocus camSetFov camSetFovRange camSetPos camSetRelPos camSetTarget camTarget camUseNVG canAdd canAddItemToBackpack canAddItemToUniform canAddItemToVest cancelSimpleTaskDestination canFire canMove canSlingLoad canStand canSuspend canUnloadInCombat canVehicleCargo captive captiveNum cbChecked cbSetChecked ceil channelEnabled cheatsEnabled checkAIFeature checkVisibility civilian className clearAllItemsFromBackpack clearBackpackCargo clearBackpackCargoGlobal clearGroupIcons clearItemCargo clearItemCargoGlobal clearItemPool clearMagazineCargo clearMagazineCargoGlobal clearMagazinePool clearOverlay clearRadio clearWeaponCargo clearWeaponCargoGlobal clearWeaponPool clientOwner closeDialog closeDisplay closeOverlay collapseObjectTree collect3DENHistory combatMode commandArtilleryFire commandChat commander commandFire commandFollow commandFSM commandGetOut commandingMenu commandMove commandRadio commandStop commandSuppressiveFire commandTarget commandWatch comment commitOverlay compile compileFinal completedFSM composeText configClasses configFile configHierarchy configName configNull configProperties configSourceAddonList configSourceMod configSourceModList connectTerminalToUAV controlNull controlsGroupCtrl copyFromClipboard copyToClipboard copyWaypoints cos count countEnemy countFriendly countSide countType countUnknown create3DENComposition create3DENEntity createAgent createCenter createDialog createDiaryLink createDiaryRecord createDiarySubject createDisplay createGearDialog createGroup createGuardedPoint createLocation createMarker createMarkerLocal createMenu createMine createMissionDisplay createMPCampaignDisplay createSimpleObject createSimpleTask createSite createSoundSource createTask createTeam createTrigger createUnit createVehicle createVehicleCrew createVehicleLocal crew ctrlActivate ctrlAddEventHandler ctrlAngle ctrlAutoScrollDelay ctrlAutoScrollRewind ctrlAutoScrollSpeed ctrlChecked ctrlClassName ctrlCommit ctrlCommitted ctrlCreate ctrlDelete ctrlEnable ctrlEnabled ctrlFade ctrlHTMLLoaded ctrlIDC ctrlIDD ctrlMapAnimAdd ctrlMapAnimClear ctrlMapAnimCommit ctrlMapAnimDone ctrlMapCursor ctrlMapMouseOver ctrlMapScale ctrlMapScreenToWorld ctrlMapWorldToScreen ctrlModel ctrlModelDirAndUp ctrlModelScale ctrlParent ctrlParentControlsGroup ctrlPosition ctrlRemoveAllEventHandlers ctrlRemoveEventHandler ctrlScale ctrlSetActiveColor ctrlSetAngle ctrlSetAutoScrollDelay ctrlSetAutoScrollRewind ctrlSetAutoScrollSpeed ctrlSetBackgroundColor ctrlSetChecked ctrlSetEventHandler ctrlSetFade ctrlSetFocus ctrlSetFont ctrlSetFontH1 ctrlSetFontH1B ctrlSetFontH2 ctrlSetFontH2B ctrlSetFontH3 ctrlSetFontH3B ctrlSetFontH4 ctrlSetFontH4B ctrlSetFontH5 ctrlSetFontH5B ctrlSetFontH6 ctrlSetFontH6B ctrlSetFontHeight ctrlSetFontHeightH1 ctrlSetFontHeightH2 ctrlSetFontHeightH3 ctrlSetFontHeightH4 ctrlSetFontHeightH5 ctrlSetFontHeightH6 ctrlSetFontHeightSecondary ctrlSetFontP ctrlSetFontPB ctrlSetFontSecondary ctrlSetForegroundColor ctrlSetModel ctrlSetModelDirAndUp ctrlSetModelScale ctrlSetPosition ctrlSetScale ctrlSetStructuredText ctrlSetText ctrlSetTextColor ctrlSetTooltip ctrlSetTooltipColorBox ctrlSetTooltipColorShade ctrlSetTooltipColorText ctrlShow ctrlShown ctrlText ctrlTextHeight ctrlType ctrlVisible curatorAddons curatorCamera curatorCameraArea curatorCameraAreaCeiling curatorCoef curatorEditableObjects curatorEditingArea curatorEditingAreaType curatorMouseOver curatorPoints curatorRegisteredObjects curatorSelected curatorWaypointCost current3DENOperation currentChannel currentCommand currentMagazine currentMagazineDetail currentMagazineDetailTurret currentMagazineTurret currentMuzzle currentNamespace currentTask currentTasks currentThrowable currentVisionMode currentWaypoint currentWeapon currentWeaponMode currentWeaponTurret currentZeroing cursorObject cursorTarget customChat customRadio cutFadeOut cutObj cutRsc cutText damage date dateToNumber daytime deActivateKey debriefingText debugFSM debugLog deg delete3DENEntities deleteAt deleteCenter deleteCollection deleteEditorObject deleteGroup deleteIdentity deleteLocation deleteMarker deleteMarkerLocal deleteRange deleteResources deleteSite deleteStatus deleteTeam deleteVehicle deleteVehicleCrew deleteWaypoint detach detectedMines diag_activeMissionFSMs diag_activeScripts diag_activeSQFScripts diag_activeSQSScripts diag_captureFrame diag_captureSlowFrame diag_codePerformance diag_drawMode diag_enable diag_enabled diag_fps diag_fpsMin diag_frameNo diag_list diag_log diag_logSlowFrame diag_mergeConfigFile diag_recordTurretLimits diag_tickTime diag_toggle dialog diarySubjectExists didJIP didJIPOwner difficulty difficultyEnabled difficultyEnabledRTD difficultyOption direction directSay disableAI disableCollisionWith disableConversation disableDebriefingStats disableNVGEquipment disableRemoteSensors disableSerialization disableTIEquipment disableUAVConnectability disableUserInput displayAddEventHandler displayCtrl displayNull displayParent displayRemoveAllEventHandlers displayRemoveEventHandler displaySetEventHandler dissolveTeam distance distance2D distanceSqr distributionRegion do3DENAction doArtilleryFire doFire doFollow doFSM doGetOut doMove doorPhase doStop doSuppressiveFire doTarget doWatch drawArrow drawEllipse drawIcon drawIcon3D drawLine drawLine3D drawLink drawLocation drawPolygon drawRectangle driver drop east echo edit3DENMissionAttributes editObject editorSetEventHandler effectiveCommander emptyPositions enableAI enableAIFeature enableAimPrecision enableAttack enableAudioFeature enableCamShake enableCaustics enableChannel enableCollisionWith enableCopilot enableDebriefingStats enableDiagLegend enableEndDialog enableEngineArtillery enableEnvironment enableFatigue enableGunLights enableIRLasers enableMimics enablePersonTurret enableRadio enableReload enableRopeAttach enableSatNormalOnDetail enableSaving enableSentences enableSimulation enableSimulationGlobal enableStamina enableTeamSwitch enableUAVConnectability enableUAVWaypoints enableVehicleCargo endLoadingScreen endMission engineOn enginesIsOnRTD enginesRpmRTD enginesTorqueRTD entities estimatedEndServerTime estimatedTimeLeft evalObjectArgument everyBackpack everyContainer exec execEditorScript execFSM execVM exp expectedDestination exportJIPMessages eyeDirection eyePos face faction fadeMusic fadeRadio fadeSound fadeSpeech failMission fillWeaponsFromPool find findCover findDisplay findEditorObject findEmptyPosition findEmptyPositionReady findNearestEnemy finishMissionInit finite fire fireAtTarget firstBackpack flag flagOwner flagSide flagTexture fleeing floor flyInHeight flyInHeightASL fog fogForecast fogParams forceAddUniform forcedMap forceEnd forceMap forceRespawn forceSpeed forceWalk forceWeaponFire forceWeatherChange forEachMember forEachMemberAgent forEachMemberTeam format formation formationDirection formationLeader formationMembers formationPosition formationTask formatText formLeader freeLook fromEditor fuel fullCrew gearIDCAmmoCount gearSlotAmmoCount gearSlotData get3DENActionState get3DENAttribute get3DENCamera get3DENConnections get3DENEntity get3DENEntityID get3DENGrid get3DENIconsVisible get3DENLayerEntities get3DENLinesVisible get3DENMissionAttribute get3DENMouseOver get3DENSelected getAimingCoef getAllHitPointsDamage getAllOwnedMines getAmmoCargo getAnimAimPrecision getAnimSpeedCoef getArray getArtilleryAmmo getArtilleryComputerSettings getArtilleryETA getAssignedCuratorLogic getAssignedCuratorUnit getBackpackCargo getBleedingRemaining getBurningValue getCameraViewDirection getCargoIndex getCenterOfMass getClientState getClientStateNumber getConnectedUAV getCustomAimingCoef getDammage getDescription getDir getDirVisual getDLCs getEditorCamera getEditorMode getEditorObjectScope getElevationOffset getFatigue getFriend getFSMVariable getFuelCargo getGroupIcon getGroupIconParams getGroupIcons getHideFrom getHit getHitIndex getHitPointDamage getItemCargo getMagazineCargo getMarkerColor getMarkerPos getMarkerSize getMarkerType getMass getMissionConfig getMissionConfigValue getMissionDLCs getMissionLayerEntities getModelInfo getMousePosition getNumber getObjectArgument getObjectChildren getObjectDLC getObjectMaterials getObjectProxy getObjectTextures getObjectType getObjectViewDistance getOxygenRemaining getPersonUsedDLCs getPilotCameraDirection getPilotCameraPosition getPilotCameraRotation getPilotCameraTarget getPlayerChannel getPlayerScores getPlayerUID getPos getPosASL getPosASLVisual getPosASLW getPosATL getPosATLVisual getPosVisual getPosWorld getRelDir getRelPos getRemoteSensorsDisabled getRepairCargo getResolution getShadowDistance getShotParents getSlingLoad getSpeed getStamina getStatValue getSuppression getTerrainHeightASL getText getUnitLoadout getUnitTrait getVariable getVehicleCargo getWeaponCargo getWeaponSway getWPPos glanceAt globalChat globalRadio goggles goto group groupChat groupFromNetId groupIconSelectable groupIconsVisible groupId groupOwner groupRadio groupSelectedUnits groupSelectUnit grpNull gunner gusts halt handgunItems handgunMagazine handgunWeapon handsHit hasInterface hasPilotCamera hasWeapon hcAllGroups hcGroupParams hcLeader hcRemoveAllGroups hcRemoveGroup hcSelected hcSelectGroup hcSetGroup hcShowBar hcShownBar headgear hideBody hideObject hideObjectGlobal hideSelection hint hintC hintCadet hintSilent hmd hostMission htmlLoad HUDMovementLevels humidity image importAllGroups importance in inArea inAreaArray incapacitatedState independent inflame inflamed inGameUISetEventHandler inheritsFrom initAmbientLife inPolygon inputAction inRangeOfArtillery insertEditorObject intersect is3DEN is3DENMultiplayer isAbleToBreathe isAgent isArray isAutoHoverOn isAutonomous isAutotest isBleeding isBurning isClass isCollisionLightOn isCopilotEnabled isDedicated isDLCAvailable isEngineOn isEqualTo isEqualType isEqualTypeAll isEqualTypeAny isEqualTypeArray isEqualTypeParams isFilePatchingEnabled isFlashlightOn isFlatEmpty isForcedWalk isFormationLeader isHidden isInRemainsCollector isInstructorFigureEnabled isIRLaserOn isKeyActive isKindOf isLightOn isLocalized isManualFire isMarkedForCollection isMultiplayer isMultiplayerSolo isNil isNull isNumber isObjectHidden isObjectRTD isOnRoad isPipEnabled isPlayer isRealTime isRemoteExecuted isRemoteExecutedJIP isServer isShowing3DIcons isSprintAllowed isStaminaEnabled isSteamMission isStreamFriendlyUIEnabled isText isTouchingGround isTurnedOut isTutHintsEnabled isUAVConnectable isUAVConnected isUniformAllowed isVehicleCargo isWalking isWeaponDeployed isWeaponRested itemCargo items itemsWithMagazines join joinAs joinAsSilent joinSilent joinString kbAddDatabase kbAddDatabaseTargets kbAddTopic kbHasTopic kbReact kbRemoveTopic kbTell kbWasSaid keyImage keyName knowsAbout land landAt landResult language laserTarget lbAdd lbClear lbColor lbCurSel lbData lbDelete lbIsSelected lbPicture lbSelection lbSetColor lbSetCurSel lbSetData lbSetPicture lbSetPictureColor lbSetPictureColorDisabled lbSetPictureColorSelected lbSetSelectColor lbSetSelectColorRight lbSetSelected lbSetTooltip lbSetValue lbSize lbSort lbSortByValue lbText lbValue leader leaderboardDeInit leaderboardGetRows leaderboardInit leaveVehicle libraryCredits libraryDisclaimers lifeState lightAttachObject lightDetachObject lightIsOn lightnings limitSpeed linearConversion lineBreak lineIntersects lineIntersectsObjs lineIntersectsSurfaces lineIntersectsWith linkItem list listObjects ln lnbAddArray lnbAddColumn lnbAddRow lnbClear lnbColor lnbCurSelRow lnbData lnbDeleteColumn lnbDeleteRow lnbGetColumnsPosition lnbPicture lnbSetColor lnbSetColumnsPos lnbSetCurSelRow lnbSetData lnbSetPicture lnbSetText lnbSetValue lnbSize lnbText lnbValue load loadAbs loadBackpack loadFile loadGame loadIdentity loadMagazine loadOverlay loadStatus loadUniform loadVest local localize locationNull locationPosition lock lockCameraTo lockCargo lockDriver locked lockedCargo lockedDriver lockedTurret lockIdentity lockTurret lockWP log logEntities logNetwork logNetworkTerminate lookAt lookAtPos magazineCargo magazines magazinesAllTurrets magazinesAmmo magazinesAmmoCargo magazinesAmmoFull magazinesDetail magazinesDetailBackpack magazinesDetailUniform magazinesDetailVest magazinesTurret magazineTurretAmmo mapAnimAdd mapAnimClear mapAnimCommit mapAnimDone mapCenterOnCamera mapGridPosition markAsFinishedOnSteam markerAlpha markerBrush markerColor markerDir markerPos markerShape markerSize markerText markerType max members menuAction menuAdd menuChecked menuClear menuCollapse menuData menuDelete menuEnable menuEnabled menuExpand menuHover menuPicture menuSetAction menuSetCheck menuSetData menuSetPicture menuSetValue menuShortcut menuShortcutText menuSize menuSort menuText menuURL menuValue min mineActive mineDetectedBy missionConfigFile missionDifficulty missionName missionNamespace missionStart missionVersion mod modelToWorld modelToWorldVisual modParams moonIntensity moonPhase morale move move3DENCamera moveInAny moveInCargo moveInCommander moveInDriver moveInGunner moveInTurret moveObjectToEnd moveOut moveTime moveTo moveToCompleted moveToFailed musicVolume name nameSound nearEntities nearestBuilding nearestLocation nearestLocations nearestLocationWithDubbing nearestObject nearestObjects nearestTerrainObjects nearObjects nearObjectsReady nearRoads nearSupplies nearTargets needReload netId netObjNull newOverlay nextMenuItemIndex nextWeatherChange nMenuItems not numberToDate objectCurators objectFromNetId objectParent objNull objStatus onBriefingGroup onBriefingNotes onBriefingPlan onBriefingTeamSwitch onCommandModeChanged onDoubleClick onEachFrame onGroupIconClick onGroupIconOverEnter onGroupIconOverLeave onHCGroupSelectionChanged onMapSingleClick onPlayerConnected onPlayerDisconnected onPreloadFinished onPreloadStarted onShowNewObject onTeamSwitch openCuratorInterface openDLCPage openMap openYoutubeVideo opfor or orderGetIn overcast overcastForecast owner param params parseNumber parseText parsingNamespace particlesQuality pi pickWeaponPool pitch pixelGrid pixelGridBase pixelGridNoUIScale pixelH pixelW playableSlotsNumber playableUnits playAction playActionNow player playerRespawnTime playerSide playersNumber playGesture playMission playMove playMoveNow playMusic playScriptedMission playSound playSound3D position positionCameraToWorld posScreenToWorld posWorldToScreen ppEffectAdjust ppEffectCommit ppEffectCommitted ppEffectCreate ppEffectDestroy ppEffectEnable ppEffectEnabled ppEffectForceInNVG precision preloadCamera preloadObject preloadSound preloadTitleObj preloadTitleRsc preprocessFile preprocessFileLineNumbers primaryWeapon primaryWeaponItems primaryWeaponMagazine priority private processDiaryLink productVersion profileName profileNamespace profileNameSteam progressLoadingScreen progressPosition progressSetPosition publicVariable publicVariableClient publicVariableServer pushBack pushBackUnique putWeaponPool queryItemsPool queryMagazinePool queryWeaponPool rad radioChannelAdd radioChannelCreate radioChannelRemove radioChannelSetCallSign radioChannelSetLabel radioVolume rain rainbow random rank rankId rating rectangular registeredTasks registerTask reload reloadEnabled remoteControl remoteExec remoteExecCall remove3DENConnection remove3DENEventHandler remove3DENLayer removeAction removeAll3DENEventHandlers removeAllActions removeAllAssignedItems removeAllContainers removeAllCuratorAddons removeAllCuratorCameraAreas removeAllCuratorEditingAreas removeAllEventHandlers removeAllHandgunItems removeAllItems removeAllItemsWithMagazines removeAllMissionEventHandlers removeAllMPEventHandlers removeAllMusicEventHandlers removeAllOwnedMines removeAllPrimaryWeaponItems removeAllWeapons removeBackpack removeBackpackGlobal removeCuratorAddons removeCuratorCameraArea removeCuratorEditableObjects removeCuratorEditingArea removeDrawIcon removeDrawLinks removeEventHandler removeFromRemainsCollector removeGoggles removeGroupIcon removeHandgunItem removeHeadgear removeItem removeItemFromBackpack removeItemFromUniform removeItemFromVest removeItems removeMagazine removeMagazineGlobal removeMagazines removeMagazinesTurret removeMagazineTurret removeMenuItem removeMissionEventHandler removeMPEventHandler removeMusicEventHandler removeOwnedMine removePrimaryWeaponItem removeSecondaryWeaponItem removeSimpleTask removeSwitchableUnit removeTeamMember removeUniform removeVest removeWeapon removeWeaponGlobal removeWeaponTurret requiredVersion resetCamShake resetSubgroupDirection resistance resize resources respawnVehicle restartEditorCamera reveal revealMine reverse reversedMouseY roadAt roadsConnectedTo roleDescription ropeAttachedObjects ropeAttachedTo ropeAttachEnabled ropeAttachTo ropeCreate ropeCut ropeDestroy ropeDetach ropeEndPosition ropeLength ropes ropeUnwind ropeUnwound rotorsForcesRTD rotorsRpmRTD round runInitScript safeZoneH safeZoneW safeZoneWAbs safeZoneX safeZoneXAbs safeZoneY save3DENInventory saveGame saveIdentity saveJoysticks saveOverlay saveProfileNamespace saveStatus saveVar savingEnabled say say2D say3D scopeName score scoreSide screenshot screenToWorld scriptDone scriptName scriptNull scudState secondaryWeapon secondaryWeaponItems secondaryWeaponMagazine select selectBestPlaces selectDiarySubject selectedEditorObjects selectEditorObject selectionNames selectionPosition selectLeader selectMax selectMin selectNoPlayer selectPlayer selectRandom selectWeapon selectWeaponTurret sendAUMessage sendSimpleCommand sendTask sendTaskResult sendUDPMessage serverCommand serverCommandAvailable serverCommandExecutable serverName serverTime set set3DENAttribute set3DENAttributes set3DENGrid set3DENIconsVisible set3DENLayer set3DENLinesVisible set3DENMissionAttributes set3DENModelsVisible set3DENObjectType set3DENSelected setAccTime setAirportSide setAmmo setAmmoCargo setAnimSpeedCoef setAperture setApertureNew setArmoryPoints setAttributes setAutonomous setBehaviour setBleedingRemaining setCameraInterest setCamShakeDefParams setCamShakeParams setCamUseTi setCaptive setCenterOfMass setCollisionLight setCombatMode setCompassOscillation setCuratorCameraAreaCeiling setCuratorCoef setCuratorEditingAreaType setCuratorWaypointCost setCurrentChannel setCurrentTask setCurrentWaypoint setCustomAimCoef setDamage setDammage setDate setDebriefingText setDefaultCamera setDestination setDetailMapBlendPars setDir setDirection setDrawIcon setDropInterval setEditorMode setEditorObjectScope setEffectCondition setFace setFaceAnimation setFatigue setFlagOwner setFlagSide setFlagTexture setFog setFormation setFormationTask setFormDir setFriend setFromEditor setFSMVariable setFuel setFuelCargo setGroupIcon setGroupIconParams setGroupIconsSelectable setGroupIconsVisible setGroupId setGroupIdGlobal setGroupOwner setGusts setHideBehind setHit setHitIndex setHitPointDamage setHorizonParallaxCoef setHUDMovementLevels setIdentity setImportance setLeader setLightAmbient setLightAttenuation setLightBrightness setLightColor setLightDayLight setLightFlareMaxDistance setLightFlareSize setLightIntensity setLightnings setLightUseFlare setLocalWindParams setMagazineTurretAmmo setMarkerAlpha setMarkerAlphaLocal setMarkerBrush setMarkerBrushLocal setMarkerColor setMarkerColorLocal setMarkerDir setMarkerDirLocal setMarkerPos setMarkerPosLocal setMarkerShape setMarkerShapeLocal setMarkerSize setMarkerSizeLocal setMarkerText setMarkerTextLocal setMarkerType setMarkerTypeLocal setMass setMimic setMousePosition setMusicEffect setMusicEventHandler setName setNameSound setObjectArguments setObjectMaterial setObjectMaterialGlobal setObjectProxy setObjectTexture setObjectTextureGlobal setObjectViewDistance setOvercast setOwner setOxygenRemaining setParticleCircle setParticleClass setParticleFire setParticleParams setParticleRandom setPilotCameraDirection setPilotCameraRotation setPilotCameraTarget setPilotLight setPiPEffect setPitch setPlayable setPlayerRespawnTime setPos setPosASL setPosASL2 setPosASLW setPosATL setPosition setPosWorld setRadioMsg setRain setRainbow setRandomLip setRank setRectangular setRepairCargo setShadowDistance setShotParents setSide setSimpleTaskAlwaysVisible setSimpleTaskCustomData setSimpleTaskDescription setSimpleTaskDestination setSimpleTaskTarget setSimpleTaskType setSimulWeatherLayers setSize setSkill setSlingLoad setSoundEffect setSpeaker setSpeech setSpeedMode setStamina setStaminaScheme setStatValue setSuppression setSystemOfUnits setTargetAge setTaskResult setTaskState setTerrainGrid setText setTimeMultiplier setTitleEffect setTriggerActivation setTriggerArea setTriggerStatements setTriggerText setTriggerTimeout setTriggerType setType setUnconscious setUnitAbility setUnitLoadout setUnitPos setUnitPosWeak setUnitRank setUnitRecoilCoefficient setUnitTrait setUnloadInCombat setUserActionText setVariable setVectorDir setVectorDirAndUp setVectorUp setVehicleAmmo setVehicleAmmoDef setVehicleArmor setVehicleCargo setVehicleId setVehicleLock setVehiclePosition setVehicleTiPars setVehicleVarName setVelocity setVelocityTransformation setViewDistance setVisibleIfTreeCollapsed setWaves setWaypointBehaviour setWaypointCombatMode setWaypointCompletionRadius setWaypointDescription setWaypointForceBehaviour setWaypointFormation setWaypointHousePosition setWaypointLoiterRadius setWaypointLoiterType setWaypointName setWaypointPosition setWaypointScript setWaypointSpeed setWaypointStatements setWaypointTimeout setWaypointType setWaypointVisible setWeaponReloadingTime setWind setWindDir setWindForce setWindStr setWPPos show3DIcons showChat showCinemaBorder showCommandingMenu showCompass showCuratorCompass showGPS showHUD showLegend showMap shownArtilleryComputer shownChat shownCompass shownCuratorCompass showNewEditorObject shownGPS shownHUD shownMap shownPad shownRadio shownScoretable shownUAVFeed shownWarrant shownWatch showPad showRadio showScoretable showSubtitles showUAVFeed showWarrant showWatch showWaypoint showWaypoints side sideAmbientLife sideChat sideEmpty sideEnemy sideFriendly sideLogic sideRadio sideUnknown simpleTasks simulationEnabled simulCloudDensity simulCloudOcclusion simulInClouds simulWeatherSync sin size sizeOf skill skillFinal skipTime sleep sliderPosition sliderRange sliderSetPosition sliderSetRange sliderSetSpeed sliderSpeed slingLoadAssistantShown soldierMagazines someAmmo sort soundVolume spawn speaker speed speedMode splitString sqrt squadParams stance startLoadingScreen step stop stopEngineRTD stopped str sunOrMoon supportInfo suppressFor surfaceIsWater surfaceNormal surfaceType swimInDepth switchableUnits switchAction switchCamera switchGesture switchLight switchMove synchronizedObjects synchronizedTriggers synchronizedWaypoints synchronizeObjectsAdd synchronizeObjectsRemove synchronizeTrigger synchronizeWaypoint systemChat systemOfUnits tan targetKnowledge targetsAggregate targetsQuery taskAlwaysVisible taskChildren taskCompleted taskCustomData taskDescription taskDestination taskHint taskMarkerOffset taskNull taskParent taskResult taskState taskType teamMember teamMemberNull teamName teams teamSwitch teamSwitchEnabled teamType terminate terrainIntersect terrainIntersectASL text textLog textLogFormat tg time timeMultiplier titleCut titleFadeOut titleObj titleRsc titleText toArray toFixed toLower toString toUpper triggerActivated triggerActivation triggerArea triggerAttachedVehicle triggerAttachObject triggerAttachVehicle triggerStatements triggerText triggerTimeout triggerTimeoutCurrent triggerType turretLocal turretOwner turretUnit tvAdd tvClear tvCollapse tvCount tvCurSel tvData tvDelete tvExpand tvPicture tvSetCurSel tvSetData tvSetPicture tvSetPictureColor tvSetPictureColorDisabled tvSetPictureColorSelected tvSetPictureRight tvSetPictureRightColor tvSetPictureRightColorDisabled tvSetPictureRightColorSelected tvSetText tvSetTooltip tvSetValue tvSort tvSortByValue tvText tvTooltip tvValue type typeName typeOf UAVControl uiNamespace uiSleep unassignCurator unassignItem unassignTeam unassignVehicle underwater uniform uniformContainer uniformItems uniformMagazines unitAddons unitAimPosition unitAimPositionVisual unitBackpack unitIsUAV unitPos unitReady unitRecoilCoefficient units unitsBelowHeight unlinkItem unlockAchievement unregisterTask updateDrawIcon updateMenuItem updateObjectTree useAISteeringComponent useAudioTimeForMoves vectorAdd vectorCos vectorCrossProduct vectorDiff vectorDir vectorDirVisual vectorDistance vectorDistanceSqr vectorDotProduct vectorFromTo vectorMagnitude vectorMagnitudeSqr vectorMultiply vectorNormalized vectorUp vectorUpVisual vehicle vehicleCargoEnabled vehicleChat vehicleRadio vehicles vehicleVarName velocity velocityModelSpace verifySignature vest vestContainer vestItems vestMagazines viewDistance visibleCompass visibleGPS visibleMap visiblePosition visiblePositionASL visibleScoretable visibleWatch waves waypointAttachedObject waypointAttachedVehicle waypointAttachObject waypointAttachVehicle waypointBehaviour waypointCombatMode waypointCompletionRadius waypointDescription waypointForceBehaviour waypointFormation waypointHousePosition waypointLoiterRadius waypointLoiterType waypointName waypointPosition waypoints waypointScript waypointsEnabledUAV waypointShow waypointSpeed waypointStatements waypointTimeout waypointTimeoutCurrent waypointType waypointVisible weaponAccessories weaponAccessoriesCargo weaponCargo weaponDirection weaponInertia weaponLowered weapons weaponsItems weaponsItemsCargo weaponState weaponsTurret weightRTD west WFSideText wind",literal:"true false nil"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.NUMBER_MODE,{className:"variable",begin:/\b_+[a-zA-Z_]\w*/},{className:"title",begin:/[a-zA-Z][a-zA-Z0-9]+_fnc_\w*/},{className:"string",variants:[{begin:'"',end:'"',contains:[{begin:'""',relevance:0}]},{begin:"'",end:"'",contains:[{begin:"''",relevance:0}]}]},t.preprocessor],illegal:/#/}}},function(e,t){e.exports=function(e){return{aliases:["ml"],keywords:{keyword:"abstype and andalso as case datatype do else end eqtype exception fn fun functor handle if in include infix infixr let local nonfix of op open orelse raise rec sharing sig signature struct structure then type val with withtype where while",built_in:"array bool char exn int list option order real ref string substring vector unit word",literal:"true false NONE SOME LESS EQUAL GREATER nil"},illegal:/\/\/|>>/,lexemes:"[a-z_]\\w*!?",contains:[{className:"literal",begin:/\[(\|\|)?\]|\(\)/,relevance:0},e.COMMENT("\\(\\*","\\*\\)",{contains:["self"]}),{className:"symbol",begin:"'[A-Za-z_](?!')[\\w']*"},{className:"type",begin:"`[A-Z][\\w']*"},{className:"type",begin:"\\b[A-Z][\\w']*",relevance:0},{begin:"[a-z_]\\w*'[\\w']*"},e.inherit(e.APOS_STRING_MODE,{className:"string",relevance:0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),{className:"number",begin:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",relevance:0},{begin:/[-=]>/}]}}},function(e,t){e.exports=function(e){var t={className:"string",begin:"\\$.{1}"},n={className:"symbol",begin:"#"+e.UNDERSCORE_IDENT_RE};return{aliases:["st"],keywords:"self super nil true false thisContext",contains:[e.COMMENT('"','"'),e.APOS_STRING_MODE,{className:"type",begin:"\\b[A-Z][A-Za-z0-9_]*",relevance:0},{begin:"[a-z][a-zA-Z0-9_]*:",relevance:0},e.C_NUMBER_MODE,n,t,{begin:"\\|[ ]*[a-z][a-zA-Z0-9_]*([ ]+[a-z][a-zA-Z0-9_]*)*[ ]*\\|",returnBegin:!0,end:/\|/,illegal:/\S/,contains:[{begin:"(\\|[ ]*)?[a-z][a-zA-Z0-9_]*"}]},{begin:"\\#\\(",end:"\\)",contains:[e.APOS_STRING_MODE,t,e.C_NUMBER_MODE,n]}]}}},function(e,t){e.exports=function(e){var t=["add","and","cmp","cmpg","cmpl","const","div","double","float","goto","if","int","long","move","mul","neg","new","nop","not","or","rem","return","shl","shr","sput","sub","throw","ushr","xor"];return{aliases:["smali"],contains:[{className:"string",begin:'"',end:'"',relevance:0},e.COMMENT("#","$",{relevance:0}),{className:"keyword",variants:[{begin:"\\s*\\.end\\s[a-zA-Z0-9]*"},{begin:"^[ ]*\\.[a-zA-Z]*",relevance:0},{begin:"\\s:[a-zA-Z_0-9]*",relevance:0},{begin:"\\s("+["transient","constructor","abstract","final","synthetic","public","private","protected","static","bridge","system"].join("|")+")"}]},{className:"built_in",variants:[{begin:"\\s("+t.join("|")+")\\s"},{begin:"\\s("+t.join("|")+")((\\-|/)[a-zA-Z0-9]+)+\\s",relevance:10},{begin:"\\s("+["aget","aput","array","check","execute","fill","filled","goto/16","goto/32","iget","instance","invoke","iput","monitor","packed","sget","sparse"].join("|")+")((\\-|/)[a-zA-Z0-9]+)*\\s",relevance:10}]},{className:"class",begin:"L[^(;:\n]*;",relevance:0},{begin:"[vp][0-9]+"}]}}},function(e,t){e.exports=function(e){return{aliases:["console"],contains:[{className:"meta",begin:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{end:"$",subLanguage:"bash"}}]}}},function(e,t){e.exports=function(e){var t={className:"variable",begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b"},n={className:"number",begin:"#[0-9A-Fa-f]+"};e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE;return{case_insensitive:!0,illegal:"[=/|']",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"selector-id",begin:"\\#[A-Za-z0-9_-]+",relevance:0},{className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0},{className:"selector-attr",begin:"\\[",end:"\\]",illegal:"$"},{className:"selector-tag",begin:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",relevance:0},{begin:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{begin:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},t,{className:"attribute",begin:"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",illegal:"[^\\s]"},{begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{begin:":",end:";",contains:[t,n,e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{className:"meta",begin:"!important"}]},{begin:"@",end:"[{;]",keywords:"mixin include extend for if else each while charset import debug media page content font-face namespace warn",contains:[t,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n,e.CSS_NUMBER_MODE,{begin:"\\s[A-Za-z0-9_.-]+",relevance:0}]}]}}},function(e,t){e.exports=function(e){var t=[e.C_NUMBER_MODE,{className:"string",begin:"'|\"",end:"'|\"",contains:[e.BACKSLASH_ESCAPE,{begin:"''"}]}];return{aliases:["sci"],lexemes:/%?\w+/,keywords:{keyword:"abort break case clear catch continue do elseif else endfunction end for function global if pause return resume select try then while",literal:"%f %F %t %T %pi %eps %inf %nan %e %i %z %s",built_in:"abs and acos asin atan ceil cd chdir clearglobal cosh cos cumprod deff disp error exec execstr exists exp eye gettext floor fprintf fread fsolve imag isdef isempty isinfisnan isvector lasterror length load linspace list listfiles log10 log2 log max min msprintf mclose mopen ones or pathconvert poly printf prod pwd rand real round sinh sin size gsort sprintf sqrt strcat strcmps tring sum system tanh tan type typename warning zeros matrix"},illegal:'("|#|/\\*|\\s+/\\w+)',contains:[{className:"function",beginKeywords:"function",end:"$",contains:[e.UNDERSCORE_TITLE_MODE,{className:"params",begin:"\\(",end:"\\)"}]},{begin:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",end:"",relevance:0},{begin:"\\[",end:"\\]'*[\\.']*",relevance:0,contains:t},e.COMMENT("//","$")].concat(t)}}},function(e,t){e.exports=function(e){var t="[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+",n={className:"literal",begin:"(#t|#f|#\\\\"+t+"|#\\\\.)"},r={className:"number",variants:[{begin:"(\\-|\\+)?\\d+([./]\\d+)?",relevance:0},{begin:"(\\-|\\+)?\\d+([./]\\d+)?[+\\-](\\-|\\+)?\\d+([./]\\d+)?i",relevance:0},{begin:"#b[0-1]+(/[0-1]+)?"},{begin:"#o[0-7]+(/[0-7]+)?"},{begin:"#x[0-9a-f]+(/[0-9a-f]+)?"}]},i=e.QUOTE_STRING_MODE,a=[e.COMMENT(";","$",{relevance:0}),e.COMMENT("#\\|","\\|#")],o={begin:t,relevance:0},s={className:"symbol",begin:"'"+t},l={endsWithParent:!0,relevance:0},c={variants:[{begin:/'/},{begin:"`"}],contains:[{begin:"\\(",end:"\\)",contains:["self",n,i,r,o,s]}]},u={className:"name",begin:t,lexemes:t,keywords:{"builtin-name":"case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules ' * + , ,@ - ... / ; < <= = => > >= ` abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string=? string>? string? substring symbol->string symbol? tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"}},d={variants:[{begin:"\\(",end:"\\)"},{begin:"\\[",end:"\\]"}],contains:[{begin:/lambda/,endsWithParent:!0,returnBegin:!0,contains:[u,{begin:/\(/,end:/\)/,endsParent:!0,contains:[o]}]},u,l]};return l.contains=[n,r,i,o,s,c,d].concat(a),{illegal:/\S/,contains:[{className:"meta",begin:"^#!",end:"$"},r,i,s,c,d].concat(a)}}},function(e,t){e.exports=function(e){var t={className:"subst",variants:[{begin:"\\$[A-Za-z0-9_]+"},{begin:"\\${",end:"}"}]},n={className:"string",variants:[{begin:'"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:'"""',end:'"""',relevance:10},{begin:'[a-z]+"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE,t]},{className:"string",begin:'[a-z]+"""',end:'"""',contains:[t],relevance:10}]},r={className:"type",begin:"\\b[A-Z][A-Za-z0-9_]*",relevance:0},i={className:"title",begin:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,relevance:0},a={className:"class",beginKeywords:"class object trait type",end:/[:={\[\n;]/,excludeEnd:!0,contains:[{beginKeywords:"extends with",relevance:10},{begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[r]},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[r]},i]},o={className:"function",beginKeywords:"def",end:/[:={\[(\n;]/,excludeEnd:!0,contains:[i]};return{keywords:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,{className:"symbol",begin:"'\\w[\\w\\d_]*(?!')"},r,o,a,e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"}]}}},function(e,t){e.exports=function(e){var t="([ui](8|16|32|64|128|size)|f(32|64))?",n="drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!";return{aliases:["rs"],keywords:{keyword:"alignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self Self sizeof static struct super trait true type typeof unsafe unsized use virtual while where yield move default",literal:"true false Some None Ok Err",built_in:n},lexemes:e.IDENT_RE+"!?",illegal:""}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN SAVE_UPDATE DETERMINANT LABEL REPORT REVENUE EACH IN FROM TOTAL CHARGE BLOCK AND OR CSV_FILE RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM NUMDAYS READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,{className:"literal",variants:[{begin:"#\\s+[a-zA-Z\\ \\.]*",relevance:0},{begin:"#[a-zA-Z\\ \\.]+"}]}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:"float color point normal vector matrix while for if do return else break extern continue",built_in:"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},illegal:"\]$/},{begin:/<\//,end:/>/},{begin:/^facet /,end:/\}/},{begin:"^1\\.\\.(\\d+)$",end:/$/}],illegal:/./},e.COMMENT("^#","$"),i,a,r,{begin:/[\w-]+\=([^\s\{\}\[\]\(\)]+)/,relevance:0,returnBegin:!0,contains:[{className:"attribute",begin:/[^=]+/},{begin:/=/,endsWithParent:!0,relevance:0,contains:[i,a,r,{className:"literal",begin:"\\b("+n.split(" ").join("|")+")\\b"},{begin:/("[^"]*"|[^\s\{\}\[\]]+)/}]}]},{className:"number",begin:/\*[0-9a-fA-F]+/},{begin:"\\b("+"add remove enable disable set get print export edit find run debug error info warning".split(" ").join("|")+")([\\s[(]|])",returnBegin:!0,contains:[{className:"builtin-name",begin:/\w+/}]},{className:"built_in",variants:[{begin:"(\\.\\./|/|\\s)(("+"traffic-flow traffic-generator firewall scheduler aaa accounting address-list address align area bandwidth-server bfd bgp bridge client clock community config connection console customer default dhcp-client dhcp-server discovery dns e-mail ethernet filter firewall firmware gps graphing group hardware health hotspot identity igmp-proxy incoming instance interface ip ipsec ipv6 irq l2tp-server lcd ldp logging mac-server mac-winbox mangle manual mirror mme mpls nat nd neighbor network note ntp ospf ospf-v3 ovpn-server page peer pim ping policy pool port ppp pppoe-client pptp-server prefix profile proposal proxy queue radius resource rip ripng route routing screen script security-profiles server service service-port settings shares smb sms sniffer snmp snooper socks sstp-server system tool tracking type upgrade upnp user-manager users user vlan secret vrrp watchdog web-access wireless pptp pppoe lan wan layer7-protocol lease simple raw".split(" ").join("|")+");?\\s)+",relevance:10},{begin:/\.\./}]}]}}},function(e,t){e.exports=function(e){var t="[a-zA-Z-_][^\\n{]+\\{",n={className:"attribute",begin:/[a-zA-Z-_]+/,end:/\s*:/,excludeEnd:!0,starts:{end:";",relevance:0,contains:[{className:"variable",begin:/\.[a-zA-Z-_]+/},{className:"keyword",begin:/\(optional\)/}]}};return{aliases:["graph","instances"],case_insensitive:!0,keywords:"import",contains:[{begin:"^facet "+t,end:"}",keywords:"facet",contains:[n,e.HASH_COMMENT_MODE]},{begin:"^\\s*instance of "+t,end:"}",keywords:"name count channels instance-data instance-state instance of",illegal:/\S/,contains:["self",n,e.HASH_COMMENT_MODE]},{begin:"^"+t,end:"}",contains:[n,e.HASH_COMMENT_MODE]},e.HASH_COMMENT_MODE]}}},function(e,t){e.exports=function(e){return{keywords:"ArchiveRecord AreaLightSource Atmosphere Attribute AttributeBegin AttributeEnd Basis Begin Blobby Bound Clipping ClippingPlane Color ColorSamples ConcatTransform Cone CoordinateSystem CoordSysTransform CropWindow Curves Cylinder DepthOfField Detail DetailRange Disk Displacement Display End ErrorHandler Exposure Exterior Format FrameAspectRatio FrameBegin FrameEnd GeneralPolygon GeometricApproximation Geometry Hider Hyperboloid Identity Illuminate Imager Interior LightSource MakeCubeFaceEnvironment MakeLatLongEnvironment MakeShadow MakeTexture Matte MotionBegin MotionEnd NuPatch ObjectBegin ObjectEnd ObjectInstance Opacity Option Orientation Paraboloid Patch PatchMesh Perspective PixelFilter PixelSamples PixelVariance Points PointsGeneralPolygons PointsPolygons Polygon Procedural Projection Quantize ReadArchive RelativeDetail ReverseOrientation Rotate Scale ScreenWindow ShadingInterpolation ShadingRate Shutter Sides Skew SolidBegin SolidEnd Sphere SubdivisionMesh Surface TextureCoordinates Torus Transform TransformBegin TransformEnd TransformPoints Translate TrimCurve WorldBegin WorldEnd",illegal:"\s*[);\]]/,relevance:0,subLanguage:"xml"}],relevance:0},{className:"keyword",begin:"\\bsignal\\b",starts:{className:"string",end:"(\\(|:|=|;|,|//|/\\*|$)",returnEnd:!0}},{className:"keyword",begin:"\\bproperty\\b",starts:{className:"string",end:"(:|=|;|,|//|/\\*|$)",returnEnd:!0}},{className:"function",beginKeywords:"function",end:/\{/,excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/}),{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}],illegal:/\[|%/},{begin:"\\."+e.IDENT_RE,relevance:0},n,r,i],illegal:/#/}}},function(e,t){e.exports=function(e){return{aliases:["k","kdb"],keywords:{keyword:"do while select delete by update from",literal:"0b 1b",built_in:"neg not null string reciprocal floor ceiling signum mod xbar xlog and or each scan over prior mmu lsq inv md5 ltime gtime count first var dev med cov cor all any rand sums prds mins maxs fills deltas ratios avgs differ prev next rank reverse iasc idesc asc desc msum mcount mavg mdev xrank mmin mmax xprev rotate distinct group where flip type key til get value attr cut set upsert raze union inter except cross sv vs sublist enlist read0 read1 hopen hclose hdel hsym hcount peach system ltrim rtrim trim lower upper ssr view tables views cols xcols keys xkey xcol xasc xdesc fkeys meta lj aj aj0 ij pj asof uj ww wj wj1 fby xgroup ungroup ej save load rsave rload show csv parse eval min max avg wavg wsum sin cos tan sum",type:"`float `double int `timestamp `timespan `datetime `time `boolean `symbol `char `byte `short `long `real `month `date `minute `second `guid"},lexemes:/(`?)[A-Za-z0-9_]+\b/,contains:[e.C_LINE_COMMENT_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},n={className:"meta",begin:/^(>>>|\.\.\.) /},r={className:"subst",begin:/\{/,end:/\}/,keywords:t,illegal:/#/},i={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/(u|b)?r?'''/,end:/'''/,contains:[n],relevance:10},{begin:/(u|b)?r?"""/,end:/"""/,contains:[n],relevance:10},{begin:/(fr|rf|f)'''/,end:/'''/,contains:[n,r]},{begin:/(fr|rf|f)"""/,end:/"""/,contains:[n,r]},{begin:/(u|r|ur)'/,end:/'/,relevance:10},{begin:/(u|r|ur)"/,end:/"/,relevance:10},{begin:/(b|br)'/,end:/'/},{begin:/(b|br)"/,end:/"/},{begin:/(fr|rf|f)'/,end:/'/,contains:[r]},{begin:/(fr|rf|f)"/,end:/"/,contains:[r]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},a={className:"number",relevance:0,variants:[{begin:e.BINARY_NUMBER_RE+"[lLjJ]?"},{begin:"\\b(0o[0-7]+)[lLjJ]?"},{begin:e.C_NUMBER_RE+"[lLjJ]?"}]},o={className:"params",begin:/\(/,end:/\)/,contains:["self",n,a,i]};return r.contains=[i,a,n],{aliases:["py","gyp"],keywords:t,illegal:/(<\/|->|\?)|=>/,contains:[n,a,i,e.HASH_COMMENT_MODE,{variants:[{className:"function",beginKeywords:"def"},{className:"class",beginKeywords:"class"}],end:/:/,illegal:/[${=;\n,]/,contains:[e.UNDERSCORE_TITLE_MODE,o,{begin:/->/,endsWithParent:!0,keywords:"None"}]},{className:"meta",begin:/^[\t ]*@/,end:/$/},{begin:/\b(print|exec)\(/}]}}},function(e,t){e.exports=function(e){return{aliases:["pb","pbi"],keywords:"And As Break CallDebugger Case CompilerCase CompilerDefault CompilerElse CompilerEndIf CompilerEndSelect CompilerError CompilerIf CompilerSelect Continue Data DataSection EndDataSection Debug DebugLevel Default Define Dim DisableASM DisableDebugger DisableExplicit Else ElseIf EnableASM EnableDebugger EnableExplicit End EndEnumeration EndIf EndImport EndInterface EndMacro EndProcedure EndSelect EndStructure EndStructureUnion EndWith Enumeration Extends FakeReturn For Next ForEach ForEver Global Gosub Goto If Import ImportC IncludeBinary IncludeFile IncludePath Interface Macro NewList Not Or ProcedureReturn Protected Prototype PrototypeC Read ReDim Repeat Until Restore Return Select Shared Static Step Structure StructureUnion Swap To Wend While With XIncludeFile XOr Procedure ProcedureC ProcedureCDLL ProcedureDLL Declare DeclareC DeclareCDLL DeclareDLL",contains:[e.COMMENT(";","$",{relevance:0}),{className:"function",begin:"\\b(Procedure|Declare)(C|CDLL|DLL)?\\b",end:"\\(",excludeEnd:!0,returnBegin:!0,contains:[{className:"keyword",begin:"(Procedure|Declare)(C|CDLL|DLL)?",excludeEnd:!0},{className:"type",begin:"\\.\\w*"},e.UNDERSCORE_TITLE_MODE]},{className:"string",begin:'(~)?"',end:'"',illegal:"\\n"},{className:"symbol",begin:"#[a-zA-Z_]\\w*\\$?"}]}}},function(e,t){e.exports=function(e){var t=e.COMMENT("#","$"),n=e.inherit(e.TITLE_MODE,{begin:"([A-Za-z_]|::)(\\w|::)*"}),r={className:"variable",begin:"\\$([A-Za-z_]|::)(\\w|::)*"},i={className:"string",contains:[e.BACKSLASH_ESCAPE,r],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/}]};return{aliases:["pp"],contains:[t,r,i,{beginKeywords:"class",end:"\\{|;",illegal:/=/,contains:[n,t]},{beginKeywords:"define",end:/\{/,contains:[{className:"section",begin:e.IDENT_RE,endsParent:!0}]},{begin:e.IDENT_RE+"\\s+\\{",returnBegin:!0,end:/\S/,contains:[{className:"keyword",begin:e.IDENT_RE},{begin:/\{/,end:/\}/,keywords:{keyword:"and case default else elsif false if in import enherits node or true undef unless main settings $string ",literal:"alias audit before loglevel noop require subscribe tag owner ensure group mode name|0 changes context force incl lens load_path onlyif provider returns root show_diff type_check en_address ip_address realname command environment hour monute month monthday special target weekday creates cwd ogoutput refresh refreshonly tries try_sleep umask backup checksum content ctime force ignore links mtime purge recurse recurselimit replace selinux_ignore_defaults selrange selrole seltype seluser source souirce_permissions sourceselect validate_cmd validate_replacement allowdupe attribute_membership auth_membership forcelocal gid ia_load_module members system host_aliases ip allowed_trunk_vlans description device_url duplex encapsulation etherchannel native_vlan speed principals allow_root auth_class auth_type authenticate_user k_of_n mechanisms rule session_owner shared options device fstype enable hasrestart directory present absent link atboot blockdevice device dump pass remounts poller_tag use message withpath adminfile allow_virtual allowcdrom category configfiles flavor install_options instance package_settings platform responsefile status uninstall_options vendor unless_system_user unless_uid binary control flags hasstatus manifest pattern restart running start stop allowdupe auths expiry gid groups home iterations key_membership keys managehome membership password password_max_age password_min_age profile_membership profiles project purge_ssh_keys role_membership roles salt shell uid baseurl cost descr enabled enablegroups exclude failovermethod gpgcheck gpgkey http_caching include includepkgs keepalive metadata_expire metalink mirrorlist priority protect proxy proxy_password proxy_username repo_gpgcheck s3_enabled skip_if_unavailable sslcacert sslclientcert sslclientkey sslverify mounted",built_in:"architecture augeasversion blockdevices boardmanufacturer boardproductname boardserialnumber cfkey dhcp_servers domain ec2_ ec2_userdata facterversion filesystems ldom fqdn gid hardwareisa hardwaremodel hostname id|0 interfaces ipaddress ipaddress_ ipaddress6 ipaddress6_ iphostnumber is_virtual kernel kernelmajversion kernelrelease kernelversion kernelrelease kernelversion lsbdistcodename lsbdistdescription lsbdistid lsbdistrelease lsbmajdistrelease lsbminordistrelease lsbrelease macaddress macaddress_ macosx_buildversion macosx_productname macosx_productversion macosx_productverson_major macosx_productversion_minor manufacturer memoryfree memorysize netmask metmask_ network_ operatingsystem operatingsystemmajrelease operatingsystemrelease osfamily partitions path physicalprocessorcount processor processorcount productname ps puppetversion rubysitedir rubyversion selinux selinux_config_mode selinux_config_policy selinux_current_mode selinux_current_mode selinux_enforced selinux_policyversion serialnumber sp_ sshdsakey sshecdsakey sshrsakey swapencrypted swapfree swapsize timezone type uniqueid uptime uptime_days uptime_hours uptime_seconds uuid virtual vlans xendomains zfs_version zonenae zones zpool_version"},relevance:0,contains:[i,t,{begin:"[a-zA-Z_]+\\s*=>",returnBegin:!0,end:"=>",contains:[{className:"attr",begin:e.IDENT_RE}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},r]}],relevance:0}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:"package import option optional required repeated group",built_in:"double float int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64 bool string bytes",literal:"true false"},contains:[e.QUOTE_STRING_MODE,e.NUMBER_MODE,e.C_LINE_COMMENT_MODE,{className:"class",beginKeywords:"message enum service",end:/\{/,illegal:/\n/,contains:[e.inherit(e.TITLE_MODE,{starts:{endsWithParent:!0,excludeEnd:!0}})]},{className:"function",beginKeywords:"rpc",end:/;/,excludeEnd:!0,keywords:"rpc returns"},{begin:/^\s*[A-Z_]+/,end:/\s*=/,excludeEnd:!0}]}}},function(e,t){e.exports=function(e){var t={begin:/\(/,end:/\)/,relevance:0},n={begin:/\[/,end:/\]/},r={className:"comment",begin:/%/,end:/$/,contains:[e.PHRASAL_WORDS_MODE]},i={className:"string",begin:/`/,end:/`/,contains:[e.BACKSLASH_ESCAPE]},a=[{begin:/[a-z][A-Za-z0-9_]*/,relevance:0},{className:"symbol",variants:[{begin:/[A-Z][a-zA-Z0-9_]*/},{begin:/_[A-Za-z0-9_]*/}],relevance:0},t,{begin:/:-/},n,r,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,i,{className:"string",begin:/0\'(\\\'|.)/},{className:"string",begin:/0\'\\s/},e.C_NUMBER_MODE];return t.contains=a,n.contains=a,{contains:a.concat([{begin:/\.$/}])}}},function(e,t){e.exports=function(e){return{contains:[e.C_NUMBER_MODE,{begin:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",end:":",excludeEnd:!0},{begin:"(ncalls|tottime|cumtime)",end:"$",keywords:"ncalls tottime|10 cumtime|10 filename",relevance:10},{begin:"function calls",end:"$",contains:[e.C_NUMBER_MODE],relevance:10},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",begin:"\\(",end:"\\)$",excludeBegin:!0,excludeEnd:!0,relevance:0}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:"BufferedReader PVector PFont PImage PGraphics HashMap boolean byte char color double float int long String Array FloatDict FloatList IntDict IntList JSONArray JSONObject Object StringDict StringList Table TableRow XML false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",literal:"P2D P3D HALF_PI PI QUARTER_PI TAU TWO_PI",title:"setup draw",built_in:"displayHeight displayWidth mouseY mouseX mousePressed pmouseX pmouseY key keyCode pixels focused frameCount frameRate height width size createGraphics beginDraw createShape loadShape PShape arc ellipse line point quad rect triangle bezier bezierDetail bezierPoint bezierTangent curve curveDetail curvePoint curveTangent curveTightness shape shapeMode beginContour beginShape bezierVertex curveVertex endContour endShape quadraticVertex vertex ellipseMode noSmooth rectMode smooth strokeCap strokeJoin strokeWeight mouseClicked mouseDragged mouseMoved mousePressed mouseReleased mouseWheel keyPressed keyPressedkeyReleased keyTyped print println save saveFrame day hour millis minute month second year background clear colorMode fill noFill noStroke stroke alpha blue brightness color green hue lerpColor red saturation modelX modelY modelZ screenX screenY screenZ ambient emissive shininess specular add createImage beginCamera camera endCamera frustum ortho perspective printCamera printProjection cursor frameRate noCursor exit loop noLoop popStyle pushStyle redraw binary boolean byte char float hex int str unbinary unhex join match matchAll nf nfc nfp nfs split splitTokens trim append arrayCopy concat expand reverse shorten sort splice subset box sphere sphereDetail createInput createReader loadBytes loadJSONArray loadJSONObject loadStrings loadTable loadXML open parseXML saveTable selectFolder selectInput beginRaw beginRecord createOutput createWriter endRaw endRecord PrintWritersaveBytes saveJSONArray saveJSONObject saveStream saveStrings saveXML selectOutput popMatrix printMatrix pushMatrix resetMatrix rotate rotateX rotateY rotateZ scale shearX shearY translate ambientLight directionalLight lightFalloff lights lightSpecular noLights normal pointLight spotLight image imageMode loadImage noTint requestImage tint texture textureMode textureWrap blend copy filter get loadPixels set updatePixels blendMode loadShader PShaderresetShader shader createFont loadFont text textFont textAlign textLeading textMode textSize textWidth textAscent textDescent abs ceil constrain dist exp floor lerp log mag map max min norm pow round sq sqrt acos asin atan atan2 cos degrees radians sin tan noise noiseDetail noiseSeed random randomGaussian randomSeed"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t={begin:"`[\\s\\S]",relevance:0},n={className:"variable",variants:[{begin:/\$[\w\d][\w\d_:]*/}]},r={className:"string",variants:[{begin:/"/,end:/"/},{begin:/@"/,end:/^"@/}],contains:[t,n,{className:"variable",begin:/\$[A-z]/,end:/[^A-z]/}]},i=e.inherit(e.COMMENT(null,null),{variants:[{begin:/#/,end:/$/},{begin:/<#/,end:/#>/}],contains:[{className:"doctag",variants:[{begin:/\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{begin:/\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/}]}]});return{aliases:["ps"],lexemes:/-?[A-z\.\-]+/,case_insensitive:!0,keywords:{keyword:"if else foreach return function do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch",built_in:"Add-Computer Add-Content Add-History Add-JobTrigger Add-Member Add-PSSnapin Add-Type Checkpoint-Computer Clear-Content Clear-EventLog Clear-History Clear-Host Clear-Item Clear-ItemProperty Clear-Variable Compare-Object Complete-Transaction Connect-PSSession Connect-WSMan Convert-Path ConvertFrom-Csv ConvertFrom-Json ConvertFrom-SecureString ConvertFrom-StringData ConvertTo-Csv ConvertTo-Html ConvertTo-Json ConvertTo-SecureString ConvertTo-Xml Copy-Item Copy-ItemProperty Debug-Process Disable-ComputerRestore Disable-JobTrigger Disable-PSBreakpoint Disable-PSRemoting Disable-PSSessionConfiguration Disable-WSManCredSSP Disconnect-PSSession Disconnect-WSMan Disable-ScheduledJob Enable-ComputerRestore Enable-JobTrigger Enable-PSBreakpoint Enable-PSRemoting Enable-PSSessionConfiguration Enable-ScheduledJob Enable-WSManCredSSP Enter-PSSession Exit-PSSession Export-Alias Export-Clixml Export-Console Export-Counter Export-Csv Export-FormatData Export-ModuleMember Export-PSSession ForEach-Object Format-Custom Format-List Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-ComputerRestorePoint Get-Content Get-ControlPanelItem Get-Counter Get-Credential Get-Culture Get-Date Get-Event Get-EventLog Get-EventSubscriber Get-ExecutionPolicy Get-FormatData Get-Host Get-HotFix Get-Help Get-History Get-IseSnippet Get-Item Get-ItemProperty Get-Job Get-JobTrigger Get-Location Get-Member Get-Module Get-PfxCertificate Get-Process Get-PSBreakpoint Get-PSCallStack Get-PSDrive Get-PSProvider Get-PSSession Get-PSSessionConfiguration Get-PSSnapin Get-Random Get-ScheduledJob Get-ScheduledJobOption Get-Service Get-TraceSource Get-Transaction Get-TypeData Get-UICulture Get-Unique Get-Variable Get-Verb Get-WinEvent Get-WmiObject Get-WSManCredSSP Get-WSManInstance Group-Object Import-Alias Import-Clixml Import-Counter Import-Csv Import-IseSnippet Import-LocalizedData Import-PSSession Import-Module Invoke-AsWorkflow Invoke-Command Invoke-Expression Invoke-History Invoke-Item Invoke-RestMethod Invoke-WebRequest Invoke-WmiMethod Invoke-WSManAction Join-Path Limit-EventLog Measure-Command Measure-Object Move-Item Move-ItemProperty New-Alias New-Event New-EventLog New-IseSnippet New-Item New-ItemProperty New-JobTrigger New-Object New-Module New-ModuleManifest New-PSDrive New-PSSession New-PSSessionConfigurationFile New-PSSessionOption New-PSTransportOption New-PSWorkflowExecutionOption New-PSWorkflowSession New-ScheduledJobOption New-Service New-TimeSpan New-Variable New-WebServiceProxy New-WinEvent New-WSManInstance New-WSManSessionOption Out-Default Out-File Out-GridView Out-Host Out-Null Out-Printer Out-String Pop-Location Push-Location Read-Host Receive-Job Register-EngineEvent Register-ObjectEvent Register-PSSessionConfiguration Register-ScheduledJob Register-WmiEvent Remove-Computer Remove-Event Remove-EventLog Remove-Item Remove-ItemProperty Remove-Job Remove-JobTrigger Remove-Module Remove-PSBreakpoint Remove-PSDrive Remove-PSSession Remove-PSSnapin Remove-TypeData Remove-Variable Remove-WmiObject Remove-WSManInstance Rename-Computer Rename-Item Rename-ItemProperty Reset-ComputerMachinePassword Resolve-Path Restart-Computer Restart-Service Restore-Computer Resume-Job Resume-Service Save-Help Select-Object Select-String Select-Xml Send-MailMessage Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-JobTrigger Set-Location Set-PSBreakpoint Set-PSDebug Set-PSSessionConfiguration Set-ScheduledJob Set-ScheduledJobOption Set-Service Set-StrictMode Set-TraceSource Set-Variable Set-WmiInstance Set-WSManInstance Set-WSManQuickConfig Show-Command Show-ControlPanelItem Show-EventLog Sort-Object Split-Path Start-Job Start-Process Start-Service Start-Sleep Start-Transaction Start-Transcript Stop-Computer Stop-Job Stop-Process Stop-Service Stop-Transcript Suspend-Job Suspend-Service Tee-Object Test-ComputerSecureChannel Test-Connection Test-ModuleManifest Test-Path Test-PSSessionConfigurationFile Trace-Command Unblock-File Undo-Transaction Unregister-Event Unregister-PSSessionConfiguration Unregister-ScheduledJob Update-FormatData Update-Help Update-List Update-TypeData Use-Transaction Wait-Event Wait-Job Wait-Process Where-Object Write-Debug Write-Error Write-EventLog Write-Host Write-Output Write-Progress Write-Verbose Write-Warning Add-MDTPersistentDrive Disable-MDTMonitorService Enable-MDTMonitorService Get-MDTDeploymentShareStatistics Get-MDTMonitorData Get-MDTOperatingSystemCatalog Get-MDTPersistentDrive Import-MDTApplication Import-MDTDriver Import-MDTOperatingSystem Import-MDTPackage Import-MDTTaskSequence New-MDTDatabase Remove-MDTMonitorData Remove-MDTPersistentDrive Restore-MDTPersistentDrive Set-MDTMonitorData Test-MDTDeploymentShare Test-MDTMonitorData Update-MDTDatabaseSchema Update-MDTDeploymentShare Update-MDTLinkedDS Update-MDTMedia Update-MDTMedia Add-VamtProductKey Export-VamtData Find-VamtManagedMachine Get-VamtConfirmationId Get-VamtProduct Get-VamtProductKey Import-VamtData Initialize-VamtData Install-VamtConfirmationId Install-VamtProductActivation Install-VamtProductKey Update-VamtProduct",nomarkup:"-ne -eq -lt -gt -ge -le -not -like -notlike -match -notmatch -contains -notcontains -in -notin -replace"},contains:[t,e.NUMBER_MODE,r,{className:"string",variants:[{begin:/'/,end:/'/},{begin:/@'/,end:/^'@/}]},{className:"literal",begin:/\$(null|true|false)\b/},n,i]}}},function(e,t){e.exports=function(e){var t={className:"string",begin:'"',end:'"',contains:[e.BACKSLASH_ESCAPE]},n={className:"string",begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE],relevance:0},r={className:"type",begin:"\\b_?[A-Z][\\w]*",relevance:0},i={begin:e.IDENT_RE+"'",relevance:0};return{keywords:{keyword:"actor addressof and as be break class compile_error compile_intrinsicconsume continue delegate digestof do else elseif embed end errorfor fun if ifdef in interface is isnt lambda let match new not objector primitive recover repeat return struct then trait try type until use var where while with xor",meta:"iso val tag trn box ref",literal:"this false true"},contains:[{className:"class",beginKeywords:"class actor",end:"$",contains:[e.TITLE_MODE,e.C_LINE_COMMENT_MODE]},{className:"function",beginKeywords:"new fun",end:"=>",contains:[e.TITLE_MODE,{begin:/\(/,end:/\)/,contains:[r,i,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},{begin:/:/,endsWithParent:!0,contains:[r]},e.C_LINE_COMMENT_MODE]},r,{className:"string",begin:'"""',end:'"""',relevance:10},t,n,i,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}}},function(e,t){e.exports=function(e){var t={begin:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},n={className:"meta",begin:/<\?(php)?|\?>/},r={className:"string",contains:[e.BACKSLASH_ESCAPE,n],variants:[{begin:'b"',end:'"'},{begin:"b'",end:"'"},e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null})]},i={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]};return{aliases:["php3","php4","php5","php6"],case_insensitive:!0,keywords:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",contains:[e.HASH_COMMENT_MODE,e.COMMENT("//","$",{contains:[n]}),e.COMMENT("/\\*","\\*/",{contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.COMMENT("__halt_compiler.+?;",!1,{endsWithParent:!0,keywords:"__halt_compiler",lexemes:e.UNDERSCORE_IDENT_RE}),{className:"string",begin:/<<<['"]?\w+['"]?$/,end:/^\w+;?$/,contains:[e.BACKSLASH_ESCAPE,{className:"subst",variants:[{begin:/\$\w+/},{begin:/\{\$/,end:/\}/}]}]},n,{className:"keyword",begin:/\$this\b/},t,{begin:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{className:"function",beginKeywords:"function",end:/[;{]/,excludeEnd:!0,illegal:"\\$|\\[|%",contains:[e.UNDERSCORE_TITLE_MODE,{className:"params",begin:"\\(",end:"\\)",contains:["self",t,e.C_BLOCK_COMMENT_MODE,r,i]}]},{className:"class",beginKeywords:"class interface",end:"{",excludeEnd:!0,illegal:/[:\(\$"]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"namespace",end:";",illegal:/[\.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"use",end:";",contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"=>"},r,i]}}},function(e,t){e.exports=function(e){return{aliases:["pf.conf"],lexemes:/[a-z0-9_<>-]+/,keywords:{built_in:"block match pass load anchor|5 antispoof|10 set table",keyword:"in out log quick on rdomain inet inet6 proto from port os to routeallow-opts divert-packet divert-reply divert-to flags group icmp-typeicmp6-type label once probability recieved-on rtable prio queuetos tag tagged user keep fragment for os dropaf-to|10 binat-to|10 nat-to|10 rdr-to|10 bitmask least-stats random round-robinsource-hash static-portdup-to reply-to route-toparent bandwidth default min max qlimitblock-policy debug fingerprints hostid limit loginterface optimizationreassemble ruleset-optimization basic none profile skip state-defaultsstate-policy timeoutconst counters persistno modulate synproxy state|5 floating if-bound no-sync pflow|10 sloppysource-track global rule max-src-nodes max-src-states max-src-connmax-src-conn-rate overload flushscrub|5 max-mss min-ttl no-df|10 random-id",literal:"all any no-route self urpf-failed egress|5 unknown"},contains:[e.HASH_COMMENT_MODE,e.NUMBER_MODE,e.QUOTE_STRING_MODE,{className:"variable",begin:/\$[\w\d#@][\w\d_]*/},{className:"variable",begin:/<(?!\/)/,end:/>/}]}}},function(e,t){e.exports=function(e){var t=e.COMMENT("{","}",{contains:["self"]});return{subLanguage:"xml",relevance:0,contains:[e.COMMENT("^#","$"),e.COMMENT("\\^rem{","}",{relevance:10,contains:[t]}),{className:"meta",begin:"^@(?:BASE|USE|CLASS|OPTIONS)$",relevance:10},{className:"title",begin:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{className:"variable",begin:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{className:"keyword",begin:"\\^[\\w\\-\\.\\:]+"},{className:"number",begin:"\\^#[0-9a-fA-F]+"},e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t="abstract add and array as asc aspect assembly async begin break block by case class concat const copy constructor continue create default delegate desc distinct div do downto dynamic each else empty end ensure enum equals event except exit extension external false final finalize finalizer finally flags for forward from function future global group has if implementation implements implies in index inherited inline interface into invariants is iterator join locked locking loop matching method mod module namespace nested new nil not notify nullable of old on operator or order out override parallel params partial pinned private procedure property protected public queryable raise read readonly record reintroduce remove repeat require result reverse sealed select self sequence set shl shr skip static step soft take then to true try tuple type union unit unsafe until uses using var virtual raises volatile where while with write xor yield await mapped deprecated stdcall cdecl pascal register safecall overload library platform reference packed strict published autoreleasepool selector strong weak unretained",n=e.COMMENT("{","}",{relevance:0}),r=e.COMMENT("\\(\\*","\\*\\)",{relevance:10}),i={className:"string",begin:"'",end:"'",contains:[{begin:"''"}]},a={className:"string",begin:"(#\\d+)+"},o={className:"function",beginKeywords:"function constructor destructor procedure method",end:"[:;]",keywords:"function constructor|10 destructor|10 procedure|10 method|10",contains:[e.TITLE_MODE,{className:"params",begin:"\\(",end:"\\)",keywords:t,contains:[i,a]},n,r]};return{case_insensitive:!0,lexemes:/\.?\w+/,keywords:t,illegal:'("|\\$[G-Zg-z]|\\/\\*||->)',contains:[n,r,e.C_LINE_COMMENT_MODE,i,a,e.NUMBER_MODE,o,{className:"class",begin:"=\\bclass\\b",end:"end;",keywords:t,contains:[i,a,n,r,e.C_LINE_COMMENT_MODE,o]}]}}},function(e,t){e.exports=function(e){var t={className:"keyword",begin:"\\$(f[asn]|t|vp[rtd]|children)"},n={className:"number",begin:"\\b\\d+(\\.\\d+)?(e-?\\d+)?",relevance:0},r=e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),i={className:"function",beginKeywords:"module function",end:"\\=|\\{",contains:[{className:"params",begin:"\\(",end:"\\)",contains:["self",n,r,t,{className:"literal",begin:"false|true|PI|undef"}]},e.UNDERSCORE_TITLE_MODE]};return{aliases:["scad"],keywords:{keyword:"function module include use for intersection_for if else \\%",literal:"false true PI undef",built_in:"circle square polygon text sphere cube cylinder polyhedron translate rotate scale resize mirror multmatrix color offset hull minkowski union difference intersection abs sign sin cos tan acos asin atan atan2 floor round ceil ln log pow sqrt exp rands min max concat lookup str chr search version version_num norm cross parent_module echo import import_dxf dxf_linear_extrude linear_extrude rotate_extrude surface projection render children dxf_cross dxf_dim let assign"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,{className:"meta",keywords:{"meta-keyword":"include use"},begin:"include|use <",end:">"},r,t,{begin:"[*!#%]",relevance:0},i]}}},function(e,t){e.exports=function(e){return{aliases:["ml"],keywords:{keyword:"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value",built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref",literal:"true false"},illegal:/\/\/|>>/,lexemes:"[a-z_]\\w*!?",contains:[{className:"literal",begin:"\\[(\\|\\|)?\\]|\\(\\)",relevance:0},e.COMMENT("\\(\\*","\\*\\)",{contains:["self"]}),{className:"symbol",begin:"'[A-Za-z_](?!')[\\w']*"},{className:"type",begin:"`[A-Z][\\w']*"},{className:"type",begin:"\\b[A-Z][\\w']*",relevance:0},{begin:"[a-z_]\\w*'[\\w']*",relevance:0},e.inherit(e.APOS_STRING_MODE,{className:"string",relevance:0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),{className:"number",begin:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",relevance:0},{begin:/[-=]>/}]}}},function(e,t){e.exports=function(e){var t=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],keywords:{keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},lexemes:t,illegal:""}]}]},{className:"class",begin:"("+n.split(" ").join("|")+")\\b",end:"({|$)",excludeEnd:!0,keywords:n,lexemes:t,contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE,relevance:0}]}}},function(e,t){e.exports=function(e){var t={className:"variable",begin:/\$+{[\w\.:-]+}/},n={className:"variable",begin:/\$+\w+/,illegal:/\(\){}/},r={className:"variable",begin:/\$+\([\w\^\.:-]+\)/},i={className:"string",variants:[{begin:'"',end:'"'},{begin:"'",end:"'"},{begin:"`",end:"`"}],illegal:/\n/,contains:[{className:"subst",begin:/\$(\\[nrt]|\$)/},{className:"variable",begin:/\$(ADMINTOOLS|APPDATA|CDBURN_AREA|CMDLINE|COMMONFILES32|COMMONFILES64|COMMONFILES|COOKIES|DESKTOP|DOCUMENTS|EXEDIR|EXEFILE|EXEPATH|FAVORITES|FONTS|HISTORY|HWNDPARENT|INSTDIR|INTERNET_CACHE|LANGUAGE|LOCALAPPDATA|MUSIC|NETHOOD|OUTDIR|PICTURES|PLUGINSDIR|PRINTHOOD|PROFILE|PROGRAMFILES32|PROGRAMFILES64|PROGRAMFILES|QUICKLAUNCH|RECENT|RESOURCES_LOCALIZED|RESOURCES|SENDTO|SMPROGRAMS|SMSTARTUP|STARTMENU|SYSDIR|TEMP|TEMPLATES|VIDEOS|WINDIR)/},t,n,r]};return{case_insensitive:!1,keywords:{keyword:"Abort AddBrandingImage AddSize AllowRootDirInstall AllowSkipFiles AutoCloseWindow BGFont BGGradient BrandingText BringToFront Call CallInstDLL Caption ChangeUI CheckBitmap ClearErrors CompletedText ComponentText CopyFiles CRCCheck CreateDirectory CreateFont CreateShortCut Delete DeleteINISec DeleteINIStr DeleteRegKey DeleteRegValue DetailPrint DetailsButtonText DirText DirVar DirVerify EnableWindow EnumRegKey EnumRegValue Exch Exec ExecShell ExecWait ExpandEnvStrings File FileBufSize FileClose FileErrorText FileOpen FileRead FileReadByte FileReadUTF16LE FileReadWord FileSeek FileWrite FileWriteByte FileWriteUTF16LE FileWriteWord FindClose FindFirst FindNext FindWindow FlushINI FunctionEnd GetCurInstType GetCurrentAddress GetDlgItem GetDLLVersion GetDLLVersionLocal GetErrorLevel GetFileTime GetFileTimeLocal GetFullPathName GetFunctionAddress GetInstDirError GetLabelAddress GetTempFileName Goto HideWindow Icon IfAbort IfErrors IfFileExists IfRebootFlag IfSilent InitPluginsDir InstallButtonText InstallColors InstallDir InstallDirRegKey InstProgressFlags InstType InstTypeGetText InstTypeSetText IntCmp IntCmpU IntFmt IntOp IsWindow LangString LicenseBkColor LicenseData LicenseForceSelection LicenseLangString LicenseText LoadLanguageFile LockWindow LogSet LogText ManifestDPIAware ManifestSupportedOS MessageBox MiscButtonText Name Nop OutFile Page PageCallbacks PageExEnd Pop Push Quit ReadEnvStr ReadINIStr ReadRegDWORD ReadRegStr Reboot RegDLL Rename RequestExecutionLevel ReserveFile Return RMDir SearchPath SectionEnd SectionGetFlags SectionGetInstTypes SectionGetSize SectionGetText SectionGroupEnd SectionIn SectionSetFlags SectionSetInstTypes SectionSetSize SectionSetText SendMessage SetAutoClose SetBrandingImage SetCompress SetCompressor SetCompressorDictSize SetCtlColors SetCurInstType SetDatablockOptimize SetDateSave SetDetailsPrint SetDetailsView SetErrorLevel SetErrors SetFileAttributes SetFont SetOutPath SetOverwrite SetRebootFlag SetRegView SetShellVarContext SetSilent ShowInstDetails ShowUninstDetails ShowWindow SilentInstall SilentUnInstall Sleep SpaceTexts StrCmp StrCmpS StrCpy StrLen SubCaption Unicode UninstallButtonText UninstallCaption UninstallIcon UninstallSubCaption UninstallText UninstPage UnRegDLL Var VIAddVersionKey VIFileVersion VIProductVersion WindowIcon WriteINIStr WriteRegBin WriteRegDWORD WriteRegExpandStr WriteRegStr WriteUninstaller XPStyle",literal:"admin all auto both bottom bzip2 colored components current custom directory false force hide highest ifdiff ifnewer instfiles lastused leave left license listonly lzma nevershow none normal notset off on open print right show silent silentlog smooth textonly top true try un.components un.custom un.directory un.instfiles un.license uninstConfirm user Win10 Win7 Win8 WinVista zlib"},contains:[e.HASH_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.COMMENT(";","$",{relevance:0}),{className:"function",beginKeywords:"Function PageEx Section SectionGroup",end:"$"},i,{className:"keyword",begin:/\!(addincludedir|addplugindir|appendfile|cd|define|delfile|echo|else|endif|error|execute|finalize|getdllversionsystem|ifdef|ifmacrodef|ifmacrondef|ifndef|if|include|insertmacro|macroend|macro|makensis|packhdr|searchparse|searchreplace|tempfile|undef|verbose|warning)/},t,n,r,{className:"params",begin:"(ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HKCR|HKCU|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM|HKPD|HKU|IDABORT|IDCANCEL|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)"},{className:"class",begin:/\w+\:\:\w+/},e.NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t={keyword:"rec with let in inherit assert if else then",literal:"true false or and null",built_in:"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},n={className:"subst",begin:/\$\{/,end:/}/,keywords:t},r={className:"string",contains:[n],variants:[{begin:"''",end:"''"},{begin:'"',end:'"'}]},i=[e.NUMBER_MODE,e.HASH_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,r,{begin:/[a-zA-Z0-9-_]+(\s*=)/,returnBegin:!0,relevance:0,contains:[{className:"attr",begin:/\S+/}]}];return n.contains=i,{aliases:["nixos"],keywords:t,contains:i}}},function(e,t){e.exports=function(e){return{aliases:["nim"],keywords:{keyword:"addr and as asm bind block break case cast const continue converter discard distinct div do elif else end enum except export finally for from generic if import in include interface is isnot iterator let macro method mixin mod nil not notin object of or out proc ptr raise ref return shl shr static template try tuple type using var when while with without xor yield",literal:"shared guarded stdin stdout stderr result true false",built_in:"int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 bool char string cstring pointer expr stmt void auto any range array openarray varargs seq set clong culong cchar cschar cshort cint csize clonglong cfloat cdouble clongdouble cuchar cushort cuint culonglong cstringarray semistatic"},contains:[{className:"meta",begin:/{\./,end:/\.}/,relevance:10},{className:"string",begin:/[a-zA-Z]\w*"/,end:/"/,contains:[{begin:/""/}]},{className:"string",begin:/([a-zA-Z]\w*)?"""/,end:/"""/},e.QUOTE_STRING_MODE,{className:"type",begin:/\b[A-Z]\w+\b/,relevance:0},{className:"number",relevance:0,variants:[{begin:/\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?/},{begin:/\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?/},{begin:/\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?/},{begin:/\b(\d[_\d]*)('?[iIuUfF](8|16|32|64))?/}]},e.HASH_COMMENT_MODE]}}},function(e,t){e.exports=function(e){var t={className:"variable",variants:[{begin:/\$\d+/},{begin:/\$\{/,end:/}/},{begin:"[\\$\\@]"+e.UNDERSCORE_IDENT_RE}]},n={endsWithParent:!0,lexemes:"[a-z/_]+",keywords:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},relevance:0,illegal:"=>",contains:[e.HASH_COMMENT_MODE,{className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:/"/,end:/"/},{begin:/'/,end:/'/}]},{begin:"([a-z]+):/",end:"\\s",endsWithParent:!0,excludeEnd:!0,contains:[t]},{className:"regexp",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:"\\s\\^",end:"\\s|{|;",returnEnd:!0},{begin:"~\\*?\\s+",end:"\\s|{|;",returnEnd:!0},{begin:"\\*(\\.[a-z\\-]+)+"},{begin:"([a-z\\-]+\\.)+\\*"}]},{className:"number",begin:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{className:"number",begin:"\\b\\d+[kKmMgGdshdwy]*\\b",relevance:0},t]};return{aliases:["nginxconf"],contains:[e.HASH_COMMENT_MODE,{begin:e.UNDERSCORE_IDENT_RE+"\\s+{",returnBegin:!0,end:"{",contains:[{className:"section",begin:e.UNDERSCORE_IDENT_RE}],relevance:0},{begin:e.UNDERSCORE_IDENT_RE+"\\s",end:";|{",returnBegin:!0,contains:[{className:"attribute",begin:e.UNDERSCORE_IDENT_RE,starts:n}],relevance:0}],illegal:"[^\\s\\}]"}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,contains:[{beginKeywords:"build create index delete drop explain infer|10 insert merge prepare select update upsert|10",end:/;/,endsWithParent:!0,keywords:{keyword:"all alter analyze and any array as asc begin between binary boolean break bucket build by call case cast cluster collate collection commit connect continue correlate cover create database dataset datastore declare decrement delete derived desc describe distinct do drop each element else end every except exclude execute exists explain fetch first flatten for force from function grant group gsi having if ignore ilike in include increment index infer inline inner insert intersect into is join key keys keyspace known last left let letting like limit lsm map mapping matched materialized merge minus namespace nest not number object offset on option or order outer over parse partition password path pool prepare primary private privilege procedure public raw realm reduce rename return returning revoke right role rollback satisfies schema select self semi set show some start statistics string system then to transaction trigger truncate under union unique unknown unnest unset update upsert use user using validate value valued values via view when where while with within work xor",literal:"true false null missing|5",built_in:"array_agg array_append array_concat array_contains array_count array_distinct array_ifnull array_length array_max array_min array_position array_prepend array_put array_range array_remove array_repeat array_replace array_reverse array_sort array_sum avg count max min sum greatest least ifmissing ifmissingornull ifnull missingif nullif ifinf ifnan ifnanorinf naninf neginfif posinfif clock_millis clock_str date_add_millis date_add_str date_diff_millis date_diff_str date_part_millis date_part_str date_trunc_millis date_trunc_str duration_to_str millis str_to_millis millis_to_str millis_to_utc millis_to_zone_name now_millis now_str str_to_duration str_to_utc str_to_zone_name decode_json encode_json encoded_size poly_length base64 base64_encode base64_decode meta uuid abs acos asin atan atan2 ceil cos degrees e exp ln log floor pi power radians random round sign sin sqrt tan trunc object_length object_names object_pairs object_inner_pairs object_values object_inner_values object_add object_put object_remove object_unwrap regexp_contains regexp_like regexp_position regexp_replace contains initcap length lower ltrim position repeat replace rtrim split substr title trim upper isarray isatom isboolean isnumber isobject isstring type toarray toatom toboolean tonumber toobject tostring"},contains:[{className:"string",begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE],relevance:0},{className:"string",begin:'"',end:'"',contains:[e.BACKSLASH_ESCAPE],relevance:0},{className:"symbol",begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE],relevance:2},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_BLOCK_COMMENT_MODE]}}},function(e,t){e.exports=function(e){var t={keyword:"if then not for in while do return else elseif break continue switch and or unless when class extends super local import export from using",literal:"true false nil",built_in:"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={className:"subst",begin:/#\{/,end:/}/,keywords:t},i=[e.inherit(e.C_NUMBER_MODE,{starts:{end:"(\\s*/)?",relevance:0}}),{className:"string",variants:[{begin:/'/,end:/'/,contains:[e.BACKSLASH_ESCAPE]},{begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,r]}]},{className:"built_in",begin:"@__"+e.IDENT_RE},{begin:"@"+e.IDENT_RE},{begin:e.IDENT_RE+"\\\\"+e.IDENT_RE}];r.contains=i;var a=e.inherit(e.TITLE_MODE,{begin:n}),o={className:"params",begin:"\\([^\\(]",returnBegin:!0,contains:[{begin:/\(/,end:/\)/,keywords:t,contains:["self"].concat(i)}]};return{aliases:["moon"],keywords:t,illegal:/\/\*/,contains:i.concat([e.COMMENT("--","$"),{className:"function",begin:"^\\s*"+n+"\\s*=\\s*(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[a,o]},{begin:/[\(,:=]\s*/,relevance:0,contains:[{className:"function",begin:"(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[o]}]},{className:"class",beginKeywords:"class",end:"$",illegal:/[:="\[\]]/,contains:[{beginKeywords:"extends",endsWithParent:!0,illegal:/[:="\[\]]/,contains:[a]},a]},{className:"name",begin:n+":",end:":",returnBegin:!0,returnEnd:!0,relevance:0}])}}},function(e,t){e.exports=function(e){var t={className:"number",relevance:0,variants:[{begin:"[$][a-fA-F0-9]+"},e.NUMBER_MODE]};return{case_insensitive:!0,keywords:{keyword:"public private property continue exit extern new try catch eachin not abstract final select case default const local global field end if then else elseif endif while wend repeat until forever for to step next return module inline throw import",built_in:"DebugLog DebugStop Error Print ACos ACosr ASin ASinr ATan ATan2 ATan2r ATanr Abs Abs Ceil Clamp Clamp Cos Cosr Exp Floor Log Max Max Min Min Pow Sgn Sgn Sin Sinr Sqrt Tan Tanr Seed PI HALFPI TWOPI",literal:"true false null and or shl shr mod"},illegal:/\/\*/,contains:[e.COMMENT("#rem","#end"),e.COMMENT("'","$",{relevance:0}),{className:"function",beginKeywords:"function method",end:"[(=:]|$",illegal:/\n/,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"class",beginKeywords:"class interface",end:"$",contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{className:"built_in",begin:"\\b(self|super)\\b"},{className:"meta",begin:"\\s*#",end:"$",keywords:{"meta-keyword":"if else elseif endif end then"}},{className:"meta",begin:"^\\s*strict\\b"},{beginKeywords:"alias",end:"=",contains:[e.UNDERSCORE_TITLE_MODE]},e.QUOTE_STRING_MODE,t]}}},function(e,t){e.exports=function(e){return{subLanguage:"xml",contains:[{className:"meta",begin:"^__(END|DATA)__$"},{begin:"^\\s*%{1,2}={0,2}",end:"$",subLanguage:"perl"},{begin:"<%{1,2}={0,2}",end:"={0,1}%>",subLanguage:"perl",excludeBegin:!0,excludeEnd:!0}]}}},function(e,t){e.exports=function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",n={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:t},r={begin:"->{",end:"}"},i={variants:[{begin:/\$\d/},{begin:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{begin:/[\$%@][^\s\w{]/,relevance:0}]},a=[e.BACKSLASH_ESCAPE,n,i],o=[i,e.HASH_COMMENT_MODE,e.COMMENT("^\\=\\w","\\=cut",{endsWithParent:!0}),r,{className:"string",contains:a,variants:[{begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[",end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*\\<",end:"\\>",relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE]},{begin:"{\\w+}",contains:[],relevance:0},{begin:"-?\\w+\\s*\\=\\>",contains:[],relevance:0}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*",keywords:"split return print reverse grep",relevance:0,contains:[e.HASH_COMMENT_MODE,{className:"regexp",begin:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",relevance:10},{className:"regexp",begin:"(m|qr)?/",end:"/[a-z]*",contains:[e.BACKSLASH_ESCAPE],relevance:0}]},{className:"function",beginKeywords:"sub",end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$",subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}]}];return n.contains=o,r.contains=o,{aliases:["pl","pm"],lexemes:/[\w\.]+/,keywords:t,contains:o}}},function(e,t){e.exports=function(e){return{keywords:"environ vocabularies notations constructors definitions registrations theorems schemes requirements begin end definition registration cluster existence pred func defpred deffunc theorem proof let take assume then thus hence ex for st holds consider reconsider such that and in provided of as from be being by means equals implies iff redefine define now not or attr is mode suppose per cases set thesis contradiction scheme reserve struct correctness compatibility coherence symmetry assymetry reflexivity irreflexivity connectedness uniqueness commutativity idempotence involutiveness projectivity",contains:[e.COMMENT("::","$")]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,aliases:["mips"],lexemes:"\\.?"+e.IDENT_RE,keywords:{meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .ltorg ",built_in:"$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 $17 $18 $19 $20 $21 $22 $23 $24 $25 $26 $27 $28 $29 $30 $31 zero at v0 v1 a0 a1 a2 a3 a4 a5 a6 a7 t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 s0 s1 s2 s3 s4 s5 s6 s7 s8 k0 k1 gp sp fp ra $f0 $f1 $f2 $f2 $f4 $f5 $f6 $f7 $f8 $f9 $f10 $f11 $f12 $f13 $f14 $f15 $f16 $f17 $f18 $f19 $f20 $f21 $f22 $f23 $f24 $f25 $f26 $f27 $f28 $f29 $f30 $f31 Context Random EntryLo0 EntryLo1 Context PageMask Wired EntryHi HWREna BadVAddr Count Compare SR IntCtl SRSCtl SRSMap Cause EPC PRId EBase Config Config1 Config2 Config3 LLAddr Debug DEPC DESAVE CacheErr ECC ErrorEPC TagLo DataLo TagHi DataHi WatchLo WatchHi PerfCtl PerfCnt "},contains:[{className:"keyword",begin:"\\b(addi?u?|andi?|b(al)?|beql?|bgez(al)?l?|bgtzl?|blezl?|bltz(al)?l?|bnel?|cl[oz]|divu?|ext|ins|j(al)?|jalr(.hb)?|jr(.hb)?|lbu?|lhu?|ll|lui|lw[lr]?|maddu?|mfhi|mflo|movn|movz|move|msubu?|mthi|mtlo|mul|multu?|nop|nor|ori?|rotrv?|sb|sc|se[bh]|sh|sllv?|slti?u?|srav?|srlv?|subu?|sw[lr]?|xori?|wsbh|abs.[sd]|add.[sd]|alnv.ps|bc1[ft]l?|c.(s?f|un|u?eq|[ou]lt|[ou]le|ngle?|seq|l[et]|ng[et]).[sd]|(ceil|floor|round|trunc).[lw].[sd]|cfc1|cvt.d.[lsw]|cvt.l.[dsw]|cvt.ps.s|cvt.s.[dlw]|cvt.s.p[lu]|cvt.w.[dls]|div.[ds]|ldx?c1|luxc1|lwx?c1|madd.[sd]|mfc1|mov[fntz]?.[ds]|msub.[sd]|mth?c1|mul.[ds]|neg.[ds]|nmadd.[ds]|nmsub.[ds]|p[lu][lu].ps|recip.fmt|r?sqrt.[ds]|sdx?c1|sub.[ds]|suxc1|swx?c1|break|cache|d?eret|[de]i|ehb|mfc0|mtc0|pause|prefx?|rdhwr|rdpgpr|sdbbp|ssnop|synci?|syscall|teqi?|tgei?u?|tlb(p|r|w[ir])|tlti?u?|tnei?|wait|wrpgpr)",end:"\\s"},e.COMMENT("[;#]","$"),e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,{className:"string",begin:"'",end:"[^\\\\]'",relevance:0},{className:"title",begin:"\\|",end:"\\|",illegal:"\\n",relevance:0},{className:"number",variants:[{begin:"0x[0-9a-f]+"},{begin:"\\b-?\\d+"}],relevance:0},{className:"symbol",variants:[{begin:"^\\s*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{begin:"^\\s*[0-9]+:"},{begin:"[0-9]+[bf]"}],relevance:0}],illegal:"/"}}},function(e,t){e.exports=function(e){var t=e.COMMENT("%","$"),n=e.inherit(e.APOS_STRING_MODE,{relevance:0}),r=e.inherit(e.QUOTE_STRING_MODE,{relevance:0});r.contains.push({className:"subst",begin:"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]",relevance:0});return{aliases:["m","moo"],keywords:{keyword:"module use_module import_module include_module end_module initialise mutable initialize finalize finalise interface implementation pred mode func type inst solver any_pred any_func is semidet det nondet multi erroneous failure cc_nondet cc_multi typeclass instance where pragma promise external trace atomic or_else require_complete_switch require_det require_semidet require_multi require_nondet require_cc_multi require_cc_nondet require_erroneous require_failure",meta:"inline no_inline type_spec source_file fact_table obsolete memo loop_check minimal_model terminates does_not_terminate check_termination promise_equivalent_clauses foreign_proc foreign_decl foreign_code foreign_type foreign_import_module foreign_export_enum foreign_export foreign_enum may_call_mercury will_not_call_mercury thread_safe not_thread_safe maybe_thread_safe promise_pure promise_semipure tabled_for_io local untrailed trailed attach_to_io_state can_pass_as_mercury_type stable will_not_throw_exception may_modify_trail will_not_modify_trail may_duplicate may_not_duplicate affects_liveness does_not_affect_liveness doesnt_affect_liveness no_sharing unknown_sharing sharing",built_in:"some all not if then else true fail false try catch catch_any semidet_true semidet_false semidet_fail impure_true impure semipure"},contains:[{className:"built_in",variants:[{begin:"<=>"},{begin:"<=",relevance:0},{begin:"=>",relevance:0},{begin:"/\\\\"},{begin:"\\\\/"}]},{className:"built_in",variants:[{begin:":-\\|--\x3e"},{begin:"=",relevance:0}]},t,e.C_BLOCK_COMMENT_MODE,{className:"number",begin:"0'.\\|0[box][0-9a-fA-F]*"},e.NUMBER_MODE,n,r,{begin:/:-/}]}}},function(e,t){e.exports=function(e){return{keywords:"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform",illegal:"\\*?",end:"\\->\\*?"},{begin:"("+n+"\\s*(?:=|:=)\\s*)?!?(\\(.*\\))?\\s*\\B[-~]{1,2}>\\*?",end:"[-~]{1,2}>\\*?"},{begin:"("+n+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B!?[-~]{1,2}>\\*?",end:"!?[-~]{1,2}>\\*?"}]},{className:"class",beginKeywords:"class",end:"$",illegal:/[:="\[\]]/,contains:[{beginKeywords:"extends",endsWithParent:!0,illegal:/[:="\[\]]/,contains:[r]},r]},{begin:n+":",end:":",returnBegin:!0,returnEnd:!0,relevance:0}])}}},function(e,t){e.exports=function(e){var t={begin:"\\b[gtps][A-Z]+[A-Za-z0-9_\\-]*\\b|\\$_[A-Z]+",relevance:0},n=[e.C_BLOCK_COMMENT_MODE,e.HASH_COMMENT_MODE,e.COMMENT("--","$"),e.COMMENT("[^:]//","$")],r=e.inherit(e.TITLE_MODE,{variants:[{begin:"\\b_*rig[A-Z]+[A-Za-z0-9_\\-]*"},{begin:"\\b_[a-z0-9\\-]+"}]}),i=e.inherit(e.TITLE_MODE,{begin:"\\b([A-Za-z0-9_\\-]+)\\b"});return{case_insensitive:!1,keywords:{keyword:"$_COOKIE $_FILES $_GET $_GET_BINARY $_GET_RAW $_POST $_POST_BINARY $_POST_RAW $_SESSION $_SERVER codepoint codepoints segment segments codeunit codeunits sentence sentences trueWord trueWords paragraph after byte bytes english the until http forever descending using line real8 with seventh for stdout finally element word words fourth before black ninth sixth characters chars stderr uInt1 uInt1s uInt2 uInt2s stdin string lines relative rel any fifth items from middle mid at else of catch then third it file milliseconds seconds second secs sec int1 int1s int4 int4s internet int2 int2s normal text item last long detailed effective uInt4 uInt4s repeat end repeat URL in try into switch to words https token binfile each tenth as ticks tick system real4 by dateItems without char character ascending eighth whole dateTime numeric short first ftp integer abbreviated abbr abbrev private case while if div mod wrap and or bitAnd bitNot bitOr bitXor among not in a an within contains ends with begins the keys of keys",literal:"SIX TEN FORMFEED NINE ZERO NONE SPACE FOUR FALSE COLON CRLF PI COMMA ENDOFFILE EOF EIGHT FIVE QUOTE EMPTY ONE TRUE RETURN CR LINEFEED RIGHT BACKSLASH NULL SEVEN TAB THREE TWO six ten formfeed nine zero none space four false colon crlf pi comma endoffile eof eight five quote empty one true return cr linefeed right backslash null seven tab three two RIVERSION RISTATE FILE_READ_MODE FILE_WRITE_MODE FILE_WRITE_MODE DIR_WRITE_MODE FILE_READ_UMASK FILE_WRITE_UMASK DIR_READ_UMASK DIR_WRITE_UMASK",built_in:"put abs acos aliasReference annuity arrayDecode arrayEncode asin atan atan2 average avg avgDev base64Decode base64Encode baseConvert binaryDecode binaryEncode byteOffset byteToNum cachedURL cachedURLs charToNum cipherNames codepointOffset codepointProperty codepointToNum codeunitOffset commandNames compound compress constantNames cos date dateFormat decompress directories diskSpace DNSServers exp exp1 exp2 exp10 extents files flushEvents folders format functionNames geometricMean global globals hasMemory harmonicMean hostAddress hostAddressToName hostName hostNameToAddress isNumber ISOToMac itemOffset keys len length libURLErrorData libUrlFormData libURLftpCommand libURLLastHTTPHeaders libURLLastRHHeaders libUrlMultipartFormAddPart libUrlMultipartFormData libURLVersion lineOffset ln ln1 localNames log log2 log10 longFilePath lower macToISO matchChunk matchText matrixMultiply max md5Digest median merge millisec millisecs millisecond milliseconds min monthNames nativeCharToNum normalizeText num number numToByte numToChar numToCodepoint numToNativeChar offset open openfiles openProcesses openProcessIDs openSockets paragraphOffset paramCount param params peerAddress pendingMessages platform popStdDev populationStandardDeviation populationVariance popVariance processID random randomBytes replaceText result revCreateXMLTree revCreateXMLTreeFromFile revCurrentRecord revCurrentRecordIsFirst revCurrentRecordIsLast revDatabaseColumnCount revDatabaseColumnIsNull revDatabaseColumnLengths revDatabaseColumnNames revDatabaseColumnNamed revDatabaseColumnNumbered revDatabaseColumnTypes revDatabaseConnectResult revDatabaseCursors revDatabaseID revDatabaseTableNames revDatabaseType revDataFromQuery revdb_closeCursor revdb_columnbynumber revdb_columncount revdb_columnisnull revdb_columnlengths revdb_columnnames revdb_columntypes revdb_commit revdb_connect revdb_connections revdb_connectionerr revdb_currentrecord revdb_cursorconnection revdb_cursorerr revdb_cursors revdb_dbtype revdb_disconnect revdb_execute revdb_iseof revdb_isbof revdb_movefirst revdb_movelast revdb_movenext revdb_moveprev revdb_query revdb_querylist revdb_recordcount revdb_rollback revdb_tablenames revGetDatabaseDriverPath revNumberOfRecords revOpenDatabase revOpenDatabases revQueryDatabase revQueryDatabaseBlob revQueryResult revQueryIsAtStart revQueryIsAtEnd revUnixFromMacPath revXMLAttribute revXMLAttributes revXMLAttributeValues revXMLChildContents revXMLChildNames revXMLCreateTreeFromFileWithNamespaces revXMLCreateTreeWithNamespaces revXMLDataFromXPathQuery revXMLEvaluateXPath revXMLFirstChild revXMLMatchingNode revXMLNextSibling revXMLNodeContents revXMLNumberOfChildren revXMLParent revXMLPreviousSibling revXMLRootNode revXMLRPC_CreateRequest revXMLRPC_Documents revXMLRPC_Error revXMLRPC_GetHost revXMLRPC_GetMethod revXMLRPC_GetParam revXMLText revXMLRPC_Execute revXMLRPC_GetParamCount revXMLRPC_GetParamNode revXMLRPC_GetParamType revXMLRPC_GetPath revXMLRPC_GetPort revXMLRPC_GetProtocol revXMLRPC_GetRequest revXMLRPC_GetResponse revXMLRPC_GetSocket revXMLTree revXMLTrees revXMLValidateDTD revZipDescribeItem revZipEnumerateItems revZipOpenArchives round sampVariance sec secs seconds sentenceOffset sha1Digest shell shortFilePath sin specialFolderPath sqrt standardDeviation statRound stdDev sum sysError systemVersion tan tempName textDecode textEncode tick ticks time to tokenOffset toLower toUpper transpose truewordOffset trunc uniDecode uniEncode upper URLDecode URLEncode URLStatus uuid value variableNames variance version waitDepth weekdayNames wordOffset xsltApplyStylesheet xsltApplyStylesheetFromFile xsltLoadStylesheet xsltLoadStylesheetFromFile add breakpoint cancel clear local variable file word line folder directory URL close socket process combine constant convert create new alias folder directory decrypt delete variable word line folder directory URL dispatch divide do encrypt filter get include intersect kill libURLDownloadToFile libURLFollowHttpRedirects libURLftpUpload libURLftpUploadFile libURLresetAll libUrlSetAuthCallback libURLSetCustomHTTPHeaders libUrlSetExpect100 libURLSetFTPListCommand libURLSetFTPMode libURLSetFTPStopTime libURLSetStatusCallback load multiply socket prepare process post seek rel relative read from process rename replace require resetAll resolve revAddXMLNode revAppendXML revCloseCursor revCloseDatabase revCommitDatabase revCopyFile revCopyFolder revCopyXMLNode revDeleteFolder revDeleteXMLNode revDeleteAllXMLTrees revDeleteXMLTree revExecuteSQL revGoURL revInsertXMLNode revMoveFolder revMoveToFirstRecord revMoveToLastRecord revMoveToNextRecord revMoveToPreviousRecord revMoveToRecord revMoveXMLNode revPutIntoXMLNode revRollBackDatabase revSetDatabaseDriverPath revSetXMLAttribute revXMLRPC_AddParam revXMLRPC_DeleteAllDocuments revXMLAddDTD revXMLRPC_Free revXMLRPC_FreeAll revXMLRPC_DeleteDocument revXMLRPC_DeleteParam revXMLRPC_SetHost revXMLRPC_SetMethod revXMLRPC_SetPort revXMLRPC_SetProtocol revXMLRPC_SetSocket revZipAddItemWithData revZipAddItemWithFile revZipAddUncompressedItemWithData revZipAddUncompressedItemWithFile revZipCancel revZipCloseArchive revZipDeleteItem revZipExtractItemToFile revZipExtractItemToVariable revZipSetProgressCallback revZipRenameItem revZipReplaceItemWithData revZipReplaceItemWithFile revZipOpenArchive send set sort split start stop subtract union unload wait write"},contains:[t,{className:"keyword",begin:"\\bend\\sif\\b"},{className:"function",beginKeywords:"function",end:"$",contains:[t,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE,r]},{className:"function",begin:"\\bend\\s+",end:"$",keywords:"end",contains:[i,r],relevance:0},{beginKeywords:"command on",end:"$",contains:[t,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE,r]},{className:"meta",variants:[{begin:"<\\?(rev|lc|livecode)",relevance:10},{begin:"<\\?"},{begin:"\\?>"}]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE,r].concat(n),illegal:";$|^\\[|^=|&|{"}}},function(e,t){e.exports=function(e){var t="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*",n="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s|D|E|F|L|S)(\\+|\\-)?\\d+)?",r={className:"literal",begin:"\\b(t{1}|nil)\\b"},i={className:"number",variants:[{begin:n,relevance:0},{begin:"#(b|B)[0-1]+(/[0-1]+)?"},{begin:"#(o|O)[0-7]+(/[0-7]+)?"},{begin:"#(x|X)[0-9a-fA-F]+(/[0-9a-fA-F]+)?"},{begin:"#(c|C)\\("+n+" +"+n,end:"\\)"}]},a=e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),o=e.COMMENT(";","$",{relevance:0}),s={begin:"\\*",end:"\\*"},l={className:"symbol",begin:"[:&]"+t},c={begin:t,relevance:0},u={begin:"\\|[^]*?\\|"},d={contains:[i,a,s,l,{begin:"\\(",end:"\\)",contains:["self",r,a,i,c]},c],variants:[{begin:"['`]\\(",end:"\\)"},{begin:"\\(quote ",end:"\\)",keywords:{name:"quote"}},{begin:"'\\|[^]*?\\|"}]},f={variants:[{begin:"'"+t},{begin:"#'"+t+"(::"+t+")*"}]},p={begin:"\\(\\s*",end:"\\)"},m={endsWithParent:!0,relevance:0};return p.contains=[{className:"name",variants:[{begin:t},{begin:"\\|[^]*?\\|"}]},m],m.contains=[d,f,p,r,i,a,o,s,l,u,c],{illegal:/\S/,contains:[i,{className:"meta",begin:"^#!",end:"$"},r,a,o,d,f,p,c]}}},function(e,t){e.exports=function(e){var t="([\\w-]+|@{[\\w-]+})",n=[],r=[],i=function(e){return{className:"string",begin:"~?"+e+".*?"+e}},a=function(e,t,n){return{className:e,begin:t,relevance:n}},o={begin:"\\(",end:"\\)",contains:r,relevance:0};r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,i("'"),i('"'),e.CSS_NUMBER_MODE,{begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]",excludeEnd:!0}},a("number","#[0-9A-Fa-f]+\\b"),o,a("variable","@@?[\\w-]+",10),a("variable","@{[\\w-]+}"),a("built_in","~?`[^`]*?`"),{className:"attribute",begin:"[\\w-]+\\s*:",end:":",returnBegin:!0,excludeEnd:!0},{className:"meta",begin:"!important"});var s=r.concat({begin:"{",end:"}",contains:n}),l={beginKeywords:"when",endsWithParent:!0,contains:[{beginKeywords:"and not"}].concat(r)},c={begin:t+"\\s*:",returnBegin:!0,end:"[;}]",relevance:0,contains:[{className:"attribute",begin:t,end:":",excludeEnd:!0,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:r}}]},u={className:"keyword",begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{end:"[;{}]",returnEnd:!0,contains:r,relevance:0}},d={className:"variable",variants:[{begin:"@[\\w-]+\\s*:",relevance:15},{begin:"@[\\w-]+"}],starts:{end:"[;}]",returnEnd:!0,contains:s}},f={variants:[{begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:t,end:"{"}],returnBegin:!0,returnEnd:!0,illegal:"[<='$\"]",relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,l,a("keyword","all\\b"),a("variable","@{[\\w-]+}"),a("selector-tag",t+"%?",0),a("selector-id","#"+t),a("selector-class","\\."+t,0),a("selector-tag","&",0),{className:"selector-attr",begin:"\\[",end:"\\]"},{className:"selector-pseudo",begin:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{begin:"\\(",end:"\\)",contains:s},{begin:"!important"}]};return n.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,u,d,c,f),{case_insensitive:!0,illegal:"[=>'/<($\"]",contains:n}}},function(e,t){e.exports=function(e){return{contains:[{className:"function",begin:"#+[A-Za-z_0-9]*\\(",end:" {",returnBegin:!0,excludeEnd:!0,contains:[{className:"keyword",begin:"#+"},{className:"title",begin:"[A-Za-z_][A-Za-z_0-9]*"},{className:"params",begin:"\\(",end:"\\)",endsParent:!0,contains:[{className:"string",begin:'"',end:'"'},{className:"variable",begin:"[A-Za-z_][A-Za-z_0-9]*"}]}]}]}}},function(e,t){e.exports=function(e){return{contains:[{className:"attribute",begin:"^dn",end:": ",excludeEnd:!0,starts:{end:"$",relevance:0},relevance:10},{className:"attribute",begin:"^\\w",end:": ",excludeEnd:!0,starts:{end:"$",relevance:0}},{className:"literal",begin:"^-",end:"$"},e.HASH_COMMENT_MODE]}}},function(e,t){e.exports=function(e){var t="\\]|\\?>",n={literal:"true false none minimal full all void and or not bw nbw ew new cn ncn lt lte gt gte eq neq rx nrx ft",built_in:"array date decimal duration integer map pair string tag xml null boolean bytes keyword list locale queue set stack staticarray local var variable global data self inherited currentcapture givenblock",keyword:"cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else fail_if fail_ifnot fail if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require returnhome skip split_thread sum take thread to trait type where with yield yieldhome"},r=e.COMMENT("\x3c!--","--\x3e",{relevance:0}),i={className:"meta",begin:"\\[noprocess\\]",starts:{end:"\\[/noprocess\\]",returnEnd:!0,contains:[r]}},a={className:"meta",begin:"\\[/noprocess|<\\?(lasso(script)?|=)"},o={className:"symbol",begin:"'[a-zA-Z_][\\w.]*'"},s=[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.inherit(e.C_NUMBER_MODE,{begin:e.C_NUMBER_RE+"|(-?infinity|NaN)\\b"}),e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),{className:"string",begin:"`",end:"`"},{variants:[{begin:"[#$][a-zA-Z_][\\w.]*"},{begin:"#",end:"\\d+",illegal:"\\W"}]},{className:"type",begin:"::\\s*",end:"[a-zA-Z_][\\w.]*",illegal:"\\W"},{className:"params",variants:[{begin:"-(?!infinity)[a-zA-Z_][\\w.]*",relevance:0},{begin:"(\\.\\.\\.)"}]},{begin:/(->|\.)\s*/,relevance:0,contains:[o]},{className:"class",beginKeywords:"define",returnEnd:!0,end:"\\(|=>",contains:[e.inherit(e.TITLE_MODE,{begin:"[a-zA-Z_][\\w.]*(=(?!>))?|[-+*/%](?!>)"})]}];return{aliases:["ls","lassoscript"],case_insensitive:!0,lexemes:"[a-zA-Z_][\\w.]*|&[lg]t;",keywords:n,contains:[{className:"meta",begin:t,relevance:0,starts:{end:"\\[|<\\?(lasso(script)?|=)",returnEnd:!0,relevance:0,contains:[r]}},i,a,{className:"meta",begin:"\\[no_square_brackets",starts:{end:"\\[/no_square_brackets\\]",lexemes:"[a-zA-Z_][\\w.]*|&[lg]t;",keywords:n,contains:[{className:"meta",begin:t,relevance:0,starts:{end:"\\[noprocess\\]|<\\?(lasso(script)?|=)",returnEnd:!0,contains:[r]}},i,a].concat(s)}},{className:"meta",begin:"\\[",relevance:0},{className:"meta",begin:"^#!",end:"lasso9$",relevance:10}].concat(s)}}},function(e,t){e.exports=function(e){var t={keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit initinterface annotation data sealed internal infix operator out by constructor super trait volatile transient native default",built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null"},n={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@"},r={className:"subst",begin:"\\${",end:"}",contains:[e.APOS_STRING_MODE,e.C_NUMBER_MODE]},i={className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},a={className:"string",variants:[{begin:'"""',end:'"""',contains:[i,r]},{begin:"'",end:"'",illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,contains:[e.BACKSLASH_ESCAPE,i,r]}]},o={className:"meta",begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?"},s={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,end:/\)/,contains:[e.inherit(a,{className:"meta-string"})]}]};return{keywords:t,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"keyword",begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",begin:/@\w+/}]}},n,o,s,{className:"function",beginKeywords:"fun",end:"[(]|$",returnBegin:!0,excludeEnd:!0,keywords:t,illegal:/fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,relevance:5,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://,keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:t,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,endsWithParent:!0,contains:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],relevance:0},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,o,s,a,e.C_NUMBER_MODE]},e.C_BLOCK_COMMENT_MODE]},{className:"class",beginKeywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,illegal:"extends implements",contains:[{beginKeywords:"public protected internal private constructor"},e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,]|$/,excludeBegin:!0,returnEnd:!0},o,s]},a,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{contains:[{className:"meta",begin:/^julia>/,relevance:10,starts:{end:/^(?![ ]{6})/,subLanguage:"julia"},aliases:["jldoctest"]}]}}},function(e,t){e.exports=function(e){var t={keyword:"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ",literal:"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ",built_in:"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},n="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",r={lexemes:n,keywords:t,illegal:/<\//},i={className:"subst",begin:/\$\(/,end:/\)/,keywords:t},a={className:"variable",begin:"\\$"+n},o={className:"string",contains:[e.BACKSLASH_ESCAPE,i,a],variants:[{begin:/\w*"""/,end:/"""\w*/,relevance:10},{begin:/\w*"/,end:/"\w*/}]},s={className:"string",contains:[e.BACKSLASH_ESCAPE,i,a],begin:"`",end:"`"},l={className:"meta",begin:"@"+n};return r.contains=[{className:"number",begin:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,relevance:0},{className:"string",begin:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},o,s,l,{className:"comment",variants:[{begin:"#=",end:"=#",relevance:10},{begin:"#",end:"$"}]},e.HASH_COMMENT_MODE,{className:"keyword",begin:"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{begin:/<:/}],i.contains=r.contains,r}},function(e,t){e.exports=function(e){var t={literal:"true false null"},n=[e.QUOTE_STRING_MODE,e.C_NUMBER_MODE],r={end:",",endsWithParent:!0,excludeEnd:!0,contains:n,keywords:t},i={begin:"{",end:"}",contains:[{className:"attr",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE],illegal:"\\n"},e.inherit(r,{begin:/:/})],illegal:"\\S"},a={begin:"\\[",end:"\\]",contains:[e.inherit(r)],illegal:"\\S"};return n.splice(n.length,0,i,a),{contains:n,keywords:t,illegal:"\\S"}}},function(e,t){e.exports=function(e){var t={className:"params",begin:/\(/,end:/\)/,contains:[{begin:/[\w-]+ *=/,returnBegin:!0,relevance:0,contains:[{className:"attr",begin:/[\w-]+/}]}],relevance:0};return{aliases:["wildfly-cli"],lexemes:"[a-z-]+",keywords:{keyword:"alias batch cd clear command connect connection-factory connection-info data-source deploy deployment-info deployment-overlay echo echo-dmr help history if jdbc-driver-info jms-queue|20 jms-topic|20 ls patch pwd quit read-attribute read-operation reload rollout-plan run-batch set shutdown try unalias undeploy unset version xa-data-source",literal:"true false"},contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,{className:"params",begin:/--[\w\-=\/]+/},{className:"function",begin:/:[\w\-.]+/,relevance:0},{className:"string",begin:/\B(([\/.])[\w\-.\/=]+)+/},t]}}},function(e,t){e.exports=function(e){var t="[A-Za-z$_][0-9A-Za-z$_]*",n={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},r={className:"number",variants:[{begin:"\\b(0[bB][01]+)"},{begin:"\\b(0[oO][0-7]+)"},{begin:e.C_NUMBER_RE}],relevance:0},i={className:"subst",begin:"\\$\\{",end:"\\}",keywords:n,contains:[]},a={className:"string",begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE,i]};i.contains=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,r,e.REGEXP_MODE];var o=i.contains.concat([e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE]);return{aliases:["js","jsx"],keywords:n,contains:[{className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},{className:"meta",begin:/^#!/,end:/$/},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,r,{begin:/[{,]\s*/,relevance:0,contains:[{begin:t+"\\s*:",returnBegin:!0,relevance:0,contains:[{className:"attr",begin:t,relevance:0}]}]},{begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.REGEXP_MODE,{className:"function",begin:"(\\(.*?\\)|"+t+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:t},{begin:/\(\s*\)/},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,contains:o}]}]},{begin://,subLanguage:"xml",contains:[{begin:/<\w+\s*\/>/,skip:!0},{begin:/<\w+/,end:/(\/\w+|\w+\/)>/,skip:!0,contains:[{begin:/<\w+\s*\/>/,skip:!0},"self"]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/\{/,excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:t}),{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:o}],illegal:/\[|%/},{begin:/\$[(.]/},e.METHOD_GUARD,{className:"class",beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"constructor",end:/\{/,excludeEnd:!0}],illegal:/#(?!!)/}}},function(e,t){e.exports=function(e){var t="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",n={className:"number",begin:"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",relevance:0};return{aliases:["jsp"],keywords:t,illegal:/<\/|#/,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"class",beginKeywords:"class interface",end:/[{;=]/,excludeEnd:!0,keywords:"class interface",illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"new throw return else",relevance:0},{className:"function",begin:"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\s*,\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\s+)+"+e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:t,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"params",begin:/\(/,end:/\)/,keywords:t,relevance:0,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},n,{className:"meta",begin:"@[A-Za-z]+"}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,keywords:{literal:".False. .True.",keyword:"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data begin_provider &begin_provider end_provider begin_shell end_shell begin_template end_template subst assert touch soft_touch provide no_dep free irp_if irp_else irp_endif irp_write irp_read",built_in:"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image IRP_ALIGN irp_here"},illegal:/\/\*/,contains:[e.inherit(e.APOS_STRING_MODE,{className:"string",relevance:0}),e.inherit(e.QUOTE_STRING_MODE,{className:"string",relevance:0}),{className:"function",beginKeywords:"subroutine function program",illegal:"[${=\\n]",contains:[e.UNDERSCORE_TITLE_MODE,{className:"params",begin:"\\(",end:"\\)"}]},e.COMMENT("!","$",{relevance:0}),e.COMMENT("begin_doc","end_doc",{relevance:10}),{className:"number",begin:"(?=\\b|\\+|\\-|\\.)(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*)(?:[de][+-]?\\d+)?\\b\\.?",relevance:0}]}}},function(e,t){e.exports=function(e){var t={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}]};return{aliases:["toml"],case_insensitive:!0,illegal:/\S/,contains:[e.COMMENT(";","$"),e.HASH_COMMENT_MODE,{className:"section",begin:/^\s*\[+/,end:/\]+/},{begin:/^[a-z0-9\[\]_-]+\s*=\s*/,end:"$",returnBegin:!0,contains:[{className:"attr",begin:/[a-z0-9\[\]_-]+/},{begin:/=/,endsWithParent:!0,relevance:0,contains:[{className:"literal",begin:/\bon|off|true|false|yes|no\b/},{className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{begin:/\$\{(.*?)}/}]},t,{className:"number",begin:/([\+\-]+)?[\d]+_[\d_]+/},e.NUMBER_MODE]}]}]}}},function(e,t){e.exports=function(e){return{aliases:["i7"],case_insensitive:!0,keywords:{keyword:"thing room person man woman animal container supporter backdrop door scenery open closed locked inside gender is are say understand kind of rule"},contains:[{className:"string",begin:'"',end:'"',relevance:0,contains:[{className:"subst",begin:"\\[",end:"\\]"}]},{className:"section",begin:/^(Volume|Book|Part|Chapter|Section|Table)\b/,end:"$"},{begin:/^(Check|Carry out|Report|Instead of|To|Rule|When|Before|After)\b/,end:":",contains:[{begin:"\\(This",end:"\\)"}]},{className:"comment",begin:"\\[",end:"\\]",contains:["self"]}]}}},function(e,t){e.exports=function(e){var t="[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*",n={begin:t,relevance:0},r={className:"number",begin:"[-+]?\\d+(\\.\\d+)?",relevance:0},i=e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),a=e.COMMENT(";","$",{relevance:0}),o={className:"literal",begin:/\b([Tt]rue|[Ff]alse|nil|None)\b/},s={begin:"[\\[\\{]",end:"[\\]\\}]"},l={className:"comment",begin:"\\^"+t},c=e.COMMENT("\\^\\{","\\}"),u={className:"symbol",begin:"[:]{1,2}"+t},d={begin:"\\(",end:"\\)"},f={endsWithParent:!0,relevance:0},p={keywords:{"builtin-name":"!= % %= & &= * ** **= *= *map + += , --build-class-- --import-- -= . / // //= /= < << <<= <= = > >= >> >>= @ @= ^ ^= abs accumulate all and any ap-compose ap-dotimes ap-each ap-each-while ap-filter ap-first ap-if ap-last ap-map ap-map-when ap-pipe ap-reduce ap-reject apply as-> ascii assert assoc bin break butlast callable calling-module-name car case cdr chain chr coll? combinations compile compress cond cons cons? continue count curry cut cycle dec def default-method defclass defmacro defmacro-alias defmacro/g! defmain defmethod defmulti defn defn-alias defnc defnr defreader defseq del delattr delete-route dict-comp dir disassemble dispatch-reader-macro distinct divmod do doto drop drop-last drop-while empty? end-sequence eval eval-and-compile eval-when-compile even? every? except exec filter first flatten float? fn fnc fnr for for* format fraction genexpr gensym get getattr global globals group-by hasattr hash hex id identity if if* if-not if-python2 import in inc input instance? integer integer-char? integer? interleave interpose is is-coll is-cons is-empty is-even is-every is-float is-instance is-integer is-integer-char is-iterable is-iterator is-keyword is-neg is-none is-not is-numeric is-odd is-pos is-string is-symbol is-zero isinstance islice issubclass iter iterable? iterate iterator? keyword keyword? lambda last len let lif lif-not list* list-comp locals loop macro-error macroexpand macroexpand-1 macroexpand-all map max merge-with method-decorator min multi-decorator multicombinations name neg? next none? nonlocal not not-in not? nth numeric? oct odd? open or ord partition permutations pos? post-route postwalk pow prewalk print product profile/calls profile/cpu put-route quasiquote quote raise range read read-str recursive-replace reduce remove repeat repeatedly repr require rest round route route-with-methods rwm second seq set-comp setattr setv some sorted string string? sum switch symbol? take take-nth take-while tee try unless unquote unquote-splicing vars walk when while with with* with-decorator with-gensyms xi xor yield yield-from zero? zip zip-longest | |= ~"},lexemes:t,className:"name",begin:t,starts:f},m=[d,i,l,c,a,u,s,r,o,n];return d.contains=[e.COMMENT("comment",""),p,f],f.contains=m,s.contains=m,{aliases:["hylang"],illegal:/\S/,contains:[{className:"meta",begin:"^#!",end:"$"},d,i,l,c,a,u,s,r,o]}}},function(e,t){e.exports=function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],illegal:"\\S",contains:[{begin:"^"+t,end:"$",contains:[{className:"number",begin:"\\b\\d{3}\\b"}]},{begin:"^[A-Z]+ (.*?) "+t+"$",returnBegin:!0,end:"$",contains:[{className:"string",begin:" ",end:" ",excludeBegin:!0,excludeEnd:!0},{begin:t},{className:"keyword",begin:"[A-Z]+"}]},{className:"attribute",begin:"^\\w",end:": ",excludeEnd:!0,illegal:"\\n|\\s|=",starts:{end:"$",relevance:0}},{begin:"\\n\\n",starts:{subLanguage:[],endsWithParent:!0}}]}}},function(e,t){e.exports=function(e){var t="action collection component concat debugger each each-in else get hash if input link-to loc log mut outlet partial query-params render textarea unbound unless with yield view",n=(e.QUOTE_STRING_MODE,{endsWithParent:!0,relevance:0,keywords:{keyword:"as",built_in:t},contains:[e.QUOTE_STRING_MODE,{illegal:/\}\}/,begin:/[a-zA-Z0-9_]+=/,returnBegin:!0,relevance:0,contains:[{className:"attr",begin:/[a-zA-Z0-9_]+/}]},e.NUMBER_MODE]});return{case_insensitive:!0,subLanguage:"xml",contains:[e.COMMENT("{{!(--)?","(--)?}}"),{className:"template-tag",begin:/\{\{[#\/]/,end:/\}\}/,contains:[{className:"name",begin:/[a-zA-Z\.\-]+/,keywords:{"builtin-name":t},starts:n}]},{className:"template-variable",begin:/\{\{[a-zA-Z][a-zA-Z\-]+/,end:/\}\}/,keywords:{keyword:"as",built_in:t},contains:[e.QUOTE_STRING_MODE]}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,lexemes:/[\w\._]+/,keywords:"goto gosub return break repeat loop continue wait await dim sdim foreach dimtype dup dupptr end stop newmod delmod mref run exgoto on mcall assert logmes newlab resume yield onexit onerror onkey onclick oncmd exist delete mkdir chdir dirlist bload bsave bcopy memfile if else poke wpoke lpoke getstr chdpm memexpand memcpy memset notesel noteadd notedel noteload notesave randomize noteunsel noteget split strrep setease button chgdisp exec dialog mmload mmplay mmstop mci pset pget syscolor mes print title pos circle cls font sysfont objsize picload color palcolor palette redraw width gsel gcopy gzoom gmode bmpsave hsvcolor getkey listbox chkbox combox input mesbox buffer screen bgscr mouse objsel groll line clrobj boxf objprm objmode stick grect grotate gsquare gradf objimage objskip objenable celload celdiv celput newcom querycom delcom cnvstow comres axobj winobj sendmsg comevent comevarg sarrayconv callfunc cnvwtos comevdisp libptr system hspstat hspver stat cnt err strsize looplev sublev iparam wparam lparam refstr refdval int rnd strlen length length2 length3 length4 vartype gettime peek wpeek lpeek varptr varuse noteinfo instr abs limit getease str strmid strf getpath strtrim sin cos tan atan sqrt double absf expf logf limitf powf geteasef mousex mousey mousew hwnd hinstance hdc ginfo objinfo dirinfo sysinfo thismod __hspver__ __hsp30__ __date__ __time__ __line__ __file__ _debug __hspdef__ and or xor not screen_normal screen_palette screen_hide screen_fixedsize screen_tool screen_frame gmode_gdi gmode_mem gmode_rgb0 gmode_alpha gmode_rgb0alpha gmode_add gmode_sub gmode_pixela ginfo_mx ginfo_my ginfo_act ginfo_sel ginfo_wx1 ginfo_wy1 ginfo_wx2 ginfo_wy2 ginfo_vx ginfo_vy ginfo_sizex ginfo_sizey ginfo_winx ginfo_winy ginfo_mesx ginfo_mesy ginfo_r ginfo_g ginfo_b ginfo_paluse ginfo_dispx ginfo_dispy ginfo_cx ginfo_cy ginfo_intid ginfo_newid ginfo_sx ginfo_sy objinfo_mode objinfo_bmscr objinfo_hwnd notemax notesize dir_cur dir_exe dir_win dir_sys dir_cmdline dir_desktop dir_mydoc dir_tv font_normal font_bold font_italic font_underline font_strikeout font_antialias objmode_normal objmode_guifont objmode_usefont gsquare_grad msgothic msmincho do until while wend for next _break _continue switch case default swbreak swend ddim ldim alloc m_pi rad2deg deg2rad ease_linear ease_quad_in ease_quad_out ease_quad_inout ease_cubic_in ease_cubic_out ease_cubic_inout ease_quartic_in ease_quartic_out ease_quartic_inout ease_bounce_in ease_bounce_out ease_bounce_inout ease_shake_in ease_shake_out ease_shake_inout ease_loop",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{className:"string",begin:'{"',end:'"}',contains:[e.BACKSLASH_ESCAPE]},e.COMMENT(";","$",{relevance:0}),{className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"addion cfunc cmd cmpopt comfunc const defcfunc deffunc define else endif enum epack func global if ifdef ifndef include modcfunc modfunc modinit modterm module pack packopt regcmd runtime undef usecom uselib"},contains:[e.inherit(e.QUOTE_STRING_MODE,{className:"meta-string"}),e.NUMBER_MODE,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"symbol",begin:"^\\*(\\w+|@)"},e.NUMBER_MODE,e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{aliases:["hx"],keywords:{keyword:"break case cast catch continue default do dynamic else enum extern for function here if import in inline never new override package private get set public return static super switch this throw trace try typedef untyped using var while Int Float String Bool Dynamic Void Array ",built_in:"trace this",literal:"true false null _"},contains:[{className:"string",begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE,{className:"subst",begin:"\\$\\{",end:"\\}"},{className:"subst",begin:"\\$",end:"\\W}"}]},e.QUOTE_STRING_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.C_NUMBER_MODE,{className:"meta",begin:"@:",end:"$"},{className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"if else elseif end error"}},{className:"type",begin:":[ \t]*",end:"[^A-Za-z0-9_ \t\\->]",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:":[ \t]*",end:"\\W",excludeBegin:!0,excludeEnd:!0},{className:"type",begin:"new *",end:"\\W",excludeBegin:!0,excludeEnd:!0},{className:"class",beginKeywords:"enum",end:"\\{",contains:[e.TITLE_MODE]},{className:"class",beginKeywords:"abstract",end:"[\\{$]",contains:[{className:"type",begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"type",begin:"from +",end:"\\W",excludeBegin:!0,excludeEnd:!0},{className:"type",begin:"to +",end:"\\W",excludeBegin:!0,excludeEnd:!0},e.TITLE_MODE],keywords:{keyword:"abstract from to"}},{className:"class",begin:"\\b(class|interface) +",end:"[\\{$]",excludeEnd:!0,keywords:"class interface",contains:[{className:"keyword",begin:"\\b(extends|implements) +",keywords:"extends implements",contains:[{className:"type",begin:e.IDENT_RE,relevance:0}]},e.TITLE_MODE]},{className:"function",beginKeywords:"function",end:"\\(",excludeEnd:!0,illegal:"\\S",contains:[e.TITLE_MODE]}],illegal:/<\//}}},function(e,t){e.exports=function(e){var t={variants:[e.COMMENT("--","$"),e.COMMENT("{-","-}",{contains:["self"]})]},n={className:"meta",begin:"{-#",end:"#-}"},r={className:"meta",begin:"^#",end:"$"},i={className:"type",begin:"\\b[A-Z][\\w']*",relevance:0},a={begin:"\\(",end:"\\)",illegal:'"',contains:[n,r,{className:"type",begin:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TITLE_MODE,{begin:"[_a-z][\\w']*"}),t]};return{aliases:["hs"],keywords:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",contains:[{beginKeywords:"module",end:"where",keywords:"module where",contains:[a,t],illegal:"\\W\\.|;"},{begin:"\\bimport\\b",end:"$",keywords:"import qualified as hiding",contains:[a,t],illegal:"\\W\\.|;"},{className:"class",begin:"^(\\s*)?(class|instance)\\b",end:"where",keywords:"class family instance where",contains:[i,a,t]},{className:"class",begin:"\\b(data|(new)?type)\\b",end:"$",keywords:"data family type newtype deriving",contains:[n,i,a,{begin:"{",end:"}",contains:a.contains},t]},{beginKeywords:"default",end:"$",contains:[i,a,t]},{beginKeywords:"infix infixl infixr",end:"$",contains:[e.C_NUMBER_MODE,t]},{begin:"\\bforeign\\b",end:"$",keywords:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",contains:[i,e.QUOTE_STRING_MODE,t]},{className:"meta",begin:"#!\\/usr\\/bin\\/env runhaskell",end:"$"},n,r,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,i,e.inherit(e.TITLE_MODE,{begin:"^[_a-z][\\w']*"}),t,{begin:"->|<-"}]}}},function(e,t){e.exports=function(e){var t={"builtin-name":"each in with if else unless bindattr action collection debugger log outlet template unbound view yield"};return{aliases:["hbs","html.hbs","html.handlebars"],case_insensitive:!0,subLanguage:"xml",contains:[e.COMMENT("{{!(--)?","(--)?}}"),{className:"template-tag",begin:/\{\{[#\/]/,end:/\}\}/,contains:[{className:"name",begin:/[a-zA-Z\.-]+/,keywords:t,starts:{endsWithParent:!0,relevance:0,contains:[e.QUOTE_STRING_MODE]}}]},{className:"template-variable",begin:/\{\{/,end:/\}\}/,keywords:t}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,contains:[{className:"meta",begin:"^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$",relevance:10},e.COMMENT("^\\s*(!=#|=#|-#|/).*$",!1,{relevance:0}),{begin:"^\\s*(-|=|!=)(?!#)",starts:{end:"\\n",subLanguage:"ruby"}},{className:"tag",begin:"^\\s*%",contains:[{className:"selector-tag",begin:"\\w+"},{className:"selector-id",begin:"#[\\w-]+"},{className:"selector-class",begin:"\\.[\\w-]+"},{begin:"{\\s*",end:"\\s*}",contains:[{begin:":\\w+\\s*=>",end:",\\s+",returnBegin:!0,endsWithParent:!0,contains:[{className:"attr",begin:":\\w+"},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{begin:"\\w+",relevance:0}]}]},{begin:"\\(\\s*",end:"\\s*\\)",excludeEnd:!0,contains:[{begin:"\\w+\\s*=",end:"\\s+",returnBegin:!0,endsWithParent:!0,contains:[{className:"attr",begin:"\\w+",relevance:0},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{begin:"\\w+",relevance:0}]}]}]},{begin:"^\\s*[=~]\\s*"},{begin:"#{",starts:{end:"}",subLanguage:"ruby"}}]}}},function(e,t){e.exports=function(e){return{keywords:{literal:"true false null",keyword:"byte short char int long boolean float double void def as in assert trait super this abstract static volatile transient public private protected synchronized final class interface enum if else for while switch case break default continue throw throws try catch finally implements extends new import package return instanceof"},contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"string",begin:'"""',end:'"""'},{className:"string",begin:"'''",end:"'''"},{className:"string",begin:"\\$/",end:"/\\$",relevance:10},e.APOS_STRING_MODE,{className:"regexp",begin:/~?\/[^\/\n]+\//,contains:[e.BACKSLASH_ESCAPE]},e.QUOTE_STRING_MODE,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},e.BINARY_NUMBER_MODE,{className:"class",beginKeywords:"class interface trait enum",end:"{",illegal:":",contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"},{className:"string",begin:/[^\?]{0}[A-Za-z0-9_$]+ *:/},{begin:/\?/,end:/\:/},{className:"symbol",begin:"^\\s*[A-Za-z0-9_$]+:",relevance:0}],illegal:/#|<\//}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,keywords:{keyword:"task project allprojects subprojects artifacts buildscript configurations dependencies repositories sourceSets description delete from into include exclude source classpath destinationDir includes options sourceCompatibility targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant def abstract break case catch continue default do else extends final finally for if implements instanceof native new private protected public return static switch synchronized throw throws transient try volatile while strictfp package import false null super this true antlrtask checkstyle codenarc copy boolean byte char class double float int interface long short void compile runTime file fileTree abs any append asList asWritable call collect compareTo count div dump each eachByte eachFile eachLine every find findAll flatten getAt getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter newReader newWriter next plus pop power previous print println push putAt read readBytes readLines reverse reverseEach round size sort splitEachLine step subMap times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader withStream withWriter withWriterAppend write writeLine"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,e.REGEXP_MODE]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:"println readln print import module function local return let var while for foreach times in case when match with break continue augment augmentation each find filter reduce if then else otherwise try catch finally raise throw orIfNull DynamicObject|10 DynamicVariable struct Observable map set vector list array",literal:"true false null"},contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"}]}}},function(e,t){e.exports=function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],keywords:t,illegal:""},e.HASH_COMMENT_MODE,{className:"string",begin:'"""',end:'"""'},e.QUOTE_STRING_MODE]}}},function(e,t){e.exports=function(e){var t=[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.COMMENT(/\(/,/\)/),e.inherit(e.C_NUMBER_MODE,{begin:"([-+]?([0-9]*\\.?[0-9]+\\.?))|"+e.C_NUMBER_RE}),e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),{className:"name",begin:"([G])([0-9]+\\.?[0-9]?)"},{className:"name",begin:"([M])([0-9]+\\.?[0-9]?)"},{className:"attr",begin:"(VC|VS|#)",end:"(\\d+)"},{className:"attr",begin:"(VZOFX|VZOFY|VZOFZ)"},{className:"built_in",begin:"(ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN)(\\[)",end:"([-+]?([0-9]*\\.?[0-9]+\\.?))(\\])"},{className:"symbol",variants:[{begin:"N",end:"\\d+",illegal:"\\W"}]}];return{aliases:["nc"],case_insensitive:!0,lexemes:"[A-Z_][A-Z0-9_.]*",keywords:"IF DO WHILE ENDWHILE CALL ENDIF SUB ENDSUB GOTO REPEAT ENDREPEAT EQ LT GT NE GE LE OR XOR",contains:[{className:"meta",begin:"\\%"},{className:"meta",begin:"([O])([0-9]+)"}].concat(t)}}},function(e,t){e.exports=function(e){var t={keyword:"and bool break call callexe checkinterrupt clear clearg closeall cls comlog compile continue create debug declare delete disable dlibrary dllcall do dos ed edit else elseif enable end endfor endif endp endo errorlog errorlogat expr external fn for format goto gosub graph if keyword let lib library line load loadarray loadexe loadf loadk loadm loadp loads loadx local locate loopnextindex lprint lpwidth lshow matrix msym ndpclex new not open or output outwidth plot plotsym pop prcsn print printdos proc push retp return rndcon rndmod rndmult rndseed run save saveall screen scroll setarray show sparse stop string struct system trace trap threadfor threadendfor threadbegin threadjoin threadstat threadend until use while winprint",built_in:"abs acf aconcat aeye amax amean AmericanBinomCall AmericanBinomCall_Greeks AmericanBinomCall_ImpVol AmericanBinomPut AmericanBinomPut_Greeks AmericanBinomPut_ImpVol AmericanBSCall AmericanBSCall_Greeks AmericanBSCall_ImpVol AmericanBSPut AmericanBSPut_Greeks AmericanBSPut_ImpVol amin amult annotationGetDefaults annotationSetBkd annotationSetFont annotationSetLineColor annotationSetLineStyle annotationSetLineThickness annualTradingDays arccos arcsin areshape arrayalloc arrayindex arrayinit arraytomat asciiload asclabel astd astds asum atan atan2 atranspose axmargin balance band bandchol bandcholsol bandltsol bandrv bandsolpd bar base10 begwind besselj bessely beta box boxcox cdfBeta cdfBetaInv cdfBinomial cdfBinomialInv cdfBvn cdfBvn2 cdfBvn2e cdfCauchy cdfCauchyInv cdfChic cdfChii cdfChinc cdfChincInv cdfExp cdfExpInv cdfFc cdfFnc cdfFncInv cdfGam cdfGenPareto cdfHyperGeo cdfLaplace cdfLaplaceInv cdfLogistic cdfLogisticInv cdfmControlCreate cdfMvn cdfMvn2e cdfMvnce cdfMvne cdfMvt2e cdfMvtce cdfMvte cdfN cdfN2 cdfNc cdfNegBinomial cdfNegBinomialInv cdfNi cdfPoisson cdfPoissonInv cdfRayleigh cdfRayleighInv cdfTc cdfTci cdfTnc cdfTvn cdfWeibull cdfWeibullInv cdir ceil ChangeDir chdir chiBarSquare chol choldn cholsol cholup chrs close code cols colsf combinate combinated complex con cond conj cons ConScore contour conv convertsatostr convertstrtosa corrm corrms corrvc corrx corrxs cos cosh counts countwts crossprd crout croutp csrcol csrlin csvReadM csvReadSA cumprodc cumsumc curve cvtos datacreate datacreatecomplex datalist dataload dataloop dataopen datasave date datestr datestring datestrymd dayinyr dayofweek dbAddDatabase dbClose dbCommit dbCreateQuery dbExecQuery dbGetConnectOptions dbGetDatabaseName dbGetDriverName dbGetDrivers dbGetHostName dbGetLastErrorNum dbGetLastErrorText dbGetNumericalPrecPolicy dbGetPassword dbGetPort dbGetTableHeaders dbGetTables dbGetUserName dbHasFeature dbIsDriverAvailable dbIsOpen dbIsOpenError dbOpen dbQueryBindValue dbQueryClear dbQueryCols dbQueryExecPrepared dbQueryFetchAllM dbQueryFetchAllSA dbQueryFetchOneM dbQueryFetchOneSA dbQueryFinish dbQueryGetBoundValue dbQueryGetBoundValues dbQueryGetField dbQueryGetLastErrorNum dbQueryGetLastErrorText dbQueryGetLastInsertID dbQueryGetLastQuery dbQueryGetPosition dbQueryIsActive dbQueryIsForwardOnly dbQueryIsNull dbQueryIsSelect dbQueryIsValid dbQueryPrepare dbQueryRows dbQuerySeek dbQuerySeekFirst dbQuerySeekLast dbQuerySeekNext dbQuerySeekPrevious dbQuerySetForwardOnly dbRemoveDatabase dbRollback dbSetConnectOptions dbSetDatabaseName dbSetHostName dbSetNumericalPrecPolicy dbSetPort dbSetUserName dbTransaction DeleteFile delif delrows denseToSp denseToSpRE denToZero design det detl dfft dffti diag diagrv digamma doswin DOSWinCloseall DOSWinOpen dotfeq dotfeqmt dotfge dotfgemt dotfgt dotfgtmt dotfle dotflemt dotflt dotfltmt dotfne dotfnemt draw drop dsCreate dstat dstatmt dstatmtControlCreate dtdate dtday dttime dttodtv dttostr dttoutc dtvnormal dtvtodt dtvtoutc dummy dummybr dummydn eig eigh eighv eigv elapsedTradingDays endwind envget eof eqSolve eqSolvemt eqSolvemtControlCreate eqSolvemtOutCreate eqSolveset erf erfc erfccplx erfcplx error etdays ethsec etstr EuropeanBinomCall EuropeanBinomCall_Greeks EuropeanBinomCall_ImpVol EuropeanBinomPut EuropeanBinomPut_Greeks EuropeanBinomPut_ImpVol EuropeanBSCall EuropeanBSCall_Greeks EuropeanBSCall_ImpVol EuropeanBSPut EuropeanBSPut_Greeks EuropeanBSPut_ImpVol exctsmpl exec execbg exp extern eye fcheckerr fclearerr feq feqmt fflush fft ffti fftm fftmi fftn fge fgemt fgets fgetsa fgetsat fgetst fgt fgtmt fileinfo filesa fle flemt floor flt fltmt fmod fne fnemt fonts fopen formatcv formatnv fputs fputst fseek fstrerror ftell ftocv ftos ftostrC gamma gammacplx gammaii gausset gdaAppend gdaCreate gdaDStat gdaDStatMat gdaGetIndex gdaGetName gdaGetNames gdaGetOrders gdaGetType gdaGetTypes gdaGetVarInfo gdaIsCplx gdaLoad gdaPack gdaRead gdaReadByIndex gdaReadSome gdaReadSparse gdaReadStruct gdaReportVarInfo gdaSave gdaUpdate gdaUpdateAndPack gdaVars gdaWrite gdaWrite32 gdaWriteSome getarray getdims getf getGAUSShome getmatrix getmatrix4D getname getnamef getNextTradingDay getNextWeekDay getnr getorders getpath getPreviousTradingDay getPreviousWeekDay getRow getscalar3D getscalar4D getTrRow getwind glm gradcplx gradMT gradMTm gradMTT gradMTTm gradp graphprt graphset hasimag header headermt hess hessMT hessMTg hessMTgw hessMTm hessMTmw hessMTT hessMTTg hessMTTgw hessMTTm hessMTw hessp hist histf histp hsec imag indcv indexcat indices indices2 indicesf indicesfn indnv indsav integrate1d integrateControlCreate intgrat2 intgrat3 inthp1 inthp2 inthp3 inthp4 inthpControlCreate intquad1 intquad2 intquad3 intrleav intrleavsa intrsect intsimp inv invpd invswp iscplx iscplxf isden isinfnanmiss ismiss key keyav keyw lag lag1 lagn lapEighb lapEighi lapEighvb lapEighvi lapgEig lapgEigh lapgEighv lapgEigv lapgSchur lapgSvdcst lapgSvds lapgSvdst lapSvdcusv lapSvds lapSvdusv ldlp ldlsol linSolve listwise ln lncdfbvn lncdfbvn2 lncdfmvn lncdfn lncdfn2 lncdfnc lnfact lngammacplx lnpdfmvn lnpdfmvt lnpdfn lnpdft loadd loadstruct loadwind loess loessmt loessmtControlCreate log loglog logx logy lower lowmat lowmat1 ltrisol lu lusol machEpsilon make makevars makewind margin matalloc matinit mattoarray maxbytes maxc maxindc maxv maxvec mbesselei mbesselei0 mbesselei1 mbesseli mbesseli0 mbesseli1 meanc median mergeby mergevar minc minindc minv miss missex missrv moment momentd movingave movingaveExpwgt movingaveWgt nextindex nextn nextnevn nextwind ntos null null1 numCombinations ols olsmt olsmtControlCreate olsqr olsqr2 olsqrmt ones optn optnevn orth outtyp pacf packedToSp packr parse pause pdfCauchy pdfChi pdfExp pdfGenPareto pdfHyperGeo pdfLaplace pdfLogistic pdfn pdfPoisson pdfRayleigh pdfWeibull pi pinv pinvmt plotAddArrow plotAddBar plotAddBox plotAddHist plotAddHistF plotAddHistP plotAddPolar plotAddScatter plotAddShape plotAddTextbox plotAddTS plotAddXY plotArea plotBar plotBox plotClearLayout plotContour plotCustomLayout plotGetDefaults plotHist plotHistF plotHistP plotLayout plotLogLog plotLogX plotLogY plotOpenWindow plotPolar plotSave plotScatter plotSetAxesPen plotSetBar plotSetBarFill plotSetBarStacked plotSetBkdColor plotSetFill plotSetGrid plotSetLegend plotSetLineColor plotSetLineStyle plotSetLineSymbol plotSetLineThickness plotSetNewWindow plotSetTitle plotSetWhichYAxis plotSetXAxisShow plotSetXLabel plotSetXRange plotSetXTicInterval plotSetXTicLabel plotSetYAxisShow plotSetYLabel plotSetYRange plotSetZAxisShow plotSetZLabel plotSurface plotTS plotXY polar polychar polyeval polygamma polyint polymake polymat polymroot polymult polyroot pqgwin previousindex princomp printfm printfmt prodc psi putarray putf putvals pvCreate pvGetIndex pvGetParNames pvGetParVector pvLength pvList pvPack pvPacki pvPackm pvPackmi pvPacks pvPacksi pvPacksm pvPacksmi pvPutParVector pvTest pvUnpack QNewton QNewtonmt QNewtonmtControlCreate QNewtonmtOutCreate QNewtonSet QProg QProgmt QProgmtInCreate qqr qqre qqrep qr qre qrep qrsol qrtsol qtyr qtyre qtyrep quantile quantiled qyr qyre qyrep qz rank rankindx readr real reclassify reclassifyCuts recode recserar recsercp recserrc rerun rescale reshape rets rev rfft rffti rfftip rfftn rfftnp rfftp rndBernoulli rndBeta rndBinomial rndCauchy rndChiSquare rndCon rndCreateState rndExp rndGamma rndGeo rndGumbel rndHyperGeo rndi rndKMbeta rndKMgam rndKMi rndKMn rndKMnb rndKMp rndKMu rndKMvm rndLaplace rndLCbeta rndLCgam rndLCi rndLCn rndLCnb rndLCp rndLCu rndLCvm rndLogNorm rndMTu rndMVn rndMVt rndn rndnb rndNegBinomial rndp rndPoisson rndRayleigh rndStateSkip rndu rndvm rndWeibull rndWishart rotater round rows rowsf rref sampleData satostrC saved saveStruct savewind scale scale3d scalerr scalinfnanmiss scalmiss schtoc schur searchsourcepath seekr select selif seqa seqm setdif setdifsa setvars setvwrmode setwind shell shiftr sin singleindex sinh sleep solpd sortc sortcc sortd sorthc sorthcc sortind sortindc sortmc sortr sortrc spBiconjGradSol spChol spConjGradSol spCreate spDenseSubmat spDiagRvMat spEigv spEye spLDL spline spLU spNumNZE spOnes spreadSheetReadM spreadSheetReadSA spreadSheetWrite spScale spSubmat spToDense spTrTDense spTScalar spZeros sqpSolve sqpSolveMT sqpSolveMTControlCreate sqpSolveMTlagrangeCreate sqpSolveMToutCreate sqpSolveSet sqrt statements stdc stdsc stocv stof strcombine strindx strlen strput strrindx strsect strsplit strsplitPad strtodt strtof strtofcplx strtriml strtrimr strtrunc strtruncl strtruncpad strtruncr submat subscat substute subvec sumc sumr surface svd svd1 svd2 svdcusv svds svdusv sysstate tab tan tanh tempname threadBegin threadEnd threadEndFor threadFor threadJoin threadStat time timedt timestr timeutc title tkf2eps tkf2ps tocart todaydt toeplitz token topolar trapchk trigamma trimr trunc type typecv typef union unionsa uniqindx uniqindxsa unique uniquesa upmat upmat1 upper utctodt utctodtv utrisol vals varCovMS varCovXS varget vargetl varmall varmares varput varputl vartypef vcm vcms vcx vcxs vec vech vecr vector vget view viewxyz vlist vnamecv volume vput vread vtypecv wait waitc walkindex where window writer xlabel xlsGetSheetCount xlsGetSheetSize xlsGetSheetTypes xlsMakeRange xlsReadM xlsReadSA xlsWrite xlsWriteM xlsWriteSA xpnd xtics xy xyz ylabel ytics zeros zeta zlabel ztics cdfEmpirical dot h5create h5open h5read h5readAttribute h5write h5writeAttribute ldl plotAddErrorBar plotAddSurface plotCDFEmpirical plotSetColormap plotSetContourLabels plotSetLegendFont plotSetTextInterpreter plotSetXTicCount plotSetYTicCount plotSetZLevels powerm strjoin strtrim sylvester",literal:"DB_AFTER_LAST_ROW DB_ALL_TABLES DB_BATCH_OPERATIONS DB_BEFORE_FIRST_ROW DB_BLOB DB_EVENT_NOTIFICATIONS DB_FINISH_QUERY DB_HIGH_PRECISION DB_LAST_INSERT_ID DB_LOW_PRECISION_DOUBLE DB_LOW_PRECISION_INT32 DB_LOW_PRECISION_INT64 DB_LOW_PRECISION_NUMBERS DB_MULTIPLE_RESULT_SETS DB_NAMED_PLACEHOLDERS DB_POSITIONAL_PLACEHOLDERS DB_PREPARED_QUERIES DB_QUERY_SIZE DB_SIMPLE_LOCKING DB_SYSTEM_TABLES DB_TABLES DB_TRANSACTIONS DB_UNICODE DB_VIEWS"},n={className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"define definecs|10 undef ifdef ifndef iflight ifdllcall ifmac ifos2win ifunix else endif lineson linesoff srcfile srcline"},contains:[{begin:/\\\n/,relevance:0},{beginKeywords:"include",end:"$",keywords:{"meta-keyword":"include"},contains:[{className:"meta-string",begin:'"',end:'"',illegal:"\\n"}]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},r=e.UNDERSCORE_IDENT_RE+"\\s*\\(?",i=[{className:"params",begin:/\(/,end:/\)/,keywords:t,relevance:0,contains:[e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}];return{aliases:["gss"],case_insensitive:!0,keywords:t,illegal:"(\\{[%#]|[%#]\\})",contains:[e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.COMMENT("@","@"),n,{className:"string",begin:'"',end:'"',contains:[e.BACKSLASH_ESCAPE]},{className:"function",beginKeywords:"proc keyword",end:";",excludeEnd:!0,keywords:t,contains:[{begin:r,returnBegin:!0,contains:[e.UNDERSCORE_TITLE_MODE],relevance:0},e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n].concat(i)},{className:"function",beginKeywords:"fn",end:";",excludeEnd:!0,keywords:t,contains:[{begin:r+e.IDENT_RE+"\\)?\\s*\\=\\s*",returnBegin:!0,contains:[e.UNDERSCORE_TITLE_MODE],relevance:0},e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE].concat(i)},{className:"function",begin:"\\bexternal (proc|keyword|fn)\\s+",end:";",excludeEnd:!0,keywords:t,contains:[{begin:r,returnBegin:!0,contains:[e.UNDERSCORE_TITLE_MODE],relevance:0},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"function",begin:"\\bexternal (matrix|string|array|sparse matrix|struct "+e.IDENT_RE+")\\s+",end:";",excludeEnd:!0,keywords:t,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}]}}},function(e,t){e.exports=function(e){var t={keyword:"abort acronym acronyms alias all and assign binary card diag display else eq file files for free ge gt if integer le loop lt maximizing minimizing model models ne negative no not option options or ord positive prod put putpage puttl repeat sameas semicont semiint smax smin solve sos1 sos2 sum system table then until using while xor yes",literal:"eps inf na","built-in":"abs arccos arcsin arctan arctan2 Beta betaReg binomial ceil centropy cos cosh cvPower div div0 eDist entropy errorf execSeed exp fact floor frac gamma gammaReg log logBeta logGamma log10 log2 mapVal max min mod ncpCM ncpF ncpVUpow ncpVUsin normal pi poly power randBinomial randLinear randTriangle round rPower sigmoid sign signPower sin sinh slexp sllog10 slrec sqexp sqlog10 sqr sqrec sqrt tan tanh trunc uniform uniformInt vcPower bool_and bool_eqv bool_imp bool_not bool_or bool_xor ifThen rel_eq rel_ge rel_gt rel_le rel_lt rel_ne gday gdow ghour gleap gmillisec gminute gmonth gsecond gyear jdate jnow jstart jtime errorLevel execError gamsRelease gamsVersion handleCollect handleDelete handleStatus handleSubmit heapFree heapLimit heapSize jobHandle jobKill jobStatus jobTerminate licenseLevel licenseStatus maxExecError sleep timeClose timeComp timeElapsed timeExec timeStart"},n={className:"symbol",variants:[{begin:/\=[lgenxc]=/},{begin:/\$/}]},r={className:"comment",variants:[{begin:"'",end:"'"},{begin:'"',end:'"'}],illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},i={begin:"/",end:"/",keywords:t,contains:[r,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_NUMBER_MODE]},a={begin:/[a-z][a-z0-9_]*(\([a-z0-9_, ]*\))?[ \t]+/,excludeBegin:!0,end:"$",endsWithParent:!0,contains:[r,i,{className:"comment",begin:/([ ]*[a-z0-9&#*=?@>\\<:\-,()$\[\]_.{}!+%^]+)+/,relevance:0}]};return{aliases:["gms"],case_insensitive:!0,keywords:t,contains:[e.COMMENT(/^\$ontext/,/^\$offtext/),{className:"meta",begin:"^\\$[a-z0-9]+",end:"$",returnBegin:!0,contains:[{className:"meta-keyword",begin:"^\\$[a-z0-9]+"}]},e.COMMENT("^\\*","$"),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{beginKeywords:"set sets parameter parameters variable variables scalar scalars equation equations",end:";",contains:[e.COMMENT("^\\*","$"),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,i,a]},{beginKeywords:"table",end:";",returnBegin:!0,contains:[{beginKeywords:"table",end:"$",contains:[a]},e.COMMENT("^\\*","$"),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_NUMBER_MODE]},{className:"function",begin:/^[a-z][a-z0-9_,\-+' ()$]+\.{2}/,returnBegin:!0,contains:[{className:"title",begin:/^[a-z0-9_]+/},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0},n]},e.C_NUMBER_MODE,n]}}},function(e,t){e.exports=function(e){var t={begin:"<",end:">",contains:[e.inherit(e.TITLE_MODE,{begin:/'[a-zA-Z0-9_]+/})]};return{aliases:["fs"],keywords:"abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield",illegal:/\/\*/,contains:[{className:"keyword",begin:/\b(yield|return|let|do)!/},{className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]},{className:"string",begin:'"""',end:'"""'},e.COMMENT("\\(\\*","\\*\\)"),{className:"class",beginKeywords:"type",end:"\\(|=|$",excludeEnd:!0,contains:[e.UNDERSCORE_TITLE_MODE,t]},{className:"meta",begin:"\\[<",end:">\\]",relevance:10},{className:"symbol",begin:"\\B('[A-Za-z])\\b",contains:[e.BACKSLASH_ESCAPE]},e.C_LINE_COMMENT_MODE,e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,aliases:["f90","f95"],keywords:{literal:".False. .True.",keyword:"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data",built_in:"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image"},illegal:/\/\*/,contains:[e.inherit(e.APOS_STRING_MODE,{className:"string",relevance:0}),e.inherit(e.QUOTE_STRING_MODE,{className:"string",relevance:0}),{className:"function",beginKeywords:"subroutine function program",illegal:"[${=\\n]",contains:[e.UNDERSCORE_TITLE_MODE,{className:"params",begin:"\\(",end:"\\)"}]},e.COMMENT("!","$",{relevance:0}),{className:"number",begin:"(?=\\b|\\+|\\-|\\.)(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*)(?:[de][+-]?\\d+)?\\b\\.?",relevance:0}]}}},function(e,t){e.exports=function(e){var t={className:"function",beginKeywords:"def",end:/[:={\[(\n;]/,excludeEnd:!0,contains:[{className:"title",begin:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/}]};return{keywords:{literal:"true false",keyword:"case class def else enum if impl import in lat rel index let match namespace switch type yield with"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"string",begin:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},{className:"string",variants:[{begin:'"',end:'"'}]},t,e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{contains:[{begin:/[^\u2401\u0001]+/,end:/[\u2401\u0001]/,excludeEnd:!0,returnBegin:!0,returnEnd:!1,contains:[{begin:/([^\u2401\u0001=]+)/,end:/=([^\u2401\u0001=]+)/,returnEnd:!0,returnBegin:!1,className:"attr"},{begin:/=/,end:/([\u2401\u0001])/,excludeEnd:!0,excludeBegin:!0,className:"string"}]}],case_insensitive:!0}}},function(e,t){e.exports=function(e){return{aliases:["xlsx","xls"],case_insensitive:!0,lexemes:/[a-zA-Z][\w\.]*/,keywords:{built_in:"ABS ACCRINT ACCRINTM ACOS ACOSH ACOT ACOTH AGGREGATE ADDRESS AMORDEGRC AMORLINC AND ARABIC AREAS ASC ASIN ASINH ATAN ATAN2 ATANH AVEDEV AVERAGE AVERAGEA AVERAGEIF AVERAGEIFS BAHTTEXT BASE BESSELI BESSELJ BESSELK BESSELY BETADIST BETA.DIST BETAINV BETA.INV BIN2DEC BIN2HEX BIN2OCT BINOMDIST BINOM.DIST BINOM.DIST.RANGE BINOM.INV BITAND BITLSHIFT BITOR BITRSHIFT BITXOR CALL CEILING CEILING.MATH CEILING.PRECISE CELL CHAR CHIDIST CHIINV CHITEST CHISQ.DIST CHISQ.DIST.RT CHISQ.INV CHISQ.INV.RT CHISQ.TEST CHOOSE CLEAN CODE COLUMN COLUMNS COMBIN COMBINA COMPLEX CONCAT CONCATENATE CONFIDENCE CONFIDENCE.NORM CONFIDENCE.T CONVERT CORREL COS COSH COT COTH COUNT COUNTA COUNTBLANK COUNTIF COUNTIFS COUPDAYBS COUPDAYS COUPDAYSNC COUPNCD COUPNUM COUPPCD COVAR COVARIANCE.P COVARIANCE.S CRITBINOM CSC CSCH CUBEKPIMEMBER CUBEMEMBER CUBEMEMBERPROPERTY CUBERANKEDMEMBER CUBESET CUBESETCOUNT CUBEVALUE CUMIPMT CUMPRINC DATE DATEDIF DATEVALUE DAVERAGE DAY DAYS DAYS360 DB DBCS DCOUNT DCOUNTA DDB DEC2BIN DEC2HEX DEC2OCT DECIMAL DEGREES DELTA DEVSQ DGET DISC DMAX DMIN DOLLAR DOLLARDE DOLLARFR DPRODUCT DSTDEV DSTDEVP DSUM DURATION DVAR DVARP EDATE EFFECT ENCODEURL EOMONTH ERF ERF.PRECISE ERFC ERFC.PRECISE ERROR.TYPE EUROCONVERT EVEN EXACT EXP EXPON.DIST EXPONDIST FACT FACTDOUBLE FALSE|0 F.DIST FDIST F.DIST.RT FILTERXML FIND FINDB F.INV F.INV.RT FINV FISHER FISHERINV FIXED FLOOR FLOOR.MATH FLOOR.PRECISE FORECAST FORECAST.ETS FORECAST.ETS.CONFINT FORECAST.ETS.SEASONALITY FORECAST.ETS.STAT FORECAST.LINEAR FORMULATEXT FREQUENCY F.TEST FTEST FV FVSCHEDULE GAMMA GAMMA.DIST GAMMADIST GAMMA.INV GAMMAINV GAMMALN GAMMALN.PRECISE GAUSS GCD GEOMEAN GESTEP GETPIVOTDATA GROWTH HARMEAN HEX2BIN HEX2DEC HEX2OCT HLOOKUP HOUR HYPERLINK HYPGEOM.DIST HYPGEOMDIST IF|0 IFERROR IFNA IFS IMABS IMAGINARY IMARGUMENT IMCONJUGATE IMCOS IMCOSH IMCOT IMCSC IMCSCH IMDIV IMEXP IMLN IMLOG10 IMLOG2 IMPOWER IMPRODUCT IMREAL IMSEC IMSECH IMSIN IMSINH IMSQRT IMSUB IMSUM IMTAN INDEX INDIRECT INFO INT INTERCEPT INTRATE IPMT IRR ISBLANK ISERR ISERROR ISEVEN ISFORMULA ISLOGICAL ISNA ISNONTEXT ISNUMBER ISODD ISREF ISTEXT ISO.CEILING ISOWEEKNUM ISPMT JIS KURT LARGE LCM LEFT LEFTB LEN LENB LINEST LN LOG LOG10 LOGEST LOGINV LOGNORM.DIST LOGNORMDIST LOGNORM.INV LOOKUP LOWER MATCH MAX MAXA MAXIFS MDETERM MDURATION MEDIAN MID MIDBs MIN MINIFS MINA MINUTE MINVERSE MIRR MMULT MOD MODE MODE.MULT MODE.SNGL MONTH MROUND MULTINOMIAL MUNIT N NA NEGBINOM.DIST NEGBINOMDIST NETWORKDAYS NETWORKDAYS.INTL NOMINAL NORM.DIST NORMDIST NORMINV NORM.INV NORM.S.DIST NORMSDIST NORM.S.INV NORMSINV NOT NOW NPER NPV NUMBERVALUE OCT2BIN OCT2DEC OCT2HEX ODD ODDFPRICE ODDFYIELD ODDLPRICE ODDLYIELD OFFSET OR PDURATION PEARSON PERCENTILE.EXC PERCENTILE.INC PERCENTILE PERCENTRANK.EXC PERCENTRANK.INC PERCENTRANK PERMUT PERMUTATIONA PHI PHONETIC PI PMT POISSON.DIST POISSON POWER PPMT PRICE PRICEDISC PRICEMAT PROB PRODUCT PROPER PV QUARTILE QUARTILE.EXC QUARTILE.INC QUOTIENT RADIANS RAND RANDBETWEEN RANK.AVG RANK.EQ RANK RATE RECEIVED REGISTER.ID REPLACE REPLACEB REPT RIGHT RIGHTB ROMAN ROUND ROUNDDOWN ROUNDUP ROW ROWS RRI RSQ RTD SEARCH SEARCHB SEC SECH SECOND SERIESSUM SHEET SHEETS SIGN SIN SINH SKEW SKEW.P SLN SLOPE SMALL SQL.REQUEST SQRT SQRTPI STANDARDIZE STDEV STDEV.P STDEV.S STDEVA STDEVP STDEVPA STEYX SUBSTITUTE SUBTOTAL SUM SUMIF SUMIFS SUMPRODUCT SUMSQ SUMX2MY2 SUMX2PY2 SUMXMY2 SWITCH SYD T TAN TANH TBILLEQ TBILLPRICE TBILLYIELD T.DIST T.DIST.2T T.DIST.RT TDIST TEXT TEXTJOIN TIME TIMEVALUE T.INV T.INV.2T TINV TODAY TRANSPOSE TREND TRIM TRIMMEAN TRUE|0 TRUNC T.TEST TTEST TYPE UNICHAR UNICODE UPPER VALUE VAR VAR.P VAR.S VARA VARP VARPA VDB VLOOKUP WEBSERVICE WEEKDAY WEEKNUM WEIBULL WEIBULL.DIST WORKDAY WORKDAY.INTL XIRR XNPV XOR YEAR YEARFRAC YIELD YIELDDISC YIELDMAT Z.TEST ZTEST"},contains:[{begin:/^=/,end:/[^=]/,returnEnd:!0,illegal:/=/,relevance:10},{className:"symbol",begin:/\b[A-Z]{1,2}\d+\b/,end:/[^\d]/,excludeEnd:!0,relevance:0},{className:"symbol",begin:/[A-Z]{0,2}\d*:[A-Z]{0,2}\d*/,relevance:0},e.BACKSLASH_ESCAPE,e.QUOTE_STRING_MODE,{className:"number",begin:e.NUMBER_RE+"(%)?",relevance:0},e.COMMENT(/\bN\(/,/\)/,{excludeBegin:!0,excludeEnd:!0,illegal:/\n/})]}}},function(e,t){e.exports=function(e){var t="[a-z'][a-zA-Z0-9_']*",n="("+t+":"+t+"|"+t+")",r={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor",literal:"false true"},i=e.COMMENT("%","$"),a={className:"number",begin:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",relevance:0},o={begin:"fun\\s+"+t+"/\\d+"},s={begin:n+"\\(",end:"\\)",returnBegin:!0,relevance:0,contains:[{begin:n,relevance:0},{begin:"\\(",end:"\\)",endsWithParent:!0,returnEnd:!0,relevance:0}]},l={begin:"{",end:"}",relevance:0},c={begin:"\\b_([A-Z][A-Za-z0-9_]*)?",relevance:0},u={begin:"[A-Z][a-zA-Z0-9_]*",relevance:0},d={begin:"#"+e.UNDERSCORE_IDENT_RE,relevance:0,returnBegin:!0,contains:[{begin:"#"+e.UNDERSCORE_IDENT_RE,relevance:0},{begin:"{",end:"}",relevance:0}]},f={beginKeywords:"fun receive if try case",end:"end",keywords:r};f.contains=[i,o,e.inherit(e.APOS_STRING_MODE,{className:""}),f,s,e.QUOTE_STRING_MODE,a,l,c,u,d];var p=[i,o,f,s,e.QUOTE_STRING_MODE,a,l,c,u,d];s.contains[1].contains=p,l.contains=p,d.contains[1].contains=p;var m={className:"params",begin:"\\(",end:"\\)",contains:p};return{aliases:["erl"],keywords:r,illegal:"(",returnBegin:!0,illegal:"\\(|#|//|/\\*|\\\\|:|;",contains:[m,e.inherit(e.TITLE_MODE,{begin:t})],starts:{end:";|\\.",keywords:r,contains:p}},i,{begin:"^-",end:"\\.",relevance:0,excludeEnd:!0,returnBegin:!0,lexemes:"-"+e.IDENT_RE,keywords:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec",contains:[m]},a,e.QUOTE_STRING_MODE,d,c,u,l,{begin:/\.$/}]}}},function(e,t){e.exports=function(e){return{keywords:{built_in:"spawn spawn_link self",keyword:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},contains:[{className:"meta",begin:"^[0-9]+> ",relevance:10},e.COMMENT("%","$"),{className:"number",begin:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",relevance:0},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{begin:"\\?(::)?([A-Z]\\w*(::)?)+"},{begin:"->"},{begin:"ok"},{begin:"!"},{begin:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",relevance:0},{begin:"[A-Z][a-zA-Z0-9_']*",relevance:0}]}}},function(e,t){e.exports=function(e){return{subLanguage:"xml",contains:[e.COMMENT("<%#","%>"),{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0}]}}},function(e,t){e.exports=function(e){var t="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",n={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},r={className:"doctag",begin:"@[A-Za-z]+"},i={begin:"#<",end:">"},a=[e.COMMENT("#","$",{contains:[r]}),e.COMMENT("^\\=begin","^\\=end",{contains:[r],relevance:10}),e.COMMENT("^__END__","\\n$")],o={className:"subst",begin:"#\\{",end:"}",keywords:n},s={className:"string",contains:[e.BACKSLASH_ESCAPE,o],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:"%[qQwWx]?\\(",end:"\\)"},{begin:"%[qQwWx]?\\[",end:"\\]"},{begin:"%[qQwWx]?{",end:"}"},{begin:"%[qQwWx]?<",end:">"},{begin:"%[qQwWx]?/",end:"/"},{begin:"%[qQwWx]?%",end:"%"},{begin:"%[qQwWx]?-",end:"-"},{begin:"%[qQwWx]?\\|",end:"\\|"},{begin:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{begin:/<<(-?)\w+$/,end:/^\s*\w+$/}]},l={className:"params",begin:"\\(",end:"\\)",endsParent:!0,keywords:n},c=[s,i,{className:"class",beginKeywords:"class module",end:"$|;",illegal:/=/,contains:[e.inherit(e.TITLE_MODE,{begin:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{begin:"<\\s*",contains:[{begin:"("+e.IDENT_RE+"::)?"+e.IDENT_RE}]}].concat(a)},{className:"function",beginKeywords:"def",end:"$|;",contains:[e.inherit(e.TITLE_MODE,{begin:t}),l].concat(a)},{begin:e.IDENT_RE+"::"},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(\\!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[s,{begin:t}],relevance:0},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{className:"params",begin:/\|/,end:/\|/,keywords:n},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[i,{className:"regexp",contains:[e.BACKSLASH_ESCAPE,o],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:"%r{",end:"}[a-z]*"},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(a),relevance:0}].concat(a);o.contains=c,l.contains=c;var u=[{begin:/^\s*=>/,starts:{end:"$",contains:c}},{className:"meta",begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{end:"$",contains:c}}];return{aliases:["rb","gemspec","podspec","thor","irb"],keywords:n,illegal:/\/\*/,contains:a.concat(u).concat(c)}}},function(e,t){e.exports=function(e){var t={variants:[e.COMMENT("--","$"),e.COMMENT("{-","-}",{contains:["self"]})]},n={className:"type",begin:"\\b[A-Z][\\w']*",relevance:0},r={begin:"\\(",end:"\\)",illegal:'"',contains:[{className:"type",begin:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},t]};return{keywords:"let in if then else case of where module import exposing type alias as infix infixl infixr port effect command subscription",contains:[{beginKeywords:"port effect module",end:"exposing",keywords:"port effect module where command subscription exposing",contains:[r,t],illegal:"\\W\\.|;"},{begin:"import",end:"$",keywords:"import as exposing",contains:[r,t],illegal:"\\W\\.|;"},{begin:"type",end:"$",keywords:"type alias",contains:[n,r,{begin:"{",end:"}",contains:r.contains},t]},{beginKeywords:"infix infixl infixr",end:"$",contains:[e.C_NUMBER_MODE,t]},{begin:"port",end:"$",keywords:"port",contains:[t]},e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,n,e.inherit(e.TITLE_MODE,{begin:"^[_a-z][\\w']*"}),t,{begin:"->|<-"}],illegal:/;/}}},function(e,t){e.exports=function(e){var t="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?",n="and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote",r={className:"subst",begin:"#\\{",end:"}",lexemes:t,keywords:n},i={className:"string",contains:[e.BACKSLASH_ESCAPE,r],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/}]},a={className:"function",beginKeywords:"def defp defmacro",end:/\B\b/,contains:[e.inherit(e.TITLE_MODE,{begin:t,endsParent:!0})]},o=e.inherit(a,{className:"class",beginKeywords:"defimpl defmodule defprotocol defrecord",end:/\bdo\b|$|;/}),s=[i,e.HASH_COMMENT_MODE,o,a,{className:"symbol",begin:":(?!\\s)",contains:[i,{begin:"[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?"}],relevance:0},{className:"symbol",begin:t+":",relevance:0},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{className:"variable",begin:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{begin:"->"},{begin:"("+e.RE_STARTERS_RE+")\\s*",contains:[e.HASH_COMMENT_MODE,{className:"regexp",illegal:"\\n",contains:[e.BACKSLASH_ESCAPE,r],variants:[{begin:"/",end:"/[a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}],relevance:0}];return r.contains=s,{lexemes:t,keywords:n,contains:s}}},function(e,t){e.exports=function(e){var t=e.COMMENT(/\(\*/,/\*\)/);return{illegal:/\S/,contains:[t,{className:"attribute",begin:/^[ ]*[a-zA-Z][a-zA-Z-]*([\s-]+[a-zA-Z][a-zA-Z]*)*/},{begin:/=/,end:/;/,contains:[t,{className:"meta",begin:/\?.*\?/},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]}]}}},function(e,t){e.exports=function(e){return{aliases:["dst"],case_insensitive:!0,subLanguage:"xml",contains:[{className:"template-tag",begin:/\{[#\/]/,end:/\}/,illegal:/;/,contains:[{className:"name",begin:/[a-zA-Z\.-]+/,starts:{endsWithParent:!0,relevance:0,contains:[e.QUOTE_STRING_MODE]}}]},{className:"template-variable",begin:/\{/,end:/\}/,illegal:/;/,keywords:"if eq ne lt lte gt gte select default math sep"}]}}},function(e,t){e.exports=function(e){var t={className:"string",variants:[e.inherit(e.QUOTE_STRING_MODE,{begin:'((u8?|U)|L)?"'}),{begin:'(u8?|U)?R"',end:'"',contains:[e.BACKSLASH_ESCAPE]},{begin:"'\\\\?.",end:"'",illegal:"."}]},n={className:"number",variants:[{begin:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},{begin:e.C_NUMBER_RE}],relevance:0},r={className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"if else elif endif define undef ifdef ifndef"},contains:[{begin:/\\\n/,relevance:0},{beginKeywords:"include",end:"$",keywords:{"meta-keyword":"include"},contains:[e.inherit(t,{className:"meta-string"}),{className:"meta-string",begin:"<",end:">",illegal:"\\n"}]},t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},i={className:"variable",begin:"\\&[a-z\\d_]*\\b"},a={className:"meta-keyword",begin:"/[a-z][a-z\\d-]*/"},o={className:"symbol",begin:"^\\s*[a-zA-Z_][a-zA-Z\\d_]*:"},s={className:"params",begin:"<",end:">",contains:[n,i]},l={className:"class",begin:/[a-zA-Z_][a-zA-Z\d_@]*\s{/,end:/[{;=]/,returnBegin:!0,excludeEnd:!0};return{keywords:"",contains:[{className:"class",begin:"/\\s*{",end:"};",relevance:10,contains:[i,a,o,l,s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,t]},i,a,o,l,s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,t,r,{begin:e.IDENT_RE+"::",keywords:""}]}}},function(e,t){e.exports=function(e){return{keywords:"dsconfig",contains:[{className:"keyword",begin:"^dsconfig",end:"\\s",excludeEnd:!0,relevance:10},{className:"built_in",begin:"(list|create|get|set|delete)-(\\w+)",end:"\\s",excludeEnd:!0,illegal:"!@#$%^&*()",relevance:10},{className:"built_in",begin:"--(\\w+)",end:"\\s",excludeEnd:!0},{className:"string",begin:/"/,end:/"/},{className:"string",begin:/'/,end:/'/},{className:"string",begin:"[\\w-?]+:\\w+",end:"\\W",relevance:0},{className:"string",begin:"\\w+-?\\w+",end:"\\W",relevance:0},e.HASH_COMMENT_MODE]}}},function(e,t){e.exports=function(e){var t=e.COMMENT(/^\s*@?rem\b/,/$/,{relevance:10});return{aliases:["bat","cmd"],case_insensitive:!0,illegal:/\/\*/,keywords:{keyword:"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq",built_in:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux shift cd dir echo setlocal endlocal set pause copy append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color comp compact convert date dir diskcomp diskcopy doskey erase fs find findstr format ftype graftabl help keyb label md mkdir mode more move path pause print popd pushd promt rd recover rem rename replace restore rmdir shiftsort start subst time title tree type ver verify vol ping net ipconfig taskkill xcopy ren del"},contains:[{className:"variable",begin:/%%[^ ]|%[^ ]+?%|![^ ]+?!/},{className:"function",begin:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",end:"goto:eof",contains:[e.inherit(e.TITLE_MODE,{begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),t]},{className:"number",begin:"\\b\\d+",relevance:0},t]}}},function(e,t){e.exports=function(e){return{aliases:["docker"],case_insensitive:!0,keywords:"from maintainer expose env arg user onbuild stopsignal",contains:[e.HASH_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{beginKeywords:"run cmd entrypoint volume add copy workdir label healthcheck shell",starts:{end:/[^\\]\n/,subLanguage:"bash"}}],illegal:""}]}}},function(e,t){e.exports=function(e){return{aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$"},{begin:"^.+?\\n[=-]{2,}$"}]},{begin:"<",end:">",subLanguage:"xml",relevance:0},{className:"bullet",begin:"^([*+-]|(\\d+\\.))\\s+"},{className:"strong",begin:"[*_]{2}.+?[*_]{2}"},{className:"emphasis",variants:[{begin:"\\*.+?\\*"},{begin:"_.+?_",relevance:0}]},{className:"quote",begin:"^>\\s+",end:"$"},{className:"code",variants:[{begin:"^```w*s*$",end:"^```s*$"},{begin:"`.+?`"},{begin:"^( {4}|\t)",end:"$",relevance:0}]},{begin:"^[-\\*]{3,}",end:"$"},{begin:"\\[.+?\\][\\(\\[].*?[\\)\\]]",returnBegin:!0,contains:[{className:"string",begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0,relevance:0},{className:"link",begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}],relevance:10},{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}}},function(e,t){e.exports=function(e){var t="((0|[1-9][\\d_]*)|0[bB][01_]+|0[xX]([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))",n="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",r={className:"number",begin:"\\b"+t+"(L|u|U|Lu|LU|uL|UL)?",relevance:0},i={className:"number",begin:"\\b(((0[xX](([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)\\.([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)|\\.?([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))[pP][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))|((0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(\\.\\d*|([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)))|\\d+\\.(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)|\\.(0|[1-9][\\d_]*)([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))?))([fF]|L|i|[fF]i|Li)?|"+t+"(i|[fF]i|Li))",relevance:0},a={className:"string",begin:"'("+n+"|.)",end:"'",illegal:"."},o={className:"string",begin:'"',contains:[{begin:n,relevance:0}],end:'"[cwd]?'},s=e.COMMENT("\\/\\+","\\+\\/",{contains:["self"],relevance:10});return{lexemes:e.UNDERSCORE_IDENT_RE,keywords:{keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,{className:"string",begin:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',relevance:10},o,{className:"string",begin:'[rq]"',end:'"[cwd]?',relevance:5},{className:"string",begin:"`",end:"`[cwd]?"},{className:"string",begin:'q"\\{',end:'\\}"'},i,r,a,{className:"meta",begin:"^#!",end:"$",relevance:5},{className:"meta",begin:"#(line)",end:"$",relevance:5},{className:"keyword",begin:"@[a-zA-Z_][a-zA-Z_\\d]*"}]}}},function(e,t){e.exports=function(e){var t={begin:/[A-Z\_\.\-]+\s*:/,returnBegin:!0,end:";",endsWithParent:!0,contains:[{className:"attribute",begin:/\S/,end:":",excludeEnd:!0,starts:{endsWithParent:!0,excludeEnd:!0,contains:[{begin:/[\w-]+\(/,returnBegin:!0,contains:[{className:"built_in",begin:/[\w-]+/},{begin:/\(/,end:/\)/,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]}]},e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE,{className:"number",begin:"#[0-9A-Fa-f]+"},{className:"meta",begin:"!important"}]}}]};return{case_insensitive:!0,illegal:/[=\/|'\$]/,contains:[e.C_BLOCK_COMMENT_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/},{className:"selector-class",begin:/\.[A-Za-z0-9_-]+/},{className:"selector-attr",begin:/\[/,end:/\]/,illegal:"$"},{className:"selector-pseudo",begin:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{begin:"@(font-face|page)",lexemes:"[a-z-]+",keywords:"font-face page"},{begin:"@",end:"[{;]",illegal:/:/,contains:[{className:"keyword",begin:/\w+/},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE]}]},{className:"selector-tag",begin:"[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0},{begin:"{",end:"}",illegal:/\S/,contains:[e.C_BLOCK_COMMENT_MODE,t]}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!1,lexemes:"[a-zA-Z][a-zA-Z0-9_-]*",keywords:{keyword:"base-uri child-src connect-src default-src font-src form-action frame-ancestors frame-src img-src media-src object-src plugin-types report-uri sandbox script-src style-src"},contains:[{className:"string",begin:"'",end:"'"},{className:"attribute",begin:"^Content",end:":",excludeEnd:!0}]}}},function(e,t){e.exports=function(e){var t={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},n={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]},r=e.inherit(n,{illegal:/\n/}),i={className:"subst",begin:"{",end:"}",keywords:t},a=e.inherit(i,{illegal:/\n/}),o={className:"string",begin:/\$"/,end:'"',illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},e.BACKSLASH_ESCAPE,a]},s={className:"string",begin:/\$@"/,end:'"',contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},i]},l=e.inherit(s,{illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},a]});i.contains=[s,o,n,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE],a.contains=[l,o,r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.inherit(e.C_BLOCK_COMMENT_MODE,{illegal:/\n/})];var c={variants:[s,o,n,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},u=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?";return{aliases:["csharp"],keywords:t,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0,contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{begin:"\x3c!--|--\x3e"},{begin:""}]}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},c,e.C_NUMBER_MODE,{beginKeywords:"class interface",end:/[{;=]/,illegal:/[^\s:]/,contains:[e.TITLE_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace",end:/[{;=]/,illegal:/[^\s:]/,contains:[e.inherit(e.TITLE_MODE,{begin:"[a-zA-Z](\\.?\\w)*"}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta",begin:"^\\s*\\[",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{className:"meta-string",begin:/"/,end:/"/}]},{beginKeywords:"new return throw await else",relevance:0},{className:"function",begin:"("+u+"\\s+)+"+e.IDENT_RE+"\\s*\\(",returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:t,contains:[{begin:e.IDENT_RE+"\\s*\\(",returnBegin:!0,contains:[e.TITLE_MODE],relevance:0},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,relevance:0,contains:[c,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}]}}},function(e,t){e.exports=function(e){var t="(_[uif](8|16|32|64))?",n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\][=?]?",r={keyword:"abstract alias as as? asm begin break case class def do else elsif end ensure enum extend for fun if include instance_sizeof is_a? lib macro module next nil? of out pointerof private protected rescue responds_to? return require select self sizeof struct super then type typeof union uninitialized unless until when while with yield __DIR__ __END_LINE__ __FILE__ __LINE__",literal:"false nil true"},i={className:"subst",begin:"#{",end:"}",keywords:r},a={className:"template-variable",variants:[{begin:"\\{\\{",end:"\\}\\}"},{begin:"\\{%",end:"%\\}"}],keywords:r};function o(e,t){var n=[{begin:e,end:t}];return n[0].contains=n,n}var s={className:"string",contains:[e.BACKSLASH_ESCAPE,i],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:"%w?\\(",end:"\\)",contains:o("\\(","\\)")},{begin:"%w?\\[",end:"\\]",contains:o("\\[","\\]")},{begin:"%w?{",end:"}",contains:o("{","}")},{begin:"%w?<",end:">",contains:o("<",">")},{begin:"%w?/",end:"/"},{begin:"%w?%",end:"%"},{begin:"%w?-",end:"-"},{begin:"%w?\\|",end:"\\|"},{begin:/<<-\w+$/,end:/^\s*\w+$/}],relevance:0},l=[a,s,{className:"string",variants:[{begin:"%q\\(",end:"\\)",contains:o("\\(","\\)")},{begin:"%q\\[",end:"\\]",contains:o("\\[","\\]")},{begin:"%q{",end:"}",contains:o("{","}")},{begin:"%q<",end:">",contains:o("<",">")},{begin:"%q/",end:"/"},{begin:"%q%",end:"%"},{begin:"%q-",end:"-"},{begin:"%q\\|",end:"\\|"},{begin:/<<-'\w+'$/,end:/^\s*\w+$/}],relevance:0},{begin:"(!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~)\\s*",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,i],variants:[{begin:"//[a-z]*",relevance:0},{begin:"/",end:"/[a-z]*"},{begin:"%r\\(",end:"\\)",contains:o("\\(","\\)")},{begin:"%r\\[",end:"\\]",contains:o("\\[","\\]")},{begin:"%r{",end:"}",contains:o("{","}")},{begin:"%r<",end:">",contains:o("<",">")},{begin:"%r/",end:"/"},{begin:"%r%",end:"%"},{begin:"%r-",end:"-"},{begin:"%r\\|",end:"\\|"}]}],relevance:0},{className:"regexp",contains:[e.BACKSLASH_ESCAPE,i],variants:[{begin:"%r\\(",end:"\\)",contains:o("\\(","\\)")},{begin:"%r\\[",end:"\\]",contains:o("\\[","\\]")},{begin:"%r{",end:"}",contains:o("{","}")},{begin:"%r<",end:">",contains:o("<",">")},{begin:"%r/",end:"/"},{begin:"%r%",end:"%"},{begin:"%r-",end:"-"},{begin:"%r\\|",end:"\\|"}],relevance:0},{className:"meta",begin:"@\\[",end:"\\]",contains:[e.inherit(e.QUOTE_STRING_MODE,{className:"meta-string"})]},e.HASH_COMMENT_MODE,{className:"class",beginKeywords:"class module struct",end:"$|;",illegal:/=/,contains:[e.HASH_COMMENT_MODE,e.inherit(e.TITLE_MODE,{begin:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{begin:"<"}]},{className:"class",beginKeywords:"lib enum union",end:"$|;",illegal:/=/,contains:[e.HASH_COMMENT_MODE,e.inherit(e.TITLE_MODE,{begin:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"})],relevance:10},{className:"function",beginKeywords:"def",end:/\B\b/,contains:[e.inherit(e.TITLE_MODE,{begin:n,endsParent:!0})]},{className:"function",beginKeywords:"fun macro",end:/\B\b/,contains:[e.inherit(e.TITLE_MODE,{begin:n,endsParent:!0})],relevance:5},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(\\!|\\?)?:",relevance:0},{className:"symbol",begin:":",contains:[s,{begin:n}],relevance:0},{className:"number",variants:[{begin:"\\b0b([01_]*[01])"+t},{begin:"\\b0o([0-7_]*[0-7])"+t},{begin:"\\b0x([A-Fa-f0-9_]*[A-Fa-f0-9])"+t},{begin:"\\b(([0-9][0-9_]*[0-9]|[0-9])(\\.[0-9_]*[0-9])?([eE][+-]?[0-9_]*[0-9])?)"+t}],relevance:0}];return i.contains=l,a.contains=l.slice(1),{aliases:["cr"],lexemes:"[a-zA-Z_]\\w*[!?=]?",keywords:r,contains:l}}},function(e,t){e.exports=function(e){var t="group clone ms master location colocation order fencing_topology rsc_ticket acl_target acl_group user role tag xml";return{aliases:["crm","pcmk"],case_insensitive:!0,keywords:{keyword:"params meta operations op rule attributes utilization read write deny defined not_defined in_range date spec in ref reference attribute type xpath version and or lt gt tag lte gte eq ne \\ number string",literal:"Master Started Slave Stopped start promote demote stop monitor true false"},contains:[e.HASH_COMMENT_MODE,{beginKeywords:"node",starts:{end:"\\s*([\\w_-]+:)?",starts:{className:"title",end:"\\s*[\\$\\w_][\\w_-]*"}}},{beginKeywords:"primitive rsc_template",starts:{className:"title",end:"\\s*[\\$\\w_][\\w_-]*",starts:{end:"\\s*@?[\\w_][\\w_\\.:-]*"}}},{begin:"\\b("+t.split(" ").join("|")+")\\s+",keywords:t,starts:{className:"title",end:"[\\$\\w_][\\w_-]*"}},{beginKeywords:"property rsc_defaults op_defaults",starts:{className:"title",end:"\\s*([\\w_-]+:)?"}},e.QUOTE_STRING_MODE,{className:"meta",begin:"(ocf|systemd|service|lsb):[\\w_:-]+",relevance:0},{className:"number",begin:"\\b\\d+(\\.\\d+)?(ms|s|h|m)?",relevance:0},{className:"literal",begin:"[-]?(infinity|inf)",relevance:0},{className:"attr",begin:/([A-Za-z\$_\#][\w_-]+)=/,relevance:0},{className:"tag",begin:"",relevance:0}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,aliases:["cos","cls"],keywords:"property parameter class classmethod clientmethod extends as break catch close continue do d|0 else elseif for goto halt hang h|0 if job j|0 kill k|0 lock l|0 merge new open quit q|0 read r|0 return set s|0 tcommit throw trollback try tstart use view while write w|0 xecute x|0 zkill znspace zn ztrap zwrite zw zzdump zzwrite print zbreak zinsert zload zprint zremove zsave zzprint mv mvcall mvcrt mvdim mvprint zquit zsync ascii",contains:[{className:"number",begin:"\\b(\\d+(\\.\\d*)?|\\.\\d+)",relevance:0},{className:"string",variants:[{begin:'"',end:'"',contains:[{begin:'""',relevance:0}]}]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"comment",begin:/;/,end:"$",relevance:0},{className:"built_in",begin:/(?:\$\$?|\.\.)\^?[a-zA-Z]+/},{className:"built_in",begin:/\$\$\$[a-zA-Z]+/},{className:"built_in",begin:/%[a-z]+(?:\.[a-z]+)*/},{className:"symbol",begin:/\^%?[a-zA-Z][\w]*/},{className:"keyword",begin:/##class|##super|#define|#dim/},{begin:/&sql\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,subLanguage:"sql"},{begin:/&(js|jscript|javascript)/,excludeBegin:!0,excludeEnd:!0,subLanguage:"javascript"},{begin:/&html<\s*\s*>/,subLanguage:"xml"}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:"_ as at cofix else end exists exists2 fix for forall fun if IF in let match mod Prop return Set then Type using where with Abort About Add Admit Admitted All Arguments Assumptions Axiom Back BackTo Backtrack Bind Blacklist Canonical Cd Check Class Classes Close Coercion Coercions CoFixpoint CoInductive Collection Combined Compute Conjecture Conjectures Constant constr Constraint Constructors Context Corollary CreateHintDb Cut Declare Defined Definition Delimit Dependencies DependentDerive Drop eauto End Equality Eval Example Existential Existentials Existing Export exporting Extern Extract Extraction Fact Field Fields File Fixpoint Focus for From Function Functional Generalizable Global Goal Grab Grammar Graph Guarded Heap Hint HintDb Hints Hypotheses Hypothesis ident Identity If Immediate Implicit Import Include Inductive Infix Info Initial Inline Inspect Instance Instances Intro Intros Inversion Inversion_clear Language Left Lemma Let Libraries Library Load LoadPath Local Locate Ltac ML Mode Module Modules Monomorphic Morphism Next NoInline Notation Obligation Obligations Opaque Open Optimize Options Parameter Parameters Parametric Path Paths pattern Polymorphic Preterm Print Printing Program Projections Proof Proposition Pwd Qed Quit Rec Record Recursive Redirect Relation Remark Remove Require Reserved Reset Resolve Restart Rewrite Right Ring Rings Save Scheme Scope Scopes Script Search SearchAbout SearchHead SearchPattern SearchRewrite Section Separate Set Setoid Show Solve Sorted Step Strategies Strategy Structure SubClass Table Tables Tactic Term Test Theorem Time Timeout Transparent Type Typeclasses Types Undelimit Undo Unfocus Unfocused Unfold Universe Universes Unset Unshelve using Variable Variables Variant Verbose Visibility where with",built_in:"abstract absurd admit after apply as assert assumption at auto autorewrite autounfold before bottom btauto by case case_eq cbn cbv change classical_left classical_right clear clearbody cofix compare compute congruence constr_eq constructor contradict contradiction cut cutrewrite cycle decide decompose dependent destruct destruction dintuition discriminate discrR do double dtauto eapply eassumption eauto ecase econstructor edestruct ediscriminate eelim eexact eexists einduction einjection eleft elim elimtype enough equality erewrite eright esimplify_eq esplit evar exact exactly_once exfalso exists f_equal fail field field_simplify field_simplify_eq first firstorder fix fold fourier functional generalize generalizing gfail give_up has_evar hnf idtac in induction injection instantiate intro intro_pattern intros intuition inversion inversion_clear is_evar is_var lapply lazy left lia lra move native_compute nia nsatz omega once pattern pose progress proof psatz quote record red refine reflexivity remember rename repeat replace revert revgoals rewrite rewrite_strat right ring ring_simplify rtauto set setoid_reflexivity setoid_replace setoid_rewrite setoid_symmetry setoid_transitivity shelve shelve_unifiable simpl simple simplify_eq solve specialize split split_Rabs split_Rmult stepl stepr subst sum swap symmetry tactic tauto time timeout top transitivity trivial try tryif unfold unify until using vm_compute with"},contains:[e.QUOTE_STRING_MODE,e.COMMENT("\\(\\*","\\*\\)"),e.C_NUMBER_MODE,{className:"type",excludeBegin:!0,begin:"\\|\\s*",end:"\\w+"},{begin:/[-=]>/}]}}},function(e,t){e.exports=function(e){var t={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={className:"subst",begin:/#\{/,end:/}/,keywords:t},i=[e.BINARY_NUMBER_MODE,e.inherit(e.C_NUMBER_MODE,{starts:{end:"(\\s*/)?",relevance:0}}),{className:"string",variants:[{begin:/'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE]},{begin:/'/,end:/'/,contains:[e.BACKSLASH_ESCAPE]},{begin:/"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,r]},{begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,r]}]},{className:"regexp",variants:[{begin:"///",end:"///",contains:[r,e.HASH_COMMENT_MODE]},{begin:"//[gim]*",relevance:0},{begin:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{begin:"@"+n},{subLanguage:"javascript",excludeBegin:!0,excludeEnd:!0,variants:[{begin:"```",end:"```"},{begin:"`",end:"`"}]}];r.contains=i;var a=e.inherit(e.TITLE_MODE,{begin:n}),o={className:"params",begin:"\\([^\\(]",returnBegin:!0,contains:[{begin:/\(/,end:/\)/,keywords:t,contains:["self"].concat(i)}]};return{aliases:["coffee","cson","iced"],keywords:t,illegal:/\/\*/,contains:i.concat([e.COMMENT("###","###"),e.HASH_COMMENT_MODE,{className:"function",begin:"^\\s*"+n+"\\s*=\\s*(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[a,o]},{begin:/[:\(,=]\s*/,relevance:0,contains:[{className:"function",begin:"(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[o]}]},{className:"class",beginKeywords:"class",end:"$",illegal:/[:="\[\]]/,contains:[{beginKeywords:"extends",endsWithParent:!0,illegal:/[:="\[\]]/,contains:[a]},a]},{begin:n+":",end:":",returnBegin:!0,returnEnd:!0,relevance:0}])}}},function(e,t){e.exports=function(e){return{aliases:["cmake.in"],case_insensitive:!0,keywords:{keyword:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file qt5_use_modules qt5_use_package qt5_wrap_cpp on off true false and or equal less greater strless strgreater strequal matches"},contains:[{className:"variable",begin:"\\${",end:"}"},e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{contains:[{className:"meta",begin:/^([\w.-]+|\s*#_)=>/,starts:{end:/$/,subLanguage:"clojure"}}]}}},function(e,t){e.exports=function(e){var t="[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*",n={begin:t,relevance:0},r={className:"number",begin:"[-+]?\\d+(\\.\\d+)?",relevance:0},i=e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),a=e.COMMENT(";","$",{relevance:0}),o={className:"literal",begin:/\b(true|false|nil)\b/},s={begin:"[\\[\\{]",end:"[\\]\\}]"},l={className:"comment",begin:"\\^"+t},c=e.COMMENT("\\^\\{","\\}"),u={className:"symbol",begin:"[:]{1,2}"+t},d={begin:"\\(",end:"\\)"},f={endsWithParent:!0,relevance:0},p={keywords:{"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},lexemes:t,className:"name",begin:t,starts:f},m=[d,i,l,c,a,u,s,r,o,n];return d.contains=[e.COMMENT("comment",""),p,f],f.contains=m,s.contains=m,c.contains=[s],{aliases:["clj"],illegal:/\S/,contains:[d,i,l,c,a,u,s,r,o]}}},function(e,t){e.exports=function(e){return{aliases:["clean","icl","dcl"],keywords:{keyword:"if let in with where case of class instance otherwise implementation definition system module from import qualified as special code inline foreign export ccall stdcall generic derive infix infixl infixr",literal:"True False"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,{begin:"->|<-[|:]?|::|#!?|>>=|\\{\\||\\|\\}|:==|=:|\\.\\.|<>|`"}]}}},function(e,t){e.exports=function(e){var t="assembly module package import alias class interface object given value assign void function new of extends satisfies abstracts in out return break continue throw assert dynamic if else switch case for while try catch finally then let this outer super is exists nonempty",n={className:"subst",excludeBegin:!0,excludeEnd:!0,begin:/``/,end:/``/,keywords:t,relevance:10},r=[{className:"string",begin:'"""',end:'"""',relevance:10},{className:"string",begin:'"',end:'"',contains:[n]},{className:"string",begin:"'",end:"'"},{className:"number",begin:"#[0-9a-fA-F_]+|\\$[01_]+|[0-9_]+(?:\\.[0-9_](?:[eE][+-]?\\d+)?)?[kMGTPmunpf]?",relevance:0}];return n.contains=r,{keywords:{keyword:t+" shared abstract formal default actual variable late native deprecatedfinal sealed annotation suppressWarnings small",meta:"doc by license see throws tagged"},illegal:"\\$[^01]|#[^0-9a-fA-F]",contains:[e.C_LINE_COMMENT_MODE,e.COMMENT("/\\*","\\*/",{contains:["self"]}),{className:"meta",begin:'@[a-z]\\w*(?:\\:"[^"]*")?'}].concat(r)}}},function(e,t){e.exports=function(e){return{aliases:["capnp"],keywords:{keyword:"struct enum interface union group import using const annotation extends in of on as with from fixed",built_in:"Void Bool Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Float32 Float64 Text Data AnyPointer AnyStruct Capability List",literal:"true false"},contains:[e.QUOTE_STRING_MODE,e.NUMBER_MODE,e.HASH_COMMENT_MODE,{className:"meta",begin:/@0x[\w\d]{16};/,illegal:/\n/},{className:"symbol",begin:/@\d+\b/},{className:"class",beginKeywords:"struct enum",end:/\{/,illegal:/\n/,contains:[e.inherit(e.TITLE_MODE,{starts:{endsWithParent:!0,excludeEnd:!0}})]},{className:"class",beginKeywords:"interface",end:/\{/,illegal:/\n/,contains:[e.inherit(e.TITLE_MODE,{starts:{endsWithParent:!0,excludeEnd:!0}})]}]}}},function(e,t){e.exports=function(e){var t="div mod in and or not xor asserterror begin case do downto else end exit for if of repeat then to until while with var",n=[e.C_LINE_COMMENT_MODE,e.COMMENT(/\{/,/\}/,{relevance:0}),e.COMMENT(/\(\*/,/\*\)/,{relevance:10})],r={className:"string",begin:/'/,end:/'/,contains:[{begin:/''/}]},i={className:"string",begin:/(#\d+)+/},a={className:"function",beginKeywords:"procedure",end:/[:;]/,keywords:"procedure|10",contains:[e.TITLE_MODE,{className:"params",begin:/\(/,end:/\)/,keywords:t,contains:[r,i]}].concat(n)},o={className:"class",begin:"OBJECT (Table|Form|Report|Dataport|Codeunit|XMLport|MenuSuite|Page|Query) (\\d+) ([^\\r\\n]+)",returnBegin:!0,contains:[e.TITLE_MODE,a]};return{case_insensitive:!0,keywords:{keyword:t,literal:"false true"},illegal:/\/\*/,contains:[r,i,{className:"number",begin:"\\b\\d+(\\.\\d+)?(DT|D|T)",relevance:0},{className:"string",begin:'"',end:'"'},e.NUMBER_MODE,o,a]}}},function(e,t){e.exports=function(e){var t={className:"literal",begin:"[\\+\\-]",relevance:0};return{aliases:["bf"],contains:[e.COMMENT("[^\\[\\]\\.,\\+\\-<> \r\n]","[\\[\\]\\.,\\+\\-<> \r\n]",{returnEnd:!0,relevance:0}),{className:"title",begin:"[\\[\\]]",relevance:0},{className:"string",begin:"[\\.,]",relevance:0},{begin:/\+\+|\-\-/,returnBegin:!0,contains:[t]},t]}}},function(e,t){e.exports=function(e){return{contains:[{className:"attribute",begin://},{begin:/::=/,starts:{end:/$/,contains:[{begin://},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]}}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,illegal:"^.",lexemes:"[a-zA-Z][a-zA-Z0-9_$%!#]*",keywords:{keyword:"ABS ASC AND ATN AUTO|0 BEEP BLOAD|10 BSAVE|10 CALL CALLS CDBL CHAIN CHDIR CHR$|10 CINT CIRCLE CLEAR CLOSE CLS COLOR COM COMMON CONT COS CSNG CSRLIN CVD CVI CVS DATA DATE$ DEFDBL DEFINT DEFSNG DEFSTR DEF|0 SEG USR DELETE DIM DRAW EDIT END ENVIRON ENVIRON$ EOF EQV ERASE ERDEV ERDEV$ ERL ERR ERROR EXP FIELD FILES FIX FOR|0 FRE GET GOSUB|10 GOTO HEX$ IF|0 THEN ELSE|0 INKEY$ INP INPUT INPUT# INPUT$ INSTR IMP INT IOCTL IOCTL$ KEY ON OFF LIST KILL LEFT$ LEN LET LINE LLIST LOAD LOC LOCATE LOF LOG LPRINT USING LSET MERGE MID$ MKDIR MKD$ MKI$ MKS$ MOD NAME NEW NEXT NOISE NOT OCT$ ON OR PEN PLAY STRIG OPEN OPTION BASE OUT PAINT PALETTE PCOPY PEEK PMAP POINT POKE POS PRINT PRINT] PSET PRESET PUT RANDOMIZE READ REM RENUM RESET|0 RESTORE RESUME RETURN|0 RIGHT$ RMDIR RND RSET RUN SAVE SCREEN SGN SHELL SIN SOUND SPACE$ SPC SQR STEP STICK STOP STR$ STRING$ SWAP SYSTEM TAB TAN TIME$ TIMER TROFF TRON TO USR VAL VARPTR VARPTR$ VIEW WAIT WHILE WEND WIDTH WINDOW WRITE XOR"},contains:[e.QUOTE_STRING_MODE,e.COMMENT("REM","$",{relevance:10}),e.COMMENT("'","$",{relevance:0}),{className:"symbol",begin:"^[0-9]+ ",relevance:10},{className:"number",begin:"\\b([0-9]+[0-9edED.]*[#!]?)",relevance:0},{className:"number",begin:"(&[hH][0-9a-fA-F]{1,4})"},{className:"number",begin:"(&[oO][0-7]{1,6})"}]}}},function(e,t){e.exports=function(e){var t={className:"variable",variants:[{begin:/\$[\w\d#@][\w\d_]*/},{begin:/\$\{(.*?)}/}]},n={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,t,{className:"variable",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]}]};return{aliases:["sh","zsh"],lexemes:/\b-?[a-z\._]+\b/,keywords:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},contains:[{className:"meta",begin:/^#![^\n]+sh\s*$/,relevance:10},{className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0},e.HASH_COMMENT_MODE,n,{className:"string",begin:/'/,end:/'/},t]}}},function(e,t){e.exports=function(e){return{keywords:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,{className:"meta",begin:"#",end:"$"},{className:"class",beginKeywords:"class interface",end:"{",excludeEnd:!0,illegal:":",contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:"BEGIN END if else while do for in break continue delete next nextfile function func exit|10"},contains:[{className:"variable",variants:[{begin:/\$[\w\d#@][\w\d_]*/},{begin:/\$\{(.*?)}/}]},{className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/(u|b)?r?'''/,end:/'''/,relevance:10},{begin:/(u|b)?r?"""/,end:/"""/,relevance:10},{begin:/(u|r|ur)'/,end:/'/,relevance:10},{begin:/(u|r|ur)"/,end:/"/,relevance:10},{begin:/(b|br)'/,end:/'/},{begin:/(b|br)"/,end:/"/},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},e.REGEXP_MODE,e.HASH_COMMENT_MODE,e.NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,lexemes:"\\.?"+e.IDENT_RE,keywords:{keyword:"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf",meta:".byte .cseg .db .def .device .dseg .dw .endmacro .equ .eseg .exit .include .list .listmac .macro .nolist .org .set"},contains:[e.C_BLOCK_COMMENT_MODE,e.COMMENT(";","$",{relevance:0}),e.C_NUMBER_MODE,e.BINARY_NUMBER_MODE,{className:"number",begin:"\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)"},e.QUOTE_STRING_MODE,{className:"string",begin:"'",end:"[^\\\\]'",illegal:"[^\\\\][^']"},{className:"symbol",begin:"^[A-Za-z0-9_.$]+:"},{className:"meta",begin:"#",end:"$"},{className:"subst",begin:"@[0-9]+"}]}}},function(e,t){e.exports=function(e){var t={variants:[e.COMMENT(";","$",{relevance:0}),e.COMMENT("#cs","#ce"),e.COMMENT("#comments-start","#comments-end")]},n={begin:"\\$[A-z0-9_]+"},r={className:"string",variants:[{begin:/"/,end:/"/,contains:[{begin:/""/,relevance:0}]},{begin:/'/,end:/'/,contains:[{begin:/''/,relevance:0}]}]},i={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]};return{case_insensitive:!0,illegal:/\/\*/,keywords:{keyword:"ByRef Case Const ContinueCase ContinueLoop Default Dim Do Else ElseIf EndFunc EndIf EndSelect EndSwitch EndWith Enum Exit ExitLoop For Func Global If In Local Next ReDim Return Select Static Step Switch Then To Until Volatile WEnd While With",built_in:"Abs ACos AdlibRegister AdlibUnRegister Asc AscW ASin Assign ATan AutoItSetOption AutoItWinGetTitle AutoItWinSetTitle Beep Binary BinaryLen BinaryMid BinaryToString BitAND BitNOT BitOR BitRotate BitShift BitXOR BlockInput Break Call CDTray Ceiling Chr ChrW ClipGet ClipPut ConsoleRead ConsoleWrite ConsoleWriteError ControlClick ControlCommand ControlDisable ControlEnable ControlFocus ControlGetFocus ControlGetHandle ControlGetPos ControlGetText ControlHide ControlListView ControlMove ControlSend ControlSetText ControlShow ControlTreeView Cos Dec DirCopy DirCreate DirGetSize DirMove DirRemove DllCall DllCallAddress DllCallbackFree DllCallbackGetPtr DllCallbackRegister DllClose DllOpen DllStructCreate DllStructGetData DllStructGetPtr DllStructGetSize DllStructSetData DriveGetDrive DriveGetFileSystem DriveGetLabel DriveGetSerial DriveGetType DriveMapAdd DriveMapDel DriveMapGet DriveSetLabel DriveSpaceFree DriveSpaceTotal DriveStatus EnvGet EnvSet EnvUpdate Eval Execute Exp FileChangeDir FileClose FileCopy FileCreateNTFSLink FileCreateShortcut FileDelete FileExists FileFindFirstFile FileFindNextFile FileFlush FileGetAttrib FileGetEncoding FileGetLongName FileGetPos FileGetShortcut FileGetShortName FileGetSize FileGetTime FileGetVersion FileInstall FileMove FileOpen FileOpenDialog FileRead FileReadLine FileReadToArray FileRecycle FileRecycleEmpty FileSaveDialog FileSelectFolder FileSetAttrib FileSetEnd FileSetPos FileSetTime FileWrite FileWriteLine Floor FtpSetProxy FuncName GUICreate GUICtrlCreateAvi GUICtrlCreateButton GUICtrlCreateCheckbox GUICtrlCreateCombo GUICtrlCreateContextMenu GUICtrlCreateDate GUICtrlCreateDummy GUICtrlCreateEdit GUICtrlCreateGraphic GUICtrlCreateGroup GUICtrlCreateIcon GUICtrlCreateInput GUICtrlCreateLabel GUICtrlCreateList GUICtrlCreateListView GUICtrlCreateListViewItem GUICtrlCreateMenu GUICtrlCreateMenuItem GUICtrlCreateMonthCal GUICtrlCreateObj GUICtrlCreatePic GUICtrlCreateProgress GUICtrlCreateRadio GUICtrlCreateSlider GUICtrlCreateTab GUICtrlCreateTabItem GUICtrlCreateTreeView GUICtrlCreateTreeViewItem GUICtrlCreateUpdown GUICtrlDelete GUICtrlGetHandle GUICtrlGetState GUICtrlRead GUICtrlRecvMsg GUICtrlRegisterListViewSort GUICtrlSendMsg GUICtrlSendToDummy GUICtrlSetBkColor GUICtrlSetColor GUICtrlSetCursor GUICtrlSetData GUICtrlSetDefBkColor GUICtrlSetDefColor GUICtrlSetFont GUICtrlSetGraphic GUICtrlSetImage GUICtrlSetLimit GUICtrlSetOnEvent GUICtrlSetPos GUICtrlSetResizing GUICtrlSetState GUICtrlSetStyle GUICtrlSetTip GUIDelete GUIGetCursorInfo GUIGetMsg GUIGetStyle GUIRegisterMsg GUISetAccelerators GUISetBkColor GUISetCoord GUISetCursor GUISetFont GUISetHelp GUISetIcon GUISetOnEvent GUISetState GUISetStyle GUIStartGroup GUISwitch Hex HotKeySet HttpSetProxy HttpSetUserAgent HWnd InetClose InetGet InetGetInfo InetGetSize InetRead IniDelete IniRead IniReadSection IniReadSectionNames IniRenameSection IniWrite IniWriteSection InputBox Int IsAdmin IsArray IsBinary IsBool IsDeclared IsDllStruct IsFloat IsFunc IsHWnd IsInt IsKeyword IsNumber IsObj IsPtr IsString Log MemGetStats Mod MouseClick MouseClickDrag MouseDown MouseGetCursor MouseGetPos MouseMove MouseUp MouseWheel MsgBox Number ObjCreate ObjCreateInterface ObjEvent ObjGet ObjName OnAutoItExitRegister OnAutoItExitUnRegister Ping PixelChecksum PixelGetColor PixelSearch ProcessClose ProcessExists ProcessGetStats ProcessList ProcessSetPriority ProcessWait ProcessWaitClose ProgressOff ProgressOn ProgressSet Ptr Random RegDelete RegEnumKey RegEnumVal RegRead RegWrite Round Run RunAs RunAsWait RunWait Send SendKeepActive SetError SetExtended ShellExecute ShellExecuteWait Shutdown Sin Sleep SoundPlay SoundSetWaveVolume SplashImageOn SplashOff SplashTextOn Sqrt SRandom StatusbarGetText StderrRead StdinWrite StdioClose StdoutRead String StringAddCR StringCompare StringFormat StringFromASCIIArray StringInStr StringIsAlNum StringIsAlpha StringIsASCII StringIsDigit StringIsFloat StringIsInt StringIsLower StringIsSpace StringIsUpper StringIsXDigit StringLeft StringLen StringLower StringMid StringRegExp StringRegExpReplace StringReplace StringReverse StringRight StringSplit StringStripCR StringStripWS StringToASCIIArray StringToBinary StringTrimLeft StringTrimRight StringUpper Tan TCPAccept TCPCloseSocket TCPConnect TCPListen TCPNameToIP TCPRecv TCPSend TCPShutdown, UDPShutdown TCPStartup, UDPStartup TimerDiff TimerInit ToolTip TrayCreateItem TrayCreateMenu TrayGetMsg TrayItemDelete TrayItemGetHandle TrayItemGetState TrayItemGetText TrayItemSetOnEvent TrayItemSetState TrayItemSetText TraySetClick TraySetIcon TraySetOnEvent TraySetPauseIcon TraySetState TraySetToolTip TrayTip UBound UDPBind UDPCloseSocket UDPOpen UDPRecv UDPSend VarGetType WinActivate WinActive WinClose WinExists WinFlash WinGetCaretPos WinGetClassList WinGetClientSize WinGetHandle WinGetPos WinGetProcess WinGetState WinGetText WinGetTitle WinKill WinList WinMenuSelectItem WinMinimizeAll WinMinimizeAllUndo WinMove WinSetOnTop WinSetState WinSetTitle WinSetTrans WinWait",literal:"True False And Null Not Or"},contains:[t,n,r,i,{className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"comments include include-once NoTrayIcon OnAutoItStartRegister pragma compile RequireAdmin"},contains:[{begin:/\\\n/,relevance:0},{beginKeywords:"include",keywords:{"meta-keyword":"include"},end:"$",contains:[r,{className:"meta-string",variants:[{begin:"<",end:">"},{begin:/"/,end:/"/,contains:[{begin:/""/,relevance:0}]},{begin:/'/,end:/'/,contains:[{begin:/''/,relevance:0}]}]}]},r,t]},{className:"symbol",begin:"@[A-z0-9_]+"},{className:"function",beginKeywords:"Func",end:"$",illegal:"\\$|\\[|%",contains:[e.UNDERSCORE_TITLE_MODE,{className:"params",begin:"\\(",end:"\\)",contains:[n,r,i]}]}]}}},function(e,t){e.exports=function(e){var t={begin:"`[\\s\\S]"};return{case_insensitive:!0,aliases:["ahk"],keywords:{keyword:"Break Continue Critical Exit ExitApp Gosub Goto New OnExit Pause return SetBatchLines SetTimer Suspend Thread Throw Until ahk_id ahk_class ahk_pid ahk_exe ahk_group",literal:"A|0 true false NOT AND OR",built_in:"ComSpec Clipboard ClipboardAll ErrorLevel"},contains:[{className:"built_in",begin:"A_[a-zA-Z0-9]+"},t,e.inherit(e.QUOTE_STRING_MODE,{contains:[t]}),e.COMMENT(";","$",{relevance:0}),e.C_BLOCK_COMMENT_MODE,{className:"number",begin:e.NUMBER_RE,relevance:0},{className:"subst",begin:"%(?=[a-zA-Z0-9#_$@])",end:"%",illegal:"[^a-zA-Z0-9#_$@]"},{className:"built_in",begin:"^\\s*\\w+\\s*,"},{className:"meta",begin:"^\\s*#w+",end:"$",relevance:0},{className:"symbol",contains:[t],variants:[{begin:'^[^\\n";]+::(?!=)'},{begin:'^[^\\n";]+:(?!=)',relevance:0}]},{begin:",\\s*,"}]}}},function(e,t){e.exports=function(e){var t="false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance";return{keywords:t,illegal:/<\/|#/,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"class",beginKeywords:"aspect",end:/[{;=]/,excludeEnd:!0,illegal:/[:;"\[\]]/,contains:[{beginKeywords:"extends implements pertypewithin perthis pertarget percflowbelow percflow issingleton"},e.UNDERSCORE_TITLE_MODE,{begin:/\([^\)]*/,end:/[)]+/,keywords:t+" get set args call",excludeEnd:!1}]},{className:"class",beginKeywords:"class interface",end:/[{;=]/,excludeEnd:!0,relevance:0,keywords:"class interface",illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"pointcut after before around throwing returning",end:/[)]/,excludeEnd:!1,illegal:/["\[\]]/,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,contains:[e.UNDERSCORE_TITLE_MODE]}]},{begin:/[:]/,returnBegin:!0,end:/[{;]/,relevance:0,excludeEnd:!1,keywords:t,illegal:/["\[\]]/,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",keywords:t+" get set args call",relevance:0},e.QUOTE_STRING_MODE]},{beginKeywords:"new throw",relevance:0},{className:"function",begin:/\w+ +\w+(\.)?\w+\s*\([^\)]*\)\s*((throws)[\w\s,]+)?[\{;]/,returnBegin:!0,end:/[{;=]/,keywords:t,excludeEnd:!0,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"params",begin:/\(/,end:/\)/,relevance:0,keywords:t,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"}]}}},function(e,t){e.exports=function(e){return{aliases:["adoc"],contains:[e.COMMENT("^/{4,}\\n","\\n/{4,}$",{relevance:10}),e.COMMENT("^//","$",{relevance:0}),{className:"title",begin:"^\\.\\w.*$"},{begin:"^[=\\*]{4,}\\n",end:"\\n^[=\\*]{4,}$",relevance:10},{className:"section",relevance:10,variants:[{begin:"^(={1,5}) .+?( \\1)?$"},{begin:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$"}]},{className:"meta",begin:"^:.+?:",end:"\\s",excludeEnd:!0,relevance:10},{className:"meta",begin:"^\\[.+?\\]$",relevance:0},{className:"quote",begin:"^_{4,}\\n",end:"\\n_{4,}$",relevance:10},{className:"code",begin:"^[\\-\\.]{4,}\\n",end:"\\n[\\-\\.]{4,}$",relevance:10},{begin:"^\\+{4,}\\n",end:"\\n\\+{4,}$",contains:[{begin:"<",end:">",subLanguage:"xml",relevance:0}],relevance:10},{className:"bullet",begin:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{className:"symbol",begin:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",relevance:10},{className:"strong",begin:"\\B\\*(?![\\*\\s])",end:"(\\n{2}|\\*)",contains:[{begin:"\\\\*\\w",relevance:0}]},{className:"emphasis",begin:"\\B'(?!['\\s])",end:"(\\n{2}|')",contains:[{begin:"\\\\'\\w",relevance:0}],relevance:0},{className:"emphasis",begin:"_(?![_\\s])",end:"(\\n{2}|_)",relevance:0},{className:"string",variants:[{begin:"``.+?''"},{begin:"`.+?'"}]},{className:"code",begin:"(`.+?`|\\+.+?\\+)",relevance:0},{className:"code",begin:"^[ \\t]",end:"$",relevance:0},{begin:"^'{3,}[ \\t]*$",relevance:10},{begin:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",returnBegin:!0,contains:[{begin:"(link|image:?):",relevance:0},{className:"link",begin:"\\w",end:"[^\\[]+",relevance:0},{className:"string",begin:"\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0,relevance:0}],relevance:10}]}}},function(e,t){e.exports=function(e){var t={endsWithParent:!0,illegal:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],case_insensitive:!0,contains:[{className:"meta",begin:"",relevance:10,contains:[{begin:"\\[",end:"\\]"}]},e.COMMENT("\x3c!--","--\x3e",{relevance:10}),{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10},{begin:/<\?(php)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*",end:"\\*/",skip:!0}]},{className:"tag",begin:"|$)",end:">",keywords:{name:"style"},contains:[t],starts:{end:"",returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:"|$)",end:">",keywords:{name:"script"},contains:[t],starts:{end:"<\/script>",returnEnd:!0,subLanguage:["actionscript","javascript","handlebars","xml"]}},{className:"meta",variants:[{begin:/<\?xml/,end:/\?>/,relevance:10},{begin:/<\?\w+/,end:/\?>/}]},{className:"tag",begin:"",contains:[{className:"name",begin:/[^\/><\s]+/,relevance:0},t]}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,aliases:["arm"],lexemes:"\\.?"+e.IDENT_RE,keywords:{meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 pc lr sp ip sl sb fp a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 {PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @"},contains:[{className:"keyword",begin:"\\b(adc|(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|wfe|wfi|yield)(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?[sptrx]?",end:"\\s"},e.COMMENT("[;@]","$",{relevance:0}),e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,{className:"string",begin:"'",end:"[^\\\\]'",relevance:0},{className:"title",begin:"\\|",end:"\\|",illegal:"\\n",relevance:0},{className:"number",variants:[{begin:"[#$=]?0x[0-9a-f]+"},{begin:"[#$=]?0b[01]+"},{begin:"[#$=]\\d+"},{begin:"\\b\\d+"}],relevance:0},{className:"symbol",variants:[{begin:"^[a-z_\\.\\$][a-z0-9_\\.\\$]+"},{begin:"^\\s*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{begin:"[=#]\\w+"}],relevance:0}]}}},function(e,t){e.exports=function(e){var t=e.getLanguage("cpp").exports;return{keywords:{keyword:"boolean byte word string String array "+t.keywords.keyword,built_in:"setup loop while catch for if do goto try switch case else default break continue return KeyboardController MouseController SoftwareSerial EthernetServer EthernetClient LiquidCrystal RobotControl GSMVoiceCall EthernetUDP EsploraTFT HttpClient RobotMotor WiFiClient GSMScanner FileSystem Scheduler GSMServer YunClient YunServer IPAddress GSMClient GSMModem Keyboard Ethernet Console GSMBand Esplora Stepper Process WiFiUDP GSM_SMS Mailbox USBHost Firmata PImage Client Server GSMPIN FileIO Bridge Serial EEPROM Stream Mouse Audio Servo File Task GPRS WiFi Wire TFT GSM SPI SD runShellCommandAsynchronously analogWriteResolution retrieveCallingNumber printFirmwareVersion analogReadResolution sendDigitalPortPair noListenOnLocalhost readJoystickButton setFirmwareVersion readJoystickSwitch scrollDisplayRight getVoiceCallStatus scrollDisplayLeft writeMicroseconds delayMicroseconds beginTransmission getSignalStrength runAsynchronously getAsynchronously listenOnLocalhost getCurrentCarrier readAccelerometer messageAvailable sendDigitalPorts lineFollowConfig countryNameWrite runShellCommand readStringUntil rewindDirectory readTemperature setClockDivider readLightSensor endTransmission analogReference detachInterrupt countryNameRead attachInterrupt encryptionType readBytesUntil robotNameWrite readMicrophone robotNameRead cityNameWrite userNameWrite readJoystickY readJoystickX mouseReleased openNextFile scanNetworks noInterrupts digitalWrite beginSpeaker mousePressed isActionDone mouseDragged displayLogos noAutoscroll addParameter remoteNumber getModifiers keyboardRead userNameRead waitContinue processInput parseCommand printVersion readNetworks writeMessage blinkVersion cityNameRead readMessage setDataMode parsePacket isListening setBitOrder beginPacket isDirectory motorsWrite drawCompass digitalRead clearScreen serialEvent rightToLeft setTextSize leftToRight requestFrom keyReleased compassRead analogWrite interrupts WiFiServer disconnect playMelody parseFloat autoscroll getPINUsed setPINUsed setTimeout sendAnalog readSlider analogRead beginWrite createChar motorsStop keyPressed tempoWrite readButton subnetMask debugPrint macAddress writeGreen randomSeed attachGPRS readString sendString remotePort releaseAll mouseMoved background getXChange getYChange answerCall getResult voiceCall endPacket constrain getSocket writeJSON getButton available connected findUntil readBytes exitValue readGreen writeBlue startLoop IPAddress isPressed sendSysex pauseMode gatewayIP setCursor getOemKey tuneWrite noDisplay loadImage switchPIN onRequest onReceive changePIN playFile noBuffer parseInt overflow checkPIN knobRead beginTFT bitClear updateIR bitWrite position writeRGB highByte writeRed setSpeed readBlue noStroke remoteIP transfer shutdown hangCall beginSMS endWrite attached maintain noCursor checkReg checkPUK shiftOut isValid shiftIn pulseIn connect println localIP pinMode getIMEI display noBlink process getBand running beginSD drawBMP lowByte setBand release bitRead prepare pointTo readRed setMode noFill remove listen stroke detach attach noTone exists buffer height bitSet circle config cursor random IRread setDNS endSMS getKey micros millis begin print write ready flush width isPIN blink clear press mkdir rmdir close point yield image BSSID click delay read text move peek beep rect line open seek fill size turn stop home find step tone sqrt RSSI SSID end bit tan cos sin pow map abs max min get run put",literal:"DIGITAL_MESSAGE FIRMATA_STRING ANALOG_MESSAGE REPORT_DIGITAL REPORT_ANALOG INPUT_PULLUP SET_PIN_MODE INTERNAL2V56 SYSTEM_RESET LED_BUILTIN INTERNAL1V1 SYSEX_START INTERNAL EXTERNAL DEFAULT OUTPUT INPUT HIGH LOW"},contains:[t.preprocessor,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t={className:"keyword",begin:"\\b[a-z\\d_]*_t\\b"},n={className:"string",variants:[{begin:'(u8?|U)?L?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:'(u8?|U)?R"',end:'"',contains:[e.BACKSLASH_ESCAPE]},{begin:"'\\\\?.",end:"'",illegal:"."}]},r={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},i={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},e.inherit(n,{className:"meta-string"}),{className:"meta-string",begin:/<[^\n>]*>/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},a=e.IDENT_RE+"\\s*\\(",o={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},s=[t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,r,n];return{aliases:["c","cc","h","c++","h++","hpp"],keywords:o,illegal:"",keywords:o,contains:["self",t]},{begin:e.IDENT_RE+"::",keywords:o},{variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:o,contains:s.concat([{begin:/\(/,end:/\)/,keywords:o,contains:s.concat(["self"]),relevance:0}]),relevance:0},{className:"function",begin:"("+e.IDENT_RE+"[\\*&\\s]+)+"+a,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:o,illegal:/[^\w\s\*&]/,contains:[{begin:a,returnBegin:!0,contains:[e.TITLE_MODE],relevance:0},{className:"params",begin:/\(/,end:/\)/,keywords:o,relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,r,t]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,i]},{className:"class",beginKeywords:"class struct",end:/[{;:]/,contains:[{begin://,contains:["self"]},e.TITLE_MODE]}]),exports:{preprocessor:i,strings:n,keywords:o}}}},function(e,t){e.exports=function(e){var t=e.inherit(e.QUOTE_STRING_MODE,{illegal:""}),n={className:"params",begin:"\\(",end:"\\)",contains:["self",e.C_NUMBER_MODE,t]},r=e.COMMENT("--","$"),i=[r,e.COMMENT("\\(\\*","\\*\\)",{contains:["self",r]}),e.HASH_COMMENT_MODE];return{aliases:["osascript"],keywords:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the|0 then third through thru timeout times to transaction try until where while whose with without",literal:"AppleScript false linefeed return pi quote result space tab true",built_in:"alias application boolean class constant date file integer list number real record string text activate beep count delay launch log offset read round run say summarize write character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},contains:[t,e.C_NUMBER_MODE,{className:"built_in",begin:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{className:"literal",begin:"\\b(text item delimiters|current application|missing value)\\b"},{className:"keyword",begin:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference)|POSIX file|POSIX path|(date|time) string|quoted form)\\b"},{beginKeywords:"on",illegal:"[${=;\\n]",contains:[e.UNDERSCORE_TITLE_MODE,n]}].concat(i),illegal:"//|->|=>|\\[\\["}}},function(e,t){e.exports=function(e){var t={className:"number",begin:"[\\$%]\\d+"};return{aliases:["apacheconf"],case_insensitive:!0,contains:[e.HASH_COMMENT_MODE,{className:"section",begin:""},{className:"attribute",begin:/\w+/,relevance:0,keywords:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{end:/$/,relevance:0,keywords:{literal:"on off all"},contains:[{className:"meta",begin:"\\s\\[",end:"\\]$"},{className:"variable",begin:"[\\$%]\\{",end:"\\}",contains:["self",t]},t,e.QUOTE_STRING_MODE]}}],illegal:/\S/}}},function(e,t){e.exports=function(e){var t="[A-Za-z](_?[A-Za-z0-9.])*",n=e.COMMENT("--","$"),r={begin:"\\s+:\\s+",end:"\\s*(:=|;|\\)|=>|$)",illegal:"[]{}%#'\"",contains:[{beginKeywords:"loop for declare others",endsParent:!0},{className:"keyword",beginKeywords:"not null constant access function procedure in out aliased exception"},{className:"type",begin:t,endsParent:!0,relevance:0}]};return{case_insensitive:!0,keywords:{keyword:"abort else new return abs elsif not reverse abstract end accept entry select access exception of separate aliased exit or some all others subtype and for out synchronized array function overriding at tagged generic package task begin goto pragma terminate body private then if procedure type case in protected constant interface is raise use declare range delay limited record when delta loop rem while digits renames with do mod requeue xor",literal:"True False"},contains:[n,{className:"string",begin:/"/,end:/"/,contains:[{begin:/""/,relevance:0}]},{className:"string",begin:/'.'/},{className:"number",begin:"\\b(\\d(_|\\d)*#\\w+(\\.\\w+)?#([eE][-+]?\\d(_|\\d)*)?|\\d(_|\\d)*(\\.\\d(_|\\d)*)?([eE][-+]?\\d(_|\\d)*)?)",relevance:0},{className:"symbol",begin:"'"+t},{className:"title",begin:"(\\bwith\\s+)?(\\bprivate\\s+)?\\bpackage\\s+(\\bbody\\s+)?",end:"(is|$)",keywords:"package body",excludeBegin:!0,excludeEnd:!0,illegal:"[]{}%#'\""},{begin:"(\\b(with|overriding)\\s+)?\\b(function|procedure)\\s+",end:"(\\bis|\\bwith|\\brenames|\\)\\s*;)",keywords:"overriding function procedure with is renames return",returnBegin:!0,contains:[n,{className:"title",begin:"(\\bwith\\s+)?\\b(function|procedure)\\s+",end:"(\\(|\\s+|$)",excludeBegin:!0,excludeEnd:!0,illegal:"[]{}%#'\""},r,{className:"type",begin:"\\breturn\\s+",end:"(\\s+|;|$)",keywords:"return",excludeBegin:!0,excludeEnd:!0,endsParent:!0,illegal:"[]{}%#'\""}]},{className:"type",begin:"\\b(sub)?type\\s+",end:"\\s+",keywords:"type",excludeBegin:!0,illegal:"[]{}%#'\""},r]}}},function(e,t){e.exports=function(e){var t={className:"rest_arg",begin:"[.]{3}",end:"[a-zA-Z_$][a-zA-Z0-9_$]*",relevance:10};return{aliases:["as"],keywords:{keyword:"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with",literal:"true false null undefined"},contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.C_NUMBER_MODE,{className:"class",beginKeywords:"package",end:"{",contains:[e.TITLE_MODE]},{className:"class",beginKeywords:"class interface",end:"{",excludeEnd:!0,contains:[{beginKeywords:"extends implements"},e.TITLE_MODE]},{className:"meta",beginKeywords:"import include",end:";",keywords:{"meta-keyword":"import include"}},{className:"function",beginKeywords:"function",end:"[{;]",excludeEnd:!0,illegal:"\\S",contains:[e.TITLE_MODE,{className:"params",begin:"\\(",end:"\\)",contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,t]},{begin:":\\s*([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)"}]},e.METHOD_GUARD],illegal:/#/}}},function(e,t){e.exports=function(e){return{contains:[{className:"number",begin:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{className:"number",begin:"\\b\\d+\\b",relevance:0},{className:"string",begin:'"(GET|POST|HEAD|PUT|DELETE|CONNECT|OPTIONS|PATCH|TRACE)',end:'"',keywords:"GET POST HEAD PUT DELETE CONNECT OPTIONS PATCH TRACE",illegal:"\\n",relevance:10},{className:"string",begin:/\[/,end:/\]/,illegal:"\\n"},{className:"string",begin:'"',end:'"',illegal:"\\n"}]}}},function(e,t){e.exports=function(e){var t="^[a-zA-Z][a-zA-Z0-9-]*",n="[!@#$^&',?+~`|:]",r=e.COMMENT(";","$"),i={begin:t+"\\s*=",returnBegin:!0,end:/=/,relevance:0,contains:[{className:"attribute",begin:t}]};return{illegal:n,keywords:["ALPHA","BIT","CHAR","CR","CRLF","CTL","DIGIT","DQUOTE","HEXDIG","HTAB","LF","LWSP","OCTET","SP","VCHAR","WSP"].join(" "),contains:[i,r,{className:"symbol",begin:/%b[0-1]+(-[0-1]+|(\.[0-1]+)+){0,1}/},{className:"symbol",begin:/%d[0-9]+(-[0-9]+|(\.[0-9]+)+){0,1}/},{className:"symbol",begin:/%x[0-9A-F]+(-[0-9A-F]+|(\.[0-9A-F]+)+){0,1}/},{className:"symbol",begin:/%[si]/},e.QUOTE_STRING_MODE,e.NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t="[A-Za-zА-Яа-яёЁ_][A-Za-zА-Яа-яёЁ_0-9]+",n="далее возврат вызватьисключение выполнить для если и из или иначе иначеесли исключение каждого конецесли конецпопытки конеццикла не новый перейти перем по пока попытка прервать продолжить тогда цикл экспорт ",r="null истина ложь неопределено",i=e.inherit(e.NUMBER_MODE),a={className:"string",begin:'"|\\|',end:'"|$',contains:[{begin:'""'}]},o={begin:"'",end:"'",excludeBegin:!0,excludeEnd:!0,contains:[{className:"number",begin:"\\d{4}([\\.\\\\/:-]?\\d{2}){0,5}"}]},s=e.inherit(e.C_LINE_COMMENT_MODE);return{case_insensitive:!0,lexemes:t,keywords:{keyword:n,built_in:"разделительстраниц разделительстрок символтабуляции ansitooem oemtoansi ввестивидсубконто ввестиперечисление ввестипериод ввестиплансчетов выбранныйплансчетов датагод датамесяц датачисло заголовоксистемы значениевстроку значениеизстроки каталогиб каталогпользователя кодсимв конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лог лог10 максимальноеколичествосубконто названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найтиссылки началопериодаби началостандартногоинтервала начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода обработкаожидания основнойжурналрасчетов основнойплансчетов основнойязык очиститьокносообщений периодстр получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта префиксавтонумерации пропись пустоезначение разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо симв создатьобъект статусвозврата стрколичествострок сформироватьпозициюдокумента счетпокоду текущеевремя типзначения типзначениястр установитьтана установитьтапо фиксшаблон шаблон acos asin atan base64значение base64строка cos exp log log10 pow sin sqrt tan xmlзначение xmlстрока xmlтип xmlтипзнч активноеокно безопасныйрежим безопасныйрежимразделенияданных булево ввестидату ввестизначение ввестистроку ввестичисло возможностьчтенияxml вопрос восстановитьзначение врег выгрузитьжурналрегистрации выполнитьобработкуоповещения выполнитьпроверкуправдоступа вычислить год данныеформывзначение дата день деньгода деньнедели добавитьмесяц заблокироватьданныедляредактирования заблокироватьработупользователя завершитьработусистемы загрузитьвнешнююкомпоненту закрытьсправку записатьjson записатьxml записатьдатуjson записьжурналарегистрации заполнитьзначениясвойств запроситьразрешениепользователя запуститьприложение запуститьсистему зафиксироватьтранзакцию значениевданныеформы значениевстрокувнутр значениевфайл значениезаполнено значениеизстрокивнутр значениеизфайла изxmlтипа импортмоделиxdto имякомпьютера имяпользователя инициализироватьпредопределенныеданные информацияобошибке каталогбиблиотекимобильногоустройства каталогвременныхфайлов каталогдокументов каталогпрограммы кодироватьстроку кодлокализацииинформационнойбазы кодсимвола командасистемы конецгода конецдня конецквартала конецмесяца конецминуты конецнедели конецчаса конфигурациябазыданныхизмененадинамически конфигурацияизменена копироватьданныеформы копироватьфайл краткоепредставлениеошибки лев макс местноевремя месяц мин минута монопольныйрежим найти найтинедопустимыесимволыxml найтиокнопонавигационнойссылке найтипомеченныенаудаление найтипоссылкам найтифайлы началогода началодня началоквартала началомесяца началоминуты началонедели началочаса начатьзапросразрешенияпользователя начатьзапускприложения начатькопированиефайла начатьперемещениефайла начатьподключениевнешнейкомпоненты начатьподключениерасширенияработыскриптографией начатьподключениерасширенияработысфайлами начатьпоискфайлов начатьполучениекаталогавременныхфайлов начатьполучениекаталогадокументов начатьполучениерабочегокаталогаданныхпользователя начатьполучениефайлов начатьпомещениефайла начатьпомещениефайлов начатьсозданиедвоичныхданныхизфайла начатьсозданиекаталога начатьтранзакцию начатьудалениефайлов начатьустановкувнешнейкомпоненты начатьустановкурасширенияработыскриптографией начатьустановкурасширенияработысфайлами неделягода необходимостьзавершениясоединения номерсеансаинформационнойбазы номерсоединенияинформационнойбазы нрег нстр обновитьинтерфейс обновитьнумерациюобъектов обновитьповторноиспользуемыезначения обработкапрерыванияпользователя объединитьфайлы окр описаниеошибки оповестить оповеститьобизменении отключитьобработчикзапросанастроекклиенталицензирования отключитьобработчикожидания отключитьобработчикоповещения открытьзначение открытьиндекссправки открытьсодержаниесправки открытьсправку открытьформу открытьформумодально отменитьтранзакцию очиститьжурналрегистрации очиститьнастройкипользователя очиститьсообщения параметрыдоступа перейтипонавигационнойссылке переместитьфайл подключитьвнешнююкомпоненту подключитьобработчикзапросанастроекклиенталицензирования подключитьобработчикожидания подключитьобработчикоповещения подключитьрасширениеработыскриптографией подключитьрасширениеработысфайлами подробноепредставлениеошибки показатьвводдаты показатьвводзначения показатьвводстроки показатьвводчисла показатьвопрос показатьзначение показатьинформациюобошибке показатьнакарте показатьоповещениепользователя показатьпредупреждение полноеимяпользователя получитьcomобъект получитьxmlтип получитьадреспоместоположению получитьблокировкусеансов получитьвремязавершенияспящегосеанса получитьвремязасыпанияпассивногосеанса получитьвремяожиданияблокировкиданных получитьданныевыбора получитьдополнительныйпараметрклиенталицензирования получитьдопустимыекодылокализации получитьдопустимыечасовыепояса получитьзаголовокклиентскогоприложения получитьзаголовоксистемы получитьзначенияотборажурналарегистрации получитьидентификаторконфигурации получитьизвременногохранилища получитьимявременногофайла получитьимяклиенталицензирования получитьинформациюэкрановклиента получитьиспользованиежурналарегистрации получитьиспользованиесобытияжурналарегистрации получитькраткийзаголовокприложения получитьмакетоформления получитьмаскувсефайлы получитьмаскувсефайлыклиента получитьмаскувсефайлысервера получитьместоположениепоадресу получитьминимальнуюдлинупаролейпользователей получитьнавигационнуюссылку получитьнавигационнуюссылкуинформационнойбазы получитьобновлениеконфигурациибазыданных получитьобновлениепредопределенныхданныхинформационнойбазы получитьобщиймакет получитьобщуюформу получитьокна получитьоперативнуюотметкувремени получитьотключениебезопасногорежима получитьпараметрыфункциональныхопцийинтерфейса получитьполноеимяпредопределенногозначения получитьпредставлениянавигационныхссылок получитьпроверкусложностипаролейпользователей получитьразделительпути получитьразделительпутиклиента получитьразделительпутисервера получитьсеансыинформационнойбазы получитьскоростьклиентскогосоединения получитьсоединенияинформационнойбазы получитьсообщенияпользователю получитьсоответствиеобъектаиформы получитьсоставстандартногоинтерфейсаodata получитьструктурухранениябазыданных получитьтекущийсеансинформационнойбазы получитьфайл получитьфайлы получитьформу получитьфункциональнуюопцию получитьфункциональнуюопциюинтерфейса получитьчасовойпоясинформационнойбазы пользователиос поместитьвовременноехранилище поместитьфайл поместитьфайлы прав праводоступа предопределенноезначение представлениекодалокализации представлениепериода представлениеправа представлениеприложения представлениесобытияжурналарегистрации представлениечасовогопояса предупреждение прекратитьработусистемы привилегированныйрежим продолжитьвызов прочитатьjson прочитатьxml прочитатьдатуjson пустаястрока рабочийкаталогданныхпользователя разблокироватьданныедляредактирования разделитьфайл разорватьсоединениесвнешнимисточникомданных раскодироватьстроку рольдоступна секунда сигнал символ скопироватьжурналрегистрации смещениелетнеговремени смещениестандартноговремени соединитьбуферыдвоичныхданных создатькаталог создатьфабрикуxdto сокрл сокрлп сокрп сообщить состояние сохранитьзначение сохранитьнастройкипользователя сред стрдлина стрзаканчиваетсяна стрзаменить стрнайти стрначинаетсяс строка строкасоединенияинформационнойбазы стрполучитьстроку стрразделить стрсоединить стрсравнить стрчисловхождений стрчислострок стршаблон текущаядата текущаядатасеанса текущаяуниверсальнаядата текущаяуниверсальнаядатавмиллисекундах текущийвариантинтерфейсаклиентскогоприложения текущийвариантосновногошрифтаклиентскогоприложения текущийкодлокализации текущийрежимзапуска текущийязык текущийязыксистемы тип типзнч транзакцияактивна трег удалитьданныеинформационнойбазы удалитьизвременногохранилища удалитьобъекты удалитьфайлы универсальноевремя установитьбезопасныйрежим установитьбезопасныйрежимразделенияданных установитьблокировкусеансов установитьвнешнююкомпоненту установитьвремязавершенияспящегосеанса установитьвремязасыпанияпассивногосеанса установитьвремяожиданияблокировкиданных установитьзаголовокклиентскогоприложения установитьзаголовоксистемы установитьиспользованиежурналарегистрации установитьиспользованиесобытияжурналарегистрации установитькраткийзаголовокприложения установитьминимальнуюдлинупаролейпользователей установитьмонопольныйрежим установитьнастройкиклиенталицензирования установитьобновлениепредопределенныхданныхинформационнойбазы установитьотключениебезопасногорежима установитьпараметрыфункциональныхопцийинтерфейса установитьпривилегированныйрежим установитьпроверкусложностипаролейпользователей установитьрасширениеработыскриптографией установитьрасширениеработысфайлами установитьсоединениесвнешнимисточникомданных установитьсоответствиеобъектаиформы установитьсоставстандартногоинтерфейсаodata установитьчасовойпоясинформационнойбазы установитьчасовойпояссеанса формат цел час часовойпояс часовойпояссеанса число числопрописью этоадресвременногохранилища wsссылки библиотекакартинок библиотекамакетовоформлениякомпоновкиданных библиотекастилей бизнеспроцессы внешниеисточникиданных внешниеобработки внешниеотчеты встроенныепокупки главныйинтерфейс главныйстиль документы доставляемыеуведомления журналыдокументов задачи информацияобинтернетсоединении использованиерабочейдаты историяработыпользователя константы критерииотбора метаданные обработки отображениерекламы отправкадоставляемыхуведомлений отчеты панельзадачос параметрзапуска параметрысеанса перечисления планывидоврасчета планывидовхарактеристик планыобмена планысчетов полнотекстовыйпоиск пользователиинформационнойбазы последовательности проверкавстроенныхпокупок рабочаядата расширенияконфигурации регистрыбухгалтерии регистрынакопления регистрырасчета регистрысведений регламентныезадания сериализаторxdto справочники средствагеопозиционирования средствакриптографии средствамультимедиа средстваотображениярекламы средствапочты средствателефонии фабрикаxdto файловыепотоки фоновыезадания хранилищанастроек хранилищевариантовотчетов хранилищенастроекданныхформ хранилищеобщихнастроек хранилищепользовательскихнастроекдинамическихсписков хранилищепользовательскихнастроекотчетов хранилищесистемныхнастроек ",class:"webцвета windowsцвета windowsшрифты библиотекакартинок рамкистиля символы цветастиля шрифтыстиля автоматическоесохранениеданныхформывнастройках автонумерациявформе автораздвижениесерий анимациядиаграммы вариантвыравниванияэлементовизаголовков вариантуправлениявысотойтаблицы вертикальнаяпрокруткаформы вертикальноеположение вертикальноеположениеэлемента видгруппыформы виддекорацииформы виддополненияэлементаформы видизмененияданных видкнопкиформы видпереключателя видподписейкдиаграмме видполяформы видфлажка влияниеразмеранапузырекдиаграммы горизонтальноеположение горизонтальноеположениеэлемента группировкаколонок группировкаподчиненныхэлементовформы группыиэлементы действиеперетаскивания дополнительныйрежимотображения допустимыедействияперетаскивания интервалмеждуэлементамиформы использованиевывода использованиеполосыпрокрутки используемоезначениеточкибиржевойдиаграммы историявыборапривводе источникзначенийоситочекдиаграммы источникзначенияразмерапузырькадиаграммы категориягруппыкоманд максимумсерий начальноеотображениедерева начальноеотображениесписка обновлениетекстаредактирования ориентациядендрограммы ориентациядиаграммы ориентацияметокдиаграммы ориентацияметоксводнойдиаграммы ориентацияэлементаформы отображениевдиаграмме отображениевлегендедиаграммы отображениегруппыкнопок отображениезаголовкашкалыдиаграммы отображениезначенийсводнойдиаграммы отображениезначенияизмерительнойдиаграммы отображениеинтерваладиаграммыганта отображениекнопки отображениекнопкивыбора отображениеобсужденийформы отображениеобычнойгруппы отображениеотрицательныхзначенийпузырьковойдиаграммы отображениепанелипоиска отображениеподсказки отображениепредупрежденияприредактировании отображениеразметкиполосырегулирования отображениестраницформы отображениетаблицы отображениетекстазначениядиаграммыганта отображениеуправленияобычнойгруппы отображениефигурыкнопки палитрацветовдиаграммы поведениеобычнойгруппы поддержкамасштабадендрограммы поддержкамасштабадиаграммыганта поддержкамасштабасводнойдиаграммы поисквтаблицепривводе положениезаголовкаэлементаформы положениекартинкикнопкиформы положениекартинкиэлементаграфическойсхемы положениекоманднойпанелиформы положениекоманднойпанелиэлементаформы положениеопорнойточкиотрисовки положениеподписейкдиаграмме положениеподписейшкалызначенийизмерительнойдиаграммы положениесостоянияпросмотра положениестрокипоиска положениетекстасоединительнойлинии положениеуправленияпоиском положениешкалывремени порядокотображенияточекгоризонтальнойгистограммы порядоксерийвлегендедиаграммы размеркартинки расположениезаголовкашкалыдиаграммы растягиваниеповертикалидиаграммыганта режимавтоотображениясостояния режимвводастроктаблицы режимвыборанезаполненного режимвыделениядаты режимвыделениястрокитаблицы режимвыделениятаблицы режимизмененияразмера режимизменениясвязанногозначения режимиспользованиядиалогапечати режимиспользованияпараметракоманды режиммасштабированияпросмотра режимосновногоокнаклиентскогоприложения режимоткрытияокнаформы режимотображениявыделения режимотображениягеографическойсхемы режимотображениязначенийсерии режимотрисовкисеткиграфическойсхемы режимполупрозрачностидиаграммы режимпробеловдиаграммы режимразмещениянастранице режимредактированияколонки режимсглаживаниядиаграммы режимсглаживанияиндикатора режимсписказадач сквозноевыравнивание сохранениеданныхформывнастройках способзаполнениятекстазаголовкашкалыдиаграммы способопределенияограничивающегозначениядиаграммы стандартнаягруппакоманд стандартноеоформление статусоповещенияпользователя стильстрелки типаппроксимациилиниитрендадиаграммы типдиаграммы типединицышкалывремени типимпортасерийслоягеографическойсхемы типлиниигеографическойсхемы типлиниидиаграммы типмаркерагеографическойсхемы типмаркерадиаграммы типобластиоформления типорганизацииисточникаданныхгеографическойсхемы типотображениясериислоягеографическойсхемы типотображенияточечногообъектагеографическойсхемы типотображенияшкалыэлементалегендыгеографическойсхемы типпоискаобъектовгеографическойсхемы типпроекциигеографическойсхемы типразмещенияизмерений типразмещенияреквизитовизмерений типрамкиэлементауправления типсводнойдиаграммы типсвязидиаграммыганта типсоединениязначенийпосериямдиаграммы типсоединенияточекдиаграммы типсоединительнойлинии типстороныэлементаграфическойсхемы типформыотчета типшкалырадарнойдиаграммы факторлиниитрендадиаграммы фигуракнопки фигурыграфическойсхемы фиксациявтаблице форматдняшкалывремени форматкартинки ширинаподчиненныхэлементовформы виддвижениябухгалтерии виддвижениянакопления видпериодарегистрарасчета видсчета видточкимаршрутабизнеспроцесса использованиеагрегатарегистранакопления использованиегруппиэлементов использованиережимапроведения использованиесреза периодичностьагрегатарегистранакопления режимавтовремя режимзаписидокумента режимпроведениядокумента авторегистрацияизменений допустимыйномерсообщения отправкаэлементаданных получениеэлементаданных использованиерасшифровкитабличногодокумента ориентациястраницы положениеитоговколоноксводнойтаблицы положениеитоговстроксводнойтаблицы положениетекстаотносительнокартинки расположениезаголовкагруппировкитабличногодокумента способчтениязначенийтабличногодокумента типдвустороннейпечати типзаполненияобластитабличногодокумента типкурсоровтабличногодокумента типлиниирисункатабличногодокумента типлинииячейкитабличногодокумента типнаправленияпереходатабличногодокумента типотображениявыделениятабличногодокумента типотображениялинийсводнойтаблицы типразмещениятекстатабличногодокумента типрисункатабличногодокумента типсмещениятабличногодокумента типузоратабличногодокумента типфайлатабличногодокумента точностьпечати чередованиерасположениястраниц отображениевремениэлементовпланировщика типфайлаформатированногодокумента обходрезультатазапроса типзаписизапроса видзаполнениярасшифровкипостроителяотчета типдобавленияпредставлений типизмеренияпостроителяотчета типразмещенияитогов доступкфайлу режимдиалогавыборафайла режимоткрытияфайла типизмеренияпостроителязапроса видданныханализа методкластеризации типединицыинтервалавременианализаданных типзаполнениятаблицырезультатаанализаданных типиспользованиячисловыхзначенийанализаданных типисточникаданныхпоискаассоциаций типколонкианализаданныхдереворешений типколонкианализаданныхкластеризация типколонкианализаданныхобщаястатистика типколонкианализаданныхпоискассоциаций типколонкианализаданныхпоискпоследовательностей типколонкимоделипрогноза типмерырасстоянияанализаданных типотсеченияправилассоциации типполяанализаданных типстандартизациианализаданных типупорядочиванияправилассоциациианализаданных типупорядочиванияшаблоновпоследовательностейанализаданных типупрощениядереварешений wsнаправлениепараметра вариантxpathxs вариантзаписидатыjson вариантпростоготипаxs видгруппымоделиxs видфасетаxdto действиепостроителяdom завершенностьпростоготипаxs завершенностьсоставноготипаxs завершенностьсхемыxs запрещенныеподстановкиxs исключениягруппподстановкиxs категорияиспользованияатрибутаxs категорияограниченияидентичностиxs категорияограниченияпространствименxs методнаследованияxs модельсодержимогоxs назначениетипаxml недопустимыеподстановкиxs обработкапробельныхсимволовxs обработкасодержимогоxs ограничениезначенияxs параметрыотбораузловdom переносстрокjson позициявдокументеdom пробельныесимволыxml типатрибутаxml типзначенияjson типканоническогоxml типкомпонентыxs типпроверкиxml типрезультатаdomxpath типузлаdom типузлаxml формаxml формапредставленияxs форматдатыjson экранированиесимволовjson видсравнениякомпоновкиданных действиеобработкирасшифровкикомпоновкиданных направлениесортировкикомпоновкиданных расположениевложенныхэлементоврезультатакомпоновкиданных расположениеитоговкомпоновкиданных расположениегруппировкикомпоновкиданных расположениеполейгруппировкикомпоновкиданных расположениеполякомпоновкиданных расположениереквизитовкомпоновкиданных расположениересурсовкомпоновкиданных типбухгалтерскогоостаткакомпоновкиданных типвыводатекстакомпоновкиданных типгруппировкикомпоновкиданных типгруппыэлементовотборакомпоновкиданных типдополненияпериодакомпоновкиданных типзаголовкаполейкомпоновкиданных типмакетагруппировкикомпоновкиданных типмакетаобластикомпоновкиданных типостаткакомпоновкиданных типпериодакомпоновкиданных типразмещениятекстакомпоновкиданных типсвязинаборовданныхкомпоновкиданных типэлементарезультатакомпоновкиданных расположениелегендыдиаграммыкомпоновкиданных типпримененияотборакомпоновкиданных режимотображенияэлементанастройкикомпоновкиданных режимотображениянастроеккомпоновкиданных состояниеэлементанастройкикомпоновкиданных способвосстановлениянастроеккомпоновкиданных режимкомпоновкирезультата использованиепараметракомпоновкиданных автопозицияресурсовкомпоновкиданных вариантиспользованиягруппировкикомпоновкиданных расположениересурсоввдиаграммекомпоновкиданных фиксациякомпоновкиданных использованиеусловногооформлениякомпоновкиданных важностьинтернетпочтовогосообщения обработкатекстаинтернетпочтовогосообщения способкодированияинтернетпочтовоговложения способкодированиянеasciiсимволовинтернетпочтовогосообщения типтекстапочтовогосообщения протоколинтернетпочты статусразборапочтовогосообщения режимтранзакциизаписижурналарегистрации статустранзакциизаписижурналарегистрации уровеньжурналарегистрации расположениехранилищасертификатовкриптографии режимвключениясертификатовкриптографии режимпроверкисертификатакриптографии типхранилищасертификатовкриптографии кодировкаименфайловвzipфайле методсжатияzip методшифрованияzip режимвосстановленияпутейфайловzip режимобработкиподкаталоговzip режимсохраненияпутейzip уровеньсжатияzip звуковоеоповещение направлениепереходакстроке позициявпотоке порядокбайтов режимблокировкиданных режимуправленияблокировкойданных сервисвстроенныхпокупок состояниефоновогозадания типподписчикадоставляемыхуведомлений уровеньиспользованиязащищенногосоединенияftp направлениепорядкасхемызапроса типдополненияпериодамисхемызапроса типконтрольнойточкисхемызапроса типобъединениясхемызапроса типпараметрадоступнойтаблицысхемызапроса типсоединениясхемызапроса httpметод автоиспользованиеобщегореквизита автопрефиксномеразадачи вариантвстроенногоязыка видиерархии видрегистранакопления видтаблицывнешнегоисточникаданных записьдвиженийприпроведении заполнениепоследовательностей индексирование использованиебазыпланавидоврасчета использованиебыстроговыбора использованиеобщегореквизита использованиеподчинения использованиеполнотекстовогопоиска использованиеразделяемыхданныхобщегореквизита использованиереквизита назначениеиспользованияприложения назначениерасширенияконфигурации направлениепередачи обновлениепредопределенныхданных оперативноепроведение основноепредставлениевидарасчета основноепредставлениевидахарактеристики основноепредставлениезадачи основноепредставлениепланаобмена основноепредставлениесправочника основноепредставлениесчета перемещениеграницыприпроведении периодичностьномерабизнеспроцесса периодичностьномерадокумента периодичностьрегистрарасчета периодичностьрегистрасведений повторноеиспользованиевозвращаемыхзначений полнотекстовыйпоискпривводепостроке принадлежностьобъекта проведение разделениеаутентификацииобщегореквизита разделениеданныхобщегореквизита разделениерасширенийконфигурацииобщегореквизита режимавтонумерацииобъектов режимзаписирегистра режимиспользованиямодальности режимиспользованиясинхронныхвызововрасширенийплатформыивнешнихкомпонент режимповторногоиспользованиясеансов режимполученияданныхвыборапривводепостроке режимсовместимости режимсовместимостиинтерфейса режимуправленияблокировкойданныхпоумолчанию сериикодовпланавидовхарактеристик сериикодовпланасчетов сериикодовсправочника созданиепривводе способвыбора способпоискастрокипривводепостроке способредактирования типданныхтаблицывнешнегоисточникаданных типкодапланавидоврасчета типкодасправочника типмакета типномерабизнеспроцесса типномерадокумента типномеразадачи типформы удалениедвижений важностьпроблемыприменениярасширенияконфигурации вариантинтерфейсаклиентскогоприложения вариантмасштабаформклиентскогоприложения вариантосновногошрифтаклиентскогоприложения вариантстандартногопериода вариантстандартнойдатыначала видграницы видкартинки видотображенияполнотекстовогопоиска видрамки видсравнения видцвета видчисловогозначения видшрифта допустимаядлина допустимыйзнак использованиеbyteordermark использованиеметаданныхполнотекстовогопоиска источникрасширенийконфигурации клавиша кодвозвратадиалога кодировкаxbase кодировкатекста направлениепоиска направлениесортировки обновлениепредопределенныхданных обновлениеприизмененииданных отображениепанелиразделов проверказаполнения режимдиалогавопрос режимзапускаклиентскогоприложения режимокругления режимоткрытияформприложения режимполнотекстовогопоиска скоростьклиентскогосоединения состояниевнешнегоисточникаданных состояниеобновленияконфигурациибазыданных способвыборасертификатаwindows способкодированиястроки статуссообщения типвнешнейкомпоненты типплатформы типповеденияклавишиenter типэлементаинформацииовыполненииобновленияконфигурациибазыданных уровеньизоляциитранзакций хешфункция частидаты",type:"comобъект ftpсоединение httpзапрос httpсервисответ httpсоединение wsопределения wsпрокси xbase анализданных аннотацияxs блокировкаданных буфердвоичныхданных включениеxs выражениекомпоновкиданных генераторслучайныхчисел географическаясхема географическиекоординаты графическаясхема группамоделиxs данныерасшифровкикомпоновкиданных двоичныеданные дендрограмма диаграмма диаграммаганта диалогвыборафайла диалогвыборацвета диалогвыборашрифта диалограсписаниярегламентногозадания диалогредактированиястандартногопериода диапазон документdom документhtml документацияxs доставляемоеуведомление записьdom записьfastinfoset записьhtml записьjson записьxml записьzipфайла записьданных записьтекста записьузловdom запрос защищенноесоединениеopenssl значенияполейрасшифровкикомпоновкиданных извлечениетекста импортxs интернетпочта интернетпочтовоесообщение интернетпочтовыйпрофиль интернетпрокси интернетсоединение информациядляприложенияxs использованиеатрибутаxs использованиесобытияжурналарегистрации источникдоступныхнастроеккомпоновкиданных итераторузловdom картинка квалификаторыдаты квалификаторыдвоичныхданных квалификаторыстроки квалификаторычисла компоновщикмакетакомпоновкиданных компоновщикнастроеккомпоновкиданных конструктормакетаоформлениякомпоновкиданных конструкторнастроеккомпоновкиданных конструкторформатнойстроки линия макеткомпоновкиданных макетобластикомпоновкиданных макетоформлениякомпоновкиданных маскаxs менеджеркриптографии наборсхемxml настройкикомпоновкиданных настройкисериализацииjson обработкакартинок обработкарасшифровкикомпоновкиданных обходдереваdom объявлениеатрибутаxs объявлениенотацииxs объявлениеэлементаxs описаниеиспользованиясобытиядоступжурналарегистрации описаниеиспользованиясобытияотказвдоступежурналарегистрации описаниеобработкирасшифровкикомпоновкиданных описаниепередаваемогофайла описаниетипов определениегруппыатрибутовxs определениегруппымоделиxs определениеограниченияидентичностиxs определениепростоготипаxs определениесоставноготипаxs определениетипадокументаdom определенияxpathxs отборкомпоновкиданных пакетотображаемыхдокументов параметрвыбора параметркомпоновкиданных параметрызаписиjson параметрызаписиxml параметрычтенияxml переопределениеxs планировщик полеанализаданных полекомпоновкиданных построительdom построительзапроса построительотчета построительотчетаанализаданных построительсхемxml поток потоквпамяти почта почтовоесообщение преобразованиеxsl преобразованиекканоническомуxml процессорвыводарезультатакомпоновкиданныхвколлекциюзначений процессорвыводарезультатакомпоновкиданныхвтабличныйдокумент процессоркомпоновкиданных разыменовательпространствименdom рамка расписаниерегламентногозадания расширенноеимяxml результатчтенияданных своднаядиаграмма связьпараметравыбора связьпотипу связьпотипукомпоновкиданных сериализаторxdto сертификатклиентаwindows сертификатклиентафайл сертификаткриптографии сертификатыудостоверяющихцентровwindows сертификатыудостоверяющихцентровфайл сжатиеданных системнаяинформация сообщениепользователю сочетаниеклавиш сравнениезначений стандартнаядатаначала стандартныйпериод схемаxml схемакомпоновкиданных табличныйдокумент текстовыйдокумент тестируемоеприложение типданныхxml уникальныйидентификатор фабрикаxdto файл файловыйпоток фасетдлиныxs фасетколичестваразрядовдробнойчастиxs фасетмаксимальноговключающегозначенияxs фасетмаксимальногоисключающегозначенияxs фасетмаксимальнойдлиныxs фасетминимальноговключающегозначенияxs фасетминимальногоисключающегозначенияxs фасетминимальнойдлиныxs фасетобразцаxs фасетобщегоколичестваразрядовxs фасетперечисленияxs фасетпробельныхсимволовxs фильтрузловdom форматированнаястрока форматированныйдокумент фрагментxs хешированиеданных хранилищезначения цвет чтениеfastinfoset чтениеhtml чтениеjson чтениеxml чтениеzipфайла чтениеданных чтениетекста чтениеузловdom шрифт элементрезультатакомпоновкиданных comsafearray деревозначений массив соответствие списокзначений структура таблицазначений фиксированнаяструктура фиксированноесоответствие фиксированныймассив ",literal:r},contains:[{className:"meta",lexemes:t,begin:"#|&",end:"$",keywords:{"meta-keyword":n+"загрузитьизфайла вебклиент вместо внешнеесоединение клиент конецобласти мобильноеприложениеклиент мобильноеприложениесервер наклиенте наклиентенасервере наклиентенасерверебезконтекста насервере насерверебезконтекста область перед после сервер толстыйклиентобычноеприложение толстыйклиентуправляемоеприложение тонкийклиент "},contains:[s]},{className:"function",lexemes:t,variants:[{begin:"процедура|функция",end:"\\)",keywords:"процедура функция"},{begin:"конецпроцедуры|конецфункции",keywords:"конецпроцедуры конецфункции"}],contains:[{begin:"\\(",end:"\\)",endsParent:!0,contains:[{className:"params",lexemes:t,begin:t,end:",",excludeEnd:!0,endsWithParent:!0,keywords:{keyword:"знач",literal:r},contains:[i,a,o]},s]},e.inherit(e.TITLE_MODE,{begin:t})]},s,{className:"symbol",begin:"~",end:";|:",excludeEnd:!0},i,a,o]}}},function(e,t,n){!function(e){"object"==typeof window&&window||"object"==typeof self&&self;(function(e){var t=[],n=Object.keys,r={},i={},a=/^(no-?highlight|plain|text)$/i,o=/\blang(?:uage)?-([\w-]+)\b/i,s=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,l="",c={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};function u(e){return e.replace(/&/g,"&").replace(//g,">")}function d(e){return e.nodeName.toLowerCase()}function f(e,t){var n=e&&e.exec(t);return n&&0===n.index}function p(e){return a.test(e)}function m(e){var t,n={},r=Array.prototype.slice.call(arguments,1);for(t in e)n[t]=e[t];return r.forEach(function(e){for(t in e)n[t]=e[t]}),n}function g(e){var t=[];return function e(n,r){for(var i=n.firstChild;i;i=i.nextSibling)3===i.nodeType?r+=i.nodeValue.length:1===i.nodeType&&(t.push({event:"start",offset:r,node:i}),r=e(i,r),d(i).match(/br|hr|img|input/)||t.push({event:"stop",offset:r,node:i}));return r}(e,0),t}function h(e){function t(e){return e&&e.source||e}function r(n,r){return new RegExp(t(n),"m"+(e.case_insensitive?"i":"")+(r?"g":""))}!function i(a,o){if(a.compiled)return;a.compiled=!0;a.keywords=a.keywords||a.beginKeywords;if(a.keywords){var s={},l=function(t,n){e.case_insensitive&&(n=n.toLowerCase()),n.split(" ").forEach(function(e){var n=e.split("|");s[n[0]]=[t,n[1]?Number(n[1]):1]})};"string"==typeof a.keywords?l("keyword",a.keywords):n(a.keywords).forEach(function(e){l(e,a.keywords[e])}),a.keywords=s}a.lexemesRe=r(a.lexemes||/\w+/,!0);o&&(a.beginKeywords&&(a.begin="\\b("+a.beginKeywords.split(" ").join("|")+")\\b"),a.begin||(a.begin=/\B|\b/),a.beginRe=r(a.begin),a.end||a.endsWithParent||(a.end=/\B|\b/),a.end&&(a.endRe=r(a.end)),a.terminator_end=t(a.end)||"",a.endsWithParent&&o.terminator_end&&(a.terminator_end+=(a.end?"|":"")+o.terminator_end));a.illegal&&(a.illegalRe=r(a.illegal));null==a.relevance&&(a.relevance=1);a.contains||(a.contains=[]);a.contains=Array.prototype.concat.apply([],a.contains.map(function(e){return function(e){e.variants&&!e.cached_variants&&(e.cached_variants=e.variants.map(function(t){return m(e,{variants:null},t)}));return e.cached_variants||e.endsWithParent&&[m(e)]||[e]}("self"===e?a:e)}));a.contains.forEach(function(e){i(e,a)});a.starts&&i(a.starts,o);var c=a.contains.map(function(e){return e.beginKeywords?"\\.?("+e.begin+")\\.?":e.begin}).concat([a.terminator_end,a.illegal]).map(t).filter(Boolean);a.terminators=c.length?r(c.join("|"),!0):{exec:function(){return null}}}(e)}function b(e,t,n,i){function a(e,t){var n=m.case_insensitive?t[0].toLowerCase():t[0];return e.keywords.hasOwnProperty(n)&&e.keywords[n]}function o(e,t,n,r){var i=r?"":c.classPrefix,a='')+t+o}function s(){x+=null!=_.subLanguage?function(){var e="string"==typeof _.subLanguage;if(e&&!r[_.subLanguage])return u(S);var t=e?b(_.subLanguage,S,!0,y[_.subLanguage]):v(S,_.subLanguage.length?_.subLanguage:void 0);_.relevance>0&&(w+=t.relevance);e&&(y[_.subLanguage]=t.top);return o(t.language,t.value,!1,!0)}():function(){var e,t,n,r;if(!_.keywords)return u(S);r="",t=0,_.lexemesRe.lastIndex=0,n=_.lexemesRe.exec(S);for(;n;)r+=u(S.substring(t,n.index)),(e=a(_,n))?(w+=e[1],r+=o(e[0],u(n[0]))):r+=u(n[0]),t=_.lexemesRe.lastIndex,n=_.lexemesRe.exec(S);return r+u(S.substr(t))}(),S=""}function d(e){x+=e.className?o(e.className,"",!0):"",_=Object.create(e,{parent:{value:_}})}function p(e,t){if(S+=e,null==t)return s(),0;var r=function(e,t){var n,r;for(n=0,r=t.contains.length;n")+'"');return S+=t,t.length||1}var m=E(e);if(!m)throw new Error('Unknown language: "'+e+'"');h(m);var g,_=i||m,y={},x="";for(g=_;g!==m;g=g.parent)g.className&&(x=o(g.className,"",!0)+x);var S="",w=0;try{for(var C,O,M=0;_.terminators.lastIndex=M,C=_.terminators.exec(t);)O=p(t.substring(M,C.index),C[0]),M=C.index+O;for(p(t.substr(M)),g=_;g.parent;g=g.parent)g.className&&(x+=l);return{relevance:w,value:x,language:e,top:_}}catch(e){if(e.message&&-1!==e.message.indexOf("Illegal"))return{relevance:0,value:u(t)};throw e}}function v(e,t){t=t||c.languages||n(r);var i={relevance:0,value:u(e)},a=i;return t.filter(E).forEach(function(t){var n=b(t,e,!1);n.language=t,n.relevance>a.relevance&&(a=n),n.relevance>i.relevance&&(a=i,i=n)}),a.language&&(i.second_best=a),i}function _(e){return c.tabReplace||c.useBR?e.replace(s,function(e,t){return c.useBR&&"\n"===e?"
":c.tabReplace?t.replace(/\t/g,c.tabReplace):""}):e}function y(e){var n,r,a,s,l,f=function(e){var t,n,r,i,a=e.className+" ";if(a+=e.parentNode?e.parentNode.className:"",n=o.exec(a))return E(n[1])?n[1]:"no-highlight";for(a=a.split(/\s+/),t=0,r=a.length;t/g,"\n"):n=e,l=n.textContent,a=f?b(f,l,!0):v(l),(r=g(n)).length&&((s=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=a.value,a.value=function(e,n,r){var i=0,a="",o=[];function s(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset"}function c(e){a+=""}function f(e){("start"===e.event?l:c)(e.node)}for(;e.length||n.length;){var p=s();if(a+=u(r.substring(i,p[0].offset)),i=p[0].offset,p===e){o.reverse().forEach(c);do{f(p.splice(0,1)[0]),p=s()}while(p===e&&p.length&&p[0].offset===i);o.reverse().forEach(l)}else"start"===p[0].event?o.push(p[0].node):o.pop(),f(p.splice(0,1)[0])}return a+u(r.substr(i))}(r,g(s),l)),a.value=_(a.value),e.innerHTML=a.value,e.className=function(e,t,n){var r=t?i[t]:n,a=[e.trim()];e.match(/\bhljs\b/)||a.push("hljs");-1===e.indexOf(r)&&a.push(r);return a.join(" ").trim()}(e.className,f,a.language),e.result={language:a.language,re:a.relevance},a.second_best&&(e.second_best={language:a.second_best.language,re:a.second_best.relevance}))}function x(){if(!x.called){x.called=!0;var e=document.querySelectorAll("pre code");t.forEach.call(e,y)}}function E(e){return e=(e||"").toLowerCase(),r[e]||r[i[e]]}e.highlight=b,e.highlightAuto=v,e.fixMarkup=_,e.highlightBlock=y,e.configure=function(e){c=m(c,e)},e.initHighlighting=x,e.initHighlightingOnLoad=function(){addEventListener("DOMContentLoaded",x,!1),addEventListener("load",x,!1)},e.registerLanguage=function(t,n){var a=r[t]=n(e);a.aliases&&a.aliases.forEach(function(e){i[e]=t})},e.listLanguages=function(){return n(r)},e.getLanguage=E,e.inherit=m,e.IDENT_RE="[a-zA-Z]\\w*",e.UNDERSCORE_IDENT_RE="[a-zA-Z_]\\w*",e.NUMBER_RE="\\b\\d+(\\.\\d+)?",e.C_NUMBER_RE="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BINARY_NUMBER_RE="\\b(0b[01]+)",e.RE_STARTERS_RE="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BACKSLASH_ESCAPE={begin:"\\\\[\\s\\S]",relevance:0},e.APOS_STRING_MODE={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},e.QUOTE_STRING_MODE={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},e.PHRASAL_WORDS_MODE={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.COMMENT=function(t,n,r){var i=e.inherit({className:"comment",begin:t,end:n,contains:[]},r||{});return i.contains.push(e.PHRASAL_WORDS_MODE),i.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|XXX):",relevance:0}),i},e.C_LINE_COMMENT_MODE=e.COMMENT("//","$"),e.C_BLOCK_COMMENT_MODE=e.COMMENT("/\\*","\\*/"),e.HASH_COMMENT_MODE=e.COMMENT("#","$"),e.NUMBER_MODE={className:"number",begin:e.NUMBER_RE,relevance:0},e.C_NUMBER_MODE={className:"number",begin:e.C_NUMBER_RE,relevance:0},e.BINARY_NUMBER_MODE={className:"number",begin:e.BINARY_NUMBER_RE,relevance:0},e.CSS_NUMBER_MODE={className:"number",begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},e.REGEXP_MODE={className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[e.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0,contains:[e.BACKSLASH_ESCAPE]}]},e.TITLE_MODE={className:"title",begin:e.IDENT_RE,relevance:0},e.UNDERSCORE_TITLE_MODE={className:"title",begin:e.UNDERSCORE_IDENT_RE,relevance:0},e.METHOD_GUARD={begin:"\\.\\s*"+e.UNDERSCORE_IDENT_RE,relevance:0}})(t)}()}]); +//# sourceMappingURL=bundle.js.map \ No newline at end of file diff --git a/build/site/bundle.js.map b/build/site/bundle.js.map new file mode 100644 index 0000000000..f8163d1a54 --- /dev/null +++ b/build/site/bundle.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bundle.js","sources":["webpack:///bundle.js"],"sourcesContent":["!function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&\"object\"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,\"default\",{enumerable:!0,value:e}),2&t&&\"string\"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,\"a\",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p=\"\",n(n.s=7)}([function(e,t,n){\"use strict\";var r=function(e,t,n){return e.fields=t||[],e.fname=n,e};function i(e){return null==e?null:e.fname}function a(e){return null==e?null:e.fields}var o=function(e){throw Error(e)},s=function(e){var t,n,r,i=[],a=null,s=0,l=e.length,c=\"\";function u(){i.push(c+e.substring(t,n)),c=\"\",t=n+1}for(e+=\"\",t=n=0;nt&&u(),s=t=n+1):\"]\"===r&&(s||o(\"Access path missing open bracket: \"+e),s>0&&u(),s=0,t=n+1):n>t?u():t=n+1}return s&&o(\"Access path missing closing bracket: \"+e),a&&o(\"Access path missing closing quote: \"+e),n>t&&(n++,u()),i},l=Array.isArray,c=function(e){return e===Object(e)},u=function(e){return\"string\"==typeof e};function d(e){return l(e)?\"[\"+e.map(d)+\"]\":c(e)||u(e)?JSON.stringify(e).replace(\"\\u2028\",\"\\\\u2028\").replace(\"\\u2029\",\"\\\\u2029\"):e}var f=function(e,t){var n=s(e),i=\"return _[\"+n.map(d).join(\"][\")+\"];\";return r(Function(\"_\",i),[e=1===n.length?n[0]:e],t||e)},p=[],m=f(\"id\"),g=r(function(e){return e},p,\"identity\"),h=r(function(){return 0},p,\"zero\"),b=r(function(){return 1},p,\"one\"),v=r(function(){return!0},p,\"true\"),_=r(function(){return!1},p,\"false\");function y(e,t,n){var r=[t].concat([].slice.call(n));console[e].apply(console,r)}var x=function(e){var t=e||0;return{level:function(e){return arguments.length?(t=+e,this):t},error:function(){return t>=1&&y(\"error\",\"ERROR\",arguments),this},warn:function(){return t>=2&&y(\"warn\",\"WARN\",arguments),this},info:function(){return t>=3&&y(\"log\",\"INFO\",arguments),this},debug:function(){return t>=4&&y(\"log\",\"DEBUG\",arguments),this}}},E=function(e){return e[e.length-1]},S=function(e){return null==e||\"\"===e?null:+e};function w(e){return function(t){return e*Math.exp(t)}}function C(e){return function(t){return Math.log(e*t)}}function O(e){return function(t){return t<0?-Math.pow(-t,e):Math.pow(t,e)}}function M(e,t,n,r){var i=n(e[0]),a=n(E(e)),o=(a-i)*t;return[r(i-o),r(a-o)]}function N(e,t){return M(e,t,S,g)}function T(e,t){var n=Math.sign(e[0]);return M(e,t,C(n),w(n))}function D(e,t,n){return M(e,t,O(n),O(1/n))}function A(e,t,n,r,i){var a=r(e[0]),o=r(E(e)),s=null!=t?r(t):(a+o)/2;return[i(s+(a-s)*n),i(s+(o-s)*n)]}function k(e,t,n){return A(e,t,n,S,g)}function R(e,t,n){var r=Math.sign(e[0]);return A(e,t,n,C(r),w(r))}function I(e,t,n,r){return A(e,t,n,O(r),O(1/r))}var L=function(e){return null!=e?l(e)?e:[e]:[]},P=function(e){return\"function\"==typeof e},F=function(e,t){var n,i,o,l,c,u,f,p,m,g=[],h=(e=L(e)).map(function(e,t){return null==e?null:(g.push(t),P(e)?e:s(e).map(d).join(\"][\"))}),b=g.length-1,v=L(t),_=\"var u,v;return \";if(b<0)return null;for(i=0;i<=b;++i)o=h[n=g[i]],P(o)?(l=\"(u=this.\"+(u=\"f\"+n)+\"(a))\",c=\"(v=this.\"+u+\"(b))\",(f=f||{})[u]=o):(l=\"(u=a[\"+o+\"])\",c=\"(v=b[\"+o+\"])\"),u=\"((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))\",\"descending\"!==v[n]?(m=1,p=-1):(m=-1,p=1),_+=\"(\"+l+\"<\"+c+\"||u==null)&&v!=null?\"+p+\":(u>v||v==null)&&u!=null?\"+m+\":\"+u+\"!==u&&v===v?\"+p+\":v!==v&&u===u?\"+m+(n=r){n=i=r;break}for(a=o=s;++sr&&(n=r,a=s),i=r){n=i=r;break}for(a=o=s;++sr&&(n=r,a=s),i0?n[l++]:t[s++];for(;s=0;)n+=e;return n},X=function(e,t,n,r){var i=n||\" \",a=e+\"\",o=t-a.length;return o<=0?a:\"left\"===r?Z(i,o)+a:\"center\"===r?Z(i,~~(o/2))+a+Z(i,Math.ceil(o/2)):a+Z(i,o)},J=function(e){return null==e||\"\"===e?null:!(!e||\"false\"===e||\"0\"===e)&&!!e};function ee(e){return V(e)?e:W(e)?e:Date.parse(e)}var te=function(e,t){return t=t||ee,null==e||\"\"===e?null:t(e)},ne=function(e){return null==e||\"\"===e?null:e+\"\"},re=function(e){for(var t={},n=0,r=e.length;n (http://kanitw.yellowpigz.com)\",\"Dominik Moritz (https://www.domoritz.de)\",\"Jeffrey Heer (http://jheer.org)\"],homepage:\"https://vega.github.io/vega-lite/\",description:\"Vega-Lite is a concise high-level language for interactive visualization.\",main:\"build/vega-lite.js\",unpkg:\"build/vega-lite.min.js\",jsdelivr:\"build/vega-lite.min.js\",module:\"build/src/index\",types:\"build/src/index.d.ts\",bin:{vl2png:\"./bin/vl2png\",vl2svg:\"./bin/vl2svg\",vl2vg:\"./bin/vl2vg\"},directories:{test:\"test\"},scripts:{prebuild:\"mkdir -p build/src\",build:\"npm run build:only\",\"build:only\":\"tsc && rollup -c\",postbuild:\"uglifyjs build/vega-lite.js -cm --source-map content=build/vega-lite.js.map,filename=build/vega-lite.min.js.map -o build/vega-lite.min.js && npm run schema\",\"build:examples\":\"npm run data && TZ=America/Los_Angeles scripts/build-examples.sh\",\"build:examples-full\":\"TZ=America/Los_Angeles scripts/build-examples.sh 1\",\"build:example\":\"TZ=America/Los_Angeles scripts/build-example.sh\",\"build:toc\":\"bundle exec jekyll build -q && scripts/generate-toc\",\"build:site\":\"tsc -p site && webpack --config site/webpack.config.js\",\"build:versions\":\"scripts/update-version.sh\",\"check:examples\":\"scripts/check-examples.sh\",\"check:schema\":\"scripts/check-schema.sh\",clean:\"rm -rf build && rm -f examples/compiled/*.png && find site/examples ! -name 'index.md' -type f -delete\",data:\"rsync -r node_modules/vega-datasets/data/* data\",deploy:\"scripts/deploy.sh\",\"deploy:gh\":\"scripts/deploy-gh.sh\",\"deploy:schema\":\"scripts/deploy-schema.sh\",preschema:\"npm run prebuild\",schema:\"node --stack-size=1200 ./node_modules/.bin/ts-json-schema-generator --path tsconfig.json --type TopLevelSpec > build/vega-lite-schema.json && npm run renameschema && cp build/vega-lite-schema.json _data/\",renameschema:\"scripts/rename-schema.sh\",presite:\"npm run prebuild && npm run data && npm run build:site && npm run build:toc && npm run build:versions && scripts/create-example-pages\",site:\"bundle exec jekyll serve --incremental\",lint:\"tslint -p . -e 'package.json'\",test:\"jest test/ && npm run lint && npm run schema && jest examples/ && npm run test:runtime\",\"test:inspect\":\"node --inspect-brk ./node_modules/.bin/jest --runInBand test\",\"test:runtime\":'TZ=America/Los_Angeles TS_NODE_COMPILER_OPTIONS=\\'{\"module\":\"commonjs\"}\\' wdio wdio.conf.js',\"test:runtime:generate\":\"rm -Rf test-runtime/resources && VL_GENERATE_TESTS=true npm run test:runtime\",\"watch:build\":\"npm run build:only && concurrently --kill-others -n Typescript,Rollup 'tsc -w' 'rollup -c -w'\",\"watch:site\":\"concurrently --kill-others -n Typescript,Webpack 'tsc -p site --watch' 'webpack --config site/webpack.config.js --mode development --watch'\",\"watch:test\":\"jest --watch\"},repository:{type:\"git\",url:\"https://github.com/vega/vega-lite.git\"},license:\"BSD-3-Clause\",bugs:{url:\"https://github.com/vega/vega-lite/issues\"},devDependencies:{\"@types/chai\":\"^4.1.4\",\"@types/d3\":\"^5.0.0\",\"@types/highlight.js\":\"^9.12.3\",\"@types/jest\":\"^23.1.1\",\"@types/mkdirp\":\"^0.5.2\",\"@types/node\":\"^9.0.0\",\"@types/webdriverio\":\"^4.10.2\",ajv:\"^6.5.1\",chai:\"^4.1.2\",cheerio:\"^1.0.0-rc.2\",chromedriver:\"^2.40.0\",codecov:\"^3.0.2\",concurrently:\"^3.6.0\",d3:\"^5.5.0\",\"highlight.js\":\"^9.12.0\",jest:\"^23.1.0\",mkdirp:\"^0.5.1\",rollup:\"^0.59.4\",\"rollup-plugin-commonjs\":\"^9.1.3\",\"rollup-plugin-json\":\"^3.0.0\",\"rollup-plugin-node-resolve\":\"^3.3.0\",\"rollup-plugin-sourcemaps\":\"^0.4.2\",\"source-map-support\":\"^0.5.6\",\"svg2png-many\":\"^0.0.7\",\"ts-jest\":\"^22.4.6\",\"ts-json-schema-generator\":\"^0.28.0\",\"ts-node\":\"^6.1.1\",tslint:\"5.10.0\",\"tslint-eslint-rules\":\"^5.3.1\",typescript:\"^2.9.2\",\"uglify-js\":\"^3.4.1\",vega:\"^4.0.0-rc.3\",\"vega-datasets\":\"^1.19.0\",\"vega-embed\":\"^3.16.0\",\"vega-tooltip\":\"^0.11.0\",\"wdio-chromedriver-service\":\"^0.1.3\",\"wdio-dot-reporter\":\"0.0.9\",\"wdio-mocha-framework\":\"^0.5.13\",\"wdio-static-server-service\":\"^1.0.1\",webdriverio:\"^4.13.0\",webpack:\"^4.12.0\",\"webpack-cli\":\"^3.0.8\",\"yaml-front-matter\":\"^4.0.0\"},dependencies:{\"@types/json-stable-stringify\":\"^1.0.32\",\"json-stable-stringify\":\"^1.0.1\",tslib:\"^1.9.2\",\"vega-event-selector\":\"^2.0.0\",\"vega-typings\":\"^0.3.17\",\"vega-util\":\"^1.7.0\",yargs:\"^11.0.0\"},jest:{transform:{\"^.+\\\\.tsx?$\":\"ts-jest\"},testRegex:\"(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.(jsx?|tsx?)$\",moduleFileExtensions:[\"ts\",\"tsx\",\"js\",\"jsx\",\"json\",\"node\"],testPathIgnorePatterns:[\"node_modules\",\"test-runtime\",\"/build\",\"_site\",\"src\"],coverageDirectory:\"./coverage/\",collectCoverage:!1}}},function(e,t,n){var r=n(194);r.registerLanguage(\"1c\",n(193)),r.registerLanguage(\"abnf\",n(192)),r.registerLanguage(\"accesslog\",n(191)),r.registerLanguage(\"actionscript\",n(190)),r.registerLanguage(\"ada\",n(189)),r.registerLanguage(\"apache\",n(188)),r.registerLanguage(\"applescript\",n(187)),r.registerLanguage(\"cpp\",n(186)),r.registerLanguage(\"arduino\",n(185)),r.registerLanguage(\"armasm\",n(184)),r.registerLanguage(\"xml\",n(183)),r.registerLanguage(\"asciidoc\",n(182)),r.registerLanguage(\"aspectj\",n(181)),r.registerLanguage(\"autohotkey\",n(180)),r.registerLanguage(\"autoit\",n(179)),r.registerLanguage(\"avrasm\",n(178)),r.registerLanguage(\"awk\",n(177)),r.registerLanguage(\"axapta\",n(176)),r.registerLanguage(\"bash\",n(175)),r.registerLanguage(\"basic\",n(174)),r.registerLanguage(\"bnf\",n(173)),r.registerLanguage(\"brainfuck\",n(172)),r.registerLanguage(\"cal\",n(171)),r.registerLanguage(\"capnproto\",n(170)),r.registerLanguage(\"ceylon\",n(169)),r.registerLanguage(\"clean\",n(168)),r.registerLanguage(\"clojure\",n(167)),r.registerLanguage(\"clojure-repl\",n(166)),r.registerLanguage(\"cmake\",n(165)),r.registerLanguage(\"coffeescript\",n(164)),r.registerLanguage(\"coq\",n(163)),r.registerLanguage(\"cos\",n(162)),r.registerLanguage(\"crmsh\",n(161)),r.registerLanguage(\"crystal\",n(160)),r.registerLanguage(\"cs\",n(159)),r.registerLanguage(\"csp\",n(158)),r.registerLanguage(\"css\",n(157)),r.registerLanguage(\"d\",n(156)),r.registerLanguage(\"markdown\",n(155)),r.registerLanguage(\"dart\",n(154)),r.registerLanguage(\"delphi\",n(153)),r.registerLanguage(\"diff\",n(152)),r.registerLanguage(\"django\",n(151)),r.registerLanguage(\"dns\",n(150)),r.registerLanguage(\"dockerfile\",n(149)),r.registerLanguage(\"dos\",n(148)),r.registerLanguage(\"dsconfig\",n(147)),r.registerLanguage(\"dts\",n(146)),r.registerLanguage(\"dust\",n(145)),r.registerLanguage(\"ebnf\",n(144)),r.registerLanguage(\"elixir\",n(143)),r.registerLanguage(\"elm\",n(142)),r.registerLanguage(\"ruby\",n(141)),r.registerLanguage(\"erb\",n(140)),r.registerLanguage(\"erlang-repl\",n(139)),r.registerLanguage(\"erlang\",n(138)),r.registerLanguage(\"excel\",n(137)),r.registerLanguage(\"fix\",n(136)),r.registerLanguage(\"flix\",n(135)),r.registerLanguage(\"fortran\",n(134)),r.registerLanguage(\"fsharp\",n(133)),r.registerLanguage(\"gams\",n(132)),r.registerLanguage(\"gauss\",n(131)),r.registerLanguage(\"gcode\",n(130)),r.registerLanguage(\"gherkin\",n(129)),r.registerLanguage(\"glsl\",n(128)),r.registerLanguage(\"go\",n(127)),r.registerLanguage(\"golo\",n(126)),r.registerLanguage(\"gradle\",n(125)),r.registerLanguage(\"groovy\",n(124)),r.registerLanguage(\"haml\",n(123)),r.registerLanguage(\"handlebars\",n(122)),r.registerLanguage(\"haskell\",n(121)),r.registerLanguage(\"haxe\",n(120)),r.registerLanguage(\"hsp\",n(119)),r.registerLanguage(\"htmlbars\",n(118)),r.registerLanguage(\"http\",n(117)),r.registerLanguage(\"hy\",n(116)),r.registerLanguage(\"inform7\",n(115)),r.registerLanguage(\"ini\",n(114)),r.registerLanguage(\"irpf90\",n(113)),r.registerLanguage(\"java\",n(112)),r.registerLanguage(\"javascript\",n(111)),r.registerLanguage(\"jboss-cli\",n(110)),r.registerLanguage(\"json\",n(109)),r.registerLanguage(\"julia\",n(108)),r.registerLanguage(\"julia-repl\",n(107)),r.registerLanguage(\"kotlin\",n(106)),r.registerLanguage(\"lasso\",n(105)),r.registerLanguage(\"ldif\",n(104)),r.registerLanguage(\"leaf\",n(103)),r.registerLanguage(\"less\",n(102)),r.registerLanguage(\"lisp\",n(101)),r.registerLanguage(\"livecodeserver\",n(100)),r.registerLanguage(\"livescript\",n(99)),r.registerLanguage(\"llvm\",n(98)),r.registerLanguage(\"lsl\",n(97)),r.registerLanguage(\"lua\",n(96)),r.registerLanguage(\"makefile\",n(95)),r.registerLanguage(\"mathematica\",n(94)),r.registerLanguage(\"matlab\",n(93)),r.registerLanguage(\"maxima\",n(92)),r.registerLanguage(\"mel\",n(91)),r.registerLanguage(\"mercury\",n(90)),r.registerLanguage(\"mipsasm\",n(89)),r.registerLanguage(\"mizar\",n(88)),r.registerLanguage(\"perl\",n(87)),r.registerLanguage(\"mojolicious\",n(86)),r.registerLanguage(\"monkey\",n(85)),r.registerLanguage(\"moonscript\",n(84)),r.registerLanguage(\"n1ql\",n(83)),r.registerLanguage(\"nginx\",n(82)),r.registerLanguage(\"nimrod\",n(81)),r.registerLanguage(\"nix\",n(80)),r.registerLanguage(\"nsis\",n(79)),r.registerLanguage(\"objectivec\",n(78)),r.registerLanguage(\"ocaml\",n(77)),r.registerLanguage(\"openscad\",n(76)),r.registerLanguage(\"oxygene\",n(75)),r.registerLanguage(\"parser3\",n(74)),r.registerLanguage(\"pf\",n(73)),r.registerLanguage(\"php\",n(72)),r.registerLanguage(\"pony\",n(71)),r.registerLanguage(\"powershell\",n(70)),r.registerLanguage(\"processing\",n(69)),r.registerLanguage(\"profile\",n(68)),r.registerLanguage(\"prolog\",n(67)),r.registerLanguage(\"protobuf\",n(66)),r.registerLanguage(\"puppet\",n(65)),r.registerLanguage(\"purebasic\",n(64)),r.registerLanguage(\"python\",n(63)),r.registerLanguage(\"q\",n(62)),r.registerLanguage(\"qml\",n(61)),r.registerLanguage(\"r\",n(60)),r.registerLanguage(\"rib\",n(59)),r.registerLanguage(\"roboconf\",n(58)),r.registerLanguage(\"routeros\",n(57)),r.registerLanguage(\"rsl\",n(56)),r.registerLanguage(\"ruleslanguage\",n(55)),r.registerLanguage(\"rust\",n(54)),r.registerLanguage(\"scala\",n(53)),r.registerLanguage(\"scheme\",n(52)),r.registerLanguage(\"scilab\",n(51)),r.registerLanguage(\"scss\",n(50)),r.registerLanguage(\"shell\",n(49)),r.registerLanguage(\"smali\",n(48)),r.registerLanguage(\"smalltalk\",n(47)),r.registerLanguage(\"sml\",n(46)),r.registerLanguage(\"sqf\",n(45)),r.registerLanguage(\"sql\",n(44)),r.registerLanguage(\"stan\",n(43)),r.registerLanguage(\"stata\",n(42)),r.registerLanguage(\"step21\",n(41)),r.registerLanguage(\"stylus\",n(40)),r.registerLanguage(\"subunit\",n(39)),r.registerLanguage(\"swift\",n(38)),r.registerLanguage(\"taggerscript\",n(37)),r.registerLanguage(\"yaml\",n(36)),r.registerLanguage(\"tap\",n(35)),r.registerLanguage(\"tcl\",n(34)),r.registerLanguage(\"tex\",n(33)),r.registerLanguage(\"thrift\",n(32)),r.registerLanguage(\"tp\",n(31)),r.registerLanguage(\"twig\",n(30)),r.registerLanguage(\"typescript\",n(29)),r.registerLanguage(\"vala\",n(28)),r.registerLanguage(\"vbnet\",n(27)),r.registerLanguage(\"vbscript\",n(26)),r.registerLanguage(\"vbscript-html\",n(25)),r.registerLanguage(\"verilog\",n(24)),r.registerLanguage(\"vhdl\",n(23)),r.registerLanguage(\"vim\",n(22)),r.registerLanguage(\"x86asm\",n(21)),r.registerLanguage(\"xl\",n(20)),r.registerLanguage(\"xquery\",n(19)),r.registerLanguage(\"zephir\",n(18)),e.exports=r},function(e,t,n){\"use strict\";n.r(t);var r={};n.r(r),n.d(r,\"aggregate\",function(){return Bi}),n.d(r,\"bin\",function(){return ji}),n.d(r,\"collect\",function(){return Gi}),n.d(r,\"compare\",function(){return $i}),n.d(r,\"countpattern\",function(){return Wi}),n.d(r,\"cross\",function(){return Ki}),n.d(r,\"density\",function(){return Ji}),n.d(r,\"extent\",function(){return na}),n.d(r,\"facet\",function(){return aa}),n.d(r,\"field\",function(){return sa}),n.d(r,\"filter\",function(){return ca}),n.d(r,\"flatten\",function(){return da}),n.d(r,\"fold\",function(){return fa}),n.d(r,\"formula\",function(){return pa}),n.d(r,\"generate\",function(){return ma}),n.d(r,\"impute\",function(){return ba}),n.d(r,\"joinaggregate\",function(){return va}),n.d(r,\"key\",function(){return ya}),n.d(r,\"lookup\",function(){return Ea}),n.d(r,\"multiextent\",function(){return Sa}),n.d(r,\"multivalues\",function(){return Ca}),n.d(r,\"params\",function(){return Ma}),n.d(r,\"pivot\",function(){return Na}),n.d(r,\"prefacet\",function(){return Da}),n.d(r,\"project\",function(){return Aa}),n.d(r,\"proxy\",function(){return ka}),n.d(r,\"relay\",function(){return Ra}),n.d(r,\"sample\",function(){return Ia}),n.d(r,\"sequence\",function(){return La}),n.d(r,\"sieve\",function(){return Pa}),n.d(r,\"subflow\",function(){return ra}),n.d(r,\"tupleindex\",function(){return Fa}),n.d(r,\"values\",function(){return Ba}),n.d(r,\"window\",function(){return Ga});var i={};n.r(i),n.d(i,\"bound\",function(){return Xu}),n.d(i,\"identifier\",function(){return td}),n.d(i,\"mark\",function(){return nd}),n.d(i,\"overlap\",function(){return rd}),n.d(i,\"render\",function(){return ld}),n.d(i,\"viewlayout\",function(){return xd});var a={};n.r(a),n.d(a,\"interpolate\",function(){return Op}),n.d(a,\"interpolateArray\",function(){return gp}),n.d(a,\"interpolateBasis\",function(){return ip}),n.d(a,\"interpolateBasisClosed\",function(){return ap}),n.d(a,\"interpolateDate\",function(){return hp}),n.d(a,\"interpolateNumber\",function(){return bp}),n.d(a,\"interpolateObject\",function(){return vp}),n.d(a,\"interpolateRound\",function(){return Mp}),n.d(a,\"interpolateString\",function(){return Cp}),n.d(a,\"interpolateTransformCss\",function(){return kp}),n.d(a,\"interpolateTransformSvg\",function(){return Rp}),n.d(a,\"interpolateZoom\",function(){return Pp}),n.d(a,\"interpolateRgb\",function(){return dp}),n.d(a,\"interpolateRgbBasis\",function(){return pp}),n.d(a,\"interpolateRgbBasisClosed\",function(){return mp}),n.d(a,\"interpolateHsl\",function(){return Bp}),n.d(a,\"interpolateHslLong\",function(){return Up}),n.d(a,\"interpolateLab\",function(){return jp}),n.d(a,\"interpolateHcl\",function(){return qp}),n.d(a,\"interpolateHclLong\",function(){return Gp}),n.d(a,\"interpolateCubehelix\",function(){return Hp}),n.d(a,\"interpolateCubehelixLong\",function(){return Wp}),n.d(a,\"piecewise\",function(){return Vp}),n.d(a,\"quantize\",function(){return Kp});var o={};n.r(o),n.d(o,\"schemeCategory10\",function(){return og}),n.d(o,\"schemeAccent\",function(){return sg}),n.d(o,\"schemeDark2\",function(){return lg}),n.d(o,\"schemePaired\",function(){return cg}),n.d(o,\"schemePastel1\",function(){return ug}),n.d(o,\"schemePastel2\",function(){return dg}),n.d(o,\"schemeSet1\",function(){return fg}),n.d(o,\"schemeSet2\",function(){return pg}),n.d(o,\"schemeSet3\",function(){return mg}),n.d(o,\"interpolateBrBG\",function(){return bg}),n.d(o,\"schemeBrBG\",function(){return hg}),n.d(o,\"interpolatePRGn\",function(){return _g}),n.d(o,\"schemePRGn\",function(){return vg}),n.d(o,\"interpolatePiYG\",function(){return xg}),n.d(o,\"schemePiYG\",function(){return yg}),n.d(o,\"interpolatePuOr\",function(){return Sg}),n.d(o,\"schemePuOr\",function(){return Eg}),n.d(o,\"interpolateRdBu\",function(){return Cg}),n.d(o,\"schemeRdBu\",function(){return wg}),n.d(o,\"interpolateRdGy\",function(){return Mg}),n.d(o,\"schemeRdGy\",function(){return Og}),n.d(o,\"interpolateRdYlBu\",function(){return Tg}),n.d(o,\"schemeRdYlBu\",function(){return Ng}),n.d(o,\"interpolateRdYlGn\",function(){return Ag}),n.d(o,\"schemeRdYlGn\",function(){return Dg}),n.d(o,\"interpolateSpectral\",function(){return Rg}),n.d(o,\"schemeSpectral\",function(){return kg}),n.d(o,\"interpolateBuGn\",function(){return Lg}),n.d(o,\"schemeBuGn\",function(){return Ig}),n.d(o,\"interpolateBuPu\",function(){return Fg}),n.d(o,\"schemeBuPu\",function(){return Pg}),n.d(o,\"interpolateGnBu\",function(){return Ug}),n.d(o,\"schemeGnBu\",function(){return Bg}),n.d(o,\"interpolateOrRd\",function(){return zg}),n.d(o,\"schemeOrRd\",function(){return jg}),n.d(o,\"interpolatePuBuGn\",function(){return Gg}),n.d(o,\"schemePuBuGn\",function(){return qg}),n.d(o,\"interpolatePuBu\",function(){return Hg}),n.d(o,\"schemePuBu\",function(){return $g}),n.d(o,\"interpolatePuRd\",function(){return Vg}),n.d(o,\"schemePuRd\",function(){return Wg}),n.d(o,\"interpolateRdPu\",function(){return Qg}),n.d(o,\"schemeRdPu\",function(){return Kg}),n.d(o,\"interpolateYlGnBu\",function(){return Zg}),n.d(o,\"schemeYlGnBu\",function(){return Yg}),n.d(o,\"interpolateYlGn\",function(){return Jg}),n.d(o,\"schemeYlGn\",function(){return Xg}),n.d(o,\"interpolateYlOrBr\",function(){return th}),n.d(o,\"schemeYlOrBr\",function(){return eh}),n.d(o,\"interpolateYlOrRd\",function(){return rh}),n.d(o,\"schemeYlOrRd\",function(){return nh}),n.d(o,\"interpolateBlues\",function(){return ah}),n.d(o,\"schemeBlues\",function(){return ih}),n.d(o,\"interpolateGreens\",function(){return sh}),n.d(o,\"schemeGreens\",function(){return oh}),n.d(o,\"interpolateGreys\",function(){return ch}),n.d(o,\"schemeGreys\",function(){return lh}),n.d(o,\"interpolatePurples\",function(){return dh}),n.d(o,\"schemePurples\",function(){return uh}),n.d(o,\"interpolateReds\",function(){return ph}),n.d(o,\"schemeReds\",function(){return fh}),n.d(o,\"interpolateOranges\",function(){return gh}),n.d(o,\"schemeOranges\",function(){return mh}),n.d(o,\"interpolateCubehelixDefault\",function(){return hh}),n.d(o,\"interpolateRainbow\",function(){return yh}),n.d(o,\"interpolateWarm\",function(){return bh}),n.d(o,\"interpolateCool\",function(){return vh}),n.d(o,\"interpolateSinebow\",function(){return wh}),n.d(o,\"interpolateViridis\",function(){return Oh}),n.d(o,\"interpolateMagma\",function(){return Mh}),n.d(o,\"interpolateInferno\",function(){return Nh}),n.d(o,\"interpolatePlasma\",function(){return Th});var s={};n.r(s),n.d(s,\"axisticks\",function(){return jh}),n.d(s,\"datajoin\",function(){return zh}),n.d(s,\"encode\",function(){return $h}),n.d(s,\"legendentries\",function(){return Yh}),n.d(s,\"linkpath\",function(){return nb}),n.d(s,\"pie\",function(){return ob}),n.d(s,\"scale\",function(){return db}),n.d(s,\"sortitems\",function(){return mb}),n.d(s,\"stack\",function(){return gb}),n.d(s,\"validTicks\",function(){return Fh});var l={};n.r(l),n.d(l,\"contour\",function(){return Lb}),n.d(l,\"geojson\",function(){return Fb}),n.d(l,\"geopath\",function(){return Qx}),n.d(l,\"geopoint\",function(){return Yx}),n.d(l,\"geoshape\",function(){return Zx}),n.d(l,\"graticule\",function(){return Xx}),n.d(l,\"projection\",function(){return Jx});var c={};n.r(c),n.d(c,\"force\",function(){return QE});var u={};n.r(u),n.d(u,\"nest\",function(){return YS}),n.d(u,\"pack\",function(){return ew}),n.d(u,\"partition\",function(){return rw}),n.d(u,\"stratify\",function(){return aw}),n.d(u,\"tree\",function(){return lw}),n.d(u,\"treelinks\",function(){return uw}),n.d(u,\"treemap\",function(){return pw});var d={};n.r(d),n.d(d,\"voronoi\",function(){return Zw});var f={};n.r(f),n.d(f,\"wordcloud\",function(){return yO});var p={};n.r(p),n.d(p,\"crossfilter\",function(){return CO}),n.d(p,\"resolvefilter\",function(){return MO});var m={};n.r(m),n.d(m,\"symbols\",function(){return iz}),n.d(m,\"gradient\",function(){return az}),n.d(m,\"labels\",function(){return oz});var g={},h={},b=34,v=10,_=13;function y(e){return new Function(\"d\",\"return {\"+e.map(function(e,t){return JSON.stringify(e)+\": d[\"+t+\"]\"}).join(\",\")+\"}\")}var x=function(e){var t=new RegExp('[\"'+e+\"\\n\\r]\"),n=e.charCodeAt(0);function r(e,t){var r,i=[],a=e.length,o=0,s=0,l=a<=0,c=!1;function u(){if(l)return h;if(c)return c=!1,g;var t,r,i=o;if(e.charCodeAt(i)===b){for(;o++=a?l=!0:(r=e.charCodeAt(o++))===v?c=!0:r===_&&(c=!0,e.charCodeAt(o)===v&&++o),e.slice(i+1,t-1).replace(/\"\"/g,'\"')}for(;o=0&&\"xmlns\"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),A.hasOwnProperty(t)?{space:A[t],local:e}:e};var R=function(e){var t=k(e);return(t.local?function(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}:function(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===D&&t.documentElement.namespaceURI===D?t.createElement(e):t.createElementNS(n,e)}})(t)};function I(){}var L=function(e){return null==e?I:function(){return this.querySelector(e)}};function P(){return[]}var F=function(e){return function(){return this.matches(e)}};if(\"undefined\"!=typeof document){var B=document.documentElement;if(!B.matches){var U=B.webkitMatchesSelector||B.msMatchesSelector||B.mozMatchesSelector||B.oMatchesSelector;F=function(e){return function(){return U.call(this,e)}}}}var j=F,z=function(e){return new Array(e.length)};function q(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}q.prototype={constructor:q,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};var G=\"$\";function $(e,t,n,r,i,a){for(var o,s=0,l=t.length,c=a.length;st?1:e>=t?0:NaN}var V=function(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView};function K(e){return e.trim().split(/^|\\s+/)}function Q(e){return e.classList||new Y(e)}function Y(e){this._node=e,this._names=K(e.getAttribute(\"class\")||\"\")}function Z(e,t){for(var n=Q(e),r=-1,i=t.length;++r=0&&(this._names.splice(t,1),this._node.setAttribute(\"class\",this._names.join(\" \")))},contains:function(e){return this._names.indexOf(e)>=0}};function J(){this.textContent=\"\"}function ee(){this.innerHTML=\"\"}function te(){this.nextSibling&&this.parentNode.appendChild(this)}function ne(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function re(){return null}function ie(){var e=this.parentNode;e&&e.removeChild(this)}function ae(){return this.parentNode.insertBefore(this.cloneNode(!1),this.nextSibling)}function oe(){return this.parentNode.insertBefore(this.cloneNode(!0),this.nextSibling)}var se={},le=null;\"undefined\"!=typeof document&&(\"onmouseenter\"in document.documentElement||(se={mouseenter:\"mouseover\",mouseleave:\"mouseout\"}));function ce(e,t,n){return e=ue(e,t,n),function(t){var n=t.relatedTarget;n&&(n===this||8&n.compareDocumentPosition(this))||e.call(this,t)}}function ue(e,t,n){return function(r){var i=le;le=r;try{e.call(this,this.__data__,t,n)}finally{le=i}}}function de(e){return function(){var t=this.__on;if(t){for(var n,r=0,i=-1,a=t.length;r=x&&(x=y+1);!(_=b[x])&&++x=0;)(r=i[a])&&(o&&o!==r.nextSibling&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=W);for(var n=this._groups,r=n.length,i=new Array(r),a=0;a1?this.each((null==t?function(e){return function(){this.style.removeProperty(e)}}:\"function\"==typeof t?function(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}:function(e,t,n){return function(){this.style.setProperty(e,t,n)}})(e,t,null==n?\"\":n)):function(e,t){return e.style.getPropertyValue(t)||V(e).getComputedStyle(e,null).getPropertyValue(t)}(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?function(e){return function(){delete this[e]}}:\"function\"==typeof t?function(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}:function(e,t){return function(){this[e]=t}})(e,t)):this.node()[e]},classed:function(e,t){var n=K(e+\"\");if(arguments.length<2){for(var r=Q(this.node()),i=-1,a=n.length;++i=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}(e+\"\"),o=a.length;if(!(arguments.length<2)){for(s=t?fe:de,null==n&&(n=!1),r=0;r=0&&n.splice(i,1)),n},n}var we=Symbol(\"vega_id\"),Ce=1;function Oe(e){return!(!e||!Me(e))}function Me(e){return e[we]}function Ne(e,t){return e[we]=t,e}function Te(e){var t=e===Object(e)?e:{data:e};return Me(t)?t:Ne(t,Ce++)}function De(e){return Ae(e,Te({}))}function Ae(e,t){for(var n in e)t[n]=e[n];return t}function ke(e,t){return Ne(t,Me(e))}function Re(e){return e&&e.constructor===Ie}function Ie(){var e=[],t=[],n=[],r=[],i=[],a=!1;return{constructor:Ie,insert:function(t){for(var n=Object(Ee.h)(t),r=0,i=n.length;r0&&(h(f,d,u.value),o.modifies(d));for(l=0,c=i.length;l0&&h(e,u.field,u.value)}),o.modifies(u.field);if(a)o.mod=t.length||r.length?s.filter(function(e){return m[Me(e)]>0}):s.slice();else for(p in g)o.mod.push(g[p]);return o}}}var Le=\"_:mod:_\";function Pe(){Object.defineProperty(this,Le,{writable:!0,value:{}})}var Fe=Pe.prototype;Fe.set=function(e,t,n,r){var i=this,a=i[e],o=i[Le];return null!=t&&t>=0?(a[t]!==n||r)&&(a[t]=n,o[t+\":\"+e]=-1,o[e]=-1):(a!==n||r)&&(i[e]=n,o[e]=Object(Ee.u)(n)?1+n.length:-1),i},Fe.modified=function(e,t){var n,r=this[Le];if(!arguments.length){for(n in r)if(r[n])return!0;return!1}if(Object(Ee.u)(e)){for(n=0;n=0?t+1e?(t=n,1):0})},We.debounce=function(e){var t=He();return this.targets().add(He(null,null,Object(Ee.k)(e,function(e){var n=e.dataflow;t.receive(e),n&&n.run&&n.run()}))),t},We.between=function(e,t){var n=!1;return e.targets().add(He(null,null,function(){n=!0})),t.targets().add(He(null,null,function(){n=!1})),this.filter(function(){return n})};var Ve=/^([A-Za-z]+:)?\\/\\//,Ke=\"file://\",Qe=function(e){return{options:e||{},sanitize:Ze,load:Ye,file:Je,http:Xe}};function Ye(e,t){var n=this;return n.sanitize(e,t).then(function(e){var r=e.href;return e.localFile?n.file(r):n.http(r,t)})}function Ze(e,t){return t=Object(Ee.m)({},this.options,t),new Promise(function(n,r){var i,a,o,s,l={href:null};null!=e&&\"string\"==typeof e?(a=Ve.test(e),(s=t.baseURL)&&!a&&(tt(e,\"/\")||\"/\"===s[s.length-1]||(e=\"/\"+e),e=s+e),o=(i=tt(e,Ke))||\"file\"===t.mode||\"http\"!==t.mode&&!a&&et(),i?e=e.slice(Ke.length):tt(e,\"//\")&&(\"file\"===t.defaultProtocol?(e=e.slice(2),o=!0):e=(t.defaultProtocol||\"http\")+\":\"+e),Object.defineProperty(l,\"localFile\",{value:!!o}),l.href=e,t.target&&(l.target=t.target+\"\"),n(l)):r(\"Sanitize failure, invalid URI: \"+Object(Ee.M)(e))})}function Xe(e,t){return function(e,t){var r=\"function\"==typeof fetch?fetch:n(17);return r?r(e,t):Promise.reject(\"No fetch method available.\")}(e,Object(Ee.m)({},this.options.http,t)).then(function(e){if(!e.ok)throw e.status+\"\"+e.statusText;return e.text()})}function Je(e){return new Promise(function(t,n){var r=et();r?r.readFile(e,function(e,r){e?n(e):t(r)}):n(\"No file system access for \"+e)})}function et(){var e=n(16);return e&&Object(Ee.x)(e.readFile)?e:null}function tt(e,t){return null!=e&&0===e.lastIndexOf(t,0)}var nt={boolean:Ee.N,integer:Ee.P,number:Ee.P,date:Ee.O,string:Ee.R,unknown:Ee.s},rt=[function(e){return\"true\"===e||\"false\"===e||!0===e||!1===e},function(e){return ot(e)&&(e=+e)==~~e},ot,function(e){return!isNaN(Date.parse(e))}],it=[\"boolean\",\"integer\",\"number\",\"date\"];function at(e,t){return t.reduce(function(t,n){return t[n]=function(e,t){if(!e||!e.length)return\"unknown\";var n,r,i,a,o=0,s=e.length,l=rt.length,c=rt.map(function(e,t){return t+1});for(r=0,s=e.length;r1)r=function(e,t,n){var r,i=[],a=[];function o(e){var t=e<0?~e:e;(a[t]||(a[t]=[])).push({i:e,g:r})}function s(e){e.forEach(o)}function l(e){e.forEach(s)}return function e(t){switch(r=t,t.type){case\"GeometryCollection\":t.geometries.forEach(e);break;case\"LineString\":s(t.arcs);break;case\"MultiLineString\":case\"Polygon\":l(t.arcs);break;case\"MultiPolygon\":t.arcs.forEach(l)}}(t),a.forEach(null==n?function(e){i.push(e[0].i)}:function(e){n(e[0].g,e[e.length-1].g)&&i.push(e[0].i)}),i}(0,t,n);else for(i=0,r=new Array(a=e.arcs.length);i0))return s;do{s.push(o=new Date(+n)),t(n,a),e(n)}while(o=t)for(;e(t),!n(t);)t.setTime(t-1)},function(e,r){if(e>=e)if(r<0)for(;++r<=0;)for(;t(e,-1),!n(e););else for(;--r>=0;)for(;t(e,1),!n(e););})},n&&(i.count=function(t,r){return _t.setTime(+t),yt.setTime(+r),e(_t),e(yt),Math.floor(n(_t,yt))},i.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?i.filter(r?function(t){return r(t)%e==0}:function(t){return i.count(0,t)%e==0}):i:null}),i}var Et=xt(function(){},function(e,t){e.setTime(+e+t)},function(e,t){return t-e});Et.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?xt(function(t){t.setTime(Math.floor(t/e)*e)},function(t,n){t.setTime(+t+n*e)},function(t,n){return(n-t)/e}):Et:null};var St=Et,wt=(Et.range,6e4),Ct=6048e5,Ot=xt(function(e){e.setTime(1e3*Math.floor(e/1e3))},function(e,t){e.setTime(+e+1e3*t)},function(e,t){return(t-e)/1e3},function(e){return e.getUTCSeconds()}),Mt=Ot,Nt=(Ot.range,xt(function(e){e.setTime(Math.floor(e/wt)*wt)},function(e,t){e.setTime(+e+t*wt)},function(e,t){return(t-e)/wt},function(e){return e.getMinutes()})),Tt=Nt,Dt=(Nt.range,xt(function(e){var t=e.getTimezoneOffset()*wt%36e5;t<0&&(t+=36e5),e.setTime(36e5*Math.floor((+e-t)/36e5)+t)},function(e,t){e.setTime(+e+36e5*t)},function(e,t){return(t-e)/36e5},function(e){return e.getHours()})),At=Dt,kt=(Dt.range,xt(function(e){e.setHours(0,0,0,0)},function(e,t){e.setDate(e.getDate()+t)},function(e,t){return(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*wt)/864e5},function(e){return e.getDate()-1})),Rt=kt;kt.range;function It(e){return xt(function(t){t.setDate(t.getDate()-(t.getDay()+7-e)%7),t.setHours(0,0,0,0)},function(e,t){e.setDate(e.getDate()+7*t)},function(e,t){return(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*wt)/Ct})}var Lt=It(0),Pt=It(1),Ft=It(2),Bt=It(3),Ut=It(4),jt=It(5),zt=It(6),qt=(Lt.range,Pt.range,Ft.range,Bt.range,Ut.range,jt.range,zt.range,xt(function(e){e.setDate(1),e.setHours(0,0,0,0)},function(e,t){e.setMonth(e.getMonth()+t)},function(e,t){return t.getMonth()-e.getMonth()+12*(t.getFullYear()-e.getFullYear())},function(e){return e.getMonth()})),Gt=qt,$t=(qt.range,xt(function(e){e.setMonth(0,1),e.setHours(0,0,0,0)},function(e,t){e.setFullYear(e.getFullYear()+t)},function(e,t){return t.getFullYear()-e.getFullYear()},function(e){return e.getFullYear()}));$t.every=function(e){return isFinite(e=Math.floor(e))&&e>0?xt(function(t){t.setFullYear(Math.floor(t.getFullYear()/e)*e),t.setMonth(0,1),t.setHours(0,0,0,0)},function(t,n){t.setFullYear(t.getFullYear()+n*e)}):null};var Ht=$t,Wt=($t.range,xt(function(e){e.setUTCSeconds(0,0)},function(e,t){e.setTime(+e+t*wt)},function(e,t){return(t-e)/wt},function(e){return e.getUTCMinutes()})),Vt=Wt,Kt=(Wt.range,xt(function(e){e.setUTCMinutes(0,0,0)},function(e,t){e.setTime(+e+36e5*t)},function(e,t){return(t-e)/36e5},function(e){return e.getUTCHours()})),Qt=Kt,Yt=(Kt.range,xt(function(e){e.setUTCHours(0,0,0,0)},function(e,t){e.setUTCDate(e.getUTCDate()+t)},function(e,t){return(t-e)/864e5},function(e){return e.getUTCDate()-1})),Zt=Yt;Yt.range;function Xt(e){return xt(function(t){t.setUTCDate(t.getUTCDate()-(t.getUTCDay()+7-e)%7),t.setUTCHours(0,0,0,0)},function(e,t){e.setUTCDate(e.getUTCDate()+7*t)},function(e,t){return(t-e)/Ct})}var Jt=Xt(0),en=Xt(1),tn=Xt(2),nn=Xt(3),rn=Xt(4),an=Xt(5),on=Xt(6),sn=(Jt.range,en.range,tn.range,nn.range,rn.range,an.range,on.range,xt(function(e){e.setUTCDate(1),e.setUTCHours(0,0,0,0)},function(e,t){e.setUTCMonth(e.getUTCMonth()+t)},function(e,t){return t.getUTCMonth()-e.getUTCMonth()+12*(t.getUTCFullYear()-e.getUTCFullYear())},function(e){return e.getUTCMonth()})),ln=sn,cn=(sn.range,xt(function(e){e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},function(e,t){e.setUTCFullYear(e.getUTCFullYear()+t)},function(e,t){return t.getUTCFullYear()-e.getUTCFullYear()},function(e){return e.getUTCFullYear()}));cn.every=function(e){return isFinite(e=Math.floor(e))&&e>0?xt(function(t){t.setUTCFullYear(Math.floor(t.getUTCFullYear()/e)*e),t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},function(t,n){t.setUTCFullYear(t.getUTCFullYear()+n*e)}):null};var un=cn;cn.range;function dn(e){if(0<=e.y&&e.y<100){var t=new Date(-1,e.m,e.d,e.H,e.M,e.S,e.L);return t.setFullYear(e.y),t}return new Date(e.y,e.m,e.d,e.H,e.M,e.S,e.L)}function fn(e){if(0<=e.y&&e.y<100){var t=new Date(Date.UTC(-1,e.m,e.d,e.H,e.M,e.S,e.L));return t.setUTCFullYear(e.y),t}return new Date(Date.UTC(e.y,e.m,e.d,e.H,e.M,e.S,e.L))}function pn(e){return{y:e,m:0,d:1,H:0,M:0,S:0,L:0}}var mn,gn,hn,bn,vn,_n={\"-\":\"\",_:\" \",0:\"0\"},yn=/^\\s*\\d+/,xn=/^%/,En=/[\\\\^$*+?|[\\]().{}]/g;function Sn(e,t,n){var r=e<0?\"-\":\"\",i=(r?-e:e)+\"\",a=i.length;return r+(a68?1900:2e3),n+r[0].length):-1}function In(e,t,n){var r=/^(Z)|([+-]\\d\\d)(?::?(\\d\\d))?/.exec(t.slice(n,n+6));return r?(e.Z=r[1]?0:-(r[2]+(r[3]||\"00\")),n+r[0].length):-1}function Ln(e,t,n){var r=yn.exec(t.slice(n,n+2));return r?(e.m=r[0]-1,n+r[0].length):-1}function Pn(e,t,n){var r=yn.exec(t.slice(n,n+2));return r?(e.d=+r[0],n+r[0].length):-1}function Fn(e,t,n){var r=yn.exec(t.slice(n,n+3));return r?(e.m=0,e.d=+r[0],n+r[0].length):-1}function Bn(e,t,n){var r=yn.exec(t.slice(n,n+2));return r?(e.H=+r[0],n+r[0].length):-1}function Un(e,t,n){var r=yn.exec(t.slice(n,n+2));return r?(e.M=+r[0],n+r[0].length):-1}function jn(e,t,n){var r=yn.exec(t.slice(n,n+2));return r?(e.S=+r[0],n+r[0].length):-1}function zn(e,t,n){var r=yn.exec(t.slice(n,n+3));return r?(e.L=+r[0],n+r[0].length):-1}function qn(e,t,n){var r=yn.exec(t.slice(n,n+6));return r?(e.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function Gn(e,t,n){var r=xn.exec(t.slice(n,n+1));return r?n+r[0].length:-1}function $n(e,t,n){var r=yn.exec(t.slice(n));return r?(e.Q=+r[0],n+r[0].length):-1}function Hn(e,t,n){var r=yn.exec(t.slice(n));return r?(e.Q=1e3*+r[0],n+r[0].length):-1}function Wn(e,t){return Sn(e.getDate(),t,2)}function Vn(e,t){return Sn(e.getHours(),t,2)}function Kn(e,t){return Sn(e.getHours()%12||12,t,2)}function Qn(e,t){return Sn(1+Rt.count(Ht(e),e),t,3)}function Yn(e,t){return Sn(e.getMilliseconds(),t,3)}function Zn(e,t){return Yn(e,t)+\"000\"}function Xn(e,t){return Sn(e.getMonth()+1,t,2)}function Jn(e,t){return Sn(e.getMinutes(),t,2)}function er(e,t){return Sn(e.getSeconds(),t,2)}function tr(e){var t=e.getDay();return 0===t?7:t}function nr(e,t){return Sn(Lt.count(Ht(e),e),t,2)}function rr(e,t){var n=e.getDay();return e=n>=4||0===n?Ut(e):Ut.ceil(e),Sn(Ut.count(Ht(e),e)+(4===Ht(e).getDay()),t,2)}function ir(e){return e.getDay()}function ar(e,t){return Sn(Pt.count(Ht(e),e),t,2)}function or(e,t){return Sn(e.getFullYear()%100,t,2)}function sr(e,t){return Sn(e.getFullYear()%1e4,t,4)}function lr(e){var t=e.getTimezoneOffset();return(t>0?\"-\":(t*=-1,\"+\"))+Sn(t/60|0,\"0\",2)+Sn(t%60,\"0\",2)}function cr(e,t){return Sn(e.getUTCDate(),t,2)}function ur(e,t){return Sn(e.getUTCHours(),t,2)}function dr(e,t){return Sn(e.getUTCHours()%12||12,t,2)}function fr(e,t){return Sn(1+Zt.count(un(e),e),t,3)}function pr(e,t){return Sn(e.getUTCMilliseconds(),t,3)}function mr(e,t){return pr(e,t)+\"000\"}function gr(e,t){return Sn(e.getUTCMonth()+1,t,2)}function hr(e,t){return Sn(e.getUTCMinutes(),t,2)}function br(e,t){return Sn(e.getUTCSeconds(),t,2)}function vr(e){var t=e.getUTCDay();return 0===t?7:t}function _r(e,t){return Sn(Jt.count(un(e),e),t,2)}function yr(e,t){var n=e.getUTCDay();return e=n>=4||0===n?rn(e):rn.ceil(e),Sn(rn.count(un(e),e)+(4===un(e).getUTCDay()),t,2)}function xr(e){return e.getUTCDay()}function Er(e,t){return Sn(en.count(un(e),e),t,2)}function Sr(e,t){return Sn(e.getUTCFullYear()%100,t,2)}function wr(e,t){return Sn(e.getUTCFullYear()%1e4,t,4)}function Cr(){return\"+0000\"}function Or(){return\"%\"}function Mr(e){return+e}function Nr(e){return Math.floor(+e/1e3)}mn=function(e){var t=e.dateTime,n=e.date,r=e.time,i=e.periods,a=e.days,o=e.shortDays,s=e.months,l=e.shortMonths,c=Cn(i),u=On(i),d=Cn(a),f=On(a),p=Cn(o),m=On(o),g=Cn(s),h=On(s),b=Cn(l),v=On(l),_={a:function(e){return o[e.getDay()]},A:function(e){return a[e.getDay()]},b:function(e){return l[e.getMonth()]},B:function(e){return s[e.getMonth()]},c:null,d:Wn,e:Wn,f:Zn,H:Vn,I:Kn,j:Qn,L:Yn,m:Xn,M:Jn,p:function(e){return i[+(e.getHours()>=12)]},Q:Mr,s:Nr,S:er,u:tr,U:nr,V:rr,w:ir,W:ar,x:null,X:null,y:or,Y:sr,Z:lr,\"%\":Or},y={a:function(e){return o[e.getUTCDay()]},A:function(e){return a[e.getUTCDay()]},b:function(e){return l[e.getUTCMonth()]},B:function(e){return s[e.getUTCMonth()]},c:null,d:cr,e:cr,f:mr,H:ur,I:dr,j:fr,L:pr,m:gr,M:hr,p:function(e){return i[+(e.getUTCHours()>=12)]},Q:Mr,s:Nr,S:br,u:vr,U:_r,V:yr,w:xr,W:Er,x:null,X:null,y:Sr,Y:wr,Z:Cr,\"%\":Or},x={a:function(e,t,n){var r=p.exec(t.slice(n));return r?(e.w=m[r[0].toLowerCase()],n+r[0].length):-1},A:function(e,t,n){var r=d.exec(t.slice(n));return r?(e.w=f[r[0].toLowerCase()],n+r[0].length):-1},b:function(e,t,n){var r=b.exec(t.slice(n));return r?(e.m=v[r[0].toLowerCase()],n+r[0].length):-1},B:function(e,t,n){var r=g.exec(t.slice(n));return r?(e.m=h[r[0].toLowerCase()],n+r[0].length):-1},c:function(e,n,r){return w(e,t,n,r)},d:Pn,e:Pn,f:qn,H:Bn,I:Bn,j:Fn,L:zn,m:Ln,M:Un,p:function(e,t,n){var r=c.exec(t.slice(n));return r?(e.p=u[r[0].toLowerCase()],n+r[0].length):-1},Q:$n,s:Hn,S:jn,u:Nn,U:Tn,V:Dn,w:Mn,W:An,x:function(e,t,r){return w(e,n,t,r)},X:function(e,t,n){return w(e,r,t,n)},y:Rn,Y:kn,Z:In,\"%\":Gn};function E(e,t){return function(n){var r,i,a,o=[],s=-1,l=0,c=e.length;for(n instanceof Date||(n=new Date(+n));++s53)return null;\"w\"in a||(a.w=1),\"Z\"in a?(r=(i=(r=fn(pn(a.y))).getUTCDay())>4||0===i?en.ceil(r):en(r),r=Zt.offset(r,7*(a.V-1)),a.y=r.getUTCFullYear(),a.m=r.getUTCMonth(),a.d=r.getUTCDate()+(a.w+6)%7):(r=(i=(r=t(pn(a.y))).getDay())>4||0===i?Pt.ceil(r):Pt(r),r=Rt.offset(r,7*(a.V-1)),a.y=r.getFullYear(),a.m=r.getMonth(),a.d=r.getDate()+(a.w+6)%7)}else(\"W\"in a||\"U\"in a)&&(\"w\"in a||(a.w=\"u\"in a?a.u%7:\"W\"in a?1:0),i=\"Z\"in a?fn(pn(a.y)).getUTCDay():t(pn(a.y)).getDay(),a.m=0,a.d=\"W\"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return\"Z\"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,fn(a)):t(a)}}function w(e,t,n,r){for(var i,a,o=0,s=t.length,l=n.length;o=l)return-1;if(37===(i=t.charCodeAt(o++))){if(i=t.charAt(o++),!(a=x[i in _n?t.charAt(o++):i])||(r=a(e,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return _.x=E(n,_),_.X=E(r,_),_.c=E(t,_),y.x=E(n,y),y.X=E(r,y),y.c=E(t,y),{format:function(e){var t=E(e+=\"\",_);return t.toString=function(){return e},t},parse:function(e){var t=S(e+=\"\",dn);return t.toString=function(){return e},t},utcFormat:function(e){var t=E(e+=\"\",y);return t.toString=function(){return e},t},utcParse:function(e){var t=S(e,fn);return t.toString=function(){return e},t}}}({dateTime:\"%x, %X\",date:\"%-m/%-d/%Y\",time:\"%-I:%M:%S %p\",periods:[\"AM\",\"PM\"],days:[\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"],shortDays:[\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"],months:[\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"],shortMonths:[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"]}),gn=mn.format,hn=mn.parse,bn=mn.utcFormat,vn=mn.utcParse;Date.prototype.toISOString||bn(\"%Y-%m-%dT%H:%M:%S.%LZ\");+new Date(\"2000-01-01T00:00:00.000Z\")||vn(\"%Y-%m-%dT%H:%M:%S.%LZ\");var Tr=function(e,t,n){var r=function(e,t){return arguments.length>1?(vt[e]=t,this):vt.hasOwnProperty(e)?vt[e]:null}((t=t||{}).type||\"json\");return r||Object(Ee.l)(\"Unknown data format type: \"+t.type),e=r(e,t),t.parse&&function(e,t,n){if(!e.length)return;n=n||hn;var r,i,a,o,s,l,c,u=e.columns||Object.keys(e[0]);\"auto\"===t&&(t=at(e,u));for(u=Object.keys(t),r=u.map(function(e){var r,i,a=t[e];if(a&&(0===a.indexOf(\"date:\")||0===a.indexOf(\"utc:\")))return(\"'\"===(i=(r=a.split(/:(.+)?/,2))[1])[0]&&\"'\"===i[i.length-1]||'\"'===i[0]&&'\"'===i[i.length-1])&&(i=i.slice(1,-1)),\"utc\"===r[0]?vn(i):n(i);if(!nt[a])throw Error(\"Illegal format pattern: \"+e+\":\"+a);return nt[a]}),o=0,l=e.length,c=u.length;ot&&r(i,a=e[o=n-1>>1])<0;)e[n]=a,n=o;return e[n]=i}function Wr(e,t,n){for(var r,i=t,a=e.length,o=e[t],s=2*t+1;s=0&&(s=r),e[t]=e[s],s=2*(t=s)+1;return e[t]=o,Hr(e,i,t,n)}function Vr(){this._log=Object(Ee.D)(),this.logLevel(Ee.b),this._clock=0,this._rank=0;try{this._loader=Qe()}catch(e){}this._touched=Se(Ee.r),this._pulses={},this._pulse=null,this._heap=new Gr(function(e,t){return e.qrank-t.qrank}),this._postrun=[]}$r.size=function(){return this.nodes.length},$r.clear=function(){return this.nodes=[],this},$r.peek=function(){return this.nodes[0]},$r.push=function(e){var t=this.nodes;return t.push(e),Hr(t,0,t.length-1,this.cmp)},$r.pop=function(){var e,t=this.nodes,n=t.pop();return t.length?(e=t[0],t[0]=n,Wr(t,0,this.cmp)):e=n,e},$r.replace=function(e){var t=this.nodes,n=t[0];return t[0]=e,Wr(t,0,this.cmp),n},$r.pushpop=function(e){var t=this.nodes,n=t[0];return t.length&&this.cmp(n,e)<0&&(t[0]=e,e=n,Wr(t,0,this.cmp)),e};var Kr=Vr.prototype;function Qr(e){return function(){return this._log[e].apply(this,arguments)}}function Yr(e,t){je.call(this,e,null,t)}Kr.stamp=function(){return this._clock},Kr.loader=function(e){return arguments.length?(this._loader=e,this):this._loader},Kr.cleanThreshold=1e4,Kr.add=function(e,t,n,r){var i,a=1;return e instanceof je?i=e:e&&e.prototype instanceof je?i=new e:Object(Ee.x)(e)?i=new je(null,e):(a=0,i=new je(e,t)),this.rank(i),a&&(r=n,n=t),n&&this.connect(i,i.parameters(n,r)),this.touch(i),i},Kr.connect=function(e,t){var n,r,i=e.rank;for(n=0,r=t.length;n=0;)i.push(t=n[r]),t===e&&Object(Ee.l)(\"Cycle detected in dataflow graph.\")},Kr.pulse=function(e,t,n){this.touch(e,n||qr);var r=new Ir(this,this._clock+(this._pulse?0:1)),i=e.pulse&&e.pulse.source||[];return r.target=e,this._pulses[e.id]=t.pulse(r,i),this},Kr.touch=function(e,t){var n=t||qr;return this._pulse?this._enqueue(e):this._touched.add(e),n.skip&&e.skip(!0),this},Kr.update=function(e,t,n){var r=n||qr;return(e.set(t)||r.force)&&this.touch(e,r),this},Kr.changeset=Ie,Kr.ingest=function(e,t,n){return this.pulse(e,this.changeset().insert(Tr(t,n)))},Kr.request=function(e,t,n){var r=this,i=r._pending||function(e){var t,n,r=new Promise(function(e,r){t=e,n=r});return r.requests=0,r.done=function(){0==--r.requests&&e.runAfter(function(){e._pending=null;try{e.run(),t(e)}catch(e){n(e)}})},e._pending=r}(r);i.requests+=1,r.loader().load(t,{context:\"dataflow\"}).then(function(t){r.ingest(e,t,n)},function(e){r.error(\"Loading failed\",t,e)}).catch(function(e){r.error(\"Data ingestion failed\",t,e)}).then(i.done,i.done)},Kr.events=function(e,t,n,r){for(var i,a=this,o=He(n,r),s=function(e){e.dataflow=a;try{o.receive(e)}catch(e){a.error(e)}finally{a.run()}},l=0,c=(i=\"string\"==typeof e&&\"undefined\"!=typeof document?document.querySelectorAll(e):Object(Ee.h)(e)).length;l=Ee.c&&(r=Date.now(),a.debug(\"-- START PROPAGATION (\"+a._clock+\") -----\")),a._touched.forEach(function(e){a._enqueue(e,!0)}),a._touched=Se(Ee.r);try{for(;a._heap.size()>0;)(t=a._heap.pop()).rank===t.qrank?(n=t.run(a._getPulse(t,e)),s>=Ee.a&&a.debug(t.id,n===Rr?\"STOP\":n,t),n!==Rr&&(a._pulse=n,t._targets&&t._targets.forEach(function(e){a._enqueue(e)})),++o):a._enqueue(t,!0)}catch(e){i=e}if(a._pulses={},a._pulse=null,s>=Ee.c&&(r=Date.now()-r,a.info(\"> Pulse \"+a._clock+\": \"+o+\" operators; \"+r+\"ms\")),i&&(a._postrun=[],a.error(i)),a._onrun)try{a._onrun(a,o,i)}catch(e){a.error(e)}if(a._postrun.length){var l=a._postrun;a._postrun=[],l.sort(function(e,t){return t.priority-e.priority}).forEach(function(e){zr(a,e.callback)})}return o},Kr.runAsync=function(){return this._pending||Promise.resolve(this.run())},Kr.runAfter=function(e,t,n){this._pulse||t?this._postrun.push({priority:n||0,callback:e}):zr(this,e)},Kr._enqueue=function(e,t){var n=!this._pulses[e.id];n&&(this._pulses[e.id]=this._pulse),(n||t)&&(e.qrank=e.rank,this._heap.push(e))},Kr._getPulse=function(e,t){var n,r=e.source,i=this._clock;return r&&Object(Ee.u)(r)?new Ur(this,i,n=r.map(function(e){return e.pulse}),t):(n=this._pulses[e.id],r&&((r=r.pulse)&&r!==Rr?r.stamp===i&&n.target!==e?n=r:n.source=r.source:n.source=[]),n)},Kr.error=Qr(\"error\"),Kr.warn=Qr(\"warn\"),Kr.info=Qr(\"info\"),Kr.debug=Qr(\"debug\"),Kr.logLevel=Qr(\"level\");var Zr=Object(Ee.t)(Yr,je);Zr.run=function(e){return e.stamp<=this.stamp?e.StopPropagation:(this.skip()?this.skip(!1):t=this.evaluate(e),(t=t||e)!==e.StopPropagation&&(this.pulse=t),this.stamp=e.stamp,t);var t},Zr.evaluate=function(e){var t=this.marshall(e.stamp),n=this.transform(t,e);return t.clear(),n},Zr.transform=function(){};var Xr={};function Jr(e){var t=function(e){return e=e&&e.toLowerCase(),Xr.hasOwnProperty(e)?Xr[e]:null}(e);return t&&t.Definition||null}function ei(e){return e&&e.length?1===e.length?e[0]:(t=e,function(e){for(var n=t.length,r=1,i=String(t[0](e));r 1 ? this.dev / (this.valid-1) : 0\",req:[\"mean\"],idx:1}),variancep:ai({name:\"variancep\",set:\"this.valid > 1 ? this.dev / this.valid : 0\",req:[\"variance\"],idx:2}),stdev:ai({name:\"stdev\",set:\"this.valid > 1 ? Math.sqrt(this.dev / (this.valid-1)) : 0\",req:[\"variance\"],idx:2}),stdevp:ai({name:\"stdevp\",set:\"this.valid > 1 ? Math.sqrt(this.dev / this.valid) : 0\",req:[\"variance\"],idx:2}),stderr:ai({name:\"stderr\",set:\"this.valid > 1 ? Math.sqrt(this.dev / (this.valid * (this.valid-1))) : 0\",req:[\"variance\"],idx:2}),distinct:ai({name:\"distinct\",set:\"cell.data.distinct(this.get)\",req:[\"values\"],idx:3}),ci0:ai({name:\"ci0\",set:\"cell.data.ci0(this.get)\",req:[\"values\"],idx:3}),ci1:ai({name:\"ci1\",set:\"cell.data.ci1(this.get)\",req:[\"values\"],idx:3}),median:ai({name:\"median\",set:\"cell.data.q2(this.get)\",req:[\"values\"],idx:3}),q1:ai({name:\"q1\",set:\"cell.data.q1(this.get)\",req:[\"values\"],idx:3}),q3:ai({name:\"q3\",set:\"cell.data.q3(this.get)\",req:[\"values\"],idx:3}),argmin:ai({name:\"argmin\",init:\"this.argmin = null;\",add:\"if (v < this.min) this.argmin = t;\",rem:\"if (v <= this.min) this.argmin = null;\",set:\"this.argmin || cell.data.argmin(this.get)\",req:[\"min\"],str:[\"values\"],idx:3}),argmax:ai({name:\"argmax\",init:\"this.argmax = null;\",add:\"if (v > this.max) this.argmax = t;\",rem:\"if (v >= this.max) this.argmax = null;\",set:\"this.argmax || cell.data.argmax(this.get)\",req:[\"max\"],str:[\"values\"],idx:3}),min:ai({name:\"min\",init:\"this.min = null;\",add:\"if (v < this.min || this.min === null) this.min = v;\",rem:\"if (v <= this.min) this.min = NaN;\",set:\"this.min = (isNaN(this.min) ? cell.data.min(this.get) : this.min)\",str:[\"values\"],idx:4}),max:ai({name:\"max\",init:\"this.max = null;\",add:\"if (v > this.max || this.max === null) this.max = v;\",rem:\"if (v >= this.max) this.max = NaN;\",set:\"this.max = (isNaN(this.max) ? cell.data.max(this.get) : this.max)\",str:[\"values\"],idx:4})},ri=Object.keys(ni);function ii(e,t){return ni[e](t)}function ai(e){return function(t){var n=Object(Ee.m)({init:\"\",add:\"\",rem:\"\",idx:0},e);return n.out=t||e.name,n}}function oi(e,t){return e.idx-t.idx}function si(e,t){var n=t||Ee.s,r=\"var cell = this.cell; this.valid = 0; this.missing = 0;\",i=\"this.cell = cell; this.init();\",a=\"if(v==null){++this.missing; return;} if(v!==v) return; ++this.valid;\",o=\"if(v==null){--this.missing; return;} if(v!==v) return; --this.valid;\",s=\"var cell = this.cell;\";return function(e,t){var n,r=e.reduce(function e(n,r){function i(t){n[t]||e(n,n[t]=ni[t]())}return r.req&&r.req.forEach(i),t&&r.str&&r.str.forEach(i),n},e.reduce(function(e,t){return e[t.name]=t,e},{})),i=[];for(n in r)i.push(r[n]);return i.sort(oi)}(e,!0).forEach(function(e){r+=e.init,a+=e.add,o+=e.rem}),e.slice().sort(oi).forEach(function(e){s+=\"t['\"+e.out+\"']=\"+e.set+\";\"}),s+=\"return t;\",(i=Function(\"cell\",i)).prototype.init=Function(r),i.prototype.add=Function(\"v\",\"t\",a),i.prototype.rem=Function(\"v\",\"t\",o),i.prototype.set=Function(\"t\",s),i.prototype.get=n,i.fields=e.map(function(e){return e.out}),i}var li=function(e,t){var n,r=[],i=e.length,a=-1;if(null==t)for(;++at?1:e>=t?0:NaN},fi=function(e){var t;return 1===e.length&&(t=e,e=function(e,n){return di(t(e),n)}),{left:function(t,n,r,i){for(null==r&&(r=0),null==i&&(i=t.length);r>>1;e(t[a],n)<0?r=a+1:i=a}return r},right:function(t,n,r,i){for(null==r&&(r=0),null==i&&(i=t.length);r>>1;e(t[a],n)>0?i=a:r=a+1}return r}}};var pi=fi(di),mi=pi.right,gi=pi.left,hi=mi;var bi=function(e){return null===e?NaN:+e},vi=function(e,t){var n,r,i=e.length,a=0,o=-1,s=0,l=0;if(null==t)for(;++o1)return l/(a-1)},_i=function(e,t){var n,r,i,a=e.length,o=-1;if(null==t){for(;++o=n)for(r=i=n;++on&&(r=n),i=n)for(r=i=n;++on&&(r=n),i0)return[e];if((r=t0)for(e=Math.ceil(e/o),t=Math.floor(t/o),a=new Array(i=Math.ceil(t-e+1));++s=0?(a>=Ei?10:a>=Si?5:a>=wi?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(a>=Ei?10:a>=Si?5:a>=wi?2:1)}function Mi(e,t,n){var r=Math.abs(t-e)/Math.max(0,n),i=Math.pow(10,Math.floor(Math.log(r)/Math.LN10)),a=r/i;return a>=Ei?i*=10:a>=Si?i*=5:a>=wi&&(i*=2),t=1)return+n(e[r-1],r-1,e);var r,i=(r-1)*t,a=Math.floor(i),o=+n(e[a],a,e);return o+(+n(e[a+1],a+1,e)-o)*(i-a)}},Di=function(e,t){var n,r,i=e.length,a=-1;if(null==t){for(;++a=n)for(r=n;++ar&&(r=n)}else for(;++a=n)for(r=n;++ar&&(r=n);return r},Ai=function(e){for(var t,n,r,i=e.length,a=-1,o=0;++a=0;)for(t=(r=e[i]).length;--t>=0;)n[--o]=r[t];return n},ki=function(e,t){var n,r,i=e.length,a=-1;if(null==t){for(;++a=n)for(r=n;++an&&(r=n)}else for(;++a=n)for(r=n;++an&&(r=n);return r},Ri=function(e,t){for(var n=t.length,r=new Array(n);n--;)r[n]=e[t[n]];return r};var Ii=function(e,t){var n=li(e,t);return[Ti(n.sort(di),.25),Ti(n,.5),Ti(n,.75)]},Li=function(e,t){var n,r,i=NaN,a={mean:function(e){return arguments.length?(n=e||0,i=NaN,a):n},stdev:function(e){return arguments.length?(r=null==e?1:e,i=NaN,a):r},sample:function(){var e,t,a=0,o=0;if(i==i)return a=i,i=NaN,a;do{e=(a=2*ui()-1)*a+(o=2*ui()-1)*o}while(0===e||e>1);return t=Math.sqrt(-2*Math.log(e)/e),i=n+o*t*r,n+a*t*r},pdf:function(e){var t=Math.exp(Math.pow(e-n,2)/(-2*Math.pow(r,2)));return 1/(r*Math.sqrt(2*Math.PI))*t},cdf:function(e){var t,i=(e-n)/r,a=Math.abs(i);if(a>37)t=0;else{var o=Math.exp(-a*a/2);a<7.07106781186547?(t=o*((((((.0352624965998911*a+.700383064443688)*a+6.37396220353165)*a+33.912866078383)*a+112.079291497871)*a+221.213596169931)*a+220.206867912376),t/=((((((.0883883476483184*a+1.75566716318264)*a+16.064177579207)*a+86.7807322029461)*a+296.564248779674)*a+637.333633378831)*a+793.826512519948)*a+440.413735824752):t=o/(a+1/(a+2/(a+3/(a+4/(a+.65)))))/2.506628274631}return i>0?1-t:t},icdf:function(e){if(e<=0||e>=1)return NaN;var t=2*e-1,i=8*(Math.PI-3)/(3*Math.PI*(4-Math.PI)),a=2/(Math.PI*i)+Math.log(1-Math.pow(t,2))/2,o=Math.log(1-t*t)/i,s=(t>0?1:-1)*Math.sqrt(Math.sqrt(a*a-o)-a);return n+r*Math.SQRT2*s}};return a.mean(e).stdev(t)};function Pi(e){this._key=e?Object(Ee.q)(e):Me,this.reset()}var Fi=Pi.prototype;function Bi(e){Yr.call(this,null,e),this._adds=[],this._mods=[],this._alen=0,this._mlen=0,this._drop=!0,this._cross=!1,this._dims=[],this._dnames=[],this._measures=[],this._countOnly=!1,this._counts=null,this._prev=null,this._inputs=null,this._outputs=null}Fi.reset=function(){this._add=[],this._rem=[],this._ext=null,this._get=null,this._q=null},Fi.add=function(e){this._add.push(e)},Fi.rem=function(e){this._rem.push(e)},Fi.values=function(){if(this._get=null,0===this._rem.length)return this._add;var e,t,n,r=this._add,i=this._rem,a=this._key,o=r.length,s=i.length,l=Array(o-s),c={};for(e=0;e=0;)t=e(n[r])+\"\",i.hasOwnProperty(t)||(i[t]=1,++a);return a},Fi.extent=function(e){if(this._get!==e||!this._ext){var t=this.values(),n=Object(Ee.n)(t,e);this._ext=[t[n[0]],t[n[1]]],this._get=e}return this._ext},Fi.argmin=function(e){return this.extent(e)[0]||{}},Fi.argmax=function(e){return this.extent(e)[1]||{}},Fi.min=function(e){var t=this.extent(e)[0];return null!=t?e(t):1/0},Fi.max=function(e){var t=this.extent(e)[1];return null!=t?e(t):-1/0},Fi.quartile=function(e){return this._get===e&&this._q||(this._q=Ii(this.values(),e),this._get=e),this._q},Fi.q1=function(e){return this.quartile(e)[0]},Fi.q2=function(e){return this.quartile(e)[1]},Fi.q3=function(e){return this.quartile(e)[2]},Fi.ci=function(e){return this._get===e&&this._ci||(this._ci=function(e,t,n,r){var i,a,o,s,l=li(e,r),c=l.length,u=t;for(o=0,s=Array(u);o1&&(r._drop=!1,this.cross()),r.changes(i)},Ui.cross=function(){var e=this,t=e.value,n=e._dnames,r=n.map(function(){return{}}),i=n.length;function a(e){var t,a,o,s;for(t in e)for(o=e[t].tuple,a=0;ac;)t*=u;for(o=0,s=f.length;o=r&&g/a<=c&&(t=a)}return i=(a=Math.log(t))>=0?0:1+~~(-a/d),l=Math.pow(u,-i-1),(e.nice||void 0===e.nice)&&(p=p<(a=Math.floor(p/t+l)*t)?a-t:a,m=Math.ceil(m/t)*t),{start:p,stop:m,step:t}}(e),a=i.start,o=i.stop,s=i.step;null!=(t=e.anchor)&&(n=t-(a+s*Math.floor((t-a)/s)),a+=n,o+=n);var l=function(e){var t=r(e);return null==t?null:(t=Math.max(a,Math.min(+t,o-s)),a+s*Math.floor((t-a)/s))};return l.start=a,l.stop=o,l.step=s,this.value=Object(Ee.e)(l,Object(Ee.f)(r),e.name||\"bin_\"+Object(Ee.g)(r))};var qi=function(e,t,n){var r=e,i=t||[],a=n||[],o={},s=0;return{add:function(e){a.push(e)},remove:function(e){o[r(e)]=++s},size:function(){return i.length},data:function(e,t){return s&&(i=i.filter(function(e){return!o[r(e)]}),o={},s=0),t&&e&&i.sort(e),a.length&&(i=e?Object(Ee.E)(e,i,a.sort(e)):i.concat(a),a=[]),i}}};function Gi(e){Yr.call(this,[],e)}function $i(e){je.call(this,null,Hi,e)}function Hi(e){return this.value&&!e.modified()?this.value:Object(Ee.i)(e.fields,e.orders)}function Wi(e){Yr.call(this,null,e)}Gi.Definition={type:\"Collect\",metadata:{source:!0},params:[{name:\"sort\",type:\"compare\"}]},Object(Ee.t)(Gi,Yr).transform=function(e,t){var n=t.fork(t.ALL),r=qi(Me,this.value,n.materialize(n.ADD).add),i=e.sort,a=t.changed()||i&&(e.modified(\"sort\")||t.modified(i.fields));return n.visit(n.REM,r.remove),this.modified(a),this.value=n.source=r.data(i,a),t.source&&t.source.root&&(this.value.root=t.source.root),n},Object(Ee.t)($i,je),Wi.Definition={type:\"CountPattern\",metadata:{generates:!0,changes:!0},params:[{name:\"field\",type:\"field\",required:!0},{name:\"case\",type:\"enum\",values:[\"upper\",\"lower\",\"mixed\"],default:\"mixed\"},{name:\"pattern\",type:\"string\",default:'[\\\\w\"]+'},{name:\"stopwords\",type:\"string\",default:\"\"},{name:\"as\",type:\"string\",array:!0,length:2,default:[\"text\",\"count\"]}]};var Vi=Object(Ee.t)(Wi,Yr);function Ki(e){Yr.call(this,null,e)}Vi.transform=function(e,t){function n(t){return function(n){for(var r,i=function(e,t,n){switch(t){case\"upper\":e=e.toUpperCase();break;case\"lower\":e=e.toLowerCase()}return e.match(n)}(s(n),e.case,a)||[],l=0,c=i.length;l=n&&e<=r?1/i:0},a.cdf=function(e){return er?1:(e-n)/i},a.icdf=function(e){return e>=0&&e<=1?n+e*i:NaN},a.min(e).max(t)}},Yi=\"distributions\",Zi=\"function\",Xi=\"field\";function Ji(e){Yr.call(this,null,e)}var ea=[{key:{function:\"normal\"},params:[{name:\"mean\",type:\"number\",default:0},{name:\"stdev\",type:\"number\",default:1}]},{key:{function:\"uniform\"},params:[{name:\"min\",type:\"number\",default:0},{name:\"max\",type:\"number\",default:1}]},{key:{function:\"kde\"},params:[{name:\"field\",type:\"field\",required:!0},{name:\"from\",type:\"data\"},{name:\"bandwidth\",type:\"number\",default:0}]}],ta={key:{function:\"mixture\"},params:[{name:\"distributions\",type:\"param\",array:!0,params:ea},{name:\"weights\",type:\"number\",array:!0}]};function na(e){Yr.call(this,[1/0,-1/0],e)}function ra(e,t){je.call(this,e),this.parent=t}Ji.Definition={type:\"Density\",metadata:{generates:!0},params:[{name:\"extent\",type:\"number\",array:!0,length:2},{name:\"steps\",type:\"number\",default:100},{name:\"method\",type:\"string\",default:\"pdf\",values:[\"pdf\",\"cdf\"]},{name:\"distribution\",type:\"param\",params:ea.concat(ta)},{name:\"as\",type:\"string\",array:!0,default:[\"value\",\"density\"]}]},Object(Ee.t)(Ji,Yr).transform=function(e,t){var n=t.fork(t.NO_SOURCE|t.NO_FIELDS);if(!this.value||t.changed()||e.modified()){var r=function e(t,n){var r=t[Zi];Qi.hasOwnProperty(r)||Object(Ee.l)(\"Unknown distribution function: \"+r);var i=Qi[r]();for(var a in t)a===Xi?i.data((t.from||n()).map(t[a])):a===Yi?i[a](t[a].map(function(t){return e(t,n)})):typeof i[a]===Zi&&i[a](t[a]);return i}(e.distribution,function(e){return function(){return e.materialize(e.SOURCE).source}}(t)),i=e.method||\"pdf\";\"pdf\"!==i&&\"cdf\"!==i&&Object(Ee.l)(\"Invalid density method: \"+i),e.extent||r.data||Object(Ee.l)(\"Missing density extent parameter.\"),i=r[i];var a=e.as||[\"value\",\"density\"],o=e.extent||_i(r.data()),s=(o[1]-o[0])/(e.steps||100),l=xi(o[0],o[1]+s/2,s).map(function(e){var t={};return t[a[0]]=e,t[a[1]]=i(e),Te(t)});this.value&&(n.rem=this.value),this.value=n.add=n.source=l}return n},na.Definition={type:\"Extent\",metadata:{},params:[{name:\"field\",type:\"field\",required:!0}]},Object(Ee.t)(na,Yr).transform=function(e,t){var n=this.value,r=e.field,i=n[0],a=n[1],o=t.ADD;(t.changed()||t.modified(r.fields)||e.modified(\"field\"))&&(o=t.SOURCE,i=1/0,a=-1/0),t.visit(o,function(e){var t=r(e);null!=t&&((t=+t)a&&(a=t))}),this.value=[i,a]};var ia=Object(Ee.t)(ra,je);function aa(e){Yr.call(this,{},e),this._keys=Object(Ee.p)();var t=this._targets=[];t.active=0,t.forEach=function(e){for(var n=0,r=t.active;nn.cleanThreshold&&n.runAfter(o.clean),t},Object(Ee.t)(sa,je),ca.Definition={type:\"Filter\",metadata:{changes:!0},params:[{name:\"expr\",type:\"expr\",required:!0}]},Object(Ee.t)(ca,Yr).transform=function(e,t){var n=t.dataflow,r=this.value,i=t.fork(),a=i.add,o=i.rem,s=i.mod,l=e.expr,c=!0;function u(t){var n=Me(t),i=l(t,e),u=r.get(n);i&&u?(r.delete(n),a.push(t)):i||u?c&&i&&!u&&s.push(t):(r.set(n,1),o.push(t))}return t.visit(t.REM,function(e){var t=Me(e);r.has(t)?r.delete(t):o.push(e)}),t.visit(t.ADD,function(t){l(t,e)?a.push(t):r.set(Me(t),1)}),t.visit(t.MOD,u),e.modified()&&(c=!1,t.visit(t.REFLOW,u)),r.empty>n.cleanThreshold&&n.runAfter(r.clean),i},da.Definition={type:\"Flatten\",metadata:{generates:!0},params:[{name:\"fields\",type:\"field\",array:!0,required:!0},{name:\"as\",type:\"string\",array:!0}]},Object(Ee.t)(da,Yr).transform=function(e,t){var n=t.fork(t.NO_SOURCE),r=e.fields,i=ua(r,e.as||[]),a=i.length;return n.rem=this.value,t.visit(t.SOURCE,function(e){for(var t,o,s,l=r.map(function(t){return t(e)}),c=l.reduce(function(e,t){return Math.max(e,t.length)},0),u=0;u0){for(n=[];--s>=0;)n.push(i=Te(l(e))),a.push(i);o.add=o.add.length?o.materialize(o.ADD).add.concat(n):n}else r=a.slice(0,-s),o.rem=o.rem.length?o.materialize(o.REM).rem.concat(r):r,a=a.slice(-s);return o.source=this.value=a,o};var ga={value:\"value\",median:function(e,t){var n,r=e.length,i=-1,a=[];if(null==t)for(;++ia&&(a=r[1]);return[i,a]}function Ca(e){je.call(this,null,Oa,e)}function Oa(e){return this.value&&!e.modified()?this.value:e.values.reduce(function(e,t){return e.concat(t)},[])}function Ma(e){Yr.call(this,null,e)}function Na(e){Bi.call(this,e)}_a.transform=function(e,t){var n,r=this,i=e.modified();return r.value&&(i||t.modified(r._inputs))?(n=r.value=i?r.init(e):{},t.visit(t.SOURCE,function(e){r.add(e)})):(n=r.value=r.value||this.init(e),t.visit(t.REM,function(e){r.rem(e)}),t.visit(t.ADD,function(e){r.add(e)})),r.changes(),t.visit(t.SOURCE,function(e){Object(Ee.m)(e,n[r.cellkey(e)].tuple)}),t.reflow(i).modifies(this._outputs)},_a.changes=function(){var e,t,n=this._adds,r=this._mods;for(e=0,t=this._alen;e1&&!a&&Object(Ee.l)('Multi-field lookup requires explicit \"as\" parameter.'),a&&a.length!==f*r&&Object(Ee.l)('The \"as\" parameter has too few output field names.'),a=a||l.map(Ee.g),n=function(e){for(var t,n,i=0,u=0;it||null==t)&&null!=e?1:(t=t instanceof Date?+t:t,(e=e instanceof Date?+e:e)!==e&&t==t?-1:t!=t&&e==e?1:0)}),t?i.slice(0,t):i}(n,e.limit||0,t);return{key:e.key,groupby:e.groupby,ops:o.map(function(){return i}),fields:o.map(function(e){return function(e,t,n,r){return Object(Ee.e)(function(r){return t(r)===e?n(r):NaN},r,e+\"\")}(e,n,r,a)}),as:o.map(function(e){return e+\"\"}),modified:e.modified.bind(e)}}(e,t),t)},Object(Ee.t)(Da,aa).transform=function(e,t){var n=this,r=e.subflow,i=e.field;return(e.modified(\"field\")||i&&t.modified(Object(Ee.f)(i)))&&Object(Ee.l)(\"PreFacet does not support field modification.\"),this._targets.active=0,t.visit(t.MOD,function(e){var a=n.subflow(Me(e),r,t,e);i?i(e).forEach(function(e){a.mod(e)}):a.mod(e)}),t.visit(t.ADD,function(e){var a=n.subflow(Me(e),r,t,e);i?i(e).forEach(function(e){a.add(Te(e))}):a.add(e)}),t.visit(t.REM,function(e){var a=n.subflow(Me(e),r,t,e);i?i(e).forEach(function(e){a.rem(e)}):a.rem(e)}),t},Aa.Definition={type:\"Project\",metadata:{generates:!0,changes:!0},params:[{name:\"fields\",type:\"field\",array:!0},{name:\"as\",type:\"string\",null:!0,array:!0}]},Object(Ee.t)(Aa,Yr).transform=function(e,t){var n,r,i=e.fields,a=ua(e.fields,e.as||[]),o=i?function(e,t){return function(e,t,n,r){for(var i=0,a=n.length;i=s&&(t=a[r],l[Me(t)]&&n.rem.push(t),a[r]=e),++o}if(t.rem.length&&(t.visit(t.REM,function(e){var t=Me(e);l[t]&&(l[t]=-1,n.rem.push(e)),--o}),a=a.filter(function(e){return-1!==l[Me(e)]})),(t.rem.length||r)&&a.lengthi){for(var u=0,d=a.length-i;un.cleanThreshold&&n.runAfter(i.clean),t.fork()},Object(Ee.t)(Ba,Yr).transform=function(e,t){(!this.value||e.modified(\"field\")||e.modified(\"sort\")||t.changed()||e.sort&&t.modified(e.sort.fields))&&(this.value=(e.sort?t.source.slice().sort(e.sort):t.source).map(e.field))};var Ua={row_number:function(){return{next:function(e){return e.index+1}}},rank:function(){var e;return{init:function(){e=1},next:function(t){var n=t.index,r=t.data;return n&&t.compare(r[n-1],r[n])?e=n+1:e}}},dense_rank:function(){var e;return{init:function(){e=1},next:function(t){var n=t.index,r=t.data;return n&&t.compare(r[n-1],r[n])?++e:e}}},percent_rank:function(){var e=Ua.rank(),t=e.next;return{init:e.init,next:function(e){return(t(e)-1)/(e.data.length-1)}}},cume_dist:function(){var e;return{init:function(){e=0},next:function(t){var n=t.index,r=t.data,i=t.compare;if(e0||Object(Ee.l)(\"ntile num must be greater than zero.\");var n=Ua.cume_dist(),r=n.next;return{init:n.init,next:function(e){return Math.ceil(t*r(e))}}},lag:function(e,t){return t=+t||1,{next:function(n){var r=n.index-t;return r>=0?e(n.data[r]):null}}},lead:function(e,t){return t=+t||1,{next:function(n){var r=n.index+t,i=n.data;return r0||Object(Ee.l)(\"nth_value nth must be greater than zero.\"),{next:function(n){var r=n.i0+(t-1);return r0&&!i(a[n],a[n-1])&&(e.i0=t.left(a,a[n])),rthis.x2&&(this.x2=e),t>this.y2&&(this.y2=t),this},Do.expand=function(e){return this.x1-=e,this.y1-=e,this.x2+=e,this.y2+=e,this},Do.round=function(){return this.x1=Math.floor(this.x1),this.y1=Math.floor(this.y1),this.x2=Math.ceil(this.x2),this.y2=Math.ceil(this.y2),this},Do.translate=function(e,t){return this.x1+=e,this.x2+=e,this.y1+=t,this.y2+=t,this},Do.rotate=function(e,t,n){var r=Math.cos(e),i=Math.sin(e),a=t-t*r+n*i,o=n-t*i-n*r,s=this.x1,l=this.x2,c=this.y1,u=this.y2;return this.clear().add(r*s-i*c+a,i*s+r*c+o).add(r*s-i*u+a,i*s+r*u+o).add(r*l-i*c+a,i*l+r*c+o).add(r*l-i*u+a,i*l+r*u+o)},Do.union=function(e){return e.x1this.x2&&(this.x2=e.x2),e.y2>this.y2&&(this.y2=e.y2),this},Do.intersect=function(e){return e.x1>this.x1&&(this.x1=e.x1),e.y1>this.y1&&(this.y1=e.y1),e.x2=e.x2&&this.y1<=e.y1&&this.y2>=e.y2},Do.alignsWith=function(e){return e&&(this.x1==e.x1||this.x2==e.x2||this.y1==e.y1||this.y2==e.y2)},Do.intersects=function(e){return e&&!(this.x2e.x2||this.y2e.y2)},Do.contains=function(e,t){return!(ethis.x2||tthis.y2)},Do.width=function(){return this.x2-this.x1},Do.height=function(){return this.y2-this.y1};var Ao=0,ko=function(e,t){var n,r=[];return n={id:\"gradient_\"+Ao++,x1:e?e[0]:0,y1:e?e[1]:0,x2:t?t[0]:1,y2:t?t[1]:0,stops:r,stop:function(e,t){return r.push({offset:e,color:t}),n}}};function Ro(e){this.mark=e,this.bounds=this.bounds||new To}function Io(e){Ro.call(this,e),this.items=this.items||[]}function Lo(e,t){if(\"undefined\"!=typeof document&&document.createElement){var n=document.createElement(\"canvas\");if(n&&n.getContext)return n.width=e,n.height=t,n}return null}function Po(){return\"undefined\"!=typeof Image?Image:null}function Fo(e){this._pending=0,this._loader=e||Qe()}Object(Ee.t)(Io,Ro);var Bo=Fo.prototype;function Uo(e){e._pending+=1}function jo(e){e._pending-=1}Bo.pending=function(){return this._pending},Bo.sanitizeURL=function(e){var t=this;return Uo(t),t._loader.sanitize(e,{context:\"href\"}).then(function(e){return jo(t),e}).catch(function(){return jo(t),null})},Bo.loadImage=function(e){var t=this,n=Po();return Uo(t),t._loader.sanitize(e,{context:\"image\"}).then(function(e){var r=e.href;if(!r||!n)throw{url:r};var i=new n;return i.onload=function(){jo(t),i.loaded=!0},i.onerror=function(){jo(t),i.loaded=!1},i.src=r,i}).catch(function(e){return jo(t),{loaded:!1,width:0,height:0,src:e&&e.url||\"\"}})},Bo.ready=function(){var e=this;return new Promise(function(t){!function n(r){e.pending()?setTimeout(function(){n(!0)},10):t(r)}(!1)})};var zo=Math.PI,qo=2*zo,Go=qo-1e-6;function $o(){this._x0=this._y0=this._x1=this._y1=null,this._=\"\"}function Ho(){return new $o}$o.prototype=Ho.prototype={constructor:$o,moveTo:function(e,t){this._+=\"M\"+(this._x0=this._x1=+e)+\",\"+(this._y0=this._y1=+t)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+=\"Z\")},lineTo:function(e,t){this._+=\"L\"+(this._x1=+e)+\",\"+(this._y1=+t)},quadraticCurveTo:function(e,t,n,r){this._+=\"Q\"+ +e+\",\"+ +t+\",\"+(this._x1=+n)+\",\"+(this._y1=+r)},bezierCurveTo:function(e,t,n,r,i,a){this._+=\"C\"+ +e+\",\"+ +t+\",\"+ +n+\",\"+ +r+\",\"+(this._x1=+i)+\",\"+(this._y1=+a)},arcTo:function(e,t,n,r,i){e=+e,t=+t,n=+n,r=+r,i=+i;var a=this._x1,o=this._y1,s=n-e,l=r-t,c=a-e,u=o-t,d=c*c+u*u;if(i<0)throw new Error(\"negative radius: \"+i);if(null===this._x1)this._+=\"M\"+(this._x1=e)+\",\"+(this._y1=t);else if(d>1e-6)if(Math.abs(u*s-l*c)>1e-6&&i){var f=n-a,p=r-o,m=s*s+l*l,g=f*f+p*p,h=Math.sqrt(m),b=Math.sqrt(d),v=i*Math.tan((zo-Math.acos((m+d-g)/(2*h*b)))/2),_=v/b,y=v/h;Math.abs(_-1)>1e-6&&(this._+=\"L\"+(e+_*c)+\",\"+(t+_*u)),this._+=\"A\"+i+\",\"+i+\",0,0,\"+ +(u*f>c*p)+\",\"+(this._x1=e+y*s)+\",\"+(this._y1=t+y*l)}else this._+=\"L\"+(this._x1=e)+\",\"+(this._y1=t);else;},arc:function(e,t,n,r,i,a){e=+e,t=+t;var o=(n=+n)*Math.cos(r),s=n*Math.sin(r),l=e+o,c=t+s,u=1^a,d=a?r-i:i-r;if(n<0)throw new Error(\"negative radius: \"+n);null===this._x1?this._+=\"M\"+l+\",\"+c:(Math.abs(this._x1-l)>1e-6||Math.abs(this._y1-c)>1e-6)&&(this._+=\"L\"+l+\",\"+c),n&&(d<0&&(d=d%qo+qo),d>Go?this._+=\"A\"+n+\",\"+n+\",0,1,\"+u+\",\"+(e-o)+\",\"+(t-s)+\"A\"+n+\",\"+n+\",0,1,\"+u+\",\"+(this._x1=l)+\",\"+(this._y1=c):d>1e-6&&(this._+=\"A\"+n+\",\"+n+\",0,\"+ +(d>=zo)+\",\"+u+\",\"+(this._x1=e+n*Math.cos(i))+\",\"+(this._y1=t+n*Math.sin(i))))},rect:function(e,t,n,r){this._+=\"M\"+(this._x0=this._x1=+e)+\",\"+(this._y0=this._y1=+t)+\"h\"+ +n+\"v\"+ +r+\"h\"+-n+\"Z\"},toString:function(){return this._}};var Wo=Ho,Vo=function(e){return function(){return e}},Ko=Math.abs,Qo=Math.atan2,Yo=Math.cos,Zo=Math.max,Xo=Math.min,Jo=Math.sin,es=Math.sqrt,ts=1e-12,ns=Math.PI,rs=ns/2,is=2*ns;function as(e){return e>=1?rs:e<=-1?-rs:Math.asin(e)}function os(e){return e.innerRadius}function ss(e){return e.outerRadius}function ls(e){return e.startAngle}function cs(e){return e.endAngle}function us(e){return e&&e.padAngle}function ds(e,t,n,r,i,a,o){var s=e-n,l=t-r,c=(o?a:-a)/es(s*s+l*l),u=c*l,d=-c*s,f=e+u,p=t+d,m=n+u,g=r+d,h=(f+m)/2,b=(p+g)/2,v=m-f,_=g-p,y=v*v+_*_,x=i-a,E=f*g-m*p,S=(_<0?-1:1)*es(Zo(0,x*x*y-E*E)),w=(E*_-v*S)/y,C=(-E*v-_*S)/y,O=(E*_+v*S)/y,M=(-E*v+_*S)/y,N=w-h,T=C-b,D=O-h,A=M-b;return N*N+T*T>D*D+A*A&&(w=O,C=M),{cx:w,cy:C,x01:-u,y01:-d,x11:w*(i/x-1),y11:C*(i/x-1)}}function fs(e){this._context=e}fs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:this._context.lineTo(e,t)}}};var ps=function(e){return new fs(e)};function ms(e){return e[0]}function gs(e){return e[1]}var hs=function(){var e=ms,t=gs,n=Vo(!0),r=null,i=ps,a=null;function o(o){var s,l,c,u=o.length,d=!1;for(null==r&&(a=i(c=Wo())),s=0;s<=u;++s)!(s=u;--d)s.point(h[d],b[d]);s.lineEnd(),s.areaEnd()}g&&(h[c]=+e(f,c,l),b[c]=+n(f,c,l),s.point(t?+t(f,c,l):h[c],r?+r(f,c,l):b[c]))}if(p)return s=null,p+\"\"||null}function c(){return hs().defined(i).curve(o).context(a)}return l.x=function(n){return arguments.length?(e=\"function\"==typeof n?n:Vo(+n),t=null,l):e},l.x0=function(t){return arguments.length?(e=\"function\"==typeof t?t:Vo(+t),l):e},l.x1=function(e){return arguments.length?(t=null==e?null:\"function\"==typeof e?e:Vo(+e),l):t},l.y=function(e){return arguments.length?(n=\"function\"==typeof e?e:Vo(+e),r=null,l):n},l.y0=function(e){return arguments.length?(n=\"function\"==typeof e?e:Vo(+e),l):n},l.y1=function(e){return arguments.length?(r=null==e?null:\"function\"==typeof e?e:Vo(+e),l):r},l.lineX0=l.lineY0=function(){return c().x(e).y(n)},l.lineY1=function(){return c().x(e).y(r)},l.lineX1=function(){return c().x(t).y(n)},l.defined=function(e){return arguments.length?(i=\"function\"==typeof e?e:Vo(!!e),l):i},l.curve=function(e){return arguments.length?(o=e,null!=a&&(s=o(a)),l):o},l.context=function(e){return arguments.length?(null==e?a=s=null:s=o(a=e),l):a},l};_s(ps);function vs(e){this._curve=e}function _s(e){function t(t){return new vs(e(t))}return t._curve=e,t}vs.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(e,t){this._curve.point(t*Math.sin(e),t*-Math.cos(e))}};Array.prototype.slice;var ys={draw:function(e,t){var n=Math.sqrt(t/ns);e.moveTo(n,0),e.arc(0,0,n,0,is)}},xs=(Math.sqrt(1/3),Math.sin(ns/10)/Math.sin(7*ns/10)),Es=(Math.sin(is/10),Math.cos(is/10),Math.sqrt(3),Math.sqrt(3),Math.sqrt(12),function(){});function Ss(e,t,n){e._context.bezierCurveTo((2*e._x0+e._x1)/3,(2*e._y0+e._y1)/3,(e._x0+2*e._x1)/3,(e._y0+2*e._y1)/3,(e._x0+4*e._x1+t)/6,(e._y0+4*e._y1+n)/6)}function ws(e){this._context=e}ws.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Ss(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Ss(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function Cs(e){this._context=e}Cs.prototype={areaStart:Es,areaEnd:Es,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x2=e,this._y2=t;break;case 1:this._point=2,this._x3=e,this._y3=t;break;case 2:this._point=3,this._x4=e,this._y4=t,this._context.moveTo((this._x0+4*this._x1+e)/6,(this._y0+4*this._y1+t)/6);break;default:Ss(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function Os(e){this._context=e}Os.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+e)/6,r=(this._y0+4*this._y1+t)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:Ss(this,e,t)}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function Ms(e,t){this._basis=new ws(e),this._beta=t}Ms.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var e=this._x,t=this._y,n=e.length-1;if(n>0)for(var r,i=e[0],a=t[0],o=e[n]-i,s=t[n]-a,l=-1;++l<=n;)r=l/n,this._basis.point(this._beta*e[l]+(1-this._beta)*(i+r*o),this._beta*t[l]+(1-this._beta)*(a+r*s));this._x=this._y=null,this._basis.lineEnd()},point:function(e,t){this._x.push(+e),this._y.push(+t)}};var Ns=function e(t){function n(e){return 1===t?new ws(e):new Ms(e,t)}return n.beta=function(t){return e(+t)},n}(.85);function Ts(e,t,n){e._context.bezierCurveTo(e._x1+e._k*(e._x2-e._x0),e._y1+e._k*(e._y2-e._y0),e._x2+e._k*(e._x1-t),e._y2+e._k*(e._y1-n),e._x2,e._y2)}function Ds(e,t){this._context=e,this._k=(1-t)/6}Ds.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Ts(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2,this._x1=e,this._y1=t;break;case 2:this._point=3;default:Ts(this,e,t)}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var As=function e(t){function n(e){return new Ds(e,t)}return n.tension=function(t){return e(+t)},n}(0);function ks(e,t){this._context=e,this._k=(1-t)/6}ks.prototype={areaStart:Es,areaEnd:Es,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x3=e,this._y3=t;break;case 1:this._point=2,this._context.moveTo(this._x4=e,this._y4=t);break;case 2:this._point=3,this._x5=e,this._y5=t;break;default:Ts(this,e,t)}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var Rs=function e(t){function n(e){return new ks(e,t)}return n.tension=function(t){return e(+t)},n}(0);function Is(e,t){this._context=e,this._k=(1-t)/6}Is.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ts(this,e,t)}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var Ls=function e(t){function n(e){return new Is(e,t)}return n.tension=function(t){return e(+t)},n}(0);function Ps(e,t,n){var r=e._x1,i=e._y1,a=e._x2,o=e._y2;if(e._l01_a>ts){var s=2*e._l01_2a+3*e._l01_a*e._l12_a+e._l12_2a,l=3*e._l01_a*(e._l01_a+e._l12_a);r=(r*s-e._x0*e._l12_2a+e._x2*e._l01_2a)/l,i=(i*s-e._y0*e._l12_2a+e._y2*e._l01_2a)/l}if(e._l23_a>ts){var c=2*e._l23_2a+3*e._l23_a*e._l12_a+e._l12_2a,u=3*e._l23_a*(e._l23_a+e._l12_a);a=(a*c+e._x1*e._l23_2a-t*e._l12_2a)/u,o=(o*c+e._y1*e._l23_2a-n*e._l12_2a)/u}e._context.bezierCurveTo(r,i,a,o,e._x2,e._y2)}function Fs(e,t){this._context=e,this._alpha=t}Fs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3;default:Ps(this,e,t)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var Bs=function e(t){function n(e){return t?new Fs(e,t):new Ds(e,0)}return n.alpha=function(t){return e(+t)},n}(.5);function Us(e,t){this._context=e,this._alpha=t}Us.prototype={areaStart:Es,areaEnd:Es,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=e,this._y3=t;break;case 1:this._point=2,this._context.moveTo(this._x4=e,this._y4=t);break;case 2:this._point=3,this._x5=e,this._y5=t;break;default:Ps(this,e,t)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var js=function e(t){function n(e){return t?new Us(e,t):new ks(e,0)}return n.alpha=function(t){return e(+t)},n}(.5);function zs(e,t){this._context=e,this._alpha=t}zs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ps(this,e,t)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};var qs=function e(t){function n(e){return t?new zs(e,t):new Is(e,0)}return n.alpha=function(t){return e(+t)},n}(.5);function Gs(e){this._context=e}Gs.prototype={areaStart:Es,areaEnd:Es,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(e,t){e=+e,t=+t,this._point?this._context.lineTo(e,t):(this._point=1,this._context.moveTo(e,t))}};function $s(e){return e<0?-1:1}function Hs(e,t,n){var r=e._x1-e._x0,i=t-e._x1,a=(e._y1-e._y0)/(r||i<0&&-0),o=(n-e._y1)/(i||r<0&&-0),s=(a*i+o*r)/(r+i);return($s(a)+$s(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(s))||0}function Ws(e,t){var n=e._x1-e._x0;return n?(3*(e._y1-e._y0)/n-t)/2:t}function Vs(e,t,n){var r=e._x0,i=e._y0,a=e._x1,o=e._y1,s=(a-r)/3;e._context.bezierCurveTo(r+s,i+s*t,a-s,o-s*n,a,o)}function Ks(e){this._context=e}function Qs(e){this._context=new Ys(e)}function Ys(e){this._context=e}function Zs(e){this._context=e}function Xs(e){var t,n,r=e.length-1,i=new Array(r),a=new Array(r),o=new Array(r);for(i[0]=0,a[0]=2,o[0]=e[0]+2*e[1],t=1;t=0;--t)i[t]=(o[t]-i[t+1])/a[t];for(a[r-1]=(e[r]+i[r-1])/2,t=0;t=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,t),this._context.lineTo(e,t);else{var n=this._x*(1-this._t)+e*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,t)}}this._x=e,this._y=t}};var el={basis:{curve:function(e){return new ws(e)}},\"basis-closed\":{curve:function(e){return new Cs(e)}},\"basis-open\":{curve:function(e){return new Os(e)}},bundle:{curve:Ns,tension:\"beta\",value:.85},cardinal:{curve:As,tension:\"tension\",value:0},\"cardinal-open\":{curve:Ls,tension:\"tension\",value:0},\"cardinal-closed\":{curve:Rs,tension:\"tension\",value:0},\"catmull-rom\":{curve:Bs,tension:\"alpha\",value:.5},\"catmull-rom-closed\":{curve:js,tension:\"alpha\",value:.5},\"catmull-rom-open\":{curve:qs,tension:\"alpha\",value:.5},linear:{curve:ps},\"linear-closed\":{curve:function(e){return new Gs(e)}},monotone:{horizontal:function(e){return new Qs(e)},vertical:function(e){return new Ks(e)}},natural:{curve:function(e){return new Zs(e)}},step:{curve:function(e){return new Js(e,.5)}},\"step-after\":{curve:function(e){return new Js(e,1)}},\"step-before\":{curve:function(e){return new Js(e,0)}}};function tl(e,t,n){var r=el.hasOwnProperty(e)&&el[e],i=null;return r&&(i=r.curve||r[t||\"vertical\"],r.tension&&null!=n&&(i=i[r.tension](n))),i}var nl={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7},rl=[/([MLHVCSQTAZmlhvcsqtaz])/g,/###/,/(\\d)([-+])/g,/\\s|,|###/],il=function(e){var t,n,r,i,a,o,s,l,c,u,d,f=[];for(l=0,u=(t=e.slice().replace(rl[0],\"###$1\").split(rl[1]).slice(1)).length;ls)for(c=1,d=i.length;c1&&(n*=g=Math.sqrt(g),r*=g);var h=f/n,b=d/n,v=-d/r,_=f/r,y=h*s+b*l,x=v*s+_*l,E=h*e+b*t,S=v*e+_*t,w=1/((E-y)*(E-y)+(S-x)*(S-x))-.25;w<0&&(w=0);var C=Math.sqrt(w);a==i&&(C=-C);var O=.5*(y+E)-C*(S-x),M=.5*(x+S)+C*(E-y),N=Math.atan2(x-M,y-O),T=Math.atan2(S-M,E-O)-N;T<0&&1===a?T+=2*Math.PI:T>0&&0===a&&(T-=2*Math.PI);for(var D=Math.ceil(Math.abs(T/(.5*Math.PI+.001))),A=[],k=0;kp;if(s||(s=l=Wo()),fts)if(g>is-ts)s.moveTo(f*Yo(p),f*Jo(p)),s.arc(0,0,f,p,m,!h),d>ts&&(s.moveTo(d*Yo(m),d*Jo(m)),s.arc(0,0,d,m,p,h));else{var b,v,_=p,y=m,x=p,E=m,S=g,w=g,C=o.apply(this,arguments)/2,O=C>ts&&(r?+r.apply(this,arguments):es(d*d+f*f)),M=Xo(Ko(f-d)/2,+n.apply(this,arguments)),N=M,T=M;if(O>ts){var D=as(O/d*Jo(C)),A=as(O/f*Jo(C));(S-=2*D)>ts?(x+=D*=h?1:-1,E-=D):(S=0,x=E=(p+m)/2),(w-=2*A)>ts?(_+=A*=h?1:-1,y-=A):(w=0,_=y=(p+m)/2)}var k=f*Yo(_),R=f*Jo(_),I=d*Yo(E),L=d*Jo(E);if(M>ts){var P=f*Yo(y),F=f*Jo(y),B=d*Yo(x),U=d*Jo(x);if(gts?function(e,t,n,r,i,a,o,s){var l=n-e,c=r-t,u=o-i,d=s-a,f=(u*(t-a)-d*(e-i))/(d*l-u*c);return[e+f*l,t+f*c]}(k,R,B,U,P,F,I,L):[I,L],z=k-j[0],q=R-j[1],G=P-j[0],$=F-j[1],H=1/Jo(((u=(z*G+q*$)/(es(z*z+q*q)*es(G*G+$*$)))>1?0:u<-1?ns:Math.acos(u))/2),W=es(j[0]*j[0]+j[1]*j[1]);N=Xo(M,(d-W)/(H-1)),T=Xo(M,(f-W)/(H+1))}}w>ts?T>ts?(b=ds(B,U,k,R,f,T,h),v=ds(P,F,I,L,f,T,h),s.moveTo(b.cx+b.x01,b.cy+b.y01),Tts&&S>ts?N>ts?(b=ds(I,L,P,F,d,-N,h),v=ds(k,R,B,U,d,-N,h),s.lineTo(b.cx+b.x01,b.cy+b.y01),Njl)return Gl(e-n,t-n),void Gl(e+n,t+n);var o,s,l,c,u=1/0,d=-1/0,f=1/0,p=-1/0;function m(e){l=n*Math.cos(e),c=n*Math.sin(e),ld&&(d=l),cp&&(p=c)}if(m(r),m(i),i!==r)if((r%=Bl)<0&&(r+=Bl),(i%=Bl)<0&&(i+=Bl),ii;++s,o-=Ul)m(o);else for(o=r-r%Ul+Ul,s=0;s<4&&o0&&(e.globalAlpha=n,e.fillStyle=$l(e,t,t.fill),!0)},Wl=[],Vl=function(e,t,n){var r=null!=(r=t.strokeWidth)?r:1;return!(r<=0)&&((n*=null==t.strokeOpacity?1:t.strokeOpacity)>0&&(e.globalAlpha=n,e.strokeStyle=$l(e,t,t.stroke),e.lineWidth=r,e.lineCap=t.strokeCap||\"butt\",e.lineJoin=t.strokeJoin||\"miter\",e.miterLimit=t.strokeMiterLimit||10,e.setLineDash&&(e.setLineDash(t.strokeDash||Wl),e.lineDashOffset=t.strokeDashOffset||0),!0))};function Kl(e,t){return e.zindex-t.zindex||e.index-t.index}function Ql(e){if(!e.zdirty)return e.zitems;var t,n,r,i=e.items,a=[];for(n=0,r=i.length;n=0;)if(n=t(i[r]))return n;if(i===a)for(r=(i=e.items).length;--r>=0;)if(!i[r].zindex&&(n=t(i[r])))return n;return null}function Xl(e){return function(t,n,r){Yl(n,function(n){r&&!r.intersects(n.bounds)||Jl(e,t,n,n)})}}function Jl(e,t,n,r){var i=null==n.opacity?1:n.opacity;0!==i&&(e(t,r)||(n.fill&&Hl(t,n,i)&&t.fill(),n.stroke&&Vl(t,n,i)&&t.stroke()))}var ec=function(){return!0};function tc(e){return e||(e=ec),function(t,n,r,i,a,o){return r*=t.pixelRatio,i*=t.pixelRatio,Zl(n,function(n){var s=n.bounds;if((!s||s.contains(a,o))&&s)return e(t,n,r,i,a,o)?n:void 0})}}function nc(e,t){return function(n,r,i,a){var o,s,l=Array.isArray(r)?r[0]:r,c=null==t?l.fill:t,u=l.stroke&&n.isPointInStroke;return u&&(o=l.strokeWidth,s=l.strokeCap,n.lineWidth=null!=o?o:1,n.lineCap=null!=s?s:\"butt\"),!e(n,r)&&(c&&n.isPointInPath(i,a)||u&&n.isPointInStroke(i,a))}}function rc(e){return tc(nc(e))}var ic=function(e,t){return\"translate(\"+e+\",\"+t+\")\"},ac=function(e){return ic(e.x||0,e.y||0)},oc=function(e,t){function n(e,n){var r=n.x||0,i=n.y||0;e.translate(r,i),e.beginPath(),t(e,n),e.translate(-r,-i)}return{type:e,tag:\"path\",nested:!1,attr:function(e,n){e(\"transform\",ac(n)),e(\"d\",t(null,n))},bound:function(e,n){return t(zl(e),n),Fl(e,n).translate(n.x||0,n.y||0)},draw:Xl(n),pick:rc(n)}},sc=oc(\"arc\",function(e,t){return Nl.context(e)(t)});var lc=function(e,t,n){function r(e,n){e.beginPath(),t(e,n)}var i,a=nc(r);return{type:e,tag:\"path\",nested:!0,attr:function(e,n){var r=n.mark.items;r.length&&e(\"d\",t(null,r))},bound:function(e,n){var r=n.items;return 0===r.length?e:(t(zl(e),r),Fl(e,r[0]))},draw:(i=r,function(e,t,n){!t.items.length||n&&!n.intersects(t.bounds)||Jl(i,e,t.items[0],t.items)}),pick:function(e,t,n,r,i,o){var s=t.items,l=t.bounds;return!s||!s.length||l&&!l.contains(i,o)?null:(n*=e.pixelRatio,r*=e.pixelRatio,a(e,s,n,r)?s[0]:null)},tip:n}},cc=lc(\"area\",function(e,t){var n=t[0],r=n.interpolate||\"linear\";return(\"horizontal\"===n.orient?Dl:Tl).curve(tl(r,n.orient,n.tension)).context(e)(t)},function(e,t){var n=\"horizontal\"===e[0].orient?t[1]:t[0],r=\"horizontal\"===e[0].orient?\"y\":\"x\",i=0,a=e.length;if(1===a)return e[0];for(;i>>1;e[o][r]0&&(pc(e,t),t.fill&&Hl(e,t,i)&&e.fill(),t.stroke&&Vl(e,t,i)&&e.stroke()),t.clip&&(e.beginPath(),e.rect(0,0,s,l),e.clip()),n&&n.translate(-a,-o),Yl(t,function(t){r.draw(e,t,n)}),n&&n.translate(a,o),e.restore()})},pick:function(e,t,n,r,i,a){if(t.bounds&&!t.bounds.contains(i,a)||!t.items)return null;var o=this,s=n*e.pixelRatio,l=r*e.pixelRatio;return Zl(t,function(c){var u,d,f,p;if(!(p=c.bounds)||p.contains(i,a))return d=c.x||0,f=c.y||0,e.save(),e.translate(d,f),d=i-d,f=a-f,!(u=Zl(c,function(e){return function(e,t,n){return(!1!==e.interactive||\"group\"===e.marktype)&&e.bounds&&e.bounds.contains(t,n)}(e,d,f)?o.pick(e,n,r,d,f):null}))&&!1!==t.interactive&&(c.fill||c.stroke)&&mc(e,c,s,l)&&(u=c),e.restore(),u||null})},background:function(e,t){var n=t.stroke?fc:0;e(\"class\",\"background\"),e(\"d\",Ll(null,t,n,n))},foreground:function(e,t,n){e(\"clip-path\",t.clip?dc(n,t,t):null)}};function hc(e,t){var n=e.image;return n&&n.url===e.url||(n={loaded:!1,width:0,height:0},t.loadImage(e.url).then(function(t){e.image=t,e.image.url=e.url})),n}function bc(e,t){return\"center\"===e?t/2:\"right\"===e?t:0}function vc(e,t){return\"middle\"===e?t/2:\"bottom\"===e?t:0}var _c={type:\"image\",tag:\"image\",nested:!1,attr:function(e,t,n){var r=hc(t,n),i=t.x||0,a=t.y||0,o=(null!=t.width?t.width:r.width)||0,s=(null!=t.height?t.height:r.height)||0,l=!1===t.aspect?\"none\":\"xMidYMid\";i-=bc(t.align,o),a-=vc(t.baseline,s),e(\"href\",r.src||\"\",\"http://www.w3.org/1999/xlink\",\"xlink:href\"),e(\"transform\",ic(i,a)),e(\"width\",o),e(\"height\",s),e(\"preserveAspectRatio\",l)},bound:function(e,t){var n=t.image,r=t.x||0,i=t.y||0,a=(null!=t.width?t.width:n&&n.width)||0,o=(null!=t.height?t.height:n&&n.height)||0;return r-=bc(t.align,a),i-=vc(t.baseline,o),e.set(r,i,r+a,i+o)},draw:function(e,t,n){var r=this;Yl(t,function(t){if(!n||n.intersects(t.bounds)){var i,a,o,s,l=hc(t,r),c=t.x||0,u=t.y||0,d=(null!=t.width?t.width:l.width)||0,f=(null!=t.height?t.height:l.height)||0;c-=bc(t.align,d),u-=vc(t.baseline,f),!1!==t.aspect&&(a=l.width/l.height,o=t.width/t.height,a==a&&o==o&&a!==o&&(o=0;)if(!1!==e[a].defined&&(n=e[a].x-t[0])*n+(r=e[a].y-t[1])*r0?function(e){var t,n=+e.limit,r=e.text+\"\";Oc?(Oc.font=jc(e),t=Lc):(Mc=Pc(e),t=Rc);if(t(r)>>1,t(r.slice(i))>n?s=i+1:l=i;return a+r.slice(s)}for(;s>>1),t(r.slice(0,i))=0;)if(!1!==e[i].defined&&(n=e[i].x-t[0])*n+(r=e[i].y-t[1])*r<(n=e[i].size||1)*n)return e[i];return null})},Wc=function(e,t,n){var r=Hc[e.mark.marktype],i=t||r.bound;return r.nested&&(e=e.mark),i(e.bounds||(e.bounds=new To),e,n)},Vc={mark:null},Kc=function(e,t,n){var r,i,a,o,s=Hc[e.marktype],l=s.bound,c=e.items,u=c&&c.length;if(s.nested)return u?a=c[0]:(Vc.mark=e,a=Vc),o=Wc(a,l,n),t=t&&t.union(o)||o;if(t=t||e.bounds&&e.bounds.clear()||new To,u)for(r=0,i=c.length;rt;)e.removeChild(n[--r]);return e}function iu(e){return\"mark-\"+e.marktype+(e.role?\" role-\"+e.role:\"\")+(e.name?\" \"+e.name:\"\")}Xc.toJSON=function(e){return function(e,t){return JSON.stringify(e,Qc,t)}(this.root,e||0)},Xc.mark=function(e,t,n){var r=Jc(e,t=t||this.root.items[0]);return t.items[n]=r,r.zindex&&(r.group.zdirty=!0),r};var au=function(e,t){var n=t.getBoundingClientRect();return[e.clientX-n.left-(t.clientLeft||0),e.clientY-n.top-(t.clientTop||0)]};function ou(e,t){this._active=null,this._handlers={},this._loader=e||Qe(),this._tooltip=t||su}function su(e,t,n,r){e.element().setAttribute(\"title\",r||\"\")}var lu=ou.prototype;function cu(e){this._el=null,this._bgcolor=null,this._loader=new Fo(e)}lu.initialize=function(e,t,n){return this._el=e,this._obj=n||null,this.origin(t)},lu.element=function(){return this._el},lu.canvas=function(){return this._el&&this._el.firstChild},lu.origin=function(e){return arguments.length?(this._origin=e||[0,0],this):this._origin.slice()},lu.scene=function(e){return arguments.length?(this._scene=e,this):this._scene},lu.on=function(){},lu.off=function(){},lu._handlerIndex=function(e,t,n){for(var r=e?e.length:0;--r>=0;)if(e[r].type===t&&(!n||e[r].handler===n))return r;return-1},lu.handlers=function(e){var t,n=this._handlers,r=[];if(e)r.push.apply(r,n[this.eventName(e)]);else for(t in n)r.push.apply(r,n[t]);return r},lu.eventName=function(e){var t=e.indexOf(\".\");return t<0?e:e.slice(0,t)},lu.handleHref=function(e,t,n){this._loader.sanitize(n,{context:\"href\"}).then(function(t){var n=new MouseEvent(e.type,e),r=eu(null,\"a\");for(var i in t)r.setAttribute(i,t[i]);r.dispatchEvent(n)}).catch(function(){})},lu.handleTooltip=function(e,t,n){if(t&&null!=t.tooltip){t=function(e,t,n,r){var i,a,o=e&&e.mark;if(o&&(i=Hc[o.marktype]).tip){for((a=au(t,n))[0]-=r[0],a[1]-=r[1];e=e.mark.group;)a[0]-=e.x||0,a[1]-=e.y||0;e=i.tip(o.items,a)}return e}(t,e,this.canvas(),this._origin);var r=n&&t&&t.tooltip||null;this._tooltip.call(this._obj,this,e,t,r)}},lu.getItemBoundingClientRect=function(e){if(t=this.canvas()){for(var t,n=t.getBoundingClientRect(),r=this._origin,i=e.bounds,a=i.x1+r[0]+n.left,o=i.y1+r[1]+n.top,s=i.width(),l=i.height();e.mark&&(e=e.mark.group);)a+=e.x||0,o+=e.y||0;return{x:a,y:o,width:s,height:l,left:a,top:o,right:a+s,bottom:o+l}}};var uu=cu.prototype;uu.initialize=function(e,t,n,r,i){return this._el=e,this.resize(t,n,r,i)},uu.element=function(){return this._el},uu.canvas=function(){return this._el&&this._el.firstChild},uu.background=function(e){return 0===arguments.length?this._bgcolor:(this._bgcolor=e,this)},uu.resize=function(e,t,n,r){return this._width=e,this._height=t,this._origin=n||[0,0],this._scale=r||1,this},uu.dirty=function(){},uu.render=function(e){var t=this;return t._call=function(){t._render(e)},t._call(),t._call=null,t},uu._render=function(){},uu.renderAsync=function(e){var t=this.render(e);return this._ready?this._ready.then(function(){return t}):Promise.resolve(t)},uu._load=function(e,t){var n=this,r=n._loader[e](t);if(!n._ready){var i=n._call;n._ready=n._loader.ready().then(function(e){e&&i(),n._ready=null})}return r},uu.sanitizeURL=function(e){return this._load(\"sanitizeURL\",e)},uu.loadImage=function(e){return this._load(\"loadImage\",e)};var du=\"mouseout\";function fu(e,t){ou.call(this,e,t),this._down=null,this._touch=null,this._first=!0}var pu=Object(Ee.t)(fu,ou);function mu(e,t,n){return function(r){var i=this._active,a=this.pickEvent(r);a===i?this.fire(e,r):(i&&i.exit||this.fire(n,r),this._active=a,this.fire(t,r),this.fire(e,r))}}function gu(e){return function(t){this.fire(e,t),this._active=null}}pu.initialize=function(e,t,n){var r=this._canvas=e&&tu(e,\"canvas\");if(r){var i=this;this.events.forEach(function(e){r.addEventListener(e,function(t){pu[e]?pu[e].call(i,t):i.fire(e,t)})})}return ou.prototype.initialize.call(this,e,t,n)},pu.canvas=function(){return this._canvas},pu.context=function(){return this._canvas.getContext(\"2d\")},pu.events=[\"keydown\",\"keypress\",\"keyup\",\"dragenter\",\"dragleave\",\"dragover\",\"mousedown\",\"mouseup\",\"mousemove\",\"mouseout\",\"mouseover\",\"click\",\"dblclick\",\"wheel\",\"mousewheel\",\"touchstart\",\"touchmove\",\"touchend\"],pu.DOMMouseScroll=function(e){this.fire(\"mousewheel\",e)},pu.mousemove=mu(\"mousemove\",\"mouseover\",\"mouseout\"),pu.dragover=mu(\"dragover\",\"dragenter\",\"dragleave\"),pu.mouseout=gu(\"mouseout\"),pu.dragleave=gu(\"dragleave\"),pu.mousedown=function(e){this._down=this._active,this.fire(\"mousedown\",e)},pu.click=function(e){this._down===this._active&&(this.fire(\"click\",e),this._down=null)},pu.touchstart=function(e){this._touch=this.pickEvent(e.changedTouches[0]),this._first&&(this._active=this._touch,this._first=!1),this.fire(\"touchstart\",e,!0)},pu.touchmove=function(e){this.fire(\"touchmove\",e,!0)},pu.touchend=function(e){this.fire(\"touchend\",e,!0),this._touch=null},pu.fire=function(e,t,n){var r,i,a=n?this._touch:this._active,o=this._handlers[e];if(t.vegaType=e,\"click\"===e&&a&&a.href?this.handleHref(t,a,a.href):\"mousemove\"!==e&&e!==du||this.handleTooltip(t,a,e!==du),o)for(r=0,i=o.length;r=0&&r.splice(i,1),this},pu.pickEvent=function(e){var t=au(e,this._canvas),n=this._origin;return this.pick(this._scene,t[0],t[1],t[0]-n[0],t[1]-n[1])},pu.pick=function(e,t,n,r,i){var a=this.context();return Hc[e.marktype].pick.call(this,a,e,t,n,r,i)};var hu=\"undefined\"!=typeof window&&window.devicePixelRatio||1;function bu(e){cu.call(this,e),this._redraw=!1,this._dirty=new To}var vu=Object(Ee.t)(bu,cu),_u=cu.prototype,yu=new To;function xu(e,t){ou.call(this,e,t);var n=this;n._hrefHandler=Su(n,function(e,t){t&&t.href&&n.handleHref(e,t,t.href)}),n._tooltipHandler=Su(n,function(e,t){n.handleTooltip(e,t,e.type!==du)})}vu.initialize=function(e,t,n,r,i){return this._canvas=Lo(1,1),e&&(ru(e,0).appendChild(this._canvas),this._canvas.setAttribute(\"class\",\"marks\")),_u.initialize.call(this,e,t,n,r,i)},vu.resize=function(e,t,n,r){return _u.resize.call(this,e,t,n,r),function(e,t,n,r,i){var a=\"undefined\"!=typeof HTMLElement&&e instanceof HTMLElement&&null!=e.parentNode,o=e.getContext(\"2d\"),s=a?hu:i;e.width=t*s,e.height=n*s,a&&1!==s&&(e.style.width=t+\"px\",e.style.height=n+\"px\"),o.pixelRatio=s,o.setTransform(s,0,0,s,s*r[0],s*r[1])}(this._canvas,this._width,this._height,this._origin,this._scale),this._redraw=!0,this},vu.canvas=function(){return this._canvas},vu.context=function(){return this._canvas?this._canvas.getContext(\"2d\"):null},vu.dirty=function(e){var t=function(e,t){if(null==t)return e;for(var n=yu.clear().union(e);null!=t;t=t.mark.group)n.translate(t.x||0,t.y||0);return n}(e.bounds,e.mark.group);this._dirty.union(t)},vu._render=function(e){var t=this.context(),n=this._origin,r=this._width,i=this._height,a=this._dirty;return t.save(),this._redraw||a.empty()?(this._redraw=!1,a=null):a=function(e,t,n){return t.expand(1).round(),t.translate(-n[0]%1,-n[1]%1),e.beginPath(),e.rect(t.x1,t.y1,t.width(),t.height()),e.clip(),t}(t,a,n),this.clear(-n[0],-n[1],r,i),this.draw(t,e,a),t.restore(),this._dirty.clear(),this},vu.draw=function(e,t,n){var r=Hc[t.marktype];t.clip&&function(e,t){var n=t.clip;if(e.save(),e.beginPath(),Object(Ee.x)(n))n(e);else{var r=t.group;e.rect(0,0,r.width||0,r.height||0)}e.clip()}(e,t),r.draw.call(this,e,t,n),t.clip&&e.restore()},vu.clear=function(e,t,n,r){var i=this.context();i.clearRect(e,t,n,r),null!=this._bgcolor&&(i.fillStyle=this._bgcolor,i.fillRect(e,t,n,r))};var Eu=Object(Ee.t)(xu,ou);function Su(e,t){return function(n){var r=n.target.__data__;n.vegaType=n.type,r=Array.isArray(r)?r[0]:r,t.call(e._obj,n,r)}}function wu(e,t,n){var r,i,a=\"<\"+e;if(t)for(r in t)null!=(i=t[r])&&(a+=\" \"+r+'=\"'+i+'\"');return n&&(a+=\" \"+n),a+\">\"}function Cu(e){return\"\"}Eu.initialize=function(e,t,n){var r=this._svg;return r&&(r.removeEventListener(\"click\",this._hrefHandler),r.removeEventListener(\"mousemove\",this._tooltipHandler),r.removeEventListener(du,this._tooltipHandler)),this._svg=r=e&&tu(e,\"svg\"),r&&(r.addEventListener(\"click\",this._hrefHandler),r.addEventListener(\"mousemove\",this._tooltipHandler),r.addEventListener(du,this._tooltipHandler)),ou.prototype.initialize.call(this,e,t,n)},Eu.canvas=function(){return this._svg},Eu.on=function(e,t){var n=this.eventName(e),r=this._handlers;if(this._handlerIndex(r[n],e,t)<0){var i={type:e,handler:t,listener:Su(this,t)};(r[n]||(r[n]=[])).push(i),this._svg&&this._svg.addEventListener(n,i.listener)}return this},Eu.off=function(e,t){var n=this.eventName(e),r=this._handlers[n],i=this._handlerIndex(r,e,t);return i>=0&&(this._svg&&this._svg.removeEventListener(n,r[i].listener),r.splice(i,1)),this};var Ou={version:\"1.1\",xmlns:\"http://www.w3.org/2000/svg\",\"xmlns:xlink\":\"http://www.w3.org/1999/xlink\"},Mu={fill:\"fill\",fillOpacity:\"fill-opacity\",stroke:\"stroke\",strokeOpacity:\"stroke-opacity\",strokeWidth:\"stroke-width\",strokeCap:\"stroke-linecap\",strokeJoin:\"stroke-linejoin\",strokeDash:\"stroke-dasharray\",strokeDashOffset:\"stroke-dashoffset\",strokeMiterLimit:\"stroke-miterlimit\",opacity:\"opacity\"},Nu=Object.keys(Mu),Tu=Ou.xmlns;function Du(e){cu.call(this,e),this._dirtyID=1,this._dirty=[],this._svg=null,this._root=null,this._defs=null}var Au=Object(Ee.t)(Du,cu),ku=cu.prototype;function Ru(e,t,n){var r,i,a;for((e=nu(e,n,\"linearGradient\",Tu)).setAttribute(\"id\",t.id),e.setAttribute(\"x1\",t.x1),e.setAttribute(\"x2\",t.x2),e.setAttribute(\"y1\",t.y1),e.setAttribute(\"y2\",t.y2),r=0,i=t.stops.length;r1}(e)&&o.previousSibling!==n)&&t.insertBefore(o,n?n.nextSibling:t.firstChild),o}Au.initialize=function(e,t,n,r){return e&&(this._svg=nu(e,0,\"svg\",Tu),this._svg.setAttribute(\"class\",\"marks\"),ru(e,1),this._root=nu(this._svg,0,\"g\",Tu),ru(this._svg,1)),this._defs={gradient:{},clipping:{}},this.background(this._bgcolor),ku.initialize.call(this,e,t,n,r)},Au.background=function(e){return arguments.length&&this._svg&&this._svg.style.setProperty(\"background-color\",e),ku.background.apply(this,arguments)},Au.resize=function(e,t,n,r){return ku.resize.call(this,e,t,n,r),this._svg&&(this._svg.setAttribute(\"width\",this._width*this._scale),this._svg.setAttribute(\"height\",this._height*this._scale),this._svg.setAttribute(\"viewBox\",\"0 0 \"+this._width+\" \"+this._height),this._root.setAttribute(\"transform\",\"translate(\"+this._origin+\")\")),this._dirty=[],this},Au.canvas=function(){return this._svg},Au.svg=function(){if(!this._svg)return null;var e={class:\"marks\",width:this._width*this._scale,height:this._height*this._scale,viewBox:\"0 0 \"+this._width+\" \"+this._height};for(var t in Ou)e[t]=Ou[t];var n=this._bgcolor?wu(\"rect\",{width:this._width,height:this._height,style:\"fill: \"+this._bgcolor+\";\"})+Cu(\"rect\"):\"\";return wu(\"svg\",e)+n+this._svg.innerHTML+Cu(\"svg\")},Au._render=function(e){return this._dirtyCheck()&&(this._dirtyAll&&this._resetDefs(),this.draw(this._root,e),ru(this._root,1)),this.updateDefs(),this._dirty=[],++this._dirtyID,this},Au.updateDefs=function(){var e,t=this._svg,n=this._defs,r=n.el,i=0;for(e in n.gradient)r||(n.el=r=nu(t,0,\"defs\",Tu)),Ru(r,n.gradient[e],i++);for(e in n.clipping)r||(n.el=r=nu(t,0,\"defs\",Tu)),Iu(r,n.clipping[e],i++);r&&(0===i?(t.removeChild(r),n.el=null):ru(r,i))},Au._resetDefs=function(){var e=this._defs;e.gradient={},e.clipping={}},Au.dirty=function(e){e.dirty!==this._dirtyID&&(e.dirty=this._dirtyID,this._dirty.push(e))},Au.isDirty=function(e){return this._dirtyAll||!e._svg||e.dirty===this._dirtyID},Au._dirtyCheck=function(){this._dirtyAll=!0;var e=this._dirty;if(!e.length)return!0;var t,n,r,i,a,o,s,l=++this._dirtyID;for(a=0,o=e.length;a0?wu(\"defs\")+a+Cu(\"defs\"):\"\"},$u.attributes=function(e,t){return Gu={},e(Wu,t,this),Gu},$u.href=function(e){var t,n=this,r=e.href;if(r){if(t=n._hrefs&&n._hrefs[r])return t;n.sanitizeURL(r).then(function(e){e[\"xlink:href\"]=e.href,e.href=null,(n._hrefs||(n._hrefs={}))[r]=e})}return null},$u.mark=function(e){var t,n=this,r=Hc[e.marktype],i=r.tag,a=this._defs,o=\"\";function s(s){var l=n.href(s);l&&(o+=wu(\"a\",l)),t=\"g\"!==i?Vu(s,e,i,a):null,o+=wu(i,n.attributes(r.attr,s),t),\"text\"===i?o+=Bc(s).replace(/&/g,\"&\").replace(//g,\">\"):\"g\"===i&&(o+=wu(\"path\",n.attributes(r.background,s),Vu(s,e,\"bgrect\",a))+Cu(\"path\"),o+=wu(\"g\",n.attributes(r.foreground,s))+n.markGroup(s)+Cu(\"g\")),o+=Cu(i),l&&(o+=Cu(\"a\"))}return\"g\"!==i&&!1===e.interactive&&(t='style=\"pointer-events: none;\"'),o+=wu(\"g\",{class:iu(e),\"clip-path\":e.clip?dc(n,e,e.group):null},t),r.nested?e.items&&e.items.length&&s(e.items[0]):Yl(e,s),o+Cu(\"g\")},$u.markGroup=function(e){var t=this,n=\"\";return Yl(e,function(e){n+=t.mark(e)}),n};var Ku={Canvas:\"canvas\",PNG:\"png\",SVG:\"svg\",None:\"none\"},Qu={};function Yu(e,t){return e=String(e||\"\").toLowerCase(),arguments.length>1?(Qu[e]=t,this):Qu[e]}Qu.canvas=Qu.png={renderer:bu,headless:bu,handler:fu},Qu.svg={renderer:Du,headless:qu,handler:xu},Qu.none={};var Zu=new To;function Xu(e){Yr.call(this,null,e)}function Ju(e,t,n){return t(e.bounds.clear(),e,n)}Object(Ee.t)(Xu,Yr).transform=function(e,t){var n,r=t.dataflow,i=e.mark,a=i.marktype,o=Hc[a],s=o.bound,l=i.bounds;return o.nested?(i.items.length&&r.dirty(i.items[0]),l=Ju(i,s),i.items.forEach(function(e){e.bounds.clear().union(l)})):a===io||e.modified()?(t.visit(t.MOD,function(e){r.dirty(e)}),l.clear(),i.items.forEach(function(e){l.union(Ju(e,s))}),i.role===co&&t.reflow()):(n=t.changed(t.REM),t.visit(t.ADD,function(e){l.union(Ju(e,s))}),t.visit(t.MOD,function(e){n=n||l.alignsWith(e.bounds),r.dirty(e),l.union(Ju(e,s))}),n&&(l.clear(),i.items.forEach(function(e){l.union(e.bounds)}))),function(e){var t=e.clip;if(Object(Ee.x)(t))t(zl(Zu.clear()));else{if(!t)return;Zu.set(0,0,e.group.width,e.group.height)}e.bounds.intersect(Zu)}(i),t.modifies(\"bounds\")};var ed=\":vega_identifier:\";function td(e){Yr.call(this,0,e)}function nd(e){Yr.call(this,null,e)}function rd(e){Yr.call(this,null,e)}td.Definition={type:\"Identifier\",metadata:{modifies:!0},params:[{name:\"as\",type:\"string\",required:!0}]},Object(Ee.t)(td,Yr).transform=function(e,t){var n=function(e){var t=e._signals[ed];t||(e._signals[ed]=t=e.add(0));return t}(t.dataflow),r=n.value,i=e.as;return t.visit(t.ADD,function(e){e[i]||(e[i]=++r)}),n.set(this.value=r),t},Object(Ee.t)(nd,Yr).transform=function(e,t){var n=this.value;n||((n=t.dataflow.scenegraph().mark(e.markdef,function(e){var t=e.groups,n=e.parent;return t&&1===t.size?t.get(Object.keys(t.object)[0]):t&&n?t.lookup(n):null}(e),e.index)).group.context=e.context,e.context.group||(e.context.group=n.group),n.source=this,n.clip=e.clip,n.interactive=e.interactive,this.value=n);var r=n.marktype===io?Io:Ro;return t.visit(t.ADD,function(e){r.call(e,n)}),(e.modified(\"clip\")||e.modified(\"interactive\"))&&(n.clip=e.clip,n.interactive=!!e.interactive,n.zdirty=!0,t.reflow()),n.items=t.source,t};var id={parity:function(e){return e.filter(function(e,t){return t%2?e.opacity=0:1})},greedy:function(e){var t;return e.filter(function(e,n){return n&&ad(t.bounds,e.bounds)?e.opacity=0:(t=e,1)})}};function ad(e,t){return!(e.x2-1t.x2||e.y2-1t.y2)}function od(e){for(var t,n=1,r=e.length,i=e[0].bounds;n1&&t.height()>1}function ld(e){Yr.call(this,null,e)}function cd(e,t){for(var n=0,r=e.length;n1&&y)for(i=0;i0&&(l.x+=c=d/2,l.bounds.translate(c,0));if(md(n.center,No)&&1!==C&&x)for(i=0;i0&&(l.y+=u=f/2,l.bounds.translate(0,u));for(i=0;ii&&(e.warn(\"Grid headers exceed limit: \"+i),t=t.slice(0,i)),w+=a,g=0,b=t.length;g=0&&null==(y=n[h]);h-=f);s?(x=null==p?y.x:Math.round(y.bounds.x1+p*y.bounds.width()),E=w):(x=w,E=null==p?y.y:Math.round(y.bounds.y1+p*y.bounds.height())),v.union(_.bounds.translate(x-(_.x||0),E-(_.y||0))),_.x=x,_.y=E,e.dirty(_),C=o(C,v[c])}return C}function vd(e,t,n,r,i,a){if(t){e.dirty(t);var o=n,s=n;r?o=Math.round(i.x1+a*i.width()):s=Math.round(i.y1+a*i.height()),t.bounds.translate(o-(t.x||0),s-(t.y||0)),t.mark.bounds.clear().union(t.bounds),t.x=o,t.y=s,e.dirty(t)}}Object(Ee.t)(rd,Yr).transform=function(e,t){var n=id[e.method]||id.parity,r=t.materialize(t.SOURCE).source;if(r){e.sort&&(r=r.slice().sort(e.sort)),\"greedy\"===e.method&&(r=r.filter(sd)),r.forEach(function(e){e.opacity=1});var i,a,o,s,l,c=r;if(c.length>=3&&od(c)){t=t.reflow(e.modified()).modifies(\"opacity\");do{c=n(c)}while(c.length>=3&&od(c));c.length<3&&!Object(Ee.K)(r).opacity&&(c.length>1&&(Object(Ee.K)(c).opacity=0),Object(Ee.K)(r).opacity=1)}if(e.boundScale){var u=(i=e.boundScale,a=e.boundOrient,o=e.boundTolerance,s=i.range(),l=new To,a===Ka||a===Za?l.set(s[0],-1/0,s[1],1/0):l.set(-1/0,s[0],1/0,s[1]),l.expand(o||1),function(e){return l.encloses(e.bounds)});r.forEach(function(e){u(e)||(e.opacity=0)})}return t}},Object(Ee.t)(ld,Yr).transform=function(e,t){var n=t.dataflow;if(t.visit(t.ALL,function(e){n.dirty(e)}),t.fields&&t.fields.zindex){var r=t.source&&t.source[0];r&&(r.mark.zdirty=!0)}};var _d=.5,yd=new To;function xd(e){Yr.call(this,null,e)}function Ed(e,t,n){return e[t]===n?0:(e[t]=n,1)}function Sd(e){var t=e.items[0].datum.orient;return t===Qa||t===Ya}function wd(e,t,n,r){var i,a,o=t.items[0],s=o.datum,l=s.orient,c=function(e){var t=+e.grid;return[e.ticks?t++:-1,e.labels?t++:-1,t+ +e.domain]}(s),u=o.range,d=o.offset,f=o.position,p=o.minExtent,m=o.maxExtent,g=s.title&&o.items[c[2]].items[0],h=o.titlePadding,b=o.bounds,v=0,_=0;switch(yd.clear().union(b),b.clear(),(i=c[0])>-1&&b.union(o.items[i].bounds),(i=c[1])>-1&&b.union(o.items[i].bounds),l){case Ka:v=f||0,_=-d,a=Math.max(p,Math.min(m,-b.y1)),g&&(a=Cd(g,a,h,0,-1,b)),b.add(0,-a).add(u,0);break;case Qa:v=-d,_=f||0,a=Math.max(p,Math.min(m,-b.x1)),g&&(a=Cd(g,a,h,1,-1,b)),b.add(-a,0).add(0,u);break;case Ya:v=n+d,_=f||0,a=Math.max(p,Math.min(m,b.x2)),g&&(a=Cd(g,a,h,1,1,b)),b.add(0,0).add(a,u);break;case Za:v=f||0,_=r+d,a=Math.max(p,Math.min(m,b.y2)),g&&(a=Cd(g,a,h,0,1,b)),b.add(0,0).add(u,a);break;default:v=o.x,_=o.y}return Fl(b.translate(v,_),o),Ed(o,\"x\",v+_d)|Ed(o,\"y\",_+_d)&&(o.bounds=yd,e.dirty(o),o.bounds=b,e.dirty(o)),o.mark.bounds.clear().union(b)}function Cd(e,t,n,r,i,a){var o=e.bounds,s=0,l=0;return e.auto?(t+=n,r?s=(e.x||0)-(e.x=i*t):l=(e.y||0)-(e.y=i*t),o.translate(-s,-l),e.mark.bounds.set(o.x1,o.y1,o.x2,o.y2),r?(a.add(0,o.y1).add(0,o.y2),t+=o.width()):(a.add(o.x1,0).add(o.x2,0),t+=o.height())):a.union(o),t}function Od(e,t,n,r,i,a,o){var s,l,c,u,d,f=t.items[0],p=f.datum,m=p.orient,g=f.offset,h=f.bounds,b=0,v=0;switch(m===Ka||m===Za?(c=i,b=n[m]):m!==Qa&&m!==Ya||(c=r,v=n[m]),yd.clear().union(h),h.clear(),f.items.forEach(function(e){h.union(e.bounds)}),s=Math.ceil(h.width()+2*f.padding-1),l=Math.ceil(h.height()+2*f.padding-1),p.type===vo&&(u=f.items[0].items[0].items[0].items,d=u.reduce(function(e,t){return e[t.column]=Math.max(t.bounds.x2-t.x,e[t.column]||0),e},{}),u.forEach(function(e){e.width=d[e.column],e.height=e.bounds.y2-e.y})),m){case Qa:b-=n.leftWidth+g-Math.floor(c.x1),n.left+=l+n.margin;break;case Ya:b+=g+Math.ceil(c.x2),n.right+=l+n.margin;break;case Ka:v-=l+g-Math.floor(c.y1),n.top+=s+n.margin;break;case Za:v+=g+Math.ceil(c.y2),n.bottom+=s+n.margin;break;case Xa:b+=g,v+=g;break;case Ja:b+=a-s-g,v+=g;break;case eo:b+=g,v+=o-l-g;break;case to:b+=a-s-g,v+=o-l-g;break;default:b=f.x,v=f.y}return Fl(h.set(b,v,b+s,v+l),f),Ed(f,\"x\",b)|Ed(f,\"width\",s)|Ed(f,\"y\",v)|Ed(f,\"height\",l)&&(f.bounds=yd,e.dirty(f),f.bounds=h,e.dirty(f)),f.mark.bounds.clear().union(h)}Object(Ee.t)(xd,Yr).transform=function(e,t){var n=t.dataflow;return e.mark.items.forEach(function(t){e.layout&&hd(n,t,e.layout),function(e,t,n){var r,i,a,o,s,l,c=t.items,u=Math.max(0,t.width||0),d=Math.max(0,t.height||0),f=(new To).set(0,0,u,d),p=f.clone(),m=f.clone(),g=[];for(s=0,l=c.length;s0?r:1:0},Ud=function(e){return function(t){var n,r=t[0],i=t[1];return i=s&&o[i]<=l&&(c<0&&(c=i),n=i);if(!(c<0))return s=e.invertExtent(o[c]),l=e.invertExtent(o[n]),[void 0===s[0]?s[1]:s[0],void 0===l[1]?l[0]:l[1]]}};function zd(){}function qd(e,t){var n=new zd;if(e instanceof zd)e.each(function(e,t){n.set(t,e)});else if(Array.isArray(e)){var r,i=-1,a=e.length;if(null==t)for(;++i=r.length)return null!=e&&n.sort(e),null!=t?t(n):n;for(var l,c,u,d=-1,f=n.length,p=r[i++],m=Gd(),g=o();++dr.length)return n;var o,s=i[a-1];return null!=t&&a>=r.length?o=n.entries():(o=[],n.each(function(t,n){o.push({key:n,values:e(t,a)})})),null!=s?o.sort(function(e,t){return s(e.key,t.key)}):o}(a(e,0,Vd,Kd),0)},key:function(e){return r.push(e),n},sortKeys:function(e){return i[r.length-1]=e,n},sortValues:function(t){return e=t,n},rollup:function(e){return t=e,n}}};function Hd(){return{}}function Wd(e,t,n){e[t]=n}function Vd(){return Gd()}function Kd(e,t,n){e.set(t,n)}function Qd(){}var Yd=Gd.prototype;function Zd(e,t){var n=new Qd;if(e instanceof Qd)e.each(function(e){n.add(e)});else if(e){var r=-1,i=e.length;if(null==t)for(;++r>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):(t=df.exec(e))?yf(parseInt(t[1],16)):(t=ff.exec(e))?new wf(t[1],t[2],t[3],1):(t=pf.exec(e))?new wf(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=mf.exec(e))?xf(t[1],t[2],t[3],t[4]):(t=gf.exec(e))?xf(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=hf.exec(e))?Of(t[1],t[2]/100,t[3]/100,1):(t=bf.exec(e))?Of(t[1],t[2]/100,t[3]/100,t[4]):vf.hasOwnProperty(e)?yf(vf[e]):\"transparent\"===e?new wf(NaN,NaN,NaN,0):null}function yf(e){return new wf(e>>16&255,e>>8&255,255&e,1)}function xf(e,t,n,r){return r<=0&&(e=t=n=NaN),new wf(e,t,n,r)}function Ef(e){return e instanceof of||(e=_f(e)),e?new wf((e=e.rgb()).r,e.g,e.b,e.opacity):new wf}function Sf(e,t,n,r){return 1===arguments.length?Ef(e):new wf(e,t,n,null==r?1:r)}function wf(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}function Cf(e){return((e=Math.max(0,Math.min(255,Math.round(e)||0)))<16?\"0\":\"\")+e.toString(16)}function Of(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Nf(e,t,n,r)}function Mf(e,t,n,r){return 1===arguments.length?function(e){if(e instanceof Nf)return new Nf(e.h,e.s,e.l,e.opacity);if(e instanceof of||(e=_f(e)),!e)return new Nf;if(e instanceof Nf)return e;var t=(e=e.rgb()).r/255,n=e.g/255,r=e.b/255,i=Math.min(t,n,r),a=Math.max(t,n,r),o=NaN,s=a-i,l=(a+i)/2;return s?(o=t===a?(n-r)/s+6*(n0&&l<1?0:o,new Nf(o,s,l,e.opacity)}(e):new Nf(e,t,n,null==r?1:r)}function Nf(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function Tf(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}rf(of,_f,{displayable:function(){return this.rgb().displayable()},hex:function(){return this.rgb().hex()},toString:function(){return this.rgb()+\"\"}}),rf(wf,Sf,af(of,{brighter:function(e){return e=null==e?1/.7:Math.pow(1/.7,e),new wf(this.r*e,this.g*e,this.b*e,this.opacity)},darker:function(e){return e=null==e?.7:Math.pow(.7,e),new wf(this.r*e,this.g*e,this.b*e,this.opacity)},rgb:function(){return this},displayable:function(){return 0<=this.r&&this.r<=255&&0<=this.g&&this.g<=255&&0<=this.b&&this.b<=255&&0<=this.opacity&&this.opacity<=1},hex:function(){return\"#\"+Cf(this.r)+Cf(this.g)+Cf(this.b)},toString:function(){var e=this.opacity;return(1===(e=isNaN(e)?1:Math.max(0,Math.min(1,e)))?\"rgb(\":\"rgba(\")+Math.max(0,Math.min(255,Math.round(this.r)||0))+\", \"+Math.max(0,Math.min(255,Math.round(this.g)||0))+\", \"+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===e?\")\":\", \"+e+\")\")}})),rf(Nf,Mf,af(of,{brighter:function(e){return e=null==e?1/.7:Math.pow(1/.7,e),new Nf(this.h,this.s,this.l*e,this.opacity)},darker:function(e){return e=null==e?.7:Math.pow(.7,e),new Nf(this.h,this.s,this.l*e,this.opacity)},rgb:function(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,i=2*n-r;return new wf(Tf(e>=240?e-240:e+120,i,r),Tf(e,i,r),Tf(e<120?e+240:e-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1}}));var Df=Math.PI/180,Af=180/Math.PI,kf=.96422,Rf=1,If=.82521,Lf=4/29,Pf=6/29,Ff=3*Pf*Pf,Bf=Pf*Pf*Pf;function Uf(e){if(e instanceof zf)return new zf(e.l,e.a,e.b,e.opacity);if(e instanceof Kf){if(isNaN(e.h))return new zf(e.l,0,0,e.opacity);var t=e.h*Df;return new zf(e.l,Math.cos(t)*e.c,Math.sin(t)*e.c,e.opacity)}e instanceof wf||(e=Ef(e));var n,r,i=Hf(e.r),a=Hf(e.g),o=Hf(e.b),s=qf((.2225045*i+.7168786*a+.0606169*o)/Rf);return i===a&&a===o?n=r=s:(n=qf((.4360747*i+.3850649*a+.1430804*o)/kf),r=qf((.0139322*i+.0971045*a+.7141733*o)/If)),new zf(116*s-16,500*(n-s),200*(s-r),e.opacity)}function jf(e,t,n,r){return 1===arguments.length?Uf(e):new zf(e,t,n,null==r?1:r)}function zf(e,t,n,r){this.l=+e,this.a=+t,this.b=+n,this.opacity=+r}function qf(e){return e>Bf?Math.pow(e,1/3):e/Ff+Lf}function Gf(e){return e>Pf?e*e*e:Ff*(e-Lf)}function $f(e){return 255*(e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055)}function Hf(e){return(e/=255)<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function Wf(e){if(e instanceof Kf)return new Kf(e.h,e.c,e.l,e.opacity);if(e instanceof zf||(e=Uf(e)),0===e.a&&0===e.b)return new Kf(NaN,0,e.l,e.opacity);var t=Math.atan2(e.b,e.a)*Af;return new Kf(t<0?t+360:t,Math.sqrt(e.a*e.a+e.b*e.b),e.l,e.opacity)}function Vf(e,t,n,r){return 1===arguments.length?Wf(e):new Kf(e,t,n,null==r?1:r)}function Kf(e,t,n,r){this.h=+e,this.c=+t,this.l=+n,this.opacity=+r}rf(zf,jf,af(of,{brighter:function(e){return new zf(this.l+18*(null==e?1:e),this.a,this.b,this.opacity)},darker:function(e){return new zf(this.l-18*(null==e?1:e),this.a,this.b,this.opacity)},rgb:function(){var e=(this.l+16)/116,t=isNaN(this.a)?e:e+this.a/500,n=isNaN(this.b)?e:e-this.b/200;return new wf($f(3.1338561*(t=kf*Gf(t))-1.6168667*(e=Rf*Gf(e))-.4906146*(n=If*Gf(n))),$f(-.9787684*t+1.9161415*e+.033454*n),$f(.0719453*t-.2289914*e+1.4052427*n),this.opacity)}})),rf(Kf,Vf,af(of,{brighter:function(e){return new Kf(this.h,this.c,this.l+18*(null==e?1:e),this.opacity)},darker:function(e){return new Kf(this.h,this.c,this.l-18*(null==e?1:e),this.opacity)},rgb:function(){return Uf(this).rgb()}}));var Qf=-.29227,Yf=-.90649,Zf=1.97294,Xf=Zf*Yf,Jf=1.78277*Zf,ep=1.78277*Qf- -.14861*Yf;function tp(e,t,n,r){return 1===arguments.length?function(e){if(e instanceof np)return new np(e.h,e.s,e.l,e.opacity);e instanceof wf||(e=Ef(e));var t=e.r/255,n=e.g/255,r=e.b/255,i=(ep*r+Xf*t-Jf*n)/(ep+Xf-Jf),a=r-i,o=(Zf*(n-i)-Qf*a)/Yf,s=Math.sqrt(o*o+a*a)/(Zf*i*(1-i)),l=s?Math.atan2(o,a)*Af-120:NaN;return new np(l<0?l+360:l,s,i,e.opacity)}(e):new np(e,t,n,null==r?1:r)}function np(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}function rp(e,t,n,r,i){var a=e*e,o=a*e;return((1-3*e+3*a-o)*t+(4-6*a+3*o)*n+(1+3*e+3*a-3*o)*r+o*i)/6}rf(np,tp,af(of,{brighter:function(e){return e=null==e?1/.7:Math.pow(1/.7,e),new np(this.h,this.s,this.l*e,this.opacity)},darker:function(e){return e=null==e?.7:Math.pow(.7,e),new np(this.h,this.s,this.l*e,this.opacity)},rgb:function(){var e=isNaN(this.h)?0:(this.h+120)*Df,t=+this.l,n=isNaN(this.s)?0:this.s*t*(1-t),r=Math.cos(e),i=Math.sin(e);return new wf(255*(t+n*(-.14861*r+1.78277*i)),255*(t+n*(Qf*r+Yf*i)),255*(t+n*(Zf*r)),this.opacity)}}));var ip=function(e){var t=e.length-1;return function(n){var r=n<=0?n=0:n>=1?(n=1,t-1):Math.floor(n*t),i=e[r],a=e[r+1],o=r>0?e[r-1]:2*i-a,s=r180||n<-180?n-360*Math.round(n/360):n):op(isNaN(e)?t:e)}function cp(e){return 1==(e=+e)?up:function(t,n){return n-t?function(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}(t,n,e):op(isNaN(t)?n:t)}}function up(e,t){var n=t-e;return n?sp(e,n):op(isNaN(e)?t:e)}var dp=function e(t){var n=cp(t);function r(e,t){var r=n((e=Sf(e)).r,(t=Sf(t)).r),i=n(e.g,t.g),a=n(e.b,t.b),o=up(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=i(t),e.b=a(t),e.opacity=o(t),e+\"\"}}return r.gamma=e,r}(1);function fp(e){return function(t){var n,r,i=t.length,a=new Array(i),o=new Array(i),s=new Array(i);for(n=0;na&&(i=t.slice(a,i),s[o]?s[o]+=i:s[++o]=i),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,l.push({i:o,x:bp(n,r)})),a=yp.lastIndex;return a180?t+=360:t-e>180&&(e+=360),a.push({i:n.push(i(n)+\"rotate(\",null,r)-2,x:bp(e,t)})):t&&n.push(i(n)+\"rotate(\"+t+r)}(a.rotate,o.rotate,s,l),function(e,t,n,a){e!==t?a.push({i:n.push(i(n)+\"skewX(\",null,r)-2,x:bp(e,t)}):t&&n.push(i(n)+\"skewX(\"+t+r)}(a.skewX,o.skewX,s,l),function(e,t,n,r,a,o){if(e!==n||t!==r){var s=a.push(i(a)+\"scale(\",null,\",\",null,\")\");o.push({i:s-4,x:bp(e,n)},{i:s-2,x:bp(t,r)})}else 1===n&&1===r||a.push(i(a)+\"scale(\"+n+\",\"+r+\")\")}(a.scaleX,a.scaleY,o.scaleX,o.scaleY,s,l),a=o=null,function(e){for(var t,n=-1,r=l.length;++n2?em:Jp,r=i=null,u}function u(t){return(r||(r=n(a,o,l?function(e){return function(t,n){var r=e(t=+t,n=+n);return function(e){return e<=t?0:e>=n?1:r(e)}}}(e):e,s)))(+t)}return u.invert=function(e){return(i||(i=n(o,a,Xp,l?function(e){return function(t,n){var r=e(t=+t,n=+n);return function(e){return e<=0?t:e>=1?n:r(e)}}}(t):t)))(+e)},u.domain=function(e){return arguments.length?(a=Jd.call(e,Yp),c()):a.slice()},u.range=function(e){return arguments.length?(o=ef.call(e),c()):o.slice()},u.rangeRound=function(e){return o=ef.call(e),s=Mp,c()},u.clamp=function(e){return arguments.length?(l=!!e,c()):l},u.interpolate=function(e){return arguments.length?(s=e,c()):s},c()}var rm=function(e,t){if((n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf(\"e\"))<0)return null;var n,r=e.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+e.slice(n+1)]},im=function(e){return(e=rm(Math.abs(e)))?e[1]:NaN},am=/^(?:(.)?([<>=^]))?([+\\-\\( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?(~)?([a-z%])?$/i;function om(e){return new sm(e)}function sm(e){if(!(t=am.exec(e)))throw new Error(\"invalid format: \"+e);var t;this.fill=t[1]||\" \",this.align=t[2]||\">\",this.sign=t[3]||\"-\",this.symbol=t[4]||\"\",this.zero=!!t[5],this.width=t[6]&&+t[6],this.comma=!!t[7],this.precision=t[8]&&+t[8].slice(1),this.trim=!!t[9],this.type=t[10]||\"\"}om.prototype=sm.prototype,sm.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?\"0\":\"\")+(null==this.width?\"\":Math.max(1,0|this.width))+(this.comma?\",\":\"\")+(null==this.precision?\"\":\".\"+Math.max(0,0|this.precision))+(this.trim?\"~\":\"\")+this.type};var lm,cm,um,dm,fm=function(e){e:for(var t,n=e.length,r=1,i=-1;r0){if(!+e[r])break e;i=0}}return i>0?e.slice(0,i)+e.slice(t+1):e},pm=function(e,t){var n=rm(e,t);if(!n)return e+\"\";var r=n[0],i=n[1];return i<0?\"0.\"+new Array(-i).join(\"0\")+r:r.length>i+1?r.slice(0,i+1)+\".\"+r.slice(i+1):r+new Array(i-r.length+2).join(\"0\")},mm={\"%\":function(e,t){return(100*e).toFixed(t)},b:function(e){return Math.round(e).toString(2)},c:function(e){return e+\"\"},d:function(e){return Math.round(e).toString(10)},e:function(e,t){return e.toExponential(t)},f:function(e,t){return e.toFixed(t)},g:function(e,t){return e.toPrecision(t)},o:function(e){return Math.round(e).toString(8)},p:function(e,t){return pm(100*e,t)},r:pm,s:function(e,t){var n=rm(e,t);if(!n)return e+\"\";var r=n[0],i=n[1],a=i-(lm=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,o=r.length;return a===o?r:a>o?r+new Array(a-o+1).join(\"0\"):a>0?r.slice(0,a)+\".\"+r.slice(a):\"0.\"+new Array(1-a).join(\"0\")+rm(e,Math.max(0,t+a-1))[0]},X:function(e){return Math.round(e).toString(16).toUpperCase()},x:function(e){return Math.round(e).toString(16)}},gm=function(e){return e},hm=[\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"µ\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"],bm=function(e){var t,n,r=e.grouping&&e.thousands?(t=e.grouping,n=e.thousands,function(e,r){for(var i=e.length,a=[],o=0,s=t[0],l=0;i>0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),a.push(e.substring(i-=s,i+s)),!((l+=s+1)>r));)s=t[o=(o+1)%t.length];return a.reverse().join(n)}):gm,i=e.currency,a=e.decimal,o=e.numerals?function(e){return function(t){return t.replace(/[0-9]/g,function(t){return e[+t]})}}(e.numerals):gm,s=e.percent||\"%\";function l(e){var t=(e=om(e)).fill,n=e.align,l=e.sign,c=e.symbol,u=e.zero,d=e.width,f=e.comma,p=e.precision,m=e.trim,g=e.type;\"n\"===g?(f=!0,g=\"g\"):mm[g]||(null==p&&(p=12),m=!0,g=\"g\"),(u||\"0\"===t&&\"=\"===n)&&(u=!0,t=\"0\",n=\"=\");var h=\"$\"===c?i[0]:\"#\"===c&&/[boxX]/.test(g)?\"0\"+g.toLowerCase():\"\",b=\"$\"===c?i[1]:/[%p]/.test(g)?s:\"\",v=mm[g],_=/[defgprs%]/.test(g);function y(e){var i,s,c,y=h,x=b;if(\"c\"===g)x=v(e)+x,e=\"\";else{var E=(e=+e)<0;if(e=v(Math.abs(e),p),m&&(e=fm(e)),E&&0==+e&&(E=!1),y=(E?\"(\"===l?l:\"-\":\"-\"===l||\"(\"===l?\"\":l)+y,x=(\"s\"===g?hm[8+lm/3]:\"\")+x+(E&&\"(\"===l?\")\":\"\"),_)for(i=-1,s=e.length;++i(c=e.charCodeAt(i))||c>57){x=(46===c?a+e.slice(i+1):e.slice(i))+x,e=e.slice(0,i);break}}f&&!u&&(e=r(e,1/0));var S=y.length+e.length+x.length,w=S>1)+y+e+x+w.slice(S);break;default:e=w+y+e+x}return o(e)}return p=null==p?6:/[gprs]/.test(g)?Math.max(1,Math.min(21,p)):Math.max(0,Math.min(20,p)),y.toString=function(){return e+\"\"},y}return{format:l,formatPrefix:function(e,t){var n=l(((e=om(e)).type=\"f\",e)),r=3*Math.max(-8,Math.min(8,Math.floor(im(t)/3))),i=Math.pow(10,-r),a=hm[8+r/3];return function(e){return n(i*e)+a}}}};!function(e){cm=bm(e),um=cm.format,dm=cm.formatPrefix}({decimal:\".\",thousands:\",\",grouping:[3],currency:[\"$\",\"\"]});var vm=function(e){return Math.max(0,-im(Math.abs(e)))},_m=function(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(im(t)/3)))-im(Math.abs(e)))},ym=function(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,im(t)-im(e))+1},xm=function(e,t,n){var r,i=e[0],a=e[e.length-1],o=Mi(i,a,null==t?10:t);switch((n=om(null==n?\",f\":n)).type){case\"s\":var s=Math.max(Math.abs(i),Math.abs(a));return null!=n.precision||isNaN(r=_m(o,s))||(n.precision=r),dm(n,s);case\"\":case\"e\":case\"g\":case\"p\":case\"r\":null!=n.precision||isNaN(r=ym(o,Math.max(Math.abs(i),Math.abs(a))))||(n.precision=r-(\"e\"===n.type));break;case\"f\":case\"%\":null!=n.precision||isNaN(r=vm(o))||(n.precision=r-2*(\"%\"===n.type))}return um(n)};function Em(e){var t=e.domain;return e.ticks=function(e){var n=t();return Ci(n[0],n[n.length-1],null==e?10:e)},e.tickFormat=function(e,n){return xm(t(),e,n)},e.nice=function(n){null==n&&(n=10);var r,i=t(),a=0,o=i.length-1,s=i[a],l=i[o];return l0?r=Oi(s=Math.floor(s/r)*r,l=Math.ceil(l/r)*r,n):r<0&&(r=Oi(s=Math.ceil(s*r)/r,l=Math.floor(l*r)/r,n)),r>0?(i[a]=Math.floor(s/r)*r,i[o]=Math.ceil(l/r)*r,t(i)):r<0&&(i[a]=Math.ceil(s*r)/r,i[o]=Math.floor(l*r)/r,t(i)),e},e}function Sm(){var e=nm(Xp,bp);return e.copy=function(){return tm(e,Sm())},Em(e)}var wm=function(e,t){var n,r=0,i=(e=e.slice()).length-1,a=e[r],o=e[i];return oa[1-u])))return n=Math.max(0,mi(d,l)-1),o=l===c?n:mi(d,c)-1,l-d[n]>t+1e-10&&++n,u&&(s=n,n=f-o,o=f-s),n>o?void 0:r().slice(n,o+1)}},n.invert=function(e){var t=n.invertRange([e,e]);return t?t[0]:t},n.copy=function(){return Gm().domain(r()).range(a).round(o).paddingInner(s).paddingOuter(l).align(c)},u()}var $m=Array.prototype.map,Hm=Array.prototype.slice;function Wm(e){return $m.call(e,function(e){return+e})}function Vm(e,t){return arguments.length>1?(Km[e]=function(e,t){return function(){var n=t();return n.invertRange||(n.invertRange=n.invert?Ud(n):n.invertExtent?jd(n):void 0),n.type=e,n}}(e,t),this):Km.hasOwnProperty(e)?Km[e]:void 0}var Km={identity:function e(){var t=[0,1];function n(e){return+e}return n.invert=n,n.domain=n.range=function(e){return arguments.length?(t=Jd.call(e,Yp),n):t.slice()},n.copy=function(){return e().domain(t)},Em(n)},linear:Sm,log:function e(){var t=nm(Cm,Om).domain([1,10]),n=t.domain,r=10,i=Tm(10),a=Nm(10);function o(){return i=Tm(r),a=Nm(r),n()[0]<0&&(i=Dm(i),a=Dm(a)),t}return t.base=function(e){return arguments.length?(r=+e,o()):r},t.domain=function(e){return arguments.length?(n(e),o()):n()},t.ticks=function(e){var t,o=n(),s=o[0],l=o[o.length-1];(t=l0){for(;fl)break;g.push(d)}}else for(;f=1;--u)if(!((d=c*u)l)break;g.push(d)}}else g=Ci(f,p,Math.min(p-f,m)).map(a);return t?g.reverse():g},t.tickFormat=function(e,n){if(null==n&&(n=10===r?\".0e\":\",\"),\"function\"!=typeof n&&(n=um(n)),e===1/0)return n;null==e&&(e=10);var o=Math.max(1,r*e/t.ticks().length);return function(e){var t=e/a(Math.round(i(e)));return t*r0?r[i-1]:t[0],i=r?[i[r-1],n]:[i[o-1],i[o]]},o.copy=function(){return e().domain([t,n]).range(a)},Em(o)},threshold:function e(){var t=[.5],n=[0,1],r=1;function i(e){if(e<=e)return n[hi(t,e,0,r)]}return i.domain=function(e){return arguments.length?(t=ef.call(e),r=Math.min(t.length,n.length-1),i):t.slice()},i.range=function(e){return arguments.length?(n=ef.call(e),r=Math.min(t.length,n.length-1),i):n.slice()},i.invertExtent=function(e){var r=n.indexOf(e);return[t[r-1],t[r]]},i.copy=function(){return e().domain(t).range(n)},i},time:function(){return qm(Ht,Gt,Lt,Rt,At,Tt,Mt,St,gn).domain([new Date(2e3,0,1),new Date(2e3,0,2)])},utc:function(){return qm(un,ln,Jt,Zt,Qt,Vt,Mt,St,bn).domain([Date.UTC(2e3,0,1),Date.UTC(2e3,0,2)])},band:Gm,point:function(){return function e(t){var n=t.copy;return t.padding=t.paddingOuter,delete t.paddingInner,t.copy=function(){return e(n())},t}(Gm().paddingInner(1))},sequential:function e(t){var n=Sm(),r=0,i=1,a=!1;function o(){var e=n.domain();r=e[0],i=Object(Ee.K)(e)-r}function s(e){var n=(e-r)/i;return t(a?Math.max(0,Math.min(1,n)):n)}return s.clamp=function(e){return arguments.length?(a=!!e,s):a},s.domain=function(e){return arguments.length?(n.domain(e),o(),s):n.domain()},s.interpolator=function(e){return arguments.length?(t=e,s):t},s.copy=function(){return e().domain(n.domain()).clamp(a).interpolator(t)},s.ticks=function(e){return n.ticks(e)},s.tickFormat=function(e,t){return n.tickFormat(e,t)},s.nice=function(e){return n.nice(e),o(),s},s},\"bin-linear\":function e(){var t=Sm(),n=[];function r(e){return t(e)}return r.domain=function(e){return arguments.length?(function(e){n=Wm(e),t.domain([n[0],Object(Ee.K)(n)])}(e),r):n.slice()},r.range=function(e){return arguments.length?(t.range(e),r):t.range()},r.rangeRound=function(e){return arguments.length?(t.rangeRound(e),r):t.rangeRound()},r.interpolate=function(e){return arguments.length?(t.interpolate(e),r):t.interpolate()},r.invert=function(e){return t.invert(e)},r.ticks=function(e){var t=n.length,i=~~(t/(e||t));return i<2?r.domain():n.filter(function(e,t){return!(t%i)})},r.tickFormat=function(){return t.tickFormat.apply(t,arguments)},r.copy=function(){return e().domain(r.domain()).range(r.range())},r},\"bin-ordinal\":function e(){var t=[],n=[];function r(e){return null==e||e!=e?void 0:n[(hi(t,e)-1)%n.length]}return r.domain=function(e){return arguments.length?(t=Wm(e),r):t.slice()},r.range=function(e){return arguments.length?(n=Hm.call(e),r):n.slice()},r.copy=function(){return e().domain(r.domain()).range(r.range())},r}};for(var Qm in Km)Vm(Qm,Km[Qm]);function Ym(e,t,n){var r=n-t;return r?\"linear\"===e.type||\"sequential\"===e.type?function(e){return(e-t)/r}:e.copy().domain([t,n]).range([0,1]).interpolate(Zm):Object(Ee.j)(0)}function Zm(e,t){var n=t-e;return function(t){return e+t*n}}function Xm(e){for(var t=e.length/6|0,n=new Array(t),r=0;r1)&&(e-=Math.floor(e));var t=Math.abs(e-.5);return _h.h=360*e-100,_h.s=1.5-1.5*t,_h.l=.8-.9*t,_h+\"\"},xh=Sf(),Eh=Math.PI/3,Sh=2*Math.PI/3,wh=function(e){var t;return e=(.5-e)*Math.PI,xh.r=255*(t=Math.sin(e))*t,xh.g=255*(t=Math.sin(e+Eh))*t,xh.b=255*(t=Math.sin(e+Sh))*t,xh+\"\"};function Ch(e){var t=e.length;return function(n){return e[Math.max(0,Math.min(t-1,Math.floor(n*t)))]}}var Oh=Ch(ag(\"44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725\")),Mh=Ch(ag(\"00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf\")),Nh=Ch(ag(\"00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4\")),Th=Ch(ag(\"0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921\")),Dh={blueorange:ig},Ah={category10:og,accent:sg,dark2:lg,paired:cg,pastel1:ug,pastel2:dg,set1:fg,set2:pg,set3:mg,category20:Jm,category20b:eg,category20c:tg,tableau10:ng,tableau20:rg,viridis:Oh,magma:Mh,inferno:Nh,plasma:Th,rainbow:yh,sinebow:wh,blueorange:pp(Object(Ee.K)(ig))};function kh(e,t){Ah[e]=o[\"interpolate\"+t],Dh[e]=o[\"scheme\"+t]}function Rh(e,t){if(arguments.length>1)return Ah[e]=t,this;var n=e.split(\"-\");return e=n[0],(n=+n[1]+1)&&Dh.hasOwnProperty(e)?Dh[e][n-1]:!n&&Ah.hasOwnProperty(e)?Ah[e]:void 0}kh(\"blues\",\"Blues\"),kh(\"greens\",\"Greens\"),kh(\"greys\",\"Greys\"),kh(\"purples\",\"Purples\"),kh(\"reds\",\"Reds\"),kh(\"oranges\",\"Oranges\"),kh(\"brownbluegreen\",\"BrBG\"),kh(\"purplegreen\",\"PRGn\"),kh(\"pinkyellowgreen\",\"PiYG\"),kh(\"purpleorange\",\"PuOr\"),kh(\"redblue\",\"RdBu\"),kh(\"redgrey\",\"RdGy\"),kh(\"redyellowblue\",\"RdYlBu\"),kh(\"redyellowgreen\",\"RdYlGn\"),kh(\"spectral\",\"Spectral\"),kh(\"bluegreen\",\"BuGn\"),kh(\"bluepurple\",\"BuPu\"),kh(\"greenblue\",\"GnBu\"),kh(\"orangered\",\"OrRd\"),kh(\"purplebluegreen\",\"PuBuGn\"),kh(\"purpleblue\",\"PuBu\"),kh(\"purplered\",\"PuRd\"),kh(\"redpurple\",\"RdPu\"),kh(\"yellowgreenblue\",\"YlGnBu\"),kh(\"yellowgreen\",\"YlGn\"),kh(\"yelloworangebrown\",\"YlOrBr\"),kh(\"yelloworangered\",\"YlOrRd\");var Ih={millisecond:St,second:Mt,minute:Tt,hour:At,day:Rt,week:Lt,month:Gt,year:Ht},Lh={millisecond:St,second:Mt,minute:Vt,hour:Qt,day:Zt,week:Jt,month:ln,year:un};function Ph(e,t){var n,r;return Object(Ee.z)(t)&&(n=t.step,t=t.interval),Object(Ee.B)(t)&&(t=\"time\"===e.type?(r=t,Ih.hasOwnProperty(r)&&Ih[r]):\"utc\"===e.type?function(e){return Lh.hasOwnProperty(e)&&Lh[e]}(t):Object(Ee.l)(\"Only time and utc scales accept interval strings.\"),n&&(t=t.every(n))),t}function Fh(e,t,n){var r=e.range(),i=r[0],a=Object(Ee.K)(r);if(i>a&&(r=a,a=i,i=r),t=t.filter(function(t){return!((t=e(t))a)}),n>0&&t.length>1){for(var o=[t[0],Object(Ee.K)(t)];t.length>n&&t.length>=3;)t=t.filter(function(e,t){return!(t%2)});t.length<3&&(t=o)}return t}function Bh(e,t){return e.ticks?e.ticks(t):e.domain()}function Uh(e,t,n){var r,i,a=e.tickFormat?e.tickFormat(t,n):n?um(n):String;return e.type===Md?(r=a,i=function(e){var t=om(e||\",\");if(null==t.precision){switch(t.precision=12,t.type){case\"%\":t.precision-=2;break;case\"e\":t.precision-=1}return n=um(t),r=um(\".1f\")(1)[1],function(e){var t,i,a=n(e),o=a.indexOf(r);if(o<0)return a;for(t=function(e,t){var n,r=e.lastIndexOf(\"e\");if(r>0)return r;for(r=e.length;--r>t;)if((n=e.charCodeAt(r))>=48&&n<=57)return r+1}(a,o),i=to;)if(\"0\"!==a[t]){++t;break}return a.slice(0,t)+i}}return um(t);var n,r}(n),function(e){return r(e)?i(e):\"\"}):a}function jh(e){Yr.call(this,null,e)}function zh(e){Yr.call(this,null,e)}function qh(){return Te({})}function Gh(e){return e.exit}function $h(e){Yr.call(this,null,e)}Object(Ee.t)(jh,Yr).transform=function(e,t){if(this.value&&!e.modified())return t.StopPropagation;var n=t.fork(t.NO_SOURCE|t.NO_FIELDS),r=this.value,i=e.scale,a=null==e.count?e.values?e.values.length:10:Ph(i,e.count),o=e.format||Uh(i,a,e.formatSpecifier),s=e.values?Fh(i,e.values,a):Bh(i,a);return r&&(n.rem=r),r=s.map(function(e,t){return Te({index:t/(s.length-1),value:e,label:o(e)})}),e.extra&&r.push(Te({index:-1,extra:{value:r[0].value},label:\"\"})),n.source=r,n.add=r,this.value=r,n},Object(Ee.t)(zh,Yr).transform=function(e,t){var n=t.dataflow,r=t.fork(t.NO_SOURCE|t.NO_FIELDS),i=e.item||qh,a=e.key||Me,o=this.value;return Object(Ee.u)(r.encode)&&(r.encode=null),o&&(e.modified(\"key\")||t.modified(a))&&Object(Ee.l)(\"DataJoin does not support modified key function or fields.\"),o||(t=t.addAll(),this.value=o=Object(Ee.p)().test(Gh),o.lookup=function(e){return o.get(a(e))}),t.visit(t.ADD,function(e){var t=a(e),n=o.get(t);n?n.exit?(o.empty--,r.add.push(n)):r.mod.push(n):(o.set(t,n=i(e)),r.add.push(n)),n.datum=e,n.exit=!1}),t.visit(t.MOD,function(e){var t=a(e),n=o.get(t);n&&(n.datum=e,r.mod.push(n))}),t.visit(t.REM,function(e){var t=a(e),n=o.get(t);e!==n.datum||n.exit||(r.rem.push(n),n.exit=!0,++o.empty)}),t.changed(t.ADD_MOD)&&r.modifies(\"datum\"),e.clean&&o.empty>n.cleanThreshold&&n.runAfter(o.clean),r},Object(Ee.t)($h,Yr).transform=function(e,t){var n=t.fork(t.ADD_REM),r=e.encoders,i=t.encode;if(Object(Ee.u)(i)){if(!n.changed()&&!i.every(function(e){return r[e]}))return t.StopPropagation;i=i[0],n.encode=null}var a=\"enter\"===i,o=r.update||Ee.o,s=r.enter||Ee.o,l=r.exit||Ee.o,c=(i&&!a?r[i]:o)||Ee.o;if(t.changed(t.ADD)&&(t.visit(t.ADD,function(t){s(t,e),o(t,e),c!==Ee.o&&c!==o&&c(t,e)}),n.modifies(s.output),n.modifies(o.output),c!==Ee.o&&c!==o&&n.modifies(c.output)),t.changed(t.REM)&&l!==Ee.o&&(t.visit(t.REM,function(t){l(t,e)}),n.modifies(l.output)),a||c!==Ee.o){var u=t.MOD|(e.modified()?t.REFLOW:0);a?(t.visit(u,function(t){var r=s(t,e);(c(t,e)||r)&&n.mod.push(t)}),n.mod.length&&n.modifies(s.output)):t.visit(u,function(t){c(t,e)&&n.mod.push(t)}),n.mod.length&&n.modifies(c.output)}return n.changed()?n:t.StopPropagation};var Hh=\"symbol\",Wh=\"discrete\",Vh={};function Kh(e,t,n){return n===Hh&&Vh[e.type]?function(e){return function(t,n,r){var i=r[n+1]||r.max||1/0,a=Qh(t,e),o=Qh(i,e);return a&&o?a+\"–\"+o:o?\"< \"+o:\"≥ \"+a}}(t):n===Wh?function(e){return function(t,n){return n?e(t):null}}(t):function(e){return function(t){return e(t)}}(t)}function Qh(e,t){return isFinite(e)?t(e):null}function Yh(e){Yr.call(this,[],e)}Vh[Rd]=function(e){var t=[-1/0].concat(e.quantiles());return t.max=1/0,t},Vh[Id]=function(e){var t=e.domain(),n=t[0],r=Object(Ee.K)(t),i=e.range().length,a=new Array(i),o=0;a[0]=-1/0;for(;++oMath.PI?n<=e:n>e;return\"M\"+t*i+\",\"+t*a+\"A\"+t+\",\"+t+\" 0 0,\"+(l?1:0)+\" \"+t*o+\",\"+t*s+\"L\"+r*o+\",\"+r*s},\"diagonal-horizontal\":function(e,t,n,r){var i=(e+n)/2;return\"M\"+e+\",\"+t+\"C\"+i+\",\"+t+\" \"+i+\",\"+r+\" \"+n+\",\"+r},\"diagonal-vertical\":function(e,t,n,r){var i=(t+r)/2;return\"M\"+e+\",\"+t+\"C\"+e+\",\"+i+\" \"+n+\",\"+i+\" \"+n+\",\"+r},\"diagonal-radial\":function(e,t,n,r){var i=Math.cos(e),a=Math.sin(e),o=Math.cos(n),s=Math.sin(n),l=(t+r)/2;return\"M\"+t*i+\",\"+t*a+\"C\"+l*i+\",\"+l*a+\" \"+l*o+\",\"+l*s+\" \"+r*o+\",\"+r*s}});function Xh(e){return e.source.x}function Jh(e){return e.source.y}function eb(e){return e.target.x}function tb(e){return e.target.y}function nb(e){Yr.call(this,{},e)}function rb(e,t,n,r){return\"M\"+e+\",\"+t+\"L\"+n+\",\"+r}function ib(e,t,n,r){var i=n-e,a=r-t,o=Math.sqrt(i*i+a*a)/2;return\"M\"+e+\",\"+t+\"A\"+o+\",\"+o+\" \"+180*Math.atan2(a,i)/Math.PI+\" 0 1 \"+n+\",\"+r}function ab(e,t,n,r){var i=n-e,a=r-t,o=.2*(i+a),s=.2*(a-i);return\"M\"+e+\",\"+t+\"C\"+(e+o)+\",\"+(t+s)+\" \"+(n+s)+\",\"+(r-o)+\" \"+n+\",\"+r}function ob(e){Yr.call(this,null,e)}nb.Definition={type:\"LinkPath\",metadata:{modifies:!0},params:[{name:\"sourceX\",type:\"field\",default:\"source.x\"},{name:\"sourceY\",type:\"field\",default:\"source.y\"},{name:\"targetX\",type:\"field\",default:\"target.x\"},{name:\"targetY\",type:\"field\",default:\"target.y\"},{name:\"orient\",type:\"enum\",default:\"vertical\",values:[\"horizontal\",\"vertical\",\"radial\"]},{name:\"shape\",type:\"enum\",default:\"line\",values:[\"line\",\"arc\",\"curve\",\"diagonal\",\"orthogonal\"]},{name:\"as\",type:\"string\",default:\"path\"}]},Object(Ee.t)(nb,Yr).transform=function(e,t){var n=e.sourceX||Xh,r=e.sourceY||Jh,i=e.targetX||eb,a=e.targetY||tb,o=e.as||\"path\",s=e.orient||\"vertical\",l=e.shape||\"line\",c=Zh.get(l+\"-\"+s)||Zh.get(l);return c||Object(Ee.l)(\"LinkPath unsupported type: \"+e.shape+(e.orient?\"-\"+e.orient:\"\")),t.visit(t.SOURCE,function(e){e[o]=c(n(e),r(e),i(e),a(e))}),t.reflow(e.modified()).modifies(o)},ob.Definition={type:\"Pie\",metadata:{modifies:!0},params:[{name:\"field\",type:\"field\"},{name:\"startAngle\",type:\"number\",default:0},{name:\"endAngle\",type:\"number\",default:6.283185307179586},{name:\"sort\",type:\"boolean\",default:!1},{name:\"as\",type:\"string\",array:!0,length:2,default:[\"startAngle\",\"endAngle\"]}]},Object(Ee.t)(ob,Yr).transform=function(e,t){var n,r,i,a=e.as||[\"startAngle\",\"endAngle\"],o=a[0],s=a[1],l=e.field||Ee.F,c=e.startAngle||0,u=null!=e.endAngle?e.endAngle:2*Math.PI,d=t.source,f=d.map(l),p=f.length,m=c,g=(u-c)/function(e,t){var n,r=e.length,i=-1,a=0;if(null==t)for(;++i-1)return r;var i,a,o=t.domain,s=e.type,l=t.zero||void 0===t.zero&&lb[s];if(!o)return 0;cb[s]&&t.padding&&o[0]!==Object(Ee.K)(o)&&(o=function(e,t,n,r,i){var a=Math.abs(Object(Ee.K)(n)-n[0]),o=a/(a-2*r),s=e===Md?Object(Ee.X)(t,null,o):e===Td?Object(Ee.Y)(t,null,o,.5):e===Nd?Object(Ee.Y)(t,null,o,i):Object(Ee.W)(t,null,o);return(t=t.slice())[0]=s[0],t[t.length-1]=s[1],t}(s,o,t.range,t.padding,t.exponent));(l||null!=t.domainMin||null!=t.domainMax||null!=t.domainMid)&&(i=(o=o.slice()).length-1||1,l&&(o[0]>0&&(o[0]=0),o[i]<0&&(o[i]=0)),null!=t.domainMin&&(o[0]=t.domainMin),null!=t.domainMax&&(o[i]=t.domainMax),null!=t.domainMid&&(((a=t.domainMid)o[i])&&n.warn(\"Scale domainMid exceeds domain min or max.\",a),o.splice(i,0,a)));e.domain(o),s===kd&&e.unknown(t.domainImplicit?tf:void 0);t.nice&&e.nice&&e.nice(!0!==t.nice&&Ph(e,t.nice)||null);return o.length}(i,e,r)),t.fork(t.NO_SOURCE|t.NO_FIELDS)},Object(Ee.t)(mb,Yr).transform=function(e,t){var n=e.modified(\"sort\")||t.changed(t.ADD)||t.modified(e.sort.fields)||t.modified(\"datum\");return n&&t.source.sort(e.sort),this.modified(n),t};function gb(e){Yr.call(this,null,e)}function hb(e,t,n,r,i){for(var a,o=(t-e.sum)/2,s=e.length,l=0;lf&&(f=d),n&&u.sort(n)}return p.max=f,p}(t.source,e.groupby,e.sort,c),r=0,i=n.length,a=n.max;rr!=p>r&&n<(f-c)*(r-u)/(p-u)+c&&(i=-i)}return i}function Cb(e,t,n){var r,i,a,o;return function(e,t,n){return(t[0]-e[0])*(n[1]-e[1])==(n[0]-e[0])*(t[1]-e[1])}(e,t,n)&&(i=e[r=+(e[0]===t[0])],a=n[r],o=t[r],i<=a&&a<=o||o<=a&&a<=i)}var Ob=function(){},Mb=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]],Nb=function(){var e=1,t=1,n=Ni,r=s;function i(e){var t=n(e);if(Array.isArray(t))t=t.slice().sort(yb);else{var r=_i(e),i=r[0],o=r[1];t=Mi(i,o,t),t=xi(Math.floor(i/t)*t,Math.floor(o/t)*t,t)}return t.map(function(t){return a(e,t)})}function a(n,i){var a=[],s=[];return function(n,r,i){var a,s,l,c,u,d,f=new Array,p=new Array;a=s=-1,c=n[0]>=r,Mb[c<<1].forEach(m);for(;++a=r,Mb[l|c<<1].forEach(m);Mb[c<<0].forEach(m);for(;++s=r,u=n[s*e]>=r,Mb[c<<1|u<<2].forEach(m);++a=r,d=u,u=n[s*e+a+1]>=r,Mb[l|c<<1|u<<2|d<<3].forEach(m);Mb[c|u<<3].forEach(m)}a=-1,u=n[s*e]>=r,Mb[u<<2].forEach(m);for(;++a=r,Mb[u<<2|d<<3].forEach(m);function m(e){var t,n,r=[e[0][0]+a,e[0][1]+s],l=[e[1][0]+a,e[1][1]+s],c=o(r),u=o(l);(t=p[c])?(n=f[u])?(delete p[t.end],delete f[n.start],t===n?(t.ring.push(l),i(t.ring)):f[t.start]=p[n.end]={start:t.start,end:n.end,ring:t.ring.concat(n.ring)}):(delete p[t.end],t.ring.push(l),p[t.end=u]=t):(t=f[u])?(n=p[c])?(delete f[t.start],delete p[n.end],t===n?(t.ring.push(l),i(t.ring)):f[n.start]=p[t.end]={start:n.start,end:t.end,ring:n.ring.concat(t.ring)}):(delete f[t.start],t.ring.unshift(r),f[t.start=c]=t):f[c]=p[u]={start:c,end:u,ring:[r,l]}}Mb[u<<3].forEach(m)}(n,i,function(e){r(e,n,i),xb(e)>0?a.push([e]):s.push(e)}),s.forEach(function(e){for(var t,n=0,r=a.length;n0&&o0&&s0&&a>0))throw new Error(\"invalid size\");return e=r,t=a,i},i.thresholds=function(e){return arguments.length?(n=\"function\"==typeof e?e:Array.isArray(e)?Eb(_b.call(e)):Eb(e),i):n},i.smooth=function(e){return arguments.length?(r=e?s:Ob,i):r===s},i};function Tb(e,t,n){for(var r=e.width,i=e.height,a=1+(n<<1),o=0;o=n&&(s>=a&&(l-=e.data[s-a+o*r]),t.data[s-n+o*r]=l/Math.min(s+1,r-1+a-s,a))}function Db(e,t,n){for(var r=e.width,i=e.height,a=1+(n<<1),o=0;o=n&&(s>=a&&(l-=e.data[o+(s-a)*r]),t.data[o+(s-n)*r]=l/Math.min(s+1,i-1+a-s,a))}function Ab(e){return e[0]}function kb(e){return e[1]}var Rb=[\"size\",\"smooth\"],Ib=[\"x\",\"y\",\"size\",\"cellSize\",\"bandwidth\"];function Lb(e){Yr.call(this,null,e)}Lb.Definition={type:\"Contour\",metadata:{generates:!0},params:[{name:\"size\",type:\"number\",array:!0,length:2,required:!0},{name:\"values\",type:\"number\",array:!0},{name:\"x\",type:\"field\"},{name:\"y\",type:\"field\"},{name:\"cellSize\",type:\"number\"},{name:\"bandwidth\",type:\"number\"},{name:\"count\",type:\"number\"},{name:\"smooth\",type:\"boolean\"},{name:\"nice\",type:\"boolean\",default:!1},{name:\"thresholds\",type:\"number\",array:!0}]},Object(Ee.t)(Lb,Yr).transform=function(e,t){if(this.value&&!t.changed()&&!e.modified())return t.StopPropagation;var n,r,i,a,o=t.fork(t.NO_SOURCE|t.NO_FIELDS),s=e.count||10;return e.values?(n=Nb(),r=Rb,i=e.values):(n=function(){var e=Ab,t=kb,n=960,r=500,i=20,a=2,o=3*i,s=n+2*o>>a,l=r+2*o>>a,c=Eb(20);function u(n){var r=new Float32Array(s*l),u=new Float32Array(s*l);n.forEach(function(n,i,c){var u=e(n,i,c)+o>>a,d=t(n,i,c)+o>>a;u>=0&&u=0&&d>a),Db({width:s,height:l,data:u},{width:s,height:l,data:r},i>>a),Tb({width:s,height:l,data:r},{width:s,height:l,data:u},i>>a),Db({width:s,height:l,data:u},{width:s,height:l,data:r},i>>a),Tb({width:s,height:l,data:r},{width:s,height:l,data:u},i>>a),Db({width:s,height:l,data:u},{width:s,height:l,data:r},i>>a);var f=c(r);if(!Array.isArray(f)){var p=Di(r);f=Mi(0,p,f),(f=xi(0,Math.floor(p/f)*f,f)).shift()}return Nb().thresholds(f).size([s,l])(r).map(d)}function d(e){return e.value*=Math.pow(2,-2*a),e.coordinates.forEach(f),e}function f(e){e.forEach(p)}function p(e){e.forEach(m)}function m(e){e[0]=e[0]*Math.pow(2,a)-o,e[1]=e[1]*Math.pow(2,a)-o}function g(){return s=n+2*(o=3*i)>>a,l=r+2*o>>a,u}return u.x=function(t){return arguments.length?(e=\"function\"==typeof t?t:Eb(+t),u):e},u.y=function(e){return arguments.length?(t=\"function\"==typeof e?e:Eb(+e),u):t},u.size=function(e){if(!arguments.length)return[n,r];var t=Math.ceil(e[0]),i=Math.ceil(e[1]);if(!(t>=0||t>=0))throw new Error(\"invalid size\");return n=t,r=i,g()},u.cellSize=function(e){if(!arguments.length)return 1<=1))throw new Error(\"invalid cell size\");return a=Math.floor(Math.log(e)/Math.LN2),g()},u.thresholds=function(e){return arguments.length?(c=\"function\"==typeof e?e:Array.isArray(e)?Eb(_b.call(e)):Eb(e),u):c},u.bandwidth=function(e){if(!arguments.length)return Math.sqrt(i*(i+1));if(!((e=+e)>=0))throw new Error(\"invalid bandwidth\");return i=Math.round((Math.sqrt(4*e*e+1)-1)/2),g()},u}(),r=Ib,i=t.materialize(t.SOURCE).source),n.thresholds(e.thresholds||(e.nice?s:(a=s,function(e){for(var t=_i(e),n=t[0],r=t[1]-n,i=[],o=1;o<=a;++o)i.push(n+r*o/(a+1));return i}))),r.forEach(function(t){null!=e[t]&&n[t](e[t])}),this.value&&(o.rem=this.value),i=i&&i.length?n(i).map(Te):[],this.value=o.source=o.add=i,o};var Pb=\"FeatureCollection\";function Fb(e){Yr.call(this,null,e)}Fb.Definition={type:\"GeoJSON\",metadata:{},params:[{name:\"fields\",type:\"field\",array:!0,length:2},{name:\"geojson\",type:\"field\"}]},Object(Ee.t)(Fb,Yr).transform=function(e,t){var n,r=this._features,i=this._points,a=e.fields,o=a&&a[0],s=a&&a[1],l=e.geojson,c=t.ADD;n=e.modified()||t.changed(t.REM)||t.modified(Object(Ee.f)(l))||o&&t.modified(Object(Ee.f)(o))||s&&t.modified(Object(Ee.f)(s)),this.value&&!n||(c=t.SOURCE,this._features=r=[],this._points=i=[]),l&&t.visit(c,function(e){r.push(l(e))}),o&&s&&(t.visit(c,function(e){var t=o(e),n=s(e);null!=t&&null!=n&&(t=+t)===t&&(n=+n)===n&&i.push([t,n])}),r=r.concat({type:\"Feature\",geometry:{type:\"MultiPoint\",coordinates:i}})),this.value={type:Pb,features:r}};var Bb=function(){return new Ub};function Ub(){this.reset()}Ub.prototype={constructor:Ub,reset:function(){this.s=this.t=0},add:function(e){zb(jb,e,this.t),zb(this,jb.s,this.s),this.s?this.t+=jb.t:this.s=jb.t},valueOf:function(){return this.s}};var jb=new Ub;function zb(e,t,n){var r=e.s=t+n,i=r-t,a=r-i;e.t=t-a+(n-i)}var qb=1e-6,Gb=Math.PI,$b=Gb/2,Hb=Gb/4,Wb=2*Gb,Vb=180/Gb,Kb=Gb/180,Qb=Math.abs,Yb=Math.atan,Zb=Math.atan2,Xb=Math.cos,Jb=Math.ceil,ev=Math.exp,tv=(Math.floor,Math.log),nv=Math.pow,rv=Math.sin,iv=Math.sign||function(e){return e>0?1:e<0?-1:0},av=Math.sqrt,ov=Math.tan;function sv(e){return e>1?0:e<-1?Gb:Math.acos(e)}function lv(e){return e>1?$b:e<-1?-$b:Math.asin(e)}function cv(){}function uv(e,t){e&&fv.hasOwnProperty(e.type)&&fv[e.type](e,t)}var dv={Feature:function(e,t){uv(e.geometry,t)},FeatureCollection:function(e,t){for(var n=e.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,a=Xb(t),o=rv(t),s=_v*o,l=vv*a+s*Xb(i),c=s*r*rv(i);xv.add(Zb(c,l)),bv=e,vv=a,_v=o}var Nv=function(e){return Ev.reset(),yv(e,Sv),2*Ev};function Tv(e){return[Zb(e[1],e[0]),lv(e[2])]}function Dv(e){var t=e[0],n=e[1],r=Xb(n);return[r*Xb(t),r*rv(t),rv(n)]}function Av(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function kv(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function Rv(e,t){e[0]+=t[0],e[1]+=t[1],e[2]+=t[2]}function Iv(e,t){return[e[0]*t,e[1]*t,e[2]*t]}function Lv(e){var t=av(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]);e[0]/=t,e[1]/=t,e[2]/=t}var Pv,Fv,Bv,Uv,jv,zv,qv,Gv,$v,Hv,Wv=Bb(),Vv={point:Kv,lineStart:Yv,lineEnd:Zv,polygonStart:function(){Vv.point=Xv,Vv.lineStart=Jv,Vv.lineEnd=e_,Wv.reset(),Sv.polygonStart()},polygonEnd:function(){Sv.polygonEnd(),Vv.point=Kv,Vv.lineStart=Yv,Vv.lineEnd=Zv,xv<0?(Pv=-(Bv=180),Fv=-(Uv=90)):Wv>qb?Uv=90:Wv<-qb&&(Fv=-90),Hv[0]=Pv,Hv[1]=Bv}};function Kv(e,t){$v.push(Hv=[Pv=e,Bv=e]),tUv&&(Uv=t)}function Qv(e,t){var n=Dv([e*Kb,t*Kb]);if(Gv){var r=kv(Gv,n),i=kv([r[1],-r[0],0],r);Lv(i),i=Tv(i);var a,o=e-jv,s=o>0?1:-1,l=i[0]*Vb*s,c=Qb(o)>180;c^(s*jvUv&&(Uv=a):c^(s*jv<(l=(l+360)%360-180)&&lUv&&(Uv=t)),c?et_(Pv,Bv)&&(Bv=e):t_(e,Bv)>t_(Pv,Bv)&&(Pv=e):Bv>=Pv?(eBv&&(Bv=e)):e>jv?t_(Pv,e)>t_(Pv,Bv)&&(Bv=e):t_(e,Bv)>t_(Pv,Bv)&&(Pv=e)}else $v.push(Hv=[Pv=e,Bv=e]);tUv&&(Uv=t),Gv=n,jv=e}function Yv(){Vv.point=Qv}function Zv(){Hv[0]=Pv,Hv[1]=Bv,Vv.point=Kv,Gv=null}function Xv(e,t){if(Gv){var n=e-jv;Wv.add(Qb(n)>180?n+(n>0?360:-360):n)}else zv=e,qv=t;Sv.point(e,t),Qv(e,t)}function Jv(){Sv.lineStart()}function e_(){Xv(zv,qv),Sv.lineEnd(),Qb(Wv)>qb&&(Pv=-(Bv=180)),Hv[0]=Pv,Hv[1]=Bv,Gv=null}function t_(e,t){return(t-=e)<0?t+360:t}function n_(e,t){return e[0]-t[0]}function r_(e,t){return e[0]<=e[1]?e[0]<=t&&t<=e[1]:tt_(r[0],r[1])&&(r[1]=i[1]),t_(i[0],r[1])>t_(r[0],r[1])&&(r[0]=i[0])):a.push(r=i);for(o=-1/0,t=0,r=a[n=a.length-1];t<=n;r=i,++t)i=a[t],(s=t_(r[1],i[0]))>o&&(o=s,Pv=i[0],Bv=r[1])}return $v=Hv=null,Pv===1/0||Fv===1/0?[[NaN,NaN],[NaN,NaN]]:[[Pv,Fv],[Bv,Uv]]},x_={sphere:cv,point:E_,lineStart:w_,lineEnd:M_,polygonStart:function(){x_.lineStart=N_,x_.lineEnd=T_},polygonEnd:function(){x_.lineStart=w_,x_.lineEnd=M_}};function E_(e,t){e*=Kb;var n=Xb(t*=Kb);S_(n*Xb(e),n*rv(e),rv(t))}function S_(e,t,n){o_+=(e-o_)/++i_,s_+=(t-s_)/i_,l_+=(n-l_)/i_}function w_(){x_.point=C_}function C_(e,t){e*=Kb;var n=Xb(t*=Kb);b_=n*Xb(e),v_=n*rv(e),__=rv(t),x_.point=O_,S_(b_,v_,__)}function O_(e,t){e*=Kb;var n=Xb(t*=Kb),r=n*Xb(e),i=n*rv(e),a=rv(t),o=Zb(av((o=v_*a-__*i)*o+(o=__*r-b_*a)*o+(o=b_*i-v_*r)*o),b_*r+v_*i+__*a);a_+=o,c_+=o*(b_+(b_=r)),u_+=o*(v_+(v_=i)),d_+=o*(__+(__=a)),S_(b_,v_,__)}function M_(){x_.point=E_}function N_(){x_.point=D_}function T_(){A_(g_,h_),x_.point=E_}function D_(e,t){g_=e,h_=t,e*=Kb,t*=Kb,x_.point=A_;var n=Xb(t);b_=n*Xb(e),v_=n*rv(e),__=rv(t),S_(b_,v_,__)}function A_(e,t){e*=Kb;var n=Xb(t*=Kb),r=n*Xb(e),i=n*rv(e),a=rv(t),o=v_*a-__*i,s=__*r-b_*a,l=b_*i-v_*r,c=av(o*o+s*s+l*l),u=lv(c),d=c&&-u/c;f_+=d*o,p_+=d*s,m_+=d*l,a_+=u,c_+=u*(b_+(b_=r)),u_+=u*(v_+(v_=i)),d_+=u*(__+(__=a)),S_(b_,v_,__)}var k_=function(e){i_=a_=o_=s_=l_=c_=u_=d_=f_=p_=m_=0,yv(e,x_);var t=f_,n=p_,r=m_,i=t*t+n*n+r*r;return i<1e-12&&(t=c_,n=u_,r=d_,a_Gb?e-Wb:e<-Gb?e+Wb:e,t]}function L_(e,t,n){return(e%=Wb)?t||n?R_(F_(e),B_(t,n)):F_(e):t||n?B_(t,n):I_}function P_(e){return function(t,n){return[(t+=e)>Gb?t-Wb:t<-Gb?t+Wb:t,n]}}function F_(e){var t=P_(e);return t.invert=P_(-e),t}function B_(e,t){var n=Xb(e),r=rv(e),i=Xb(t),a=rv(t);function o(e,t){var o=Xb(t),s=Xb(e)*o,l=rv(e)*o,c=rv(t),u=c*n+s*r;return[Zb(l*i-u*a,s*n-c*r),lv(u*i+l*a)]}return o.invert=function(e,t){var o=Xb(t),s=Xb(e)*o,l=rv(e)*o,c=rv(t),u=c*i-l*a;return[Zb(l*i+c*a,s*n+u*r),lv(u*n-s*r)]},o}I_.invert=I_;var U_=function(e){function t(t){return(t=e(t[0]*Kb,t[1]*Kb))[0]*=Vb,t[1]*=Vb,t}return e=L_(e[0]*Kb,e[1]*Kb,e.length>2?e[2]*Kb:0),t.invert=function(t){return(t=e.invert(t[0]*Kb,t[1]*Kb))[0]*=Vb,t[1]*=Vb,t},t};function j_(e,t,n,r,i,a){if(n){var o=Xb(t),s=rv(t),l=r*n;null==i?(i=t+r*Wb,a=t-l/2):(i=z_(o,i),a=z_(o,a),(r>0?ia)&&(i+=r*Wb));for(var c,u=i;r>0?u>a:u1&&t.push(t.pop().concat(t.shift()))},result:function(){var n=t;return t=[],e=null,n}}},G_=function(e,t){return Qb(e[0]-t[0])=0;--a)i.point((u=c[a])[0],u[1]);else r(f.x,f.p.x,-1,i);f=f.p}c=(f=f.o).z,p=!p}while(!f.v);i.lineEnd()}}};function W_(e){if(t=e.length){for(var t,n,r=0,i=e[0];++r=0?1:-1,C=w*S,O=C>Gb,M=g*x;if(V_.add(Zb(M*w*rv(C),h*E+M*Xb(C))),o+=O?S+w*Wb:S,O^p>=n^_>=n){var N=kv(Dv(f),Dv(v));Lv(N);var T=kv(a,N);Lv(T);var D=(O^S>=0?-1:1)*lv(T[2]);(r>D||r===D&&(N[0]||N[1]))&&(s+=O^S>=0?1:-1)}}return(o<-qb||o0){for(d||(i.polygonStart(),d=!0),i.lineStart(),e=0;e1&&2&l&&f.push(f.pop().concat(f.shift())),o.push(f.filter(Y_))}return f}};function Y_(e){return e.length>1}function Z_(e,t){return((e=e.x)[0]<0?e[1]-$b-qb:$b-e[1])-((t=t.x)[0]<0?t[1]-$b-qb:$b-t[1])}var X_=Q_(function(){return!0},function(e){var t,n=NaN,r=NaN,i=NaN;return{lineStart:function(){e.lineStart(),t=1},point:function(a,o){var s=a>0?Gb:-Gb,l=Qb(a-n);Qb(l-Gb)0?$b:-$b),e.point(i,r),e.lineEnd(),e.lineStart(),e.point(s,r),e.point(a,r),t=0):i!==s&&l>=Gb&&(Qb(n-i)qb?Yb((rv(t)*(a=Xb(r))*rv(n)-rv(r)*(i=Xb(t))*rv(e))/(i*a*o)):(t+r)/2}(n,r,a,o),e.point(i,r),e.lineEnd(),e.lineStart(),e.point(s,r),t=0),e.point(n=a,r=o),i=s},lineEnd:function(){e.lineEnd(),n=r=NaN},clean:function(){return 2-t}}},function(e,t,n,r){var i;if(null==e)i=n*$b,r.point(-Gb,i),r.point(0,i),r.point(Gb,i),r.point(Gb,0),r.point(Gb,-i),r.point(0,-i),r.point(-Gb,-i),r.point(-Gb,0),r.point(-Gb,i);else if(Qb(e[0]-t[0])>qb){var a=e[0]0,i=Qb(t)>qb;function a(e,n){return Xb(e)*Xb(n)>t}function o(e,n,r){var i=[1,0,0],a=kv(Dv(e),Dv(n)),o=Av(a,a),s=a[0],l=o-s*s;if(!l)return!r&&e;var c=t*o/l,u=-t*s/l,d=kv(i,a),f=Iv(i,c);Rv(f,Iv(a,u));var p=d,m=Av(f,p),g=Av(p,p),h=m*m-g*(Av(f,f)-1);if(!(h<0)){var b=av(h),v=Iv(p,(-m-b)/g);if(Rv(v,f),v=Tv(v),!r)return v;var _,y=e[0],x=n[0],E=e[1],S=n[1];x0^v[1]<(Qb(v[0]-y)Gb^(y<=v[0]&&v[0]<=x)){var O=Iv(p,(-m+b)/g);return Rv(O,f),[v,Tv(O)]}}}function s(t,n){var i=r?e:Gb-e,a=0;return t<-i?a|=1:t>i&&(a|=2),n<-i?a|=4:n>i&&(a|=8),a}return Q_(a,function(e){var t,n,l,c,u;return{lineStart:function(){c=l=!1,u=1},point:function(d,f){var p,m=[d,f],g=a(d,f),h=r?g?0:s(d,f):g?s(d+(d<0?Gb:-Gb),f):0;if(!t&&(c=l=g)&&e.lineStart(),g!==l&&(!(p=o(t,m))||G_(t,p)||G_(m,p))&&(m[0]+=qb,m[1]+=qb,g=a(m[0],m[1])),g!==l)u=0,g?(e.lineStart(),p=o(m,t),e.point(p[0],p[1])):(p=o(t,m),e.point(p[0],p[1]),e.lineEnd()),t=p;else if(i&&t&&r^g){var b;h&n||!(b=o(m,t,!0))||(u=0,r?(e.lineStart(),e.point(b[0][0],b[0][1]),e.point(b[1][0],b[1][1]),e.lineEnd()):(e.point(b[1][0],b[1][1]),e.lineEnd(),e.lineStart(),e.point(b[0][0],b[0][1])))}!g||t&&G_(t,m)||e.point(m[0],m[1]),t=m,l=g,n=h},lineEnd:function(){l&&e.lineEnd(),t=null},clean:function(){return u|(c&&l)<<1}}},function(t,r,i,a){j_(a,e,n,i,t,r)},r?[0,-e]:[-Gb,e-Gb])},ey=function(e,t,n,r,i,a){var o,s=e[0],l=e[1],c=0,u=1,d=t[0]-s,f=t[1]-l;if(o=n-s,d||!(o>0)){if(o/=d,d<0){if(o0){if(o>u)return;o>c&&(c=o)}if(o=i-s,d||!(o<0)){if(o/=d,d<0){if(o>u)return;o>c&&(c=o)}else if(d>0){if(o0)){if(o/=f,f<0){if(o0){if(o>u)return;o>c&&(c=o)}if(o=a-l,f||!(o<0)){if(o/=f,f<0){if(o>u)return;o>c&&(c=o)}else if(f>0){if(o0&&(e[0]=s+c*d,e[1]=l+c*f),u<1&&(t[0]=s+u*d,t[1]=l+u*f),!0}}}}},ty=1e9,ny=-ty;function ry(e,t,n,r){function i(i,a){return e<=i&&i<=n&&t<=a&&a<=r}function a(i,a,s,c){var u=0,d=0;if(null==i||(u=o(i,s))!==(d=o(a,s))||l(i,a)<0^s>0)do{c.point(0===u||3===u?e:n,u>1?r:t)}while((u=(u+s+4)%4)!==d);else c.point(a[0],a[1])}function o(r,i){return Qb(r[0]-e)0?0:3:Qb(r[0]-n)0?2:1:Qb(r[1]-t)0?1:0:i>0?3:2}function s(e,t){return l(e.x,t.x)}function l(e,t){var n=o(e,1),r=o(t,1);return n!==r?n-r:0===n?t[1]-e[1]:1===n?e[0]-t[0]:2===n?e[1]-t[1]:t[0]-e[0]}return function(o){var l,c,u,d,f,p,m,g,h,b,v,_=o,y=q_(),x={point:E,lineStart:function(){x.point=S,c&&c.push(u=[]);b=!0,h=!1,m=g=NaN},lineEnd:function(){l&&(S(d,f),p&&h&&y.rejoin(),l.push(y.result()));x.point=E,h&&_.lineEnd()},polygonStart:function(){_=y,l=[],c=[],v=!0},polygonEnd:function(){var t=function(){for(var t=0,n=0,i=c.length;nr&&(f-a)*(r-o)>(p-o)*(e-a)&&++t:p<=r&&(f-a)*(r-o)<(p-o)*(e-a)&&--t;return t}(),n=v&&t,i=(l=Ai(l)).length;(n||i)&&(o.polygonStart(),n&&(o.lineStart(),a(null,null,1,o),o.lineEnd()),i&&H_(l,s,t,a,o),o.polygonEnd());_=o,l=c=u=null}};function E(e,t){i(e,t)&&_.point(e,t)}function S(a,o){var s=i(a,o);if(c&&u.push([a,o]),b)d=a,f=o,p=s,b=!1,s&&(_.lineStart(),_.point(a,o));else if(s&&h)_.point(a,o);else{var l=[m=Math.max(ny,Math.min(ty,m)),g=Math.max(ny,Math.min(ty,g))],y=[a=Math.max(ny,Math.min(ty,a)),o=Math.max(ny,Math.min(ty,o))];ey(l,y,e,t,n,r)?(h||(_.lineStart(),_.point(l[0],l[1])),_.point(y[0],y[1]),s||_.lineEnd(),v=!1):s&&(_.lineStart(),_.point(a,o),v=!1)}m=a,g=o,h=s}return x}}Bb();function iy(e,t,n){var r=xi(e,t-qb,n).concat(t);return function(e){return r.map(function(t){return[e,t]})}}function ay(e,t,n){var r=xi(e,t-qb,n).concat(t);return function(e){return r.map(function(t){return[t,e]})}}function oy(){var e,t,n,r,i,a,o,s,l,c,u,d,f=10,p=f,m=90,g=360,h=2.5;function b(){return{type:\"MultiLineString\",coordinates:v()}}function v(){return xi(Jb(r/m)*m,n,m).map(u).concat(xi(Jb(s/g)*g,o,g).map(d)).concat(xi(Jb(t/f)*f,e,f).filter(function(e){return Qb(e%m)>qb}).map(l)).concat(xi(Jb(a/p)*p,i,p).filter(function(e){return Qb(e%g)>qb}).map(c))}return b.lines=function(){return v().map(function(e){return{type:\"LineString\",coordinates:e}})},b.outline=function(){return{type:\"Polygon\",coordinates:[u(r).concat(d(o).slice(1),u(n).reverse().slice(1),d(s).reverse().slice(1))]}},b.extent=function(e){return arguments.length?b.extentMajor(e).extentMinor(e):b.extentMinor()},b.extentMajor=function(e){return arguments.length?(r=+e[0][0],n=+e[1][0],s=+e[0][1],o=+e[1][1],r>n&&(e=r,r=n,n=e),s>o&&(e=s,s=o,o=e),b.precision(h)):[[r,s],[n,o]]},b.extentMinor=function(n){return arguments.length?(t=+n[0][0],e=+n[1][0],a=+n[0][1],i=+n[1][1],t>e&&(n=t,t=e,e=n),a>i&&(n=a,a=i,i=n),b.precision(h)):[[t,a],[e,i]]},b.step=function(e){return arguments.length?b.stepMajor(e).stepMinor(e):b.stepMinor()},b.stepMajor=function(e){return arguments.length?(m=+e[0],g=+e[1],b):[m,g]},b.stepMinor=function(e){return arguments.length?(f=+e[0],p=+e[1],b):[f,p]},b.precision=function(f){return arguments.length?(h=+f,l=iy(a,i,90),c=ay(t,e,h),u=iy(s,o,90),d=ay(r,n,h),b):h},b.extentMajor([[-180,-90+qb],[180,90-qb]]).extentMinor([[-180,-80-qb],[180,80+qb]])}var sy,ly,cy,uy,dy=function(e){return e},fy=Bb(),py=Bb(),my={point:cv,lineStart:cv,lineEnd:cv,polygonStart:function(){my.lineStart=gy,my.lineEnd=vy},polygonEnd:function(){my.lineStart=my.lineEnd=my.point=cv,fy.add(Qb(py)),py.reset()},result:function(){var e=fy/2;return fy.reset(),e}};function gy(){my.point=hy}function hy(e,t){my.point=by,sy=cy=e,ly=uy=t}function by(e,t){py.add(uy*e-cy*t),cy=e,uy=t}function vy(){by(sy,ly)}var _y=my,yy=1/0,xy=yy,Ey=-yy,Sy=Ey;var wy,Cy,Oy,My,Ny={point:function(e,t){eEy&&(Ey=e);tSy&&(Sy=t)},lineStart:cv,lineEnd:cv,polygonStart:cv,polygonEnd:cv,result:function(){var e=[[yy,xy],[Ey,Sy]];return Ey=Sy=-(xy=yy=1/0),e}},Ty=0,Dy=0,Ay=0,ky=0,Ry=0,Iy=0,Ly=0,Py=0,Fy=0,By={point:Uy,lineStart:jy,lineEnd:Gy,polygonStart:function(){By.lineStart=$y,By.lineEnd=Hy},polygonEnd:function(){By.point=Uy,By.lineStart=jy,By.lineEnd=Gy},result:function(){var e=Fy?[Ly/Fy,Py/Fy]:Iy?[ky/Iy,Ry/Iy]:Ay?[Ty/Ay,Dy/Ay]:[NaN,NaN];return Ty=Dy=Ay=ky=Ry=Iy=Ly=Py=Fy=0,e}};function Uy(e,t){Ty+=e,Dy+=t,++Ay}function jy(){By.point=zy}function zy(e,t){By.point=qy,Uy(Oy=e,My=t)}function qy(e,t){var n=e-Oy,r=t-My,i=av(n*n+r*r);ky+=i*(Oy+e)/2,Ry+=i*(My+t)/2,Iy+=i,Uy(Oy=e,My=t)}function Gy(){By.point=Uy}function $y(){By.point=Wy}function Hy(){Vy(wy,Cy)}function Wy(e,t){By.point=Vy,Uy(wy=Oy=e,Cy=My=t)}function Vy(e,t){var n=e-Oy,r=t-My,i=av(n*n+r*r);ky+=i*(Oy+e)/2,Ry+=i*(My+t)/2,Iy+=i,Ly+=(i=My*e-Oy*t)*(Oy+e),Py+=i*(My+t),Fy+=3*i,Uy(Oy=e,My=t)}var Ky=By;function Qy(e){this._context=e}Qy.prototype={_radius:4.5,pointRadius:function(e){return this._radius=e,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(e,t){switch(this._point){case 0:this._context.moveTo(e,t),this._point=1;break;case 1:this._context.lineTo(e,t);break;default:this._context.moveTo(e+this._radius,t),this._context.arc(e,t,this._radius,0,Wb)}},result:cv};var Yy,Zy,Xy,Jy,ex,tx=Bb(),nx={point:cv,lineStart:function(){nx.point=rx},lineEnd:function(){Yy&&ix(Zy,Xy),nx.point=cv},polygonStart:function(){Yy=!0},polygonEnd:function(){Yy=null},result:function(){var e=+tx;return tx.reset(),e}};function rx(e,t){nx.point=ix,Zy=Jy=e,Xy=ex=t}function ix(e,t){Jy-=e,ex-=t,tx.add(av(Jy*Jy+ex*ex)),Jy=e,ex=t}var ax=nx;function ox(){this._string=[]}function sx(e){return\"m0,\"+e+\"a\"+e+\",\"+e+\" 0 1,1 0,\"+-2*e+\"a\"+e+\",\"+e+\" 0 1,1 0,\"+2*e+\"z\"}ox.prototype={_radius:4.5,_circle:sx(4.5),pointRadius:function(e){return(e=+e)!==this._radius&&(this._radius=e,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._string.push(\"Z\"),this._point=NaN},point:function(e,t){switch(this._point){case 0:this._string.push(\"M\",e,\",\",t),this._point=1;break;case 1:this._string.push(\"L\",e,\",\",t);break;default:null==this._circle&&(this._circle=sx(this._radius)),this._string.push(\"M\",e,\",\",t,this._circle)}},result:function(){if(this._string.length){var e=this._string.join(\"\");return this._string=[],e}return null}};var lx=function(e,t){var n,r,i=4.5;function a(e){return e&&(\"function\"==typeof i&&r.pointRadius(+i.apply(this,arguments)),yv(e,n(r))),r.result()}return a.area=function(e){return yv(e,n(_y)),_y.result()},a.measure=function(e){return yv(e,n(ax)),ax.result()},a.bounds=function(e){return yv(e,n(Ny)),Ny.result()},a.centroid=function(e){return yv(e,n(Ky)),Ky.result()},a.projection=function(t){return arguments.length?(n=null==t?(e=null,dy):(e=t).stream,a):e},a.context=function(e){return arguments.length?(r=null==e?(t=null,new ox):new Qy(t=e),\"function\"!=typeof i&&r.pointRadius(i),a):t},a.pointRadius=function(e){return arguments.length?(i=\"function\"==typeof e?e:(r.pointRadius(+e),+e),a):i},a.projection(e).context(t)};function cx(e){return function(t){var n=new ux;for(var r in e)n[r]=e[r];return n.stream=t,n}}function ux(){}function dx(e,t,n){var r=e.clipExtent&&e.clipExtent();return e.scale(150).translate([0,0]),null!=r&&e.clipExtent(null),yv(n,e.stream(Ny)),t(Ny.result()),null!=r&&e.clipExtent(r),e}function fx(e,t,n){return dx(e,function(n){var r=t[1][0]-t[0][0],i=t[1][1]-t[0][1],a=Math.min(r/(n[1][0]-n[0][0]),i/(n[1][1]-n[0][1])),o=+t[0][0]+(r-a*(n[1][0]+n[0][0]))/2,s=+t[0][1]+(i-a*(n[1][1]+n[0][1]))/2;e.scale(150*a).translate([o,s])},n)}function px(e,t,n){return fx(e,[[0,0],t],n)}function mx(e,t,n){return dx(e,function(n){var r=+t,i=r/(n[1][0]-n[0][0]),a=(r-i*(n[1][0]+n[0][0]))/2,o=-i*n[0][1];e.scale(150*i).translate([a,o])},n)}function gx(e,t,n){return dx(e,function(n){var r=+t,i=r/(n[1][1]-n[0][1]),a=-i*n[0][0],o=(r-i*(n[1][1]+n[0][1]))/2;e.scale(150*i).translate([a,o])},n)}ux.prototype={constructor:ux,point:function(e,t){this.stream.point(e,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var hx=16,bx=Xb(30*Kb),vx=function(e,t){return+t?function(e,t){function n(r,i,a,o,s,l,c,u,d,f,p,m,g,h){var b=c-r,v=u-i,_=b*b+v*v;if(_>4*t&&g--){var y=o+f,x=s+p,E=l+m,S=av(y*y+x*x+E*E),w=lv(E/=S),C=Qb(Qb(E)-1)t||Qb((b*T+v*D)/_-.5)>.3||o*f+s*p+l*m2?e[2]%360*Kb:0,M()):[h*Vb,b*Vb,v*Vb]},C.angle=function(e){return arguments.length?(_=e%360*Kb,M()):_*Vb},C.precision=function(e){return arguments.length?(o=vx(s,w=e*e),N()):av(w)},C.fitExtent=function(e,t){return fx(C,e,t)},C.fitSize=function(e,t){return px(C,e,t)},C.fitWidth=function(e,t){return mx(C,e,t)},C.fitHeight=function(e,t){return gx(C,e,t)},function(){return t=e.apply(this,arguments),C.invert=t.invert&&O,M()}}function Sx(e){var t=0,n=Gb/3,r=Ex(e),i=r(t,n);return i.parallels=function(e){return arguments.length?r(t=e[0]*Kb,n=e[1]*Kb):[t*Vb,n*Vb]},i}function wx(e,t){var n=rv(e),r=(n+rv(t))/2;if(Qb(r)0?t<-$b+qb&&(t=-$b+qb):t>$b-qb&&(t=$b-qb);var n=i/nv(Rx(t),r);return[n*rv(r*e),i-n*Xb(r*e)]}return a.invert=function(e,t){var n=i-t,a=iv(r)*av(e*e+n*n);return[Zb(e,Qb(n))/r*iv(n),2*Yb(nv(i/a,1/r))-$b]},a}function Lx(e,t){return[e,t]}Lx.invert=Lx;function Px(e,t){var n=Xb(e),r=e===t?rv(e):(n-Xb(t))/(t-e),i=n/r+e;if(Qb(r)qb&&--i>0);return[e/(.8707+(a=r*r)*(a*(a*a*a*(.003971-.001529*a)-.013791)-.131979)),r]};function jx(e,t){return[Xb(t)*rv(e),rv(t)]}jx.invert=Nx(lv);function zx(e,t){var n=Xb(t),r=1+Xb(e)*n;return[n*rv(e)/r,rv(t)/r]}zx.invert=Nx(function(e){return 2*Yb(e)});function qx(e,t){return[tv(ov(($b+t)/2)),-e]}qx.invert=function(e,t){return[-t,2*Yb(ev(e))-$b]};var Gx=lx(),$x=[\"clipAngle\",\"clipExtent\",\"scale\",\"translate\",\"center\",\"rotate\",\"parallels\",\"precision\",\"reflectX\",\"reflectY\",\"coefficient\",\"distance\",\"fraction\",\"lobes\",\"parallel\",\"radius\",\"ratio\",\"spacing\",\"tilt\"];function Hx(e,t){if(!e||\"string\"!=typeof e)throw new Error(\"Projection type must be a name string.\");return e=e.toLowerCase(),arguments.length>1?(Vx[e]=function(e,t){return function n(){var r=t();return r.type=e,r.path=lx().projection(r),r.copy=r.copy||function(){var e=n();return $x.forEach(function(t){r.hasOwnProperty(t)&&e[t](r[t]())}),e.path.pointRadius(r.path.pointRadius()),e},r}}(e,t),this):Vx.hasOwnProperty(e)?Vx[e]:null}function Wx(e){return e&&e.path||Gx}var Vx={albers:Ox,albersusa:function(){var e,t,n,r,i,a,o=Ox(),s=Cx().rotate([154,0]).center([-2,58.5]).parallels([55,65]),l=Cx().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(e,t){a=[e,t]}};function u(e){var t=e[0],o=e[1];return a=null,n.point(t,o),a||(r.point(t,o),a)||(i.point(t,o),a)}function d(){return e=t=null,u}return u.invert=function(e){var t=o.scale(),n=o.translate(),r=(e[0]-n[0])/t,i=(e[1]-n[1])/t;return(i>=.12&&i<.234&&r>=-.425&&r<-.214?s:i>=.166&&i<.234&&r>=-.214&&r<-.115?l:o).invert(e)},u.stream=function(n){return e&&t===n?e:(r=[o.stream(t=n),s.stream(n),l.stream(n)],i=r.length,e={point:function(e,t){for(var n=-1;++n2?e[2]+90:90]):[(e=n())[0],e[1],e[2]-90]},n([0,0,90]).scale(159.155)}};for(var Kx in Vx)Hx(Kx,Vx[Kx]);function Qx(e){Yr.call(this,null,e)}function Yx(e){Yr.call(this,null,e)}function Zx(e){Yr.call(this,null,e)}function Xx(e){Yr.call(this,[],e),this.generator=oy()}function Jx(e){Yr.call(this,null,e),this.modified(!0)}function eE(e,t,n){Object(Ee.x)(e[t])&&e[t](n)}Qx.Definition={type:\"GeoPath\",metadata:{modifies:!0},params:[{name:\"projection\",type:\"projection\"},{name:\"field\",type:\"field\"},{name:\"pointRadius\",type:\"number\",expr:!0},{name:\"as\",type:\"string\",default:\"path\"}]},Object(Ee.t)(Qx,Yr).transform=function(e,t){var n=t.fork(t.ALL),r=this.value,i=e.field||Ee.s,a=e.as||\"path\",o=n.SOURCE;!r||e.modified()?(this.value=r=Wx(e.projection),n.materialize().reflow()):o=i===Ee.s||t.modified(i.fields)?n.ADD_MOD:n.ADD;var s=function(e,t){var n=e.pointRadius();e.context(null),null!=t&&e.pointRadius(t);return n}(r,e.pointRadius);return n.visit(o,function(e){e[a]=r(i(e))}),r.pointRadius(s),n.modifies(a)},Yx.Definition={type:\"GeoPoint\",metadata:{modifies:!0},params:[{name:\"projection\",type:\"projection\",required:!0},{name:\"fields\",type:\"field\",array:!0,required:!0,length:2},{name:\"as\",type:\"string\",array:!0,length:2,default:[\"x\",\"y\"]}]},Object(Ee.t)(Yx,Yr).transform=function(e,t){var n,r=e.projection,i=e.fields[0],a=e.fields[1],o=e.as||[\"x\",\"y\"],s=o[0],l=o[1];function c(e){var t=r([i(e),a(e)]);t?(e[s]=t[0],e[l]=t[1]):(e[s]=void 0,e[l]=void 0)}return e.modified()?t=t.materialize().reflow(!0).visit(t.SOURCE,c):(n=t.modified(i.fields)||t.modified(a.fields),t.visit(n?t.ADD_MOD:t.ADD,c)),t.modifies(o)},Zx.Definition={type:\"GeoShape\",metadata:{modifies:!0},params:[{name:\"projection\",type:\"projection\"},{name:\"field\",type:\"field\",default:\"datum\"},{name:\"pointRadius\",type:\"number\",expr:!0},{name:\"as\",type:\"string\",default:\"shape\"}]},Object(Ee.t)(Zx,Yr).transform=function(e,t){var n=t.fork(t.ALL),r=this.value,i=e.field||Object(Ee.q)(\"datum\"),a=e.as||\"shape\",o=n.ADD_MOD;return r&&!e.modified()||(this.value=r=function(e,t,n){var r=null==n?function(n){return e(t(n))}:function(r){var i=e.pointRadius(),a=e.pointRadius(n)(t(r));return e.pointRadius(i),a};return r.context=function(t){return e.context(t),r},r}(Wx(e.projection),i,e.pointRadius),n.materialize().reflow(),o=n.SOURCE),n.visit(o,function(e){e[a]=r}),n.modifies(a)},Xx.Definition={type:\"Graticule\",metadata:{changes:!0},params:[{name:\"extent\",type:\"array\",array:!0,length:2,content:{type:\"number\",array:!0,length:2}},{name:\"extentMajor\",type:\"array\",array:!0,length:2,content:{type:\"number\",array:!0,length:2}},{name:\"extentMinor\",type:\"array\",array:!0,length:2,content:{type:\"number\",array:!0,length:2}},{name:\"step\",type:\"number\",array:!0,length:2},{name:\"stepMajor\",type:\"number\",array:!0,length:2,default:[90,360]},{name:\"stepMinor\",type:\"number\",array:!0,length:2,default:[10,10]},{name:\"precision\",type:\"number\",default:2.5}]},Object(Ee.t)(Xx,Yr).transform=function(e,t){var n,r=this.value,i=this.generator;if(!r.length||e.modified())for(var a in e)Object(Ee.x)(i[a])&&i[a](e[a]);return n=i(),r.length?t.mod.push(ke(r[0],n)):t.add.push(Te(n)),r[0]=n,t},Object(Ee.t)(Jx,Yr).transform=function(e,t){var n=this.value;return!n||e.modified(\"type\")?(this.value=n=function(e){var t=Hx((e||\"mercator\").toLowerCase());t||Object(Ee.l)(\"Unrecognized projection type: \"+e);return t()}(e.type),$x.forEach(function(t){null!=e[t]&&eE(n,t,e[t])})):$x.forEach(function(t){e.modified(t)&&eE(n,t,e[t])}),null!=e.pointRadius&&n.path.pointRadius(e.pointRadius),e.fit&&function(e,t){var n=(r=t.fit,1===(r=Object(Ee.h)(r)).length?r[0]:{type:Pb,features:r.reduce(function(e,t){return t&&t.type===Pb?e.push.apply(e,t.features):Object(Ee.u)(t)?e.push.apply(e,t):e.push(t),e},[])});var r;t.extent?e.fitExtent(t.extent,n):t.size&&e.fitSize(t.size,n)}(n,e),t.fork(t.NO_SOURCE|t.NO_FIELDS)};var tE=function(e){return function(){return e}},nE=function(){return 1e-6*(Math.random()-.5)};function rE(e,t,n,r){if(isNaN(t)||isNaN(n))return e;var i,a,o,s,l,c,u,d,f,p=e._root,m={data:r},g=e._x0,h=e._y0,b=e._x1,v=e._y1;if(!p)return e._root=m,e;for(;p.length;)if((c=t>=(a=(g+b)/2))?g=a:b=a,(u=n>=(o=(h+v)/2))?h=o:v=o,i=p,!(p=p[d=u<<1|c]))return i[d]=m,e;if(s=+e._x.call(null,p.data),l=+e._y.call(null,p.data),t===s&&n===l)return m.next=p,i?i[d]=m:e._root=m,e;do{i=i?i[d]=new Array(4):e._root=new Array(4),(c=t>=(a=(g+b)/2))?g=a:b=a,(u=n>=(o=(h+v)/2))?h=o:v=o}while((d=u<<1|c)==(f=(l>=o)<<1|s>=a));return i[f]=p,i[d]=m,e}var iE=function(e,t,n,r,i){this.node=e,this.x0=t,this.y0=n,this.x1=r,this.y1=i};function aE(e){return e[0]}function oE(e){return e[1]}function sE(e,t,n){var r=new lE(null==t?aE:t,null==n?oE:n,NaN,NaN,NaN,NaN);return null==e?r:r.addAll(e)}function lE(e,t,n,r,i,a){this._x=e,this._y=t,this._x0=n,this._y0=r,this._x1=i,this._y1=a,this._root=void 0}function cE(e){for(var t={data:e.data},n=t;e=e.next;)n=n.next={data:e.data};return t}var uE=sE.prototype=lE.prototype;function dE(e){return e.x+e.vx}function fE(e){return e.y+e.vy}uE.copy=function(){var e,t,n=new lE(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return n;if(!r.length)return n._root=cE(r),n;for(e=[{source:r,target:n._root=new Array(4)}];r=e.pop();)for(var i=0;i<4;++i)(t=r.source[i])&&(t.length?e.push({source:t,target:r.target[i]=new Array(4)}):r.target[i]=cE(t));return n},uE.add=function(e){var t=+this._x.call(null,e),n=+this._y.call(null,e);return rE(this.cover(t,n),t,n,e)},uE.addAll=function(e){var t,n,r,i,a=e.length,o=new Array(a),s=new Array(a),l=1/0,c=1/0,u=-1/0,d=-1/0;for(n=0;nu&&(u=r),id&&(d=i));for(ue||e>i||r>t||t>a))return this;var o,s,l=i-n,c=this._root;switch(s=(t<(r+a)/2)<<1|e<(n+i)/2){case 0:do{(o=new Array(4))[s]=c,c=o}while(a=r+(l*=2),e>(i=n+l)||t>a);break;case 1:do{(o=new Array(4))[s]=c,c=o}while(a=r+(l*=2),(n=i-l)>e||t>a);break;case 2:do{(o=new Array(4))[s]=c,c=o}while(r=a-(l*=2),e>(i=n+l)||r>t);break;case 3:do{(o=new Array(4))[s]=c,c=o}while(r=a-(l*=2),(n=i-l)>e||r>t)}this._root&&this._root.length&&(this._root=c)}return this._x0=n,this._y0=r,this._x1=i,this._y1=a,this},uE.data=function(){var e=[];return this.visit(function(t){if(!t.length)do{e.push(t.data)}while(t=t.next)}),e},uE.extent=function(e){return arguments.length?this.cover(+e[0][0],+e[0][1]).cover(+e[1][0],+e[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]},uE.find=function(e,t,n){var r,i,a,o,s,l,c,u=this._x0,d=this._y0,f=this._x1,p=this._y1,m=[],g=this._root;for(g&&m.push(new iE(g,u,d,f,p)),null==n?n=1/0:(u=e-n,d=t-n,f=e+n,p=t+n,n*=n);l=m.pop();)if(!(!(g=l.node)||(i=l.x0)>f||(a=l.y0)>p||(o=l.x1)=b)<<1|e>=h)&&(l=m[m.length-1],m[m.length-1]=m[m.length-1-c],m[m.length-1-c]=l)}else{var v=e-+this._x.call(null,g.data),_=t-+this._y.call(null,g.data),y=v*v+_*_;if(y=(s=(m+h)/2))?m=s:h=s,(u=o>=(l=(g+b)/2))?g=l:b=l,t=p,!(p=p[d=u<<1|c]))return this;if(!p.length)break;(t[d+1&3]||t[d+2&3]||t[d+3&3])&&(n=t,f=d)}for(;p.data!==e;)if(r=p,!(p=p.next))return this;return(i=p.next)&&delete p.next,r?(i?r.next=i:delete r.next,this):t?(i?t[d]=i:delete t[d],(p=t[0]||t[1]||t[2]||t[3])&&p===(t[3]||t[2]||t[1]||t[0])&&!p.length&&(n?n[f]=p:this._root=p),this):(this._root=i,this)},uE.removeAll=function(e){for(var t=0,n=e.length;t=0&&(t=e.slice(n+1),e=e.slice(0,n)),e&&!r.hasOwnProperty(e))throw new Error(\"unknown type: \"+e);return{type:e,name:t}})),o=-1,s=a.length;if(!(arguments.length<2)){if(null!=t&&\"function\"!=typeof t)throw new Error(\"invalid callback: \"+t);for(;++o0)for(var n,r,i=new Array(n),a=0;a=0&&t._call.call(null,e),t=t._next;--SE}()}finally{SE=0,function(){var e,t,n=yE,r=1/0;for(;n;)n._call?(r>n._time&&(r=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:yE=t);xE=e,BE(r)}(),NE=0}}function FE(){var e=DE.now(),t=e-ME;t>OE&&(TE-=t,ME=e)}function BE(e){SE||(wE&&(wE=clearTimeout(wE)),e-NE>24?(e<1/0&&(wE=setTimeout(PE,e-DE.now()-TE)),CE&&(CE=clearInterval(CE))):(CE||(ME=DE.now(),CE=setInterval(FE,OE)),SE=1,AE(PE)))}IE.prototype=LE.prototype={constructor:IE,restart:function(e,t,n){if(\"function\"!=typeof e)throw new TypeError(\"callback is not a function\");n=(null==n?kE():+n)+(null==t?0:+t),this._next||xE===this||(xE?xE._next=this:yE=this,xE=this),this._call=e,this._time=n,BE()},stop:function(){this._call&&(this._call=null,this._time=1/0,BE())}};function UE(e){return e.x}function jE(e){return e.y}var zE=10,qE=Math.PI*(3-Math.sqrt(5)),GE=function(e){var t,n=1,r=.001,i=1-Math.pow(r,1/300),a=0,o=.6,s=Gd(),l=LE(u),c=EE(\"tick\",\"end\");function u(){d(),c.call(\"tick\",t),n1?(null==n?s.remove(e):s.set(e,p(n)),t):s.get(e)},find:function(t,n,r){var i,a,o,s,l,c=0,u=e.length;for(null==r?r=1/0:r*=r,c=0;c1?(c.on(e,n),t):c.on(e)}}},$E={center:function(e,t){var n;function r(){var r,i,a=n.length,o=0,s=0;for(r=0;rl+p||ic+p||as.index){var m=l-o.x-o.vx,g=c-o.y-o.vy,h=m*m+g*g;he.r&&(e.r=e[t].r)}function s(){if(t){var r,i,a=t.length;for(n=new Array(a),r=0;r=o)){(e.data!==t||e.next)&&(0===u&&(p+=(u=nE())*u),0===d&&(p+=(d=nE())*d),p=0;)i.tick();else if(i.stopped()&&i.restart(),!a)return t.StopPropagation;return this.finish(e,t)},YE.finish=function(e,t){for(var n,r=t.dataflow,i=this._argops,a=0,o=i.length;a=0;)t+=n[r].value;else t=1;e.value=t}function oS(e,t){var n,r,i,a,o,s=new uS(e),l=+e.value&&(s.value=e.value),c=[s];for(null==t&&(t=sS);n=c.pop();)if(l&&(n.value=+n.data.value),(i=t(n.data))&&(o=i.length))for(n.children=new Array(o),a=o-1;a>=0;--a)c.push(r=n.children[a]=new uS(i[a])),r.parent=n,r.depth=n.depth+1;return s.eachBefore(cS)}function sS(e){return e.children}function lS(e){e.data=e.data.data}function cS(e){var t=0;do{e.height=t}while((e=e.parent)&&e.height<++t)}function uS(e){this.data=e,this.depth=this.height=0,this.parent=null}uS.prototype=oS.prototype={constructor:uS,count:function(){return this.eachAfter(aS)},each:function(e){var t,n,r,i,a=this,o=[a];do{for(t=o.reverse(),o=[];a=t.pop();)if(e(a),n=a.children)for(r=0,i=n.length;r=0;--n)i.push(t[n]);return this},sum:function(e){return this.eachAfter(function(t){for(var n=+e(t.data)||0,r=t.children,i=r&&r.length;--i>=0;)n+=r[i].value;t.value=n})},sort:function(e){return this.eachBefore(function(t){t.children&&t.children.sort(e)})},path:function(e){for(var t=this,n=function(e,t){if(e===t)return e;var n=e.ancestors(),r=t.ancestors(),i=null;for(e=n.pop(),t=r.pop();e===t;)i=e,e=n.pop(),t=r.pop();return i}(t,e),r=[t];t!==n;)t=t.parent,r.push(t);for(var i=r.length;e!==n;)r.splice(i,0,e),e=e.parent;return r},ancestors:function(){for(var e=this,t=[e];e=e.parent;)t.push(e);return t},descendants:function(){var e=[];return this.each(function(t){e.push(t)}),e},leaves:function(){var e=[];return this.eachBefore(function(t){t.children||e.push(t)}),e},links:function(){var e=this,t=[];return e.each(function(n){n!==e&&t.push({source:n.parent,target:n})}),t},copy:function(){return oS(this).eachBefore(lS)}};var dS=Array.prototype.slice;var fS=function(e){for(var t,n,r=0,i=(e=function(e){for(var t,n,r=e.length;r;)n=Math.random()*r--|0,t=e[r],e[r]=e[n],e[n]=t;return e}(dS.call(e))).length,a=[];r0&&n*n>r*r+i*i}function hS(e,t){for(var n=0;n(o*=o)?(r=(c+o-i)/(2*c),a=Math.sqrt(Math.max(0,o/c-r*r)),n.x=e.x-r*s-a*l,n.y=e.y-r*l+a*s):(r=(c+i-o)/(2*c),a=Math.sqrt(Math.max(0,i/c-r*r)),n.x=t.x+r*s-a*l,n.y=t.y+r*l+a*s)):(n.x=t.x+n.r,n.y=t.y)}function xS(e,t){var n=e.r+t.r-1e-6,r=t.x-e.x,i=t.y-e.y;return n>0&&n*n>r*r+i*i}function ES(e){var t=e._,n=e.next._,r=t.r+n.r,i=(t.x*n.r+n.x*t.r)/r,a=(t.y*n.r+n.y*t.r)/r;return i*i+a*a}function SS(e){this._=e,this.next=null,this.previous=null}function wS(e){if(!(i=e.length))return 0;var t,n,r,i,a,o,s,l,c,u,d;if((t=e[0]).x=0,t.y=0,!(i>1))return t.r;if(n=e[1],t.x=-n.r,n.x=t.r,n.y=0,!(i>2))return t.r+n.r;yS(n,t,r=e[2]),t=new SS(t),n=new SS(n),r=new SS(r),t.next=r.previous=n,n.next=t.previous=r,r.next=n.previous=t;e:for(s=3;sf&&(f=s),h=u*u*g,(p=Math.max(f/h,h/d))>m){u-=s;break}m=p}b.push(o={value:u,dice:l1?t:1)},n}(WS),QS=function e(t){function n(e,n,r,i,a){if((o=e._squarify)&&o.ratio===t)for(var o,s,l,c,u,d=-1,f=o.length,p=e.value;++d1?t:1)},n}(WS);function YS(e){Yr.call(this,null,e)}function ZS(e){return e.values}function XS(e){Yr.call(this,null,e)}YS.Definition={type:\"Nest\",metadata:{treesource:!0,changes:!0},params:[{name:\"keys\",type:\"field\",array:!0},{name:\"generate\",type:\"boolean\"}]},Object(Ee.t)(YS,Yr).transform=function(e,t){t.source||Object(Ee.l)(\"Nest transform requires an upstream data source.\");var n=e.generate,r=e.modified(),i=t.clone(),a=this.value;return(!a||r||t.changed())&&(a&&a.each(function(e){e.children&&Oe(e.data)&&i.rem.push(e.data)}),this.value=a=oS({values:Object(Ee.h)(e.keys).reduce(function(e,t){return e.key(t),e},$d()).entries(i.source)},ZS),n&&a.each(function(e){e.children&&(e=Te(e.data),i.add.push(e),i.source.push(e))}),tS(a,Me,Me)),i.source.root=a,i},Object(Ee.t)(XS,Yr).transform=function(e,t){t.source&&t.source.root||Object(Ee.l)(this.constructor.name+\" transform requires a backing tree data source.\");var n=this.layout(e.method),r=this.fields,i=t.source.root,a=e.as||r;e.field&&i.sum(e.field),e.sort&&i.sort(e.sort),function(e,t,n){for(var r,i=0,a=t.length;i0)throw new Error(\"cycle\");return a}return n.id=function(t){return arguments.length?(e=CS(t),n):e},n.parentId=function(e){return arguments.length?(t=CS(e),n):t},n}().id(e.key).parentId(e.parentKey)(r.source),e.key,Ee.T)),r.source.root=this.value,r};var ow={tidy:function(){var e=US,t=1,n=1,r=null;function i(i){var l=function(e){for(var t,n,r,i,a,o=new $S(e,0),s=[o];t=s.pop();)if(r=t._.children)for(t.children=new Array(a=r.length),i=a-1;i>=0;--i)s.push(n=t.children[i]=new $S(r[i],i)),n.parent=t;return(o.parent=new $S(null,0)).children=[o],o}(i);if(l.eachAfter(a),l.parent.m=-l.z,l.eachBefore(o),r)i.eachBefore(s);else{var c=i,u=i,d=i;i.eachBefore(function(e){e.xu.x&&(u=e),e.depth>d.depth&&(d=e)});var f=c===u?1:e(c,u)/2,p=f-c.x,m=t/(u.x+f+p),g=n/(d.depth||1);i.eachBefore(function(e){e.x=(e.x+p)*m,e.y=e.depth*g})}return i}function a(t){var n=t.children,r=t.parent.children,i=t.i?r[t.i-1]:null;if(n){!function(e){for(var t,n=0,r=0,i=e.children,a=i.length;--a>=0;)(t=i[a]).z+=n,t.m+=n,n+=t.s+(r+=t.c)}(t);var a=(n[0].z+n[n.length-1].z)/2;i?(t.z=i.z+e(t._,i._),t.m=t.z-a):t.z=a}else i&&(t.z=i.z+e(t._,i._));t.parent.A=function(t,n,r){if(n){for(var i,a=t,o=t,s=n,l=a.parent.children[0],c=a.m,u=o.m,d=s.m,f=l.m;s=zS(s),a=jS(a),s&&a;)l=jS(l),(o=zS(o)).a=t,(i=s.z+d-a.z-c+e(s._,a._))>0&&(qS(GS(s,t,r),t,i),c+=i,u+=i),d+=s.m,c+=a.m,f+=l.m,u+=o.m;s&&!zS(o)&&(o.t=s,o.m+=d-u),a&&!jS(l)&&(l.t=a,l.m+=c-f,r=t)}return r}(t,i,t.parent.A||r[0])}function o(e){e._.x=e.z+e.parent.m,e.m+=e.parent.m}function s(e){e.x*=t,e.y=e.depth*n}return i.separation=function(t){return arguments.length?(e=t,i):e},i.size=function(e){return arguments.length?(r=!1,t=+e[0],n=+e[1],i):r?null:[t,n]},i.nodeSize=function(e){return arguments.length?(r=!0,t=+e[0],n=+e[1],i):r?[t,n]:null},i},cluster:function(){var e=nS,t=1,n=1,r=!1;function i(i){var a,o=0;i.eachAfter(function(t){var n=t.children;n?(t.x=function(e){return e.reduce(rS,0)/e.length}(n),t.y=function(e){return 1+e.reduce(iS,0)}(n)):(t.x=a?o+=e(t,a):0,t.y=0,a=t)});var s=function(e){for(var t;t=e.children;)e=t[0];return e}(i),l=function(e){for(var t;t=e.children;)e=t[t.length-1];return e}(i),c=s.x-e(s,l)/2,u=l.x+e(l,s)/2;return i.eachAfter(r?function(e){e.x=(e.x-i.x)*t,e.y=(i.y-e.y)*n}:function(e){e.x=(e.x-c)/(u-c)*t,e.y=(1-(i.y?e.y/i.y:1))*n})}return i.separation=function(t){return arguments.length?(e=t,i):e},i.size=function(e){return arguments.length?(r=!1,t=+e[0],n=+e[1],i):r?null:[t,n]},i.nodeSize=function(e){return arguments.length?(r=!0,t=+e[0],n=+e[1],i):r?[t,n]:null},i}},sw=[\"x\",\"y\",\"depth\",\"children\"];function lw(e){XS.call(this,e)}lw.Definition={type:\"Tree\",metadata:{tree:!0,modifies:!0},params:[{name:\"field\",type:\"field\"},{name:\"sort\",type:\"compare\"},{name:\"method\",type:\"enum\",default:\"tidy\",values:[\"tidy\",\"cluster\"]},{name:\"size\",type:\"number\",array:!0,length:2},{name:\"nodeSize\",type:\"number\",array:!0,length:2},{name:\"as\",type:\"string\",array:!0,length:4,default:sw}]};var cw=Object(Ee.t)(lw,XS);function uw(e){Yr.call(this,[],e)}cw.layout=function(e){var t=e||\"tidy\";if(ow.hasOwnProperty(t))return ow[t]();Object(Ee.l)(\"Unrecognized Tree layout method: \"+t)},cw.params=[\"size\",\"nodeSize\",\"separation\"],cw.fields=sw,uw.Definition={type:\"TreeLinks\",metadata:{tree:!0,generates:!0,changes:!0},params:[]},Object(Ee.t)(uw,Yr).transform=function(e,t){var n=this.value,r=t.source&&t.source.root,i=t.fork(t.NO_SOURCE),a={};return r||Object(Ee.l)(\"TreeLinks transform requires a tree data source.\"),t.changed(t.ADD_REM)?(i.rem=n,t.visit(t.SOURCE,function(e){a[Me(e)]=1}),r.each(function(e){var t=e.data,n=e.parent&&e.parent.data;n&&a[Me(t)]&&a[Me(n)]&&i.add.push(Te({source:n,target:t}))}),this.value=i.add):t.changed(t.MOD)&&(t.visit(t.MOD,function(e){a[Me(e)]=1}),n.forEach(function(e){(a[Me(e.source)]||a[Me(e.target)])&&i.mod.push(e)})),i};var dw={binary:function(e,t,n,r,i){var a,o,s=e.children,l=s.length,c=new Array(l+1);for(c[0]=o=a=0;a=n-1){var u=s[t];return u.x0=i,u.y0=a,u.x1=o,void(u.y1=l)}for(var d=c[t],f=r/2+d,p=t+1,m=n-1;p>>1;c[g]l-a){var v=(i*b+o*h)/r;e(t,p,h,i,a,v,l),e(p,n,b,v,a,o,l)}else{var _=(a*b+l*h)/r;e(t,p,h,i,a,o,_),e(p,n,b,i,_,o,l)}}(0,l,e.value,t,n,r,i)},dice:RS,slice:HS,slicedice:function(e,t,n,r,i){(1&e.depth?HS:RS)(e,t,n,r,i)},squarify:KS,resquarify:QS},fw=[\"x0\",\"y0\",\"x1\",\"y1\",\"depth\",\"children\"];function pw(e){XS.call(this,e)}pw.Definition={type:\"Treemap\",metadata:{tree:!0,modifies:!0},params:[{name:\"field\",type:\"field\"},{name:\"sort\",type:\"compare\"},{name:\"method\",type:\"enum\",default:\"squarify\",values:[\"squarify\",\"resquarify\",\"binary\",\"dice\",\"slice\",\"slicedice\"]},{name:\"padding\",type:\"number\",default:0},{name:\"paddingInner\",type:\"number\",default:0},{name:\"paddingOuter\",type:\"number\",default:0},{name:\"paddingTop\",type:\"number\",default:0},{name:\"paddingRight\",type:\"number\",default:0},{name:\"paddingBottom\",type:\"number\",default:0},{name:\"paddingLeft\",type:\"number\",default:0},{name:\"ratio\",type:\"number\",default:1.618033988749895},{name:\"round\",type:\"boolean\",default:!1},{name:\"size\",type:\"number\",array:!0,length:2},{name:\"as\",type:\"string\",array:!0,length:4,default:fw}]};var mw=Object(Ee.t)(pw,XS);mw.layout=function(){var e=function(){var e=KS,t=!1,n=1,r=1,i=[0],a=OS,o=OS,s=OS,l=OS,c=OS;function u(e){return e.x0=e.y0=0,e.x1=n,e.y1=r,e.eachBefore(d),i=[0],t&&e.eachBefore(kS),e}function d(t){var n=i[t.depth],r=t.x0+n,u=t.y0+n,d=t.x1-n,f=t.y1-n;d0)){if(a/=f,f<0){if(a0){if(a>d)return;a>u&&(u=a)}if(a=r-l,f||!(a<0)){if(a/=f,f<0){if(a>d)return;a>u&&(u=a)}else if(f>0){if(a0)){if(a/=p,p<0){if(a0){if(a>d)return;a>u&&(u=a)}if(a=i-c,p||!(a<0)){if(a/=p,p<0){if(a>d)return;a>u&&(u=a)}else if(p>0){if(a0||d<1)||(u>0&&(e[0]=[l+u*f,c+u*p]),d<1&&(e[1]=[l+d*f,c+d*p]),!0)}}}}}function Nw(e,t,n,r,i){var a=e[1];if(a)return!0;var o,s,l=e[0],c=e.left,u=e.right,d=c[0],f=c[1],p=u[0],m=u[1],g=(d+p)/2,h=(f+m)/2;if(m===f){if(g=r)return;if(d>p){if(l){if(l[1]>=i)return}else l=[g,n];a=[g,i]}else{if(l){if(l[1]1)if(d>p){if(l){if(l[1]>=i)return}else l=[(n-s)/o,n];a=[(i-s)/o,i]}else{if(l){if(l[1]=r)return}else l=[t,o*t+s];a=[r,o*r+s]}else{if(l){if(l[0]=-Kw)){var p=l*l+c*c,m=u*u+d*d,g=(d*p-c*m)/f,h=(l*m-u*p)/f,b=Rw.pop()||new function(){_w(this),this.x=this.y=this.arc=this.site=this.cy=null};b.arc=e,b.site=i,b.x=g+o,b.y=(b.cy=h+s)+Math.sqrt(g*g+h*h),e.circle=b;for(var v=null,_=Hw._;_;)if(b.y<_.y||b.y===_.y&&b.x<=_.x){if(!_.L){v=_.P;break}_=_.L}else{if(!_.R){v=_;break}_=_.R}Hw.insert(v,b),v||(kw=b)}}}}function Lw(e){var t=e.circle;t&&(t.P||(kw=t.N),Hw.remove(t),Rw.push(t),_w(t),e.circle=null)}var Pw=[];function Fw(e){var t=Pw.pop()||new function(){_w(this),this.edge=this.site=this.circle=null};return t.site=e,t}function Bw(e){Lw(e),Gw.remove(e),Pw.push(e),_w(e)}function Uw(e){var t=e.circle,n=t.x,r=t.cy,i=[n,r],a=e.P,o=e.N,s=[e];Bw(e);for(var l=a;l.circle&&Math.abs(n-l.circle.x)Vw)s=s.L;else{if(!((i=a-qw(s,o))>Vw)){r>-Vw?(t=s.P,n=s):i>-Vw?(t=s,n=s.N):t=n=s;break}if(!s.R){t=s;break}s=s.R}!function(e){$w[e.index]={site:e,halfedges:[]}}(e);var l=Fw(e);if(Gw.insert(t,l),t||n){if(t===n)return Lw(t),n=Fw(t.site),Gw.insert(l,n),l.edge=n.edge=ww(t.site,l.site),Iw(t),void Iw(n);if(n){Lw(t),Lw(n);var c=t.site,u=c[0],d=c[1],f=e[0]-u,p=e[1]-d,m=n.site,g=m[0]-u,h=m[1]-d,b=2*(f*h-p*g),v=f*f+p*p,_=g*g+h*h,y=[(h*v-p*_)/b+u,(f*_-g*v)/b+d];Ow(n.edge,c,m,y),l.edge=ww(c,e,null,y),n.edge=ww(e,m,null,y),Iw(t),Iw(n)}else l.edge=ww(t.site,l.site)}}function zw(e,t){var n=e.site,r=n[0],i=n[1],a=i-t;if(!a)return r;var o=e.P;if(!o)return-1/0;var s=(n=o.site)[0],l=n[1],c=l-t;if(!c)return s;var u=s-r,d=1/a-1/c,f=u/c;return d?(-f+Math.sqrt(f*f-2*d*(u*u/(-2*c)-l+c/2+i-a/2)))/d+r:(r+s)/2}function qw(e,t){var n=e.N;if(n)return zw(n,t);var r=e.site;return r[1]===t?r[0]:1/0}var Gw,$w,Hw,Ww,Vw=1e-6,Kw=1e-12;function Qw(e,t){return t[1]-e[1]||t[0]-e[0]}function Yw(e,t){var n,r,i,a=e.sort(Qw).pop();for(Ww=[],$w=new Array(e.length),Gw=new Sw,Hw=new Sw;;)if(i=kw,a&&(!i||a[1]Vw||Math.abs(i[0][1]-i[1][1])>Vw)||delete Ww[a]}(o,s,l,c),function(e,t,n,r){var i,a,o,s,l,c,u,d,f,p,m,g,h=$w.length,b=!0;for(i=0;iVw||Math.abs(g-f)>Vw)&&(l.splice(s,0,Ww.push(Cw(o,p,Math.abs(m-e)Vw?[e,Math.abs(d-e)Vw?[Math.abs(f-r)Vw?[n,Math.abs(d-n)Vw?[Math.abs(f-t)=s)return null;var l=e-i.site[0],c=t-i.site[1],u=l*l+c*c;do{i=a.cells[r=o],o=null,i.halfedges.forEach(function(n){var r=a.edges[n],s=r.left;if(s!==i.site&&s||(s=r.right)){var l=e-s[0],c=t-s[1],d=l*l+c*c;d=p));)if(t.x=d+i,t.y=f+a,!(t.x+t.x0<0||t.y+t.y0<0||t.x+t.x1>s[0]||t.y+t.y1>s[1]||n&&iC(t,e,s[0])||n&&(c=n,!((o=t).x+o.x1>c[0].x&&o.x+o.x0c[0].y&&o.y+o.y0>5,y=s[0]>>5,x=t.x-(_<<4),E=127&x,S=32-E,w=t.y1-t.y0,C=(t.y+t.y0)*y+(x>>5),O=0;O>>E:0);C+=y}return t.sprite=null,!0}return!1}return d.layout=function(){for(var l=function(e){e.width=e.height=1;var t=Math.sqrt(e.getContext(\"2d\").getImageData(0,0,1,1).data.length>>2);e.width=(eC<<5)/t,e.height=tC/t;var n=e.getContext(\"2d\");return n.fillStyle=n.strokeStyle=\"red\",n.textAlign=\"center\",{context:n,ratio:t}}(Lo()),d=function(e){var t=[],n=-1;for(;++n>5)*s[1]),p=null,m=c.length,g=-1,h=[],b=c.map(function(s){return{text:e(s),font:t(s),style:r(s),weight:i(s),rotate:a(s),size:~~n(s),padding:o(s),xoff:0,yoff:0,x1:0,y1:0,x0:0,y0:0,hasText:!1,sprite:null,datum:s}}).sort(function(e,t){return t.size-e.size});++g>1,v.y=s[1]*(u()+.5)>>1,rC(l,v,b,g),v.hasText&&f(d,v,p)&&(h.push(v),p?aC(p,v):p=[{x:v.x+v.x0,y:v.y+v.y0},{x:v.x+v.x1,y:v.y+v.y1}],v.x-=s[0]>>1,v.y-=s[1]>>1)}return h},d.words=function(e){return arguments.length?(c=e,d):c},d.size=function(e){return arguments.length?(s=[+e[0],+e[1]],d):s},d.font=function(e){return arguments.length?(t=sC(e),d):t},d.fontStyle=function(e){return arguments.length?(r=sC(e),d):r},d.fontWeight=function(e){return arguments.length?(i=sC(e),d):i},d.rotate=function(e){return arguments.length?(a=sC(e),d):a},d.text=function(t){return arguments.length?(e=sC(t),d):e},d.spiral=function(e){return arguments.length?(l=lC[e]||e,d):l},d.fontSize=function(e){return arguments.length?(n=sC(e),d):n},d.padding=function(e){return arguments.length?(o=sC(e),d):o},d.random=function(e){return arguments.length?(u=e,d):u},d};function rC(e,t,n,r){if(!t.sprite){var i=e.context,a=e.ratio;i.clearRect(0,0,(eC<<5)/a,tC/a);var o,s,l,c,u,d=0,f=0,p=0,m=n.length;for(--r;++r>5<<5,l=~~Math.max(Math.abs(v+_),Math.abs(v-_))}else o=o+31>>5<<5;if(l>p&&(p=l),d+o>=eC<<5&&(d=0,f+=p,p=0),f+l>=tC)break;i.translate((d+(o>>1))/a,(f+(l>>1))/a),t.rotate&&i.rotate(t.rotate*Jw),i.fillText(t.text,0,0),t.padding&&(i.lineWidth=2*t.padding,i.strokeText(t.text,0,0)),i.restore(),t.width=o,t.height=l,t.xoff=d,t.yoff=f,t.x1=o>>1,t.y1=l>>1,t.x0=-t.x1,t.y0=-t.y1,t.hasText=!0,d+=o}for(var x=i.getImageData(0,0,(eC<<5)/a,tC/a).data,E=[];--r>=0;)if((t=n[r]).hasText){for(s=(o=t.width)>>5,l=t.y1-t.y0,c=0;c>5),O=x[(f+u)*(eC<<5)+(d+c)<<2]?1<<31-c%32:0;E[C]|=O,S|=O}S?w=u:(t.y0++,l--,u--,f++)}t.y1=t.y0+w,t.sprite=E.slice(0,(t.y1-t.y0)*s)}}}function iC(e,t,n){n>>=5;for(var r,i=e.sprite,a=e.width>>5,o=e.x-(a<<4),s=127&o,l=32-s,c=e.y1-e.y0,u=(e.y+e.y0)*n+(o>>5),d=0;d>>s:0))&t[u+f])return!0;u+=n}return!1}function aC(e,t){var n=e[0],r=e[1];t.x+t.x0r.x&&(r.x=t.x+t.x1),t.y+t.y1>r.y&&(r.y=t.y+t.y1)}function oC(e){var t=e[0]/e[1];return function(e){return[t*(e*=.1)*Math.cos(e),e*Math.sin(e)]}}function sC(e){return\"function\"==typeof e?e:function(){return e}}var lC={archimedean:oC,rectangular:function(e){var t=4*e[0]/e[1],n=0,r=0;return function(e){var i=e<0?-1:1;switch(Math.sqrt(1+4*i*e)-i&3){case 0:n+=t;break;case 1:r+=4;break;case 2:n-=t;break;default:r-=4}return[n,r]}}},cC=function(e,t,n){var r=e-t+2*n;return e?r>0?r:1:0},uC=function(e){return function(t){var n,r=t[0],i=t[1];return i=s&&o[i]<=l&&(c<0&&(c=i),n=i);if(!(c<0))return s=e.invertExtent(o[c]),l=e.invertExtent(o[n]),[void 0===s[0]?s[1]:s[0],void 0===l[1]?l[0]:l[1]]}},fC=Array.prototype,pC=fC.map,mC=fC.slice,gC={name:\"implicit\"};function hC(e){var t=Gd(),n=[],r=gC;function i(i){var a=i+\"\",o=t.get(a);if(!o){if(r!==gC)return r;t.set(a,o=n.push(i))}return e[(o-1)%e.length]}return e=null==e?[]:mC.call(e),i.domain=function(e){if(!arguments.length)return n.slice();n=[],t=Gd();for(var r,a,o=-1,s=e.length;++o2?EC:xC,r=i=null,u}function u(t){return(r||(r=n(a,o,l?function(e){return function(t,n){var r=e(t=+t,n=+n);return function(e){return e<=t?0:e>=n?1:r(e)}}}(e):e,s)))(+t)}return u.invert=function(e){return(i||(i=n(o,a,yC,l?function(e){return function(t,n){var r=e(t=+t,n=+n);return function(e){return e<=0?t:e>=1?n:r(e)}}}(t):t)))(+e)},u.domain=function(e){return arguments.length?(a=pC.call(e,vC),c()):a.slice()},u.range=function(e){return arguments.length?(o=mC.call(e),c()):o.slice()},u.rangeRound=function(e){return o=mC.call(e),s=Mp,c()},u.clamp=function(e){return arguments.length?(l=!!e,c()):l},u.interpolate=function(e){return arguments.length?(s=e,c()):s},c()}var CC=function(e,t,n){var r,i=e[0],a=e[e.length-1],o=Mi(i,a,null==t?10:t);switch((n=om(null==n?\",f\":n)).type){case\"s\":var s=Math.max(Math.abs(i),Math.abs(a));return null!=n.precision||isNaN(r=_m(o,s))||(n.precision=r),dm(n,s);case\"\":case\"e\":case\"g\":case\"p\":case\"r\":null!=n.precision||isNaN(r=ym(o,Math.max(Math.abs(i),Math.abs(a))))||(n.precision=r-(\"e\"===n.type));break;case\"f\":case\"%\":null!=n.precision||isNaN(r=vm(o))||(n.precision=r-2*(\"%\"===n.type))}return um(n)};function OC(e){var t=e.domain;return e.ticks=function(e){var n=t();return Ci(n[0],n[n.length-1],null==e?10:e)},e.tickFormat=function(e,n){return CC(t(),e,n)},e.nice=function(n){null==n&&(n=10);var r,i=t(),a=0,o=i.length-1,s=i[a],l=i[o];return l0?r=Oi(s=Math.floor(s/r)*r,l=Math.ceil(l/r)*r,n):r<0&&(r=Oi(s=Math.ceil(s*r)/r,l=Math.floor(l*r)/r,n)),r>0?(i[a]=Math.floor(s/r)*r,i[o]=Math.ceil(l/r)*r,t(i)):r<0&&(i[a]=Math.ceil(s*r)/r,i[o]=Math.floor(l*r)/r,t(i)),e},e}function MC(){var e=wC(yC,bp);return e.copy=function(){return SC(e,MC())},OC(e)}function NC(){var e=[0,1];function t(e){return+e}return t.invert=t,t.domain=t.range=function(n){return arguments.length?(e=pC.call(n,vC),t):e.slice()},t.copy=function(){return NC().domain(e)},OC(t)}var TC=function(e,t){var n,r=0,i=(e=e.slice()).length-1,a=e[r],o=e[i];return o0){for(;fl)break;g.push(d)}}else for(;f=1;--u)if(!((d=c*u)l)break;g.push(d)}}else g=Ci(f,p,Math.min(p-f,m)).map(i);return a?g.reverse():g},e.tickFormat=function(t,a){if(null==a&&(a=10===n?\".0e\":\",\"),\"function\"!=typeof a&&(a=um(a)),t===1/0)return a;null==t&&(t=10);var o=Math.max(1,n*t/e.ticks().length);return function(e){var t=e/i(Math.round(r(e)));return t*n0?n[i-1]:e[0],i=n?[r[n-1],t]:[r[o-1],r[o]]},a.copy=function(){return zC().domain([e,t]).range(i)},OC(a)}function qC(){var e=[.5],t=[0,1],n=1;function r(r){if(r<=r)return t[hi(e,r,0,n)]}return r.domain=function(i){return arguments.length?(e=mC.call(i),n=Math.min(e.length,t.length-1),r):e.slice()},r.range=function(i){return arguments.length?(t=mC.call(i),n=Math.min(e.length,t.length-1),r):t.slice()},r.invertExtent=function(n){var r=t.indexOf(n);return[e[r-1],e[r]]},r.copy=function(){return qC().domain(e).range(t)},r}var GC=1e3,$C=60*GC,HC=60*$C,WC=24*HC,VC=7*WC,KC=30*WC,QC=365*WC;function YC(e){return new Date(e)}function ZC(e){return e instanceof Date?+e:+new Date(+e)}function XC(e,t,n,r,i,a,o,s,l){var c=wC(yC,bp),u=c.invert,d=c.domain,f=l(\".%L\"),p=l(\":%S\"),m=l(\"%I:%M\"),g=l(\"%I %p\"),h=l(\"%a %d\"),b=l(\"%b %d\"),v=l(\"%B\"),_=l(\"%Y\"),y=[[o,1,GC],[o,5,5*GC],[o,15,15*GC],[o,30,30*GC],[a,1,$C],[a,5,5*$C],[a,15,15*$C],[a,30,30*$C],[i,1,HC],[i,3,3*HC],[i,6,6*HC],[i,12,12*HC],[r,1,WC],[r,2,2*WC],[n,1,VC],[t,1,KC],[t,3,3*KC],[e,1,QC]];function x(s){return(o(s)a[1-u])))return n=Math.max(0,mi(d,l)-1),o=l===c?n:mi(d,c)-1,l-d[n]>t+1e-10&&++n,u&&(s=n,n=f-o,o=f-s),n>o?void 0:r().slice(n,o+1)}},n.invert=function(e){var t=n.invertRange([e,e]);return t?t[0]:t},n.copy=function(){return tO().domain(r()).range(a).round(o).paddingInner(s).paddingOuter(l).align(c)},u()}var nO=Array.prototype.map,rO=Array.prototype.slice;function iO(e){return nO.call(e,function(e){return+e})}function aO(e,t){return arguments.length>1?(oO[e]=function(e,t){return function(){var n=t();return n.invertRange||(n.invertRange=n.invert?uC(n):n.invertExtent?dC(n):void 0),n.type=e,n}}(e,t),this):oO.hasOwnProperty(e)?oO[e]:void 0}var oO={identity:NC,linear:MC,log:PC,ordinal:hC,pow:BC,sqrt:UC,quantile:jC,quantize:zC,threshold:qC,time:JC,utc:eO,band:tO,point:function(){return function e(t){var n=t.copy;return t.padding=t.paddingOuter,delete t.paddingInner,t.copy=function(){return e(n())},t}(tO().paddingInner(1))},sequential:function e(t){var n=MC(),r=0,i=1,a=!1;function o(){var e=n.domain();r=e[0],i=Object(Ee.K)(e)-r}function s(e){var n=(e-r)/i;return t(a?Math.max(0,Math.min(1,n)):n)}return s.clamp=function(e){return arguments.length?(a=!!e,s):a},s.domain=function(e){return arguments.length?(n.domain(e),o(),s):n.domain()},s.interpolator=function(e){return arguments.length?(t=e,s):t},s.copy=function(){return e().domain(n.domain()).clamp(a).interpolator(t)},s.ticks=function(e){return n.ticks(e)},s.tickFormat=function(e,t){return n.tickFormat(e,t)},s.nice=function(e){return n.nice(e),o(),s},s},\"bin-linear\":function e(){var t=MC(),n=[];function r(e){return t(e)}return r.domain=function(e){return arguments.length?(function(e){n=iO(e),t.domain([n[0],Object(Ee.K)(n)])}(e),r):n.slice()},r.range=function(e){return arguments.length?(t.range(e),r):t.range()},r.rangeRound=function(e){return arguments.length?(t.rangeRound(e),r):t.rangeRound()},r.interpolate=function(e){return arguments.length?(t.interpolate(e),r):t.interpolate()},r.invert=function(e){return t.invert(e)},r.ticks=function(e){var t=n.length,i=~~(t/(e||t));return i<2?r.domain():n.filter(function(e,t){return!(t%i)})},r.tickFormat=function(){return t.tickFormat.apply(t,arguments)},r.copy=function(){return e().domain(r.domain()).range(r.range())},r},\"bin-ordinal\":function e(){var t=[],n=[];function r(e){return null==e||e!=e?void 0:n[(hi(t,e)-1)%n.length]}return r.domain=function(e){return arguments.length?(t=iO(e),r):t.slice()},r.range=function(e){return arguments.length?(n=rO.call(e),r):n.slice()},r.copy=function(){return e().domain(r.domain()).range(r.range())},r}};for(var sO in oO)aO(sO,oO[sO]);function lO(e){for(var t=e.length/6|0,n=new Array(t),r=0;ri&&(i=n);return[r,i]}(l,i)).range(r);s=function(e){return c(l(e))}}i.forEach(function(e){e[o[0]]=NaN,e[o[1]]=NaN,e[o[3]]=0});for(var u,d,f=a.words(i).text(e.text).size(e.size||[500,500]).padding(e.padding||1).spiral(e.spiral||\"archimedean\").rotate(e.rotate||0).font(e.font||\"sans-serif\").fontStyle(e.fontStyle||\"normal\").fontWeight(e.fontWeight||\"normal\").fontSize(s).random(ui).layout(),p=a.size(),m=p[0]>>1,g=p[1]>>1,h=0,b=f.length;hi?1:0}),Ri(e,t)}(d,f),c)o=t,s=e,t=Array(c+u),e=xO(c+u),function(e,t,n,r,i,a,o,s,l){var c,u=0,d=0;for(c=0;u0)for(l=0;l=t?e:((i=i||new e.constructor(t)).set(e),i);var e,t,i},add:function(e){for(var t,r=0,i=n.length,a=e.length;ri.length||n>t)&&(t=Math.max(n,t),i=EO(e,t,i),a=EO(e,t))}}),e),this._indices=null,this._dims=null}CO.Definition={type:\"CrossFilter\",metadata:{},params:[{name:\"fields\",type:\"field\",array:!0,required:!0},{name:\"query\",type:\"array\",array:!0,required:!0,content:{type:\"number\",array:!0,length:2}}]};var OO=Object(Ee.t)(CO,Yr);function MO(e){Yr.call(this,null,e)}OO.transform=function(e,t){return this._dims?e.modified(\"fields\")||e.fields.some(function(e){return t.modified(e.fields)})?this.reinit(e,t):this.eval(e,t):this.init(e,t)},OO.init=function(e,t){for(var n,r,i=e.fields,a=e.query,o=this._indices={},s=this._dims=[],l=a.length,c=0;ch)for(i=h,a=Math.min(m,b);ib)for(i=Math.max(m,b),a=g;ip)for(i=p,a=Math.min(d,m);im)for(i=Math.max(d,m),a=f;i\",iM[fM]=\"Identifier\",iM[pM]=\"Keyword\",iM[mM]=\"Null\",iM[gM]=\"Numeric\",iM[hM]=\"Punctuator\",iM[bM]=\"String\",iM[9]=\"RegularExpression\";var vM=\"ArrayExpression\",_M=\"BinaryExpression\",yM=\"CallExpression\",xM=\"ConditionalExpression\",EM=\"Identifier\",SM=\"Literal\",wM=\"LogicalExpression\",CM=\"MemberExpression\",OM=\"ObjectExpression\",MM=\"Property\",NM=\"UnaryExpression\",TM=\"Unexpected token %0\",DM=\"Unexpected number\",AM=\"Unexpected string\",kM=\"Unexpected identifier\",RM=\"Unexpected reserved word\",IM=\"Unexpected end of input\",LM=\"Invalid regular expression\",PM=\"Invalid regular expression: missing /\",FM=\"Octal literals are not allowed in strict mode.\",BM=\"Duplicate data property in object literal not allowed in strict mode\",UM=\"ILLEGAL\",jM=\"Disabled.\",zM=new RegExp(\"[ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々-〇〡-〩〱-〵〸-〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]\"),qM=new RegExp(\"[ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮ̀-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁ҃-҇Ҋ-ԯԱ-Ֆՙա-և֑-ׇֽֿׁׂׅׄא-תװ-ײؐ-ؚؠ-٩ٮ-ۓە-ۜ۟-۪ۨ-ۼۿܐ-݊ݍ-ޱ߀-ߵߺࠀ-࠭ࡀ-࡛ࢠ-ࢲࣤ-ॣ०-९ॱ-ঃঅ-ঌএঐও-নপ-রলশ-হ়-ৄেৈো-ৎৗড়ঢ়য়-ৣ০-ৱਁ-ਃਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹ਼ਾ-ੂੇੈੋ-੍ੑਖ਼-ੜਫ਼੦-ੵઁ-ઃઅ-ઍએ-ઑઓ-નપ-રલળવ-હ઼-ૅે-ૉો-્ૐૠ-ૣ૦-૯ଁ-ଃଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହ଼-ୄେୈୋ-୍ୖୗଡ଼ଢ଼ୟ-ୣ୦-୯ୱஂஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹா-ூெ-ைொ-்ௐௗ௦-௯ఀ-ఃఅ-ఌఎ-ఐఒ-నప-హఽ-ౄె-ైొ-్ౕౖౘౙౠ-ౣ౦-౯ಁ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹ಼-ೄೆ-ೈೊ-್ೕೖೞೠ-ೣ೦-೯ೱೲഁ-ഃഅ-ഌഎ-ഐഒ-ഺഽ-ൄെ-ൈൊ-ൎൗൠ-ൣ൦-൯ൺ-ൿංඃඅ-ඖක-නඳ-රලව-ෆ්ා-ුූෘ-ෟ෦-෯ෲෳก-ฺเ-๎๐-๙ກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ູົ-ຽເ-ໄໆ່-ໍ໐-໙ໜ-ໟༀ༘༙༠-༩༹༵༷༾-ཇཉ-ཬཱ-྄྆-ྗྙ-ྼ࿆က-၉ၐ-ႝႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ፝-፟ᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-᜔ᜠ-᜴ᝀ-ᝓᝠ-ᝬᝮ-ᝰᝲᝳក-៓ៗៜ៝០-៩᠋-᠍᠐-᠙ᠠ-ᡷᢀ-ᢪᢰ-ᣵᤀ-ᤞᤠ-ᤫᤰ-᤻᥆-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉ᧐-᧙ᨀ-ᨛᨠ-ᩞ᩠-᩿᩼-᪉᪐-᪙ᪧ᪰-᪽ᬀ-ᭋ᭐-᭙᭫-᭳ᮀ-᯳ᰀ-᰷᱀-᱉ᱍ-ᱽ᳐-᳔᳒-ᳶ᳸᳹ᴀ-᷵᷼-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼ‌‍‿⁀⁔ⁱⁿₐ-ₜ⃐-⃥⃜⃡-⃰ℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯ⵿-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⷠ-ⷿⸯ々-〇〡-〯〱-〵〸-〼ぁ-ゖ゙゚ゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘫꙀ-꙯ꙴ-꙽ꙿ-ꚝꚟ-꛱ꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠧꡀ-ꡳꢀ-꣄꣐-꣙꣠-ꣷꣻ꤀-꤭ꤰ-꥓ꥠ-ꥼꦀ-꧀ꧏ-꧙ꧠ-ꧾꨀ-ꨶꩀ-ꩍ꩐-꩙ꩠ-ꩶꩺ-ꫂꫛ-ꫝꫠ-ꫯꫲ-꫶ꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯪ꯬꯭꯰-꯹가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻ︀-️︠-︭︳︴﹍-﹏ﹰ-ﹴﹶ-ﻼ0-9A-Z_a-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]\");function GM(e,t){if(!e)throw new Error(\"ASSERT: \"+t)}function $M(e){return e>=48&&e<=57}function HM(e){return\"0123456789abcdefABCDEF\".indexOf(e)>=0}function WM(e){return\"01234567\".indexOf(e)>=0}function VM(e){return 32===e||9===e||11===e||12===e||160===e||e>=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(e)>=0}function KM(e){return 10===e||13===e||8232===e||8233===e}function QM(e){return 36===e||95===e||e>=65&&e<=90||e>=97&&e<=122||92===e||e>=128&&zM.test(String.fromCharCode(e))}function YM(e){return 36===e||95===e||e>=65&&e<=90||e>=97&&e<=122||e>=48&&e<=57||92===e||e>=128&&qM.test(String.fromCharCode(e))}var ZM={if:1,in:1,do:1,var:1,for:1,new:1,try:1,let:1,this:1,else:1,case:1,void:1,with:1,enum:1,while:1,break:1,catch:1,throw:1,const:1,yield:1,class:1,super:1,return:1,typeof:1,delete:1,switch:1,export:1,import:1,public:1,static:1,default:1,finally:1,extends:1,package:1,private:1,function:1,continue:1,debugger:1,interface:1,protected:1,instanceof:1,implements:1};function XM(){for(var e;oM1114111||\"}\"!==e)&&gN({},TM,UM),t<=65535?String.fromCharCode(t):(n=55296+(t-65536>>10),r=56320+(t-65536&1023),String.fromCharCode(n,r))}function tN(){var e,t;for(e=aM.charCodeAt(oM++),t=String.fromCharCode(e),92===e&&(117!==aM.charCodeAt(oM)&&gN({},TM,UM),++oM,(e=JM(\"u\"))&&\"\\\\\"!==e&&QM(e.charCodeAt(0))||gN({},TM,UM),t=e);oM>>=\"===(r=aM.substr(oM,4))?{type:hM,value:r,start:i,end:oM+=4}:\">>>\"===(n=r.substr(0,3))||\"<<=\"===n||\">>=\"===n?{type:hM,value:n,start:i,end:oM+=3}:o===(t=n.substr(0,2))[1]&&\"+-<>&|\".indexOf(o)>=0||\"=>\"===t?{type:hM,value:t,start:i,end:oM+=2}:\"<>=!+-*%&|^/\".indexOf(o)>=0?{type:hM,value:o,start:i,end:++oM}:void gN({},TM,UM)}function iN(){var e,t,n;if(GM($M((n=aM[oM]).charCodeAt(0))||\".\"===n,\"Numeric literal must start with a decimal digit or a decimal point\"),t=oM,e=\"\",\".\"!==n){if(e=aM[oM++],n=aM[oM],\"0\"===e){if(\"x\"===n||\"X\"===n)return++oM,function(e){for(var t=\"\";oM=0&&gN({},LM,n),{value:n,literal:t}}(),r=function(e,t){var n=e;t.indexOf(\"u\")>=0&&(n=n.replace(/\\\\u\\{([0-9a-fA-F]+)\\}/g,function(e,t){if(parseInt(t,16)<=1114111)return\"x\";gN({},LM)}).replace(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g,\"x\"));try{new RegExp(n)}catch(e){gN({},LM)}try{return new RegExp(e,t)}catch(e){return null}}(t.value,n.value),{literal:t.literal+n.literal,value:r,regex:{pattern:t.value,flags:n.value},start:e,end:oM}}function oN(){var e;return XM(),oM>=sM?{type:dM,start:oM,end:oM}:QM(e=aM.charCodeAt(oM))?nN():40===e||41===e||59===e?rN():39===e||34===e?function(){var e,t,n,r,i=\"\",a=!1;for(GM(\"'\"===(e=aM[oM])||'\"'===e,\"String literal must starts with a quote\"),t=oM,++oM;oM=0&&oM\":case\"<=\":case\">=\":case\"instanceof\":case\"in\":t=7;break;case\"<<\":case\">>\":case\">>>\":t=8;break;case\"+\":case\"-\":t=9;break;case\"*\":case\"/\":case\"%\":t=11}return t}function kN(){var e,t;return e=function(){var e,t,n,r,i,a,o,s,l,c;if(e=lM,l=DN(),0===(i=AN(r=lM)))return l;for(r.prec=i,sN(),t=[e,lM],a=[l,r,o=DN()];(i=AN(lM))>0;){for(;a.length>2&&i<=a[a.length-2].prec;)o=a.pop(),s=a.pop().value,l=a.pop(),t.pop(),n=cN(s,l,o),a.push(n);(r=sN()).prec=i,a.push(r),t.push(lM),n=DN(),a.push(n)}for(n=a[c=a.length-1],t.pop();c>1;)t.pop(),n=cN(a[c-1].value,a[c-2],n),c-=2;return n}(),vN(\"?\")&&(sN(),t=kN(),bN(\":\"),e=function(e,t,n){var r=new cM(xM);return r.test=e,r.consequent=t,r.alternate=n,r}(e,t,kN())),e}function RN(){var e=kN();if(vN(\",\"))throw new Error(jM);return e}var IN=function(e){oM=0,sM=(aM=e).length,lM=null,lN();var t=RN();if(lM.type!==dM)throw new Error(\"Unexpect token after expression.\");return t},LN={NaN:\"NaN\",E:\"Math.E\",LN2:\"Math.LN2\",LN10:\"Math.LN10\",LOG2E:\"Math.LOG2E\",LOG10E:\"Math.LOG10E\",PI:\"Math.PI\",SQRT1_2:\"Math.SQRT1_2\",SQRT2:\"Math.SQRT2\",MIN_VALUE:\"Number.MIN_VALUE\",MAX_VALUE:\"Number.MAX_VALUE\"},PN=function(e){function t(t,n,r){return function(i){return function(t,n,r,i){var a=e(n[0]);return r&&(a=r+\"(\"+a+\")\",0===r.lastIndexOf(\"new \",0)&&(a=\"(\"+a+\")\")),a+\".\"+t+(i<0?\"\":0===i?\"()\":\"(\"+n.slice(1).map(e).join(\",\")+\")\")}(t,i,n,r)}}var n=\"new Date\";return{isNaN:\"isNaN\",isFinite:\"isFinite\",abs:\"Math.abs\",acos:\"Math.acos\",asin:\"Math.asin\",atan:\"Math.atan\",atan2:\"Math.atan2\",ceil:\"Math.ceil\",cos:\"Math.cos\",exp:\"Math.exp\",floor:\"Math.floor\",log:\"Math.log\",max:\"Math.max\",min:\"Math.min\",pow:\"Math.pow\",random:\"Math.random\",round:\"Math.round\",sin:\"Math.sin\",sqrt:\"Math.sqrt\",tan:\"Math.tan\",clamp:function(t){t.length<3&&Object(Ee.l)(\"Missing arguments to clamp function.\"),t.length>3&&Object(Ee.l)(\"Too many arguments to clamp function.\");var n=t.map(e);return\"Math.max(\"+n[1]+\", Math.min(\"+n[2]+\",\"+n[0]+\"))\"},now:\"Date.now\",utc:\"Date.UTC\",datetime:n,date:t(\"getDate\",n,0),day:t(\"getDay\",n,0),year:t(\"getFullYear\",n,0),month:t(\"getMonth\",n,0),hours:t(\"getHours\",n,0),minutes:t(\"getMinutes\",n,0),seconds:t(\"getSeconds\",n,0),milliseconds:t(\"getMilliseconds\",n,0),time:t(\"getTime\",n,0),timezoneoffset:t(\"getTimezoneOffset\",n,0),utcdate:t(\"getUTCDate\",n,0),utcday:t(\"getUTCDay\",n,0),utcyear:t(\"getUTCFullYear\",n,0),utcmonth:t(\"getUTCMonth\",n,0),utchours:t(\"getUTCHours\",n,0),utcminutes:t(\"getUTCMinutes\",n,0),utcseconds:t(\"getUTCSeconds\",n,0),utcmilliseconds:t(\"getUTCMilliseconds\",n,0),length:t(\"length\",null,-1),indexof:t(\"indexOf\",null),lastindexof:t(\"lastIndexOf\",null),slice:t(\"slice\",null),parseFloat:\"parseFloat\",parseInt:\"parseInt\",upper:t(\"toUpperCase\",\"String\",0),lower:t(\"toLowerCase\",\"String\",0),substring:t(\"substring\",\"String\"),replace:t(\"replace\",\"String\"),regexp:\"RegExp\",test:t(\"test\",\"RegExp\"),if:function(t){t.length<3&&Object(Ee.l)(\"Missing arguments to if function.\"),t.length>3&&Object(Ee.l)(\"Too many arguments to if function.\");var n=t.map(e);return\"(\"+n[0]+\"?\"+n[1]+\":\"+n[2]+\")\"}}},FN=function(e){var t=(e=e||{}).whitelist?Object(Ee.Q)(e.whitelist):{},n=e.blacklist?Object(Ee.Q)(e.blacklist):{},r=e.constants||LN,i=(e.functions||PN)(d),a=e.globalvar,o=e.fieldvar,s={},l={},c=0,u=Object(Ee.x)(a)?a:function(e){return a+'[\"'+e+'\"]'};function d(e){if(Object(Ee.B)(e))return e;var t=f[e.type];return null==t&&Object(Ee.l)(\"Unsupported type: \"+e.type),t(e)}var f={Literal:function(e){return e.raw},Identifier:function(e){var i=e.name;return c>0?i:n.hasOwnProperty(i)?Object(Ee.l)(\"Illegal identifier: \"+i):r.hasOwnProperty(i)?r[i]:t.hasOwnProperty(i)?i:(s[i]=1,u(i))},MemberExpression:function(e){var t=!e.computed,n=d(e.object);t&&(c+=1);var r=d(e.property);return n===o&&(l[r]=1),t&&(c-=1),n+(t?\".\"+r:\"[\"+r+\"]\")},CallExpression:function(e){\"Identifier\"!==e.callee.type&&Object(Ee.l)(\"Illegal callee type: \"+e.callee.type);var t=e.callee.name,n=e.arguments,r=i.hasOwnProperty(t)&&i[t];return r||Object(Ee.l)(\"Unrecognized function: \"+t),Object(Ee.x)(r)?r(n):r+\"(\"+n.map(d).join(\",\")+\")\"},ArrayExpression:function(e){return\"[\"+e.elements.map(d).join(\",\")+\"]\"},BinaryExpression:function(e){return\"(\"+d(e.left)+e.operator+d(e.right)+\")\"},UnaryExpression:function(e){return\"(\"+e.operator+d(e.argument)+\")\"},ConditionalExpression:function(e){return\"(\"+d(e.test)+\"?\"+d(e.consequent)+\":\"+d(e.alternate)+\")\"},LogicalExpression:function(e){return\"(\"+d(e.left)+e.operator+d(e.right)+\")\"},ObjectExpression:function(e){return\"{\"+e.properties.map(d).join(\",\")+\"}\"},Property:function(e){c+=1;var t=d(e.key);return c-=1,t+\":\"+d(e.value)}};function p(e){var t={code:d(e),globals:Object.keys(s),fields:Object.keys(l)};return s={},l={},t}return p.functions=i,p.constants=r,p},BN={};function UN(e,t,n){var r=e+\":\"+n,i=BN[r];return i&&i[0]===t||(BN[r]=i=[t,t(n)]),i[1]}function jN(e,t){return UN(\"timeFormat\",gn,t)(e)}var zN=new Date(2e3,0,1);function qN(e,t,n){return zN.setMonth(e),zN.setDate(t),jN(zN,n)}function GN(e,t,n){try{e[t].apply(e,[\"EXPRESSION\"].concat([].slice.call(n)))}catch(t){e.warn(t)}return n[n.length-1]}var $N=\"undefined\"!=typeof window&&window||null;var HN=\"Literal\",WN=\"Identifier\",VN=\"@\",KN=\"%\",QN=\":\";function YN(e,t){var n;return Object(Ee.x)(e)?e:Object(Ee.B)(e)?(n=t.scales[e])&&n.value:void 0}function ZN(e,t,n){var r=KN+n;if(!t.hasOwnProperty(r))try{t[r]=e.scaleRef(n)}catch(e){}}function XN(e,t,n,r){if(t[0].type===HN)ZN(n,r,t[0].value);else if(t[0].type===WN)for(e in n.scales)ZN(n,r,e)}function JN(e,t){return function(n,r,i){if(n){var a=YN(n,(i||this).context);return a&&a.path[e](r)}return t(r)}}var eT=JN(\"area\",Nv),tT=JN(\"bounds\",y_),nT=JN(\"centroid\",k_);function rT(e){var t=this.context.data[e];return t?t.values.value:[]}function iT(e,t,n,r){t[0].type!==HN&&Object(Ee.l)(\"First argument to data functions must be a string literal.\");var i=t[0].value,a=QN+i;r.hasOwnProperty(a)||(r[a]=n.getData(i).tuplesRef())}var aT={};function oT(e){return e.data}function sT(e,t){var n=rT.call(t,e);return n.root&&n.root.lookup||aT}var lT=function(e,t,n,r){var i,a=t[0],o=t[t.length-1];return a>o&&(i=a,a=o,o=i),n=void 0===n||n,r=void 0===r||r,(n?a<=e:a=2&&t[t.length-1].value,o=VN+\"unit\";a!==fT||r.hasOwnProperty(o)||(r[o]=n.getData(i).indataRef(n,\"unit\")),iT(0,t,n,r)}function yT(e,t,n,r){var i,a,o,s,l,c=this.context.data[e],u=c?c.values.value:[],d=c?c[mT]&&c[mT].value:void 0,f=u[0],p=0;if(f){for(i=t?f.encodings.length:f.fields.length;p(a=n[1])&&(a=n[0],i=n[1]),r=r?o(r,i,a):[i,a];return r&&r.length&&+r[0]!=+r[1]?r:void 0}function ST(e,t,n){return e[0]>t&&(e[0]=t),e[1]n&&(e[1]=n),e)}var CT={random:function(){return ui()},isArray:Ee.u,isBoolean:Ee.v,isDate:Ee.w,isNumber:Ee.y,isObject:Ee.z,isRegExp:Ee.A,isString:Ee.B,isTuple:Oe,toBoolean:Ee.N,toDate:Ee.O,toNumber:Ee.P,toString:Ee.R,pad:Ee.G,peek:Ee.K,truncate:Ee.S,rgb:Sf,lab:jf,hcl:Vf,hsl:Mf,sequence:xi,format:function(e,t){return UN(\"format\",um,t)(e)},utcFormat:function(e,t){return UN(\"utcFormat\",bn,t)(e)},utcParse:function(e,t){return UN(\"utcParse\",vn,t)(e)},timeFormat:jN,timeParse:function(e,t){return UN(\"timeParse\",hn,t)(e)},monthFormat:function(e){return qN(e,1,\"%B\")},monthAbbrevFormat:function(e){return qN(e,1,\"%b\")},dayFormat:function(e){return qN(0,2+e,\"%A\")},dayAbbrevFormat:function(e){return qN(0,2+e,\"%a\")},quarter:function(e){return 1+~~(new Date(e).getMonth()/3)},utcquarter:function(e){return 1+~~(new Date(e).getUTCMonth()/3)},warn:function(){return GN(this.context.dataflow,\"warn\",arguments)},info:function(){return GN(this.context.dataflow,\"info\",arguments)},debug:function(){return GN(this.context.dataflow,\"debug\",arguments)},inScope:function(e){var t=this.context.group,n=!1;if(t)for(;e;){if(e===t){n=!0;break}e=e.mark.group}return n},clampRange:function(e,t,n){var r,i=e[0],a=e[1];return a=n-t?[t,n]:[Math.min(Math.max(i,t),n-r),Math.min(Math.max(a,r),n)]},pinchDistance:function(e){var t=e.touches,n=t[0].clientX-t[1].clientX,r=t[0].clientY-t[1].clientY;return Math.sqrt(n*n+r*r)},pinchAngle:function(e){var t=e.touches;return Math.atan2(t[0].clientY-t[1].clientY,t[0].clientX-t[1].clientX)},screen:function(){return $N?$N.screen:{}},containerSize:function(){var e=this.context.dataflow,t=e.container&&e.container();return t?[t.clientWidth,t.clientHeight]:[void 0,void 0]},windowSize:function(){return $N?[$N.innerWidth,$N.innerHeight]:[void 0,void 0]},span:function(e){return e[e.length-1]-e[0]||0},merge:function(){var e=[].slice.call(arguments);return e.unshift({}),Ee.m.apply(null,e)},flush:function(e,t,n,r,i,a){var o,s,l=e[0],c=Object(Ee.K)(e);return c2;break}return s=u.reduce(function(e,t){var n=t.intervals[o].extent,r=l?n.map(function(e){return{unit:t.unit,value:e}}):{unit:t.unit,value:n};return l?e.push.apply(e,r):e.push(r),e},[]),l?xT(s,r):ET(s,r)}},iT),DT(\"treePath\",function(e,t,n){var r=sT(e,this),i=r[t],a=r[n];return i&&a?i.path(a).map(oT):void 0},iT),DT(\"treeAncestors\",function(e,t){var n=sT(e,this)[t];return n?n.ancestors().map(oT):void 0},iT);var AT={blacklist:[\"_\"],whitelist:[\"datum\",\"event\",\"item\"],fieldvar:\"datum\",globalvar:function(e){return\"_[\"+Object(Ee.M)(\"$\"+e)+\"]\"},functions:function(e){var t=PN(e);for(var n in OT.forEach(function(e){t[e]=MT+e}),CT)t[n]=NT+n;return t},constants:LN,visitors:TT},kT=FN(AT),RT=function(e,t,n){var r,i,a={};try{e=Object(Ee.B)(e)?e:Object(Ee.M)(e)+\"\",r=IN(e)}catch(t){Object(Ee.l)(\"Expression parse error: \"+e)}return r.visit(function(e){if(\"CallExpression\"===e.type){var n=e.callee.name,r=AT.visitors[n];r&&r(n,e.arguments,t,a)}}),(i=kT(r)).globals.forEach(function(e){var n=\"$\"+e;!a.hasOwnProperty(n)&&t.getSignal(e)&&(a[n]=t.signalRef(e))}),{$expr:n?n+\"return(\"+i.code+\");\":i.code,$fields:i.fields,$params:a}};function IT(e,t,n,r){this.id=-1,this.type=e,this.value=t,this.params=n,r&&(this.parent=r)}function LT(e,t,n,r){return new IT(e,t,n,r)}function PT(e,t){return LT(\"operator\",e,t)}function FT(e){var t={$ref:e.id};return e.id<0&&(e.refs=e.refs||[]).push(t),t}var BT={$tupleid:1,toString:function(){return\":_tupleid_:\"}};function UT(e,t){return t?{$field:e,$name:t}:{$field:e}}var jT=UT(\"key\");function zT(e,t){return{$compare:e,$order:t}}var qT=\"descending\";function GT(e,t){return(e&&e.signal?\"$\"+e.signal:e||\"\")+(e&&t?\"_\":\"\")+(t&&t.signal?\"$\"+t.signal:t||\"\")}function $T(e){return e&&e.signal}var HT,WT,VT=function(e,t,n){return HT=t||KT,WT=n||iD,oD(e.trim()).map(sD)},KT=\"view\",QT=\"[\",YT=\"]\",ZT=\"{\",XT=\"}\",JT=\":\",eD=\",\",tD=\"@\",nD=\">\",rD=/[[\\]{}]/,iD={\"*\":1,arc:1,area:1,group:1,image:1,line:1,path:1,rect:1,rule:1,shape:1,symbol:1,text:1,trail:1};function aD(e,t,n,r,i){for(var a,o=0,s=e.length;t=0?--o:r&&r.indexOf(a)>=0&&++o}return t}function oD(e){for(var t=[],n=0,r=e.length,i=0;i' after between selector: \"+e;if(t=t.map(sD),(n=sD(e.slice(1).trim())).between)return{between:t,stream:n};n.between=t;return n}(e):function(e){var t,n,r={source:HT},i=[],a=[0,0],o=0,s=0,l=e.length,c=0;if(e[l-1]===XT){if(!((c=e.lastIndexOf(ZT))>=0))throw\"Unmatched right brace: \"+e;try{a=function(e){var t=e.split(eD);if(!e.length||t.length>2)throw e;return t.map(function(t){var n=+t;if(n!=n)throw e;return n})}(e.substring(c+1,l-1))}catch(t){throw\"Invalid throttle specification: \"+e}e=e.slice(0,c).trim(),l=e.length,c=0}if(!l)throw e;e[0]===tD&&(o=++c);(t=aD(e,c,JT))1?(r.type=i[1],o?r.markname=i[0].slice(1):(u=i[0],WT.hasOwnProperty(u)?r.marktype=i[0]:r.source=i[0])):r.type=i[0];var u;\"!\"===r.type.slice(-1)&&(r.consume=!0,r.type=r.type.slice(0,-1));null!=n&&(r.filter=n);a[0]&&(r.throttle=a[0]);a[1]&&(r.debounce=a[1]);return r}(e)}function lD(e){return function(t,n,r){return LT(e,n,t||void 0,r)}}var cD=lD(\"aggregate\"),uD=(lD(\"axisticks\"),lD(\"bound\"),lD(\"collect\")),dD=lD(\"compare\"),fD=(lD(\"datajoin\"),lD(\"encode\"),lD(\"expression\")),pD=(lD(\"extent\"),lD(\"facet\"),lD(\"field\")),mD=lD(\"key\"),gD=(lD(\"legendentries\"),lD(\"mark\"),lD(\"multiextent\"),lD(\"multivalues\"),lD(\"overlap\"),lD(\"params\"),lD(\"prefacet\"),lD(\"projection\")),hD=lD(\"proxy\"),bD=(lD(\"relay\"),lD(\"render\"),lD(\"scale\")),vD=lD(\"sieve\"),_D=(lD(\"sortitems\"),lD(\"viewlayout\"),lD(\"values\"),[\"identity\",\"ordinal\",\"band\",\"point\",\"bin-linear\",\"bin-ordinal\",\"quantize\",\"quantile\",\"threshold\",\"linear\",\"pow\",\"sqrt\",\"log\",\"sequential\",\"time\",\"utc\"]);Object(Ee.Q)(_D),Object(Ee.Q)(_D.slice(4,9)),Object(Ee.Q)(_D.slice(9)),Object(Ee.Q)(_D.slice(1,6));var yD=\"left\",xD=\"start\",ED=\"end\";Object(Ee.Q)([\"rule\"]),Object(Ee.Q)([\"group\",\"image\",\"rect\"]);function SD(e,t,n,r,i){this.scope=e,this.input=t,this.output=n,this.values=r,this.aggregate=i,this.index={}}SD.fromEntries=function(e,t){var n=t.length,r=1,i=t[0],a=t[n-1],o=t[n-2],s=null;for(e.add(t[0]);r0?\",\":\"\")+(Object(Ee.z)(t)?t.signal||kD(t):Object(Ee.M)(t));return n+\"]\"}:function(e){var t,n,r=\"{\",i=0;for(t in e)n=e[t],r+=(++i>1?\",\":\"\")+Object(Ee.M)(t)+\":\"+(Object(Ee.z)(n)?n.signal||kD(n):Object(Ee.M)(n));return r+\"}\"})(e)}AD.fork=function(){return new DD(this)},AD.isSubscope=function(){return this._subid>0},AD.toRuntime=function(){return this.finish(),{background:this.background,operators:this.operators,streams:this.streams,updates:this.updates,bindings:this.bindings,eventConfig:this.eventConfig}},AD.id=function(){return(this._subid?this._subid+\":\":0)+this._id++},AD.add=function(e){return this.operators.push(e),e.id=this.id(),e.refs&&(e.refs.forEach(function(t){t.$ref=e.id}),e.refs=null),e},AD.proxy=function(e){var t=e instanceof IT?FT(e):e;return this.add(hD({value:t}))},AD.addStream=function(e){return this.streams.push(e),e.id=this.id(),e},AD.addUpdate=function(e){return this.updates.push(e),e},AD.finish=function(){var e,t;for(e in this.root&&(this.root.root=!0),this.signals)this.signals[e].signal=e;for(e in this.scales)this.scales[e].scale=e;function n(e,t,n){var r;e&&((r=e.data||(e.data={}))[t]||(r[t]=[])).push(n)}for(e in this.data)for(var r in n((t=this.data[e]).input,e,\"input\"),n(t.output,e,\"output\"),n(t.values,e,\"values\"),t.index)n(t.index[r],e,\"index:\"+r);return this},AD.pushState=function(e,t,n){this._encode.push(FT(this.add(vD({pulse:e})))),this._parent.push(t),this._lookup.push(n?FT(this.proxy(n)):null),this._markpath.push(-1)},AD.popState=function(){this._encode.pop(),this._parent.pop(),this._lookup.pop(),this._markpath.pop()},AD.parent=function(){return Object(Ee.K)(this._parent)},AD.encode=function(){return Object(Ee.K)(this._encode)},AD.lookup=function(){return Object(Ee.K)(this._lookup)},AD.markpath=function(){var e=this._markpath;return++e[e.length-1]},AD.fieldRef=function(e,t){if(Object(Ee.B)(e))return UT(e,t);e.signal||Object(Ee.l)(\"Unsupported field reference: \"+Object(Ee.M)(e));var n,r=e.signal,i=this.field[r];return i||(n={name:this.signalRef(r)},t&&(n.as=t),this.field[r]=i=FT(this.add(pD(n)))),i},AD.compareRef=function(e,t){function n(e){return $T(e)?(i=!0,FT(r[e.signal])):e}var r=this.signals,i=!1,a=Object(Ee.h)(e.field).map(n),o=Object(Ee.h)(e.order).map(n);return t&&a.push(BT),i?FT(this.add(dD({fields:a,orders:o}))):zT(a,o)},AD.keyRef=function(e,t){var n=this.signals,r=!1;return e=Object(Ee.h)(e).map(function(e){return $T(e)?(r=!0,FT(n[e.signal])):e}),r?FT(this.add(mD({fields:e,flat:t}))):function(e,t){var n={$key:e};return t&&(n.$flat=!0),n}(e,t)},AD.sortRef=function(e){if(!e)return e;var t=[GT(e.op,e.field),BT],n=e.order||\"ascending\";return n.signal?FT(this.add(dD({fields:t,orders:[n=this.signalRef(n.signal),n]}))):zT(t,[n,n])},AD.event=function(e,t){var n=e+\":\"+t;if(!this.events[n]){var r=this.id();this.streams.push({id:r,source:e,type:t}),this.events[n]=r}return this.events[n]},AD.addSignal=function(e,t){this.signals.hasOwnProperty(e)&&Object(Ee.l)(\"Duplicate signal name: \"+Object(Ee.M)(e));var n=t instanceof IT?t:this.add(PT(t));return this.signals[e]=n},AD.getSignal=function(e){return this.signals[e]||Object(Ee.l)(\"Unrecognized signal name: \"+Object(Ee.M)(e)),this.signals[e]},AD.signalRef=function(e){return this.signals[e]?FT(this.signals[e]):(this.lambdas.hasOwnProperty(e)||(this.lambdas[e]=this.add(PT(null))),FT(this.lambdas[e]))},AD.parseLambdas=function(){for(var e=Object.keys(this.lambdas),t=0,n=e.length;t=0;)if(r=i[a].type,n=i[a].handler,e===r&&(t===n||t===n.raw)){this._handler.off(r,n);break}return this},aA.addResizeListener=function(e){var t=this._resizeListeners;return t.indexOf(e)<0&&t.push(e),this},aA.removeResizeListener=function(e){var t=this._resizeListeners,n=t.indexOf(e);return n>=0&&t.splice(n,1),this},aA.addSignalListener=function(e,t){var n=oA(this,e),r=sA(n,t);return r||((r=tM(this,function(){t(e,n.value)})).handler=t,this.on(n,null,r)),this},aA.removeSignalListener=function(e,t){var n=oA(this,e),r=sA(n,t);return r&&n._targets.remove(r),this},aA.preventDefault=function(e){return arguments.length?(this._preventDefault=e,this):this._preventDefault},aA.timer=function(e,t){this._timers.push(function(e,t,n){var r=new IE,i=t;return null==t?(r.restart(e,t,n),r):(t=+t,n=null==n?kE():+n,r.restart(function a(o){o+=i,r.restart(a,i+=t,n),e(o)},t,n),r)}(function(t){e({timestamp:Date.now(),elapsed:t})},t))},aA.events=function(e,t,n){var r,i=this,a=new $e(n),o=function(n,r){e===LO&&function(e,t){var n=e._eventConfig.defaults,r=n&&n.prevent,i=n&&n.allow;return!1!==r&&!0!==i&&(!0===r||!1===i||(r?r[t]:i?!i[t]:e.preventDefault()))}(i,t)&&n.preventDefault();try{a.receive(IO(i,n,r))}catch(e){i.error(e)}finally{i.run()}};if(e===PO)i.timer(o,t);else if(e===LO)i.addEventListener(t,o,BO);else if(e===FO?\"undefined\"!=typeof window&&(r=[window]):\"undefined\"!=typeof document&&(r=document.querySelectorAll(e)),r){for(var s=0,l=r.length;s=0;)i[e].stop();for(e=a.length;--e>=0;)for(t=(n=a[e]).sources.length;--t>=0;)n.sources[t].removeEventListener(n.type,n.handler);return r&&r.call(this,this._handler,null,null,null),this},aA.hover=function(e,t){return e=[e||\"hover\"],t=[t||\"update\",e[0]],this.on(this.events(\"view\",\"mouseover\",UO),jO,zO(e)),this.on(this.events(\"view\",\"mouseout\",UO),jO,zO(t)),this},aA.data=function(e){return TO(this,e).values.value},aA.change=DO,aA.insert=function(e,t){return DO.call(this,e,Ie().insert(t))},aA.remove=function(e,t){return DO.call(this,e,Ie().remove(t))},aA.scale=function(e){var t=this._runtime.scales;return t.hasOwnProperty(e)||Object(Ee.l)(\"Unrecognized scale or projection: \"+e),t[e].value},aA.initialize=function(e,t){var n,r,i=this,a=i._renderType,o=Yu(a);return e=i._el=e?nM(i,e):null,o||i.error(\"Unrecognized renderer type: \"+a),n=o.handler||fu,r=e?o.renderer:o.headless,i._renderer=r?eM(i,i._renderer,e,r):null,i._handler=function(e,t,n,r){var i=new r(e.loader(),tM(e,e.tooltip())).scene(e.scenegraph().root).initialize(n,RO(e),e);return t&&t.handlers().forEach(function(e){i.on(e.type,e.handler)}),i}(i,i._handler,e,n),i._redraw=!0,e&&(t=t?nM(i,t):e.appendChild(qO(\"div\",{class:\"vega-bindings\"})),i._bind.forEach(function(e){e.param.element&&(e.element=nM(i,e.param.element))}),i._bind.forEach(function(e){VO(i,e.element||t,e)})),i},aA.toImageURL=function(e,t){return e!==Ku.Canvas&&e!==Ku.SVG&&e!==Ku.PNG?Promise.reject(\"Unrecognized image type: \"+e):rM(this,e,t).then(function(t){return e===Ku.SVG?(n=t.svg(),r=new Blob([n],{type:\"image/svg+xml\"}),window.URL.createObjectURL(r)):t.canvas().toDataURL(\"image/png\");var n,r})},aA.toCanvas=function(e){return rM(this,Ku.Canvas,e).then(function(e){return e.canvas()})},aA.toSVG=function(e){return rM(this,Ku.SVG,e).then(function(e){return e.svg()})},aA.getState=function(e){return this._runtime.getState(e||{data:JD,signals:eA,recurse:!0})},aA.setState=function(e){var t=this;return t.runAfter(function(){t._trigger=!1,t._runtime.setState(e),t.run().runAfter(function(){t._trigger=!0})}),this};var lA=function(e,t){return e=e||t.autosize,Object(Ee.z)(e)?e:{type:e=e||\"pad\"}},cA=function(e,t){return e=e||t.padding,Object(Ee.z)(e)?{top:uA(e.top),bottom:uA(e.bottom),left:uA(e.left),right:uA(e.right)}:{top:n=uA(e),bottom:n,left:n,right:n};var n};function uA(e){return+e||0}var dA=[\"value\",\"update\",\"react\",\"bind\"];function fA(e,t){Object(Ee.l)(e+' for \"outer\" push: '+Object(Ee.M)(t))}var pA=function(e,t){var n=e.name;if(\"outer\"===e.push)t.signals[n]||fA(\"No prior signal definition\",n),dA.forEach(function(t){void 0!==e[t]&&fA(\"Invalid property \",t)});else{var r=t.addSignal(n,e.value);!1===e.react&&(r.react=!1),e.bind&&t.addBinding(n,e.bind)}},mA={};function gA(e,t,n){var r=e+\":\"+n,i=mA[r];return i&&i[0]===t||(mA[r]=i=[t,t(n)]),i[1]}function hA(e,t){return gA(\"timeFormat\",gn,t)(e)}var bA=new Date(2e3,0,1);function vA(e,t,n){return bA.setMonth(e),bA.setDate(t),hA(bA,n)}function _A(e,t,n){try{e[t].apply(e,[\"EXPRESSION\"].concat([].slice.call(n)))}catch(t){e.warn(t)}return n[n.length-1]}var yA=\"undefined\"!=typeof window&&window||null;var xA=\"Literal\",EA=\"Identifier\",SA=\"@\",wA=\"%\",CA=\":\",OA=function(e,t,n){var r=e-t+2*n;return e?r>0?r:1:0},MA=function(e){return function(t){var n,r=t[0],i=t[1];return i=s&&o[i]<=l&&(c<0&&(c=i),n=i);if(!(c<0))return s=e.invertExtent(o[c]),l=e.invertExtent(o[n]),[void 0===s[0]?s[1]:s[0],void 0===l[1]?l[0]:l[1]]}};function TA(){var e,t,n=hC().unknown(void 0),r=n.domain,i=n.range,a=[0,1],o=!1,s=0,l=0,c=.5;function u(){var n=r().length,u=a[1]a[1-u])))return n=Math.max(0,mi(d,l)-1),o=l===c?n:mi(d,c)-1,l-d[n]>t+1e-10&&++n,u&&(s=n,n=f-o,o=f-s),n>o?void 0:r().slice(n,o+1)}},n.invert=function(e){var t=n.invertRange([e,e]);return t?t[0]:t},n.copy=function(){return TA().domain(r()).range(a).round(o).paddingInner(s).paddingOuter(l).align(c)},u()}var DA=Array.prototype.map,AA=Array.prototype.slice;function kA(e){return DA.call(e,function(e){return+e})}function RA(e,t){return arguments.length>1?(IA[e]=function(e,t){return function(){var n=t();return n.invertRange||(n.invertRange=n.invert?MA(n):n.invertExtent?NA(n):void 0),n.type=e,n}}(e,t),this):IA.hasOwnProperty(e)?IA[e]:void 0}var IA={identity:NC,linear:MC,log:PC,ordinal:hC,pow:BC,sqrt:UC,quantile:jC,quantize:zC,threshold:qC,time:JC,utc:eO,band:TA,point:function(){return function e(t){var n=t.copy;return t.padding=t.paddingOuter,delete t.paddingInner,t.copy=function(){return e(n())},t}(TA().paddingInner(1))},sequential:function e(t){var n=MC(),r=0,i=1,a=!1;function o(){var e=n.domain();r=e[0],i=Object(Ee.K)(e)-r}function s(e){var n=(e-r)/i;return t(a?Math.max(0,Math.min(1,n)):n)}return s.clamp=function(e){return arguments.length?(a=!!e,s):a},s.domain=function(e){return arguments.length?(n.domain(e),o(),s):n.domain()},s.interpolator=function(e){return arguments.length?(t=e,s):t},s.copy=function(){return e().domain(n.domain()).clamp(a).interpolator(t)},s.ticks=function(e){return n.ticks(e)},s.tickFormat=function(e,t){return n.tickFormat(e,t)},s.nice=function(e){return n.nice(e),o(),s},s},\"bin-linear\":function e(){var t=MC(),n=[];function r(e){return t(e)}return r.domain=function(e){return arguments.length?(function(e){n=kA(e),t.domain([n[0],Object(Ee.K)(n)])}(e),r):n.slice()},r.range=function(e){return arguments.length?(t.range(e),r):t.range()},r.rangeRound=function(e){return arguments.length?(t.rangeRound(e),r):t.rangeRound()},r.interpolate=function(e){return arguments.length?(t.interpolate(e),r):t.interpolate()},r.invert=function(e){return t.invert(e)},r.ticks=function(e){var t=n.length,i=~~(t/(e||t));return i<2?r.domain():n.filter(function(e,t){return!(t%i)})},r.tickFormat=function(){return t.tickFormat.apply(t,arguments)},r.copy=function(){return e().domain(r.domain()).range(r.range())},r},\"bin-ordinal\":function e(){var t=[],n=[];function r(e){return null==e||e!=e?void 0:n[(hi(t,e)-1)%n.length]}return r.domain=function(e){return arguments.length?(t=kA(e),r):t.slice()},r.range=function(e){return arguments.length?(n=AA.call(e),r):n.slice()},r.copy=function(){return e().domain(r.domain()).range(r.range())},r}};for(var LA in IA)RA(LA,IA[LA]);function PA(e,t){var n=t-e;return function(t){return e+t*n}}function FA(e){for(var t=e.length/6|0,n=new Array(t),r=0;ro&&(i=a,a=o,o=i),n=void 0===n||n,r=void 0===r||r,(n?a<=e:a=2&&t[t.length-1].value,o=SA+\"unit\";a!==ck||r.hasOwnProperty(o)||(r[o]=n.getData(i).indataRef(n,\"unit\")),tk(0,t,n,r)}function bk(e,t,n,r){var i,a,o,s,l,c=this.context.data[e],u=c?c.values.value:[],d=c?c[dk]&&c[dk].value:void 0,f=u[0],p=0;if(f){for(i=t?f.encodings.length:f.fields.length;p(a=n[1])&&(a=n[0],i=n[1]),r=r?o(r,i,a):[i,a];return r&&r.length&&+r[0]!=+r[1]?r:void 0}function yk(e,t,n){return e[0]>t&&(e[0]=t),e[1]n&&(e[1]=n),e)}var Ek={random:function(){return ui()},isArray:Ee.u,isBoolean:Ee.v,isDate:Ee.w,isNumber:Ee.y,isObject:Ee.z,isRegExp:Ee.A,isString:Ee.B,isTuple:Oe,toBoolean:Ee.N,toDate:Ee.O,toNumber:Ee.P,toString:Ee.R,pad:Ee.G,peek:Ee.K,truncate:Ee.S,rgb:Sf,lab:jf,hcl:Vf,hsl:Mf,sequence:xi,format:function(e,t){return gA(\"format\",um,t)(e)},utcFormat:function(e,t){return gA(\"utcFormat\",bn,t)(e)},utcParse:function(e,t){return gA(\"utcParse\",vn,t)(e)},timeFormat:hA,timeParse:function(e,t){return gA(\"timeParse\",hn,t)(e)},monthFormat:function(e){return vA(e,1,\"%B\")},monthAbbrevFormat:function(e){return vA(e,1,\"%b\")},dayFormat:function(e){return vA(0,2+e,\"%A\")},dayAbbrevFormat:function(e){return vA(0,2+e,\"%a\")},quarter:function(e){return 1+~~(new Date(e).getMonth()/3)},utcquarter:function(e){return 1+~~(new Date(e).getUTCMonth()/3)},warn:function(){return _A(this.context.dataflow,\"warn\",arguments)},info:function(){return _A(this.context.dataflow,\"info\",arguments)},debug:function(){return _A(this.context.dataflow,\"debug\",arguments)},inScope:function(e){var t=this.context.group,n=!1;if(t)for(;e;){if(e===t){n=!0;break}e=e.mark.group}return n},clampRange:function(e,t,n){var r,i=e[0],a=e[1];return a=n-t?[t,n]:[Math.min(Math.max(i,t),n-r),Math.min(Math.max(a,r),n)]},pinchDistance:function(e){var t=e.touches,n=t[0].clientX-t[1].clientX,r=t[0].clientY-t[1].clientY;return Math.sqrt(n*n+r*r)},pinchAngle:function(e){var t=e.touches;return Math.atan2(t[0].clientY-t[1].clientY,t[0].clientX-t[1].clientX)},screen:function(){return yA?yA.screen:{}},containerSize:function(){var e=this.context.dataflow,t=e.container&&e.container();return t?[t.clientWidth,t.clientHeight]:[void 0,void 0]},windowSize:function(){return yA?[yA.innerWidth,yA.innerHeight]:[void 0,void 0]},span:function(e){return e[e.length-1]-e[0]||0},merge:function(){var e=[].slice.call(arguments);return e.unshift({}),Ee.m.apply(null,e)},flush:function(e,t,n,r,i,a){var o,s,l=e[0],c=Object(Ee.K)(e);return c2;break}return s=u.reduce(function(e,t){var n=t.intervals[o].extent,r=l?n.map(function(e){return{unit:t.unit,value:e}}):{unit:t.unit,value:n};return l?e.push.apply(e,r):e.push(r),e},[]),l?vk(s,r):_k(s,r)}},tk),Mk(\"treePath\",function(e,t,n){var r=ik(e,this),i=r[t],a=r[n];return i&&a?i.path(a).map(rk):void 0},tk),Mk(\"treeAncestors\",function(e,t){var n=ik(e,this)[t];return n?n.ancestors().map(rk):void 0},tk);var Nk={blacklist:[\"_\"],whitelist:[\"datum\",\"event\",\"item\"],fieldvar:\"datum\",globalvar:function(e){return\"_[\"+Object(Ee.M)(\"$\"+e)+\"]\"},functions:function(e){var t=PN(e);for(var n in Sk.forEach(function(e){t[e]=wk+e}),Ek)t[n]=Ck+n;return t},constants:LN,visitors:Ok},Tk=FN(Nk),Dk=function(e,t,n){var r,i,a={};try{e=Object(Ee.B)(e)?e:Object(Ee.M)(e)+\"\",r=IN(e)}catch(t){Object(Ee.l)(\"Expression parse error: \"+e)}return r.visit(function(e){if(\"CallExpression\"===e.type){var n=e.callee.name,r=Nk.visitors[n];r&&r(n,e.arguments,t,a)}}),(i=Tk(r)).globals.forEach(function(e){var n=\"$\"+e;!a.hasOwnProperty(n)&&t.getSignal(e)&&(a[n]=t.signalRef(e))}),{$expr:n?n+\"return(\"+i.code+\");\":i.code,$fields:i.fields,$params:a}};function Ak(e,t,n,r){this.id=-1,this.type=e,this.value=t,this.params=n,r&&(this.parent=r)}function kk(e,t,n,r){return new Ak(e,t,n,r)}function Rk(e,t){return kk(\"operator\",e,t)}function Ik(e){var t={$ref:e.id};return e.id<0&&(e.refs=e.refs||[]).push(t),t}var Lk={$tupleid:1,toString:function(){return\":_tupleid_:\"}};function Pk(e,t){return t?{$field:e,$name:t}:{$field:e}}var Fk=Pk(\"key\");function Bk(e,t){return{$compare:e,$order:t}}var Uk=\"descending\";function jk(e,t){return(e&&e.signal?\"$\"+e.signal:e||\"\")+(e&&t?\"_\":\"\")+(t&&t.signal?\"$\"+t.signal:t||\"\")}var zk=\"scope\",qk=\"view\";function Gk(e){return e&&e.signal}function $k(e,t){return null!=e?e:t}function Hk(e){return e&&e.signal||e}var Wk=\"timer\";function Vk(e,t){return(e.merge?Kk:e.stream?Qk:e.type?Yk:Object(Ee.l)(\"Invalid stream specification: \"+Object(Ee.M)(e)))(e,t)}function Kk(e,t){var n=Zk({merge:e.merge.map(function(e){return Vk(e,t)})},e,t);return t.addStream(n).id}function Qk(e,t){var n=Zk({stream:Vk(e.stream,t)},e,t);return t.addStream(n).id}function Yk(e,t){var n,r,i;return e.type===Wk?(n=t.event(Wk,e.throttle),e={between:e.between,filter:e.filter}):n=t.event((i=e.source)===zk?qk:i||qk,e.type),r=Zk({stream:n},e,t),1===Object.keys(r).length?n:t.addStream(r).id}function Zk(e,t,n){var r,i,a,o,s=t.between;return s&&(2!==s.length&&Object(Ee.l)('Stream \"between\" parameter must have 2 entries: '+Object(Ee.M)(t)),e.between=[Vk(s[0],n),Vk(s[1],n)]),s=t.filter?Object(Ee.h)(t.filter):[],(t.marktype||t.markname||t.markrole)&&s.push((r=t.marktype,i=t.markname,a=t.markrole,(o=\"event.item\")+(r&&\"*\"!==r?\"&&\"+o+\".mark.marktype==='\"+r+\"'\":\"\")+(a?\"&&\"+o+\".mark.role==='\"+a+\"'\":\"\")+(i?\"&&\"+o+\".mark.name==='\"+i+\"'\":\"\"))),t.source===zk&&s.push(\"inScope(event.item)\"),s.length&&(e.filter=Dk(\"(\"+s.join(\")&&(\")+\")\").$expr),null!=(s=t.throttle)&&(e.throttle=+s),null!=(s=t.debounce)&&(e.debounce=+s),t.consume&&(e.consume=!0),e}var Xk=function(e,t,n){var r,i,a=e.events,o=e.update,s=e.encode,l=[];a||Object(Ee.l)(\"Signal update missing events specification.\"),Object(Ee.B)(a)&&(a=VT(a,t.isSubscope()?zk:qk)),(a=Object(Ee.h)(a).filter(function(e){return e.signal||e.scale?(l.push(e),0):1})).length&&l.push(a.length>1?{merge:a}:a[0]),null!=s&&(o&&Object(Ee.l)(\"Signal encode and update are mutually exclusive.\"),o=\"encode(item(),\"+Object(Ee.M)(s)+\")\"),r=Object(Ee.B)(o)?Dk(o,t,\"var datum=event.item&&event.item.datum;\"):null!=o.expr?Dk(o.expr,t,\"var datum=event.item&&event.item.datum;\"):null!=o.value?o.value:null!=o.signal?{$expr:\"_.value\",$params:{value:t.signalRef(o.signal)}}:Object(Ee.l)(\"Invalid signal update specification.\"),i={target:n,update:r},e.force&&(i.options={force:!0}),l.forEach(function(e){t.addUpdate(Object(Ee.m)(function(e,t){return{source:e.signal?t.signalRef(e.signal):e.scale?t.scaleRef(e.scale):Vk(e,t)}}(e,t),i))})};function Jk(e){return function(t,n,r){return kk(e,n,t||void 0,r)}}var eR=Jk(\"aggregate\"),tR=Jk(\"axisticks\"),nR=Jk(\"bound\"),rR=Jk(\"collect\"),iR=Jk(\"compare\"),aR=Jk(\"datajoin\"),oR=Jk(\"encode\"),sR=(Jk(\"extent\"),Jk(\"facet\")),lR=Jk(\"field\"),cR=Jk(\"key\"),uR=Jk(\"legendentries\"),dR=Jk(\"mark\"),fR=Jk(\"multiextent\"),pR=Jk(\"multivalues\"),mR=Jk(\"overlap\"),gR=Jk(\"params\"),hR=Jk(\"prefacet\"),bR=Jk(\"projection\"),vR=Jk(\"proxy\"),_R=Jk(\"relay\"),yR=Jk(\"render\"),xR=Jk(\"scale\"),ER=Jk(\"sieve\"),SR=Jk(\"sortitems\"),wR=Jk(\"viewlayout\"),CR=Jk(\"values\"),OR=0,MR=[\"identity\",\"ordinal\",\"band\",\"point\",\"bin-linear\",\"bin-ordinal\",\"quantize\",\"quantile\",\"threshold\",\"linear\",\"pow\",\"sqrt\",\"log\",\"sequential\",\"time\",\"utc\"],NR=Object(Ee.Q)(MR),TR=Object(Ee.Q)(MR.slice(4,9)),DR=Object(Ee.Q)(MR.slice(9)),AR=Object(Ee.Q)(MR.slice(1,6));function kR(e){return AR.hasOwnProperty(e)}function RR(e){return TR.hasOwnProperty(e)}function IR(e){return\"quantile\"===e}function LR(e,t){var n,r=t.getScale(e.name).params;for(n in r.domain=BR(e.domain,e,t),null!=e.range&&(r.range=function e(t,n,r){var i=t.range,a=n.config.range;if(i.signal)return n.signalRef(i.signal);if(Object(Ee.B)(i)){if(a&&a.hasOwnProperty(i))return t=Object(Ee.m)({},t,{range:a[i]}),e(t,n,r);\"width\"===i?i=[0,{signal:\"width\"}]:\"height\"===i?i=kR(t.type)?[0,{signal:\"height\"}]:[{signal:\"height\"},0]:Object(Ee.l)(\"Unrecognized scale range value: \"+Object(Ee.M)(i))}else{if(i.scheme)return r.scheme=PR(i.scheme,n),i.extent&&(r.schemeExtent=function(e,t){return e.signal?t.signalRef(e.signal):e.map(function(e){return PR(e,t)})}(i.extent,n)),void(i.count&&(r.schemeCount=PR(i.count,n)));if(i.step)return void(r.rangeStep=PR(i.step,n));if(kR(t.type)&&!Object(Ee.u)(i))return BR(i,t,n);Object(Ee.u)(i)||Object(Ee.l)(\"Unsupported range type: \"+Object(Ee.M)(i))}return i.map(function(e){return PR(e,n)})}(e,t,r)),null!=e.interpolate&&function(e,t){t.interpolate=PR(e.type||e),null!=e.gamma&&(t.interpolateGamma=PR(e.gamma))}(e.interpolate,r),null!=e.nice&&function(e,t){t.nice=Object(Ee.z)(e)?{interval:PR(e.interval),step:PR(e.step)}:PR(e)}(e.nice,r),e)r.hasOwnProperty(n)||\"name\"===n||(r[n]=PR(e[n],t))}function PR(e,t){return Object(Ee.z)(e)?e.signal?t.signalRef(e.signal):Object(Ee.l)(\"Unsupported object: \"+Object(Ee.M)(e)):e}function FR(e){Object(Ee.l)(\"Can not find data set: \"+Object(Ee.M)(e))}function BR(e,t,n){if(e)return e.signal?n.signalRef(e.signal):(Object(Ee.u)(e)?function(e,t,n){return e.map(function(e){return PR(e,n)})}:e.fields?function(e,t,n){var r=e.data,i=e.fields.reduce(function(e,t){return t=Object(Ee.B)(t)?{data:r,field:t}:Object(Ee.u)(t)||t.signal?function(e,t){var n=\"_:vega:_\"+OR++,r=rR({});if(Object(Ee.u)(e))r.value={$ingest:e};else if(e.signal){var i=\"setdata(\"+Object(Ee.M)(n)+\",\"+e.signal+\")\";r.params.input=t.signalRef(i)}return t.addDataPipeline(n,[r,ER({})]),{data:n,field:\"data\"}}(t,n):t,e.push(t),e},[]);return(kR(t.type)?function(e,t,n){var r,i,a;return r=n.map(function(e){var n=t.getData(e.data);return n||FR(e.data),n.countsRef(t,e.field)}),i=t.add(eR({groupby:Fk,ops:[\"sum\"],fields:[t.fieldRef(\"count\")],as:[\"count\"],pulse:r})),a=t.add(rR({pulse:Ik(i)})),Ik(t.add(CR({field:Fk,sort:t.sortRef(UR(e.sort,!0)),pulse:Ik(a)})))}:IR(t.type)?function(e,t,n){var r=n.map(function(e){var n=t.getData(e.data);return n||FR(e.data),n.domainRef(t,e.field)});return Ik(t.add(pR({values:r})))}:function(e,t,n){var r=n.map(function(e){var n=t.getData(e.data);return n||FR(e.data),n.extentRef(t,e.field)});return Ik(t.add(fR({extents:r})))})(e,n,i)}:function(e,t,n){var r=n.getData(e.data);r||FR(e.data);return kR(t.type)?r.valuesRef(n,e.field,UR(e.sort,!1)):IR(t.type)?r.domainRef(n,e.field):r.extentRef(n,e.field)})(e,t,n);null==t.domainMin&&null==t.domainMax||Object(Ee.l)(\"No scale domain defined for domainMin/domainMax to override.\")}function UR(e,t){return e&&(e.field||e.op?e.field||\"count\"===e.op?t&&e.field?Object(Ee.l)(\"Multiple domain scales can not sort by field.\"):t&&e.op&&\"count\"!==e.op&&Object(Ee.l)(\"Multiple domain scales support op count only.\"):Object(Ee.l)(\"No field provided for sort aggregate op: \"+e.op):Object(Ee.z)(e)?e.field=\"key\":e={field:\"key\"}),e}function jR(e,t,n){return Object(Ee.u)(e)?e.map(function(e){return jR(e,t,n)}):Object(Ee.z)(e)?e.signal?n.signalRef(e.signal):\"fit\"===t?e:Object(Ee.l)(\"Unsupported parameter object: \"+Object(Ee.M)(e)):e}var zR=\"top\",qR=\"left\",GR=\"bottom\",$R=\"vertical\",HR=\"start\",WR=\"end\",VR=\"guide-label\",KR=\"group-title\",QR=\"symbol\",YR=\"gradient\",ZR=\"discrete\",XR=[\"size\",\"shape\",\"fill\",\"stroke\",\"strokeDash\",\"opacity\"],JR={name:1,interactive:1},eI=Object(Ee.Q)([\"rule\"]),tI=Object(Ee.Q)([\"group\",\"image\",\"rect\"]),nI=function(e,t){var n=\"\";return eI[t]?n:(e.x2&&(e.x?(tI[t]&&(n+=\"if(o.x>o.x2)$=o.x,o.x=o.x2,o.x2=$;\"),n+=\"o.width=o.x2-o.x;\"):n+=\"o.x=o.x2-(o.width||0);\"),e.xc&&(n+=\"o.x=o.xc-(o.width||0)/2;\"),e.y2&&(e.y?(tI[t]&&(n+=\"if(o.y>o.y2)$=o.y,o.y=o.y2,o.y2=$;\"),n+=\"o.height=o.y2-o.y;\"):n+=\"o.y=o.y2-(o.height||0);\"),e.yc&&(n+=\"o.y=o.yc-(o.height||0)/2;\"),n)},rI=function(e,t,n,r){var i=Dk(e,t);return i.$fields.forEach(function(e){r[e]=1}),Object(Ee.m)(n,i.$params),i.$expr},iI=function(e,t,n,r){return function e(t,n,r,i){var a,o,s;if(t.signal)a=\"datum\",s=rI(t.signal,n,r,i);else if(t.group||t.parent){for(o=Math.max(1,t.level||1),a=\"item\";o-- >0;)a+=\".mark.group\";t.parent?(s=t.parent,a+=\".datum\"):s=t.group}else t.datum?(a=\"datum\",s=t.datum):Object(Ee.l)(\"Invalid field reference: \"+Object(Ee.M)(t));t.signal||(Object(Ee.B)(s)?(i[s]=1,s=Object(Ee.L)(s).map(Ee.M).join(\"][\")):s=e(s,n,r,i));return a+\"[\"+s+\"]\"}(Object(Ee.z)(e)?e:{datum:e},t,n,r)};var aI=function(e,t,n,r,i){var a,o,s,l=oI(e.scale,n,r,i);return null!=e.range?(o=l+\".range()\",t=0===(a=+e.range)?o+\"[0]\":\"($=\"+o+\",\"+(1===a?\"$[$.length-1]\":\"$[0]+\"+a+\"*($[$.length-1]-$[0])\")+\")\"):(void 0!==t&&(t=l+\"(\"+t+\")\"),e.band&&(s=function(e,t){if(!Object(Ee.B)(e))return-1;var n=t.scaleType(e);return\"band\"===n||\"point\"===n?1:0}(e.scale,n))&&(a=(o=l+\".bandwidth\")+\"()\"+(1===(a=+e.band)?\"\":\"*\"+a),s<0&&(a=\"(\"+o+\"?\"+a+\":0)\"),t=(t?t+\"+\":\"\")+a,e.extra&&(t=\"(datum.extra?\"+l+\"(datum.extra.value):\"+t+\")\")),null==t&&(t=\"0\")),t};function oI(e,t,n,r){var i;if(Object(Ee.B)(e))i=wA+e,n.hasOwnProperty(i)||(n[i]=t.scaleRef(e)),i=Object(Ee.M)(i);else{for(i in t.scales)n[wA+i]=t.scaleRef(i);i=Object(Ee.M)(wA)+\"+\"+(e.signal?\"(\"+rI(e.signal,t,n,r)+\")\":iI(e,t,n,r))}return\"_[\"+i+\"]\"}var sI=function(e,t,n,r){return Object(Ee.z)(e)?\"(\"+lI(null,e,t,n,r)+\")\":e},lI=function(e,t,n,r,i){if(null!=t.gradient)return function(e,t,n,r){return\"this.gradient(\"+oI(e.gradient,t,n,r)+\",\"+Object(Ee.M)(e.start)+\",\"+Object(Ee.M)(e.stop)+\",\"+Object(Ee.M)(e.count)+\")\"}(t,n,r,i);var a=t.signal?rI(t.signal,n,r,i):t.color?function(e,t,n,r){function i(e,i,a,o){return\"this.\"+e+\"(\"+[lI(null,i,t,n,r),lI(null,a,t,n,r),lI(null,o,t,n,r)].join(\",\")+\").toString()\"}return e.c?i(\"hcl\",e.h,e.c,e.l):e.h||e.s?i(\"hsl\",e.h,e.s,e.l):e.l||e.a?i(\"lab\",e.l,e.a,e.b):e.r||e.g||e.b?i(\"rgb\",e.r,e.g,e.b):null}(t.color,n,r,i):null!=t.field?iI(t.field,n,r,i):void 0!==t.value?Object(Ee.M)(t.value):void 0;return null!=t.scale&&(a=aI(t,a,n,r,i)),void 0===a&&(a=null),null!=t.exponent&&(a=\"Math.pow(\"+a+\",\"+sI(t.exponent,n,r,i)+\")\"),null!=t.mult&&(a+=\"*\"+sI(t.mult,n,r,i)),null!=t.offset&&(a+=\"+\"+sI(t.offset,n,r,i)),t.round&&(a=\"Math.round(\"+a+\")\"),a},cI=function(e,t,n){return e+\"[\"+Object(Ee.M)(t)+\"]=\"+n+\";\"},uI=function(e,t,n,r,i){var a=\"\";return t.forEach(function(t){var o=lI(e,t,n,r,i);a+=t.test?rI(t.test,n,r,i)+\"?\"+o+\":\":o}),cI(\"o\",e,a)};function dI(e,t,n,r){var i,a,o,s={},l=\"var o=item,datum=o.datum,$;\";for(i in e)a=e[i],Object(Ee.u)(a)?l+=uI(i,a,r,n,s):(o=lI(i,a,r,n,s),l+=cI(\"o\",i,o));return l+=nI(e,t),{$expr:l+=\"return 1;\",$fields:Object.keys(s),$output:Object.keys(e)}}var fI=\"mark\",pI=\"frame\",mI=\"title\";function gI(e){return Object(Ee.z)(e)?Object(Ee.m)({},e):{value:e}}function hI(e,t,n){return null!=n?(e[t]=Object(Ee.z)(n)&&!Object(Ee.u)(n)?n:{value:n},1):0}function bI(e,t,n){for(var r in t)n&&n.hasOwnProperty(r)||(e[r]=Object(Ee.m)(e[r]||{},t[r]));return e}function vI(e,t,n,r,i,a){var o,s;for(s in(a=a||{}).encoders={$encode:o={}},e=function(e,t,n,r,i){var a,o,s={};\"legend\"!=n&&0!==String(n).indexOf(\"axis\")||(n=null);for(a in o=n===pI?i.group:n===fI?Object(Ee.m)({},i.mark,i[t]):null)yI(a,e)||(\"fill\"===a||\"stroke\"===a)&&(yI(\"fill\",e)||yI(\"stroke\",e))||(s[a]=_I(o[a]));return Object(Ee.h)(r).forEach(function(t){var n=i.style&&i.style[t];for(var r in n)yI(r,e)||(s[r]=_I(n[r]))}),(e=Object(Ee.m)({},e)).enter=Object(Ee.m)(s,e.enter),e}(e,t,n,r,i.config))o[s]=dI(e[s],t,a,i);return a}function _I(e){return e&&e.signal?{signal:e.signal}:{value:e}}function yI(e,t){return t&&(t.enter&&t.enter[e]||t.update&&t.update[e])}var xI=function(e,t,n,r,i,a,o){return{type:e,name:o?o.name:void 0,role:t,style:o&&o.style||n,key:r,from:i,interactive:!(!o||!o.interactive),encode:bI(a,o,JR)}};function EI(e,t,n){return $k(t[e],n[e])}function SI(e,t){return $k(e.direction,t)===$R}function wI(e,t){return $k(e.gradientLength,t.gradientLength||t.gradientWidth)}function CI(e,t){return $k(e.gradientThickness,t.gradientThickness||t.gradientHeight)}function OI(e,t){var n=t&&(t.update&&t.update[e]||t.enter&&t.enter[e]);return n&&n.signal?n:n?n.value:null}var MI=\"group\",NI=\"text\",TI=function(e,t,n,r){var i,a,o,s,l={value:0},c=SI(e,t.gradientDirection),u=gI(CI(e,t)),d=wI(e,t),f=EI(\"labelOverlap\",e,t),p={},m=\"\";return p.enter=i={opacity:l},hI(i,\"fill\",EI(\"labelColor\",e,t)),hI(i,\"font\",EI(\"labelFont\",e,t)),hI(i,\"fontSize\",EI(\"labelFontSize\",e,t)),hI(i,\"fontWeight\",EI(\"labelFontWeight\",e,t)),hI(i,\"limit\",$k(e.labelLimit,t.gradientLabelLimit)),p.exit={opacity:l},p.update=a={opacity:{value:1},text:{field:\"label\"}},c?(i.align={value:\"left\"},i.baseline=a.baseline={signal:'datum.perc<=0?\"bottom\":datum.perc>=1?\"top\":\"middle\"'},o=\"y\",s=\"x\",m=\"1-\"):(i.align=a.align={signal:'datum.perc<=0?\"left\":datum.perc>=1?\"right\":\"center\"'},i.baseline={value:\"top\"},o=\"x\",s=\"y\"),i[o]=a[o]={signal:m+\"datum.perc\",mult:d},i[s]=a[s]=u,u.offset=$k(e.labelOffset,t.gradientLabelOffset)||0,e=xI(NI,\"legend-label\",VR,\"value\",r,p,n),f&&(e.overlap={method:f,order:\"datum.index\"}),e},DI=function(e,t,n,r,i,a,o,s){return{type:MI,name:n,role:e,style:t,from:r,interactive:i||!1,encode:a,marks:o,layout:s}},AI={value:0};function kI(e,t){return{align:EI(\"gridAlign\",e,t),center:{row:!0,column:!1},columns:function(e,t){return $k(e.columns,$k(t.columns,+SI(e,t.symbolDirection)))}(e,t),padding:{row:EI(\"rowPadding\",e,t),column:EI(\"columnPadding\",e,t)}}}function RI(e){return Object(Ee.z)(e)&&e.signal?e.signal:Object(Ee.M)(e)}var II=function(e){var t=e.role||\"\";return t.indexOf(\"axis\")&&t.indexOf(\"legend\")?e.type===MI?\"scope\":t||fI:t},LI=function(e,t){var n=Jr(e.type);n||Object(Ee.l)(\"Unrecognized transform type: \"+Object(Ee.M)(e.type));var r=kk(n.type.toLowerCase(),null,PI(n,e,t));return e.signal&&t.addSignal(e.signal,t.proxy(r)),r.metadata=n.metadata||{},r};function PI(e,t,n){var r,i,a,o={};for(i=0,a=e.params.length;i0?\",\":\"\")+(Object(Ee.z)(t)?t.signal||fL(t):Object(Ee.M)(t));return n+\"]\"}:function(e){var t,n,r=\"{\",i=0;for(t in e)n=e[t],r+=(++i>1?\",\":\"\")+Object(Ee.M)(t)+\":\"+(Object(Ee.z)(n)?n.signal||fL(n):Object(Ee.M)(n));return r+\"}\"})(e)}dL.fork=function(){return new uL(this)},dL.isSubscope=function(){return this._subid>0},dL.toRuntime=function(){return this.finish(),{background:this.background,operators:this.operators,streams:this.streams,updates:this.updates,bindings:this.bindings,eventConfig:this.eventConfig}},dL.id=function(){return(this._subid?this._subid+\":\":0)+this._id++},dL.add=function(e){return this.operators.push(e),e.id=this.id(),e.refs&&(e.refs.forEach(function(t){t.$ref=e.id}),e.refs=null),e},dL.proxy=function(e){var t=e instanceof Ak?Ik(e):e;return this.add(vR({value:t}))},dL.addStream=function(e){return this.streams.push(e),e.id=this.id(),e},dL.addUpdate=function(e){return this.updates.push(e),e},dL.finish=function(){var e,t;for(e in this.root&&(this.root.root=!0),this.signals)this.signals[e].signal=e;for(e in this.scales)this.scales[e].scale=e;function n(e,t,n){var r;e&&((r=e.data||(e.data={}))[t]||(r[t]=[])).push(n)}for(e in this.data)for(var r in n((t=this.data[e]).input,e,\"input\"),n(t.output,e,\"output\"),n(t.values,e,\"values\"),t.index)n(t.index[r],e,\"index:\"+r);return this},dL.pushState=function(e,t,n){this._encode.push(Ik(this.add(ER({pulse:e})))),this._parent.push(t),this._lookup.push(n?Ik(this.proxy(n)):null),this._markpath.push(-1)},dL.popState=function(){this._encode.pop(),this._parent.pop(),this._lookup.pop(),this._markpath.pop()},dL.parent=function(){return Object(Ee.K)(this._parent)},dL.encode=function(){return Object(Ee.K)(this._encode)},dL.lookup=function(){return Object(Ee.K)(this._lookup)},dL.markpath=function(){var e=this._markpath;return++e[e.length-1]},dL.fieldRef=function(e,t){if(Object(Ee.B)(e))return Pk(e,t);e.signal||Object(Ee.l)(\"Unsupported field reference: \"+Object(Ee.M)(e));var n,r=e.signal,i=this.field[r];return i||(n={name:this.signalRef(r)},t&&(n.as=t),this.field[r]=i=Ik(this.add(lR(n)))),i},dL.compareRef=function(e,t){function n(e){return Gk(e)?(i=!0,Ik(r[e.signal])):e}var r=this.signals,i=!1,a=Object(Ee.h)(e.field).map(n),o=Object(Ee.h)(e.order).map(n);return t&&a.push(Lk),i?Ik(this.add(iR({fields:a,orders:o}))):Bk(a,o)},dL.keyRef=function(e,t){var n=this.signals,r=!1;return e=Object(Ee.h)(e).map(function(e){return Gk(e)?(r=!0,Ik(n[e.signal])):e}),r?Ik(this.add(cR({fields:e,flat:t}))):function(e,t){var n={$key:e};return t&&(n.$flat=!0),n}(e,t)},dL.sortRef=function(e){if(!e)return e;var t=[jk(e.op,e.field),Lk],n=e.order||\"ascending\";return n.signal?Ik(this.add(iR({fields:t,orders:[n=this.signalRef(n.signal),n]}))):Bk(t,[n,n])},dL.event=function(e,t){var n=e+\":\"+t;if(!this.events[n]){var r=this.id();this.streams.push({id:r,source:e,type:t}),this.events[n]=r}return this.events[n]},dL.addSignal=function(e,t){this.signals.hasOwnProperty(e)&&Object(Ee.l)(\"Duplicate signal name: \"+Object(Ee.M)(e));var n=t instanceof Ak?t:this.add(Rk(t));return this.signals[e]=n},dL.getSignal=function(e){return this.signals[e]||Object(Ee.l)(\"Unrecognized signal name: \"+Object(Ee.M)(e)),this.signals[e]},dL.signalRef=function(e){return this.signals[e]?Ik(this.signals[e]):(this.lambdas.hasOwnProperty(e)||(this.lambdas[e]=this.add(Rk(null))),Ik(this.lambdas[e]))},dL.parseLambdas=function(){for(var e=Object.keys(this.lambdas),t=0,n=e.length;te?\"[Object]\":t.indexOf(r)>=0?\"[Circular]\":(t.push(r),r)}}(t))}var LL=function(){function e(e){this.options=NL({},kL,e);var t=this.options.id;if(this.call=this.tooltip_handler.bind(this),!this.options.disableDefaultStyle&&!document.getElementById(this.options.styleId)){var n=document.createElement(\"style\");n.setAttribute(\"id\",this.options.styleId),n.innerHTML=function(e){if(!/^[A-Za-z]+[-:.\\w]*$/.test(e))throw new Error(\"Invalid HTML ID\");return DL.toString().replace(AL,e)}(t),document.head.childNodes.length>0?document.head.insertBefore(n,document.head.childNodes[0]):document.head.appendChild(n)}this.el=document.getElementById(t),this.el||(this.el=document.createElement(\"div\"),this.el.setAttribute(\"id\",t),this.el.classList.add(\"vg-tooltip\"),document.body.appendChild(this.el))}return e.prototype.tooltip_handler=function(e,t,n,r){if(null!=r&&\"\"!==r){this.el.innerHTML=function(e,t,n){if(Object(Ee.u)(e))return\"[\"+e.map(function(e){return t(Object(Ee.B)(e)?e:IL(e,n))}).join(\", \")+\"]\";if(Object(Ee.z)(e)){var r=\"\",i=e,a=i.title,o=TL(i,[\"title\"]);a&&(r+=\"

\"+t(a)+\"

\");var s=Object.keys(o);if(s.length>0){r+=\"\";for(var l=0,c=s;l\"}r+=\"
'+t(u)+':'+t(d)+\"
\"}return r||\"{}\"}return t(e)}(r,RL,this.options.maxDepth),this.el.classList.add(\"visible\",this.options.theme+\"-theme\");var i=function(e,t,n,r){var i=e.clientX+n;i+t.width>window.innerWidth&&(i=+e.clientX-n-t.width);var a=e.clientY+r;return a+t.height>window.innerHeight&&(a=+e.clientY-r-t.height),{x:i,y:a}}(t,this.el.getBoundingClientRect(),this.options.offsetX,this.options.offsetY),a=i.x,o=i.y;this.el.setAttribute(\"style\",\"top: \"+o+\"px; left: \"+a+\"px\")}else this.el.classList.remove(\"visible\",this.options.theme+\"-theme\")},e}(),PL=n(2),FL=n.n(PL);function BL(e){return!!e.or}function UL(e){return!!e.and}function jL(e){return!!e.not}function zL(e,t){for(var n={},r=0,i=t;r-1}function HL(e,t){for(var n=0,r=0;r1&&(kF(OF.droppedDay(e)),delete(e=eP(e)).day),void 0!==e.year?n.push(e.year):void 0!==e.day?n.push(RF):n.push(0),void 0!==e.month){var r=t?function(e){if(Object(Ee.y)(e))return e-1+\"\";var t=e.toLowerCase(),n=PF.indexOf(t);if(-1!==n)return n+\"\";var r=t.substr(0,3),i=FF.indexOf(r);if(-1!==i)return i+\"\";throw new Error(OF.invalidTimeUnit(\"month\",e))}(e.month):e.month;n.push(r)}else if(void 0!==e.quarter){var i=t?function(e){if(Object(Ee.y)(e))return e>4&&kF(OF.invalidTimeUnit(\"quarter\",e)),e-1+\"\";throw new Error(OF.invalidTimeUnit(\"quarter\",e))}(e.quarter):e.quarter;n.push(i+\"*3\")}else n.push(0);if(void 0!==e.date)n.push(e.date);else if(void 0!==e.day){var a=t?function(e){if(Object(Ee.y)(e))return e%7+\"\";var t=e.toLowerCase(),n=BF.indexOf(t);if(-1!==n)return n+\"\";var r=t.substr(0,3),i=UF.indexOf(r);if(-1!==i)return i+\"\";throw new Error(OF.invalidTimeUnit(\"day\",e))}(e.day):e.day;n.push(a+\"+1\")}else n.push(1);for(var o=0,s=[\"hours\",\"minutes\",\"seconds\",\"milliseconds\"];o-1&&(t!==LF.SECONDS||0===n||\"i\"!==e.charAt(n-1))}function YF(e,t){var n=aP(t),r=WF(e)?\"utc\":\"\";return jF(qF.reduce(function(t,i){var a;return QF(e,i)&&(t[i]=(a=i)===LF.QUARTER?\"(\"+r+\"quarter(\"+n+\")-1)\":\"\"+r+a+\"(\"+n+\")\"),t},{}))}function ZF(e){return\"day\"!==e&&e.indexOf(\"day\")>=0?(kF(OF.dayReplacedWithDate(e)),e.replace(\"day\",\"date\")):e}!function(e){e.QUANTITATIVE=\"quantitative\",e.ORDINAL=\"ordinal\",e.TEMPORAL=\"temporal\",e.NOMINAL=\"nominal\",e.LATITUDE=\"latitude\",e.LONGITUDE=\"longitude\",e.GEOJSON=\"geojson\"}(KF||(KF={}));var XF={quantitative:1,ordinal:1,temporal:1,nominal:1,latitude:1,longitude:1,geojson:1};var JF=KF.QUANTITATIVE,eB=KF.ORDINAL,tB=KF.TEMPORAL,nB=KF.NOMINAL,rB=KF.GEOJSON;function iB(e){var t=e.field,n=e.timeUnit,r=e.bin,i=e.aggregate;return NL({},n?{timeUnit:n}:{},r?{bin:r}:{},i?{aggregate:i}:{},{field:t})}function aB(e){return!!e&&!!e.condition}function oB(e){return!!e&&!!e.condition&&!Object(Ee.u)(e.condition)&&sB(e.condition)}function sB(e){return!(!e||!e.field&&\"count\"!==e.aggregate)}function lB(e){return sB(e)&&Object(Ee.B)(e.field)}function cB(e){return e&&\"value\"in e&&void 0!==e.value}function uB(e){return!(!e||!e.scale&&!e.sort)}function dB(e,t){void 0===t&&(t={});var n,r,i=e.field,a=t.prefix,o=t.suffix;if(function(e){return\"count\"===e.aggregate}(e))i=\"count_*\";else{var s=void 0;t.nofn||(!function(e){return!!e.op}(e)?e.bin?(s=oF(e.bin),o=t.binSuffix||\"\"):e.aggregate?s=String(e.aggregate):e.timeUnit&&(s=String(e.timeUnit)):s=e.op),s&&(i=i?s+\"_\"+i:s)}return o&&(i=i+\"_\"+o),a&&(i=a+\"_\"+i),t.expr?(n=i,void 0===(r=t.expr)&&(r=\"datum\"),r+\"[\"+Object(Ee.M)(Object(Ee.L)(n).join(\".\"))+\"]\"):oP(i)}function fB(e){return!function(e){switch(e.type){case\"nominal\":case\"ordinal\":case\"geojson\":return!0;case\"quantitative\":return!!e.bin;case\"latitude\":case\"longitude\":case\"temporal\":return!1}throw new Error(OF.invalidFieldType(e.type))}(e)}function pB(e,t){var n,r=e.field,i=e.bin,a=e.timeUnit,o=e.aggregate;return\"count\"===o?t.countTitle:i?r+\" (binned)\":a?r+\" (\"+function(e){return qF.reduce(function(t,n){return QF(e,n)?t.concat(n):t},[])}(a).join(\"-\")+\")\":o?(n=o).charAt(0).toUpperCase()+n.substr(1)+\" of \"+r:r}var mB=function(e,t){switch(t.fieldTitle){case\"plain\":return e.field;case\"functional\":return function(e,t){var n=e.aggregate||e.timeUnit||e.bin&&\"bin\";return n?n.toUpperCase()+\"(\"+e.field+\")\":e.field}(e);default:return pB(e,t)}},gB=mB;function hB(e){gB=e}function bB(e,t){return gB(e,t)}function vB(e){return sB(e)?e:oB(e)?e.condition:void 0}function _B(e,t){if(Object(Ee.B)(e)||Object(Ee.y)(e)||Object(Ee.v)(e)){var n=Object(Ee.B)(e)?\"string\":Object(Ee.y)(e)?\"number\":\"boolean\";return kF(OF.primitiveChannelDef(t,n,e)),{value:e}}return sB(e)?yB(e,t):oB(e)?NL({},e,{condition:yB(e.condition,t)}):e}function yB(e,t){if(e.aggregate&&(r=e.aggregate,!lP[r])){e.aggregate;var n=TL(e,[\"aggregate\"]);kF(OF.invalidAggregate(e.aggregate)),e=n}var r;if(e.timeUnit&&(e=NL({},e,{timeUnit:ZF(e.timeUnit)})),e.bin&&(e=NL({},e,{bin:xB(e.bin,t)})),e.type){var i=function(e){if(e)switch(e=e.toLowerCase()){case\"q\":case JF:return\"quantitative\";case\"t\":case tB:return\"temporal\";case\"o\":case eB:return\"ordinal\";case\"n\":case nB:return\"nominal\";case KF.LATITUDE:return\"latitude\";case KF.LONGITUDE:return\"longitude\";case rB:return\"geojson\"}}(e.type);e.type!==i&&(e=NL({},e,{type:i})),\"quantitative\"!==e.type&&uP(e.aggregate)&&(kF(OF.invalidFieldTypeForCountAggregate(e.type,e.aggregate)),e=NL({},e,{type:\"quantitative\"}))}else{var a=function(e,t){if(e.timeUnit)return\"temporal\";if(e.bin)return\"quantitative\";switch(aF(t)){case\"continuous\":return\"quantitative\";case\"discrete\":case\"flexible\":return\"nominal\";default:return\"quantitative\"}}(e,t);kF(OF.emptyOrInvalidFieldType(e.type,t,a)),e=NL({},e,{type:a})}var o=function(e,t){var n=e.type;switch(t){case\"row\":case\"column\":return fB(e)?{compatible:!1,warning:OF.facetChannelShouldBeDiscrete(t)}:EB;case\"x\":case\"y\":case\"color\":case\"fill\":case\"stroke\":case\"text\":case\"detail\":case\"key\":case\"tooltip\":case\"href\":return EB;case\"longitude\":case\"longitude2\":case\"latitude\":case\"latitude2\":return n!==JF?{compatible:!1,warning:\"Channel \"+t+\" should be used with a quantitative field only, not \"+e.type+\" field.\"}:EB;case\"opacity\":case\"size\":case\"x2\":case\"y2\":return\"nominal\"===n&&!e.sort||\"geojson\"===n?{compatible:!1,warning:\"Channel \"+t+\" should not be used with an unsorted discrete field.\"}:EB;case\"shape\":return\"nominal\"!==e.type&&\"geojson\"!==e.type?{compatible:!1,warning:\"Shape channel should be used with only either nominal or geojson data\"}:EB;case\"order\":return\"nominal\"!==e.type||\"sort\"in e?EB:{compatible:!1,warning:\"Channel order is inappropriate for nominal field, which has no inherent order.\"}}throw new Error(\"channelCompatability not implemented for channel \"+t)}(e,t),s=o.compatible,l=o.warning;return s||kF(l),e}function xB(e,t){return Object(Ee.v)(e)?{maxbins:sF(t)}:e.maxbins||e.step?e:NL({},e,{maxbins:sF(t)})}var EB={compatible:!0};function SB(e){return\"temporal\"===e.type||!!e.timeUnit}function wB(e,t){var n,r,i=t.timeUnit,a=t.type,o=t.time,s=t.undefinedIfExprNotRequired,l=void 0;return IF(e)?l=jF(e,!0):(Object(Ee.B)(e)||Object(Ee.y)(e))&&(i||\"temporal\"===a)&&(l=function(e){return!!zF[e]}(i)?jF(((n={})[i]=e,n),!0):function(e){return!!GF[e]}(i)?wB(e,{timeUnit:(r=i,r.substr(3))}):\"datetime(\"+JSON.stringify(e)+\")\"),l?o?\"time(\"+l+\")\":l:s?void 0:JSON.stringify(e)}function CB(e,t){var n=e.timeUnit,r=e.type;return t.map(function(e){var t=wB(e,{timeUnit:n,type:r,undefinedIfExprNotRequired:!0});return void 0!==t?{signal:t}:e})}function OB(e,t){var n=e&&e[t];return!!n&&(Object(Ee.u)(n)?HL(n,function(e){return!!e.field}):sB(n)||oB(n))}function MB(e){return HL(WP,function(t){if(OB(e,t)){var n=e[t];if(Object(Ee.u)(n))return HL(n,function(e){return!!e.aggregate});var r=vB(n);return r&&!!r.aggregate}return!1})}function NB(e,t,n){if(e)for(var r=function(r){Object(Ee.u)(e[r])?e[r].forEach(function(e){t.call(n,e,r)}):t.call(n,e[r],r)},i=0,a=ZL(e);i-1?e[n]=t:kF(OF.incompatibleChannel(n,AB)),e},{})})}(e)).mark,s=(e.encoding,e.selection),l=(e.projection,TL(e,[\"mark\",\"encoding\",\"selection\",\"projection\"])),c=void 0;Object(Ee.y)(t.box.extent)&&(c=t.box.extent),kB(o)&&o.extent&&\"min-max\"===o.extent&&(c=void 0);var u=function(e,t,n){var r=function(e,t){e.mark;var n,r,i=e.encoding;if(e.projection,TL(e,[\"mark\",\"encoding\",\"projection\"]),\"vertical\"===t?(r=\"y\",n=i.y):(r=\"x\",n=i.x),n&&n.aggregate){var a=n.aggregate,o=TL(n,[\"aggregate\"]);a!==AB&&kF(\"Continuous axis should not have customized aggregation function \"+a),n=o}return{continuousAxisChannelDef:n,continuousAxis:r}}(e,t),i=r.continuousAxisChannelDef,a=r.continuousAxis,o=e.encoding,s=void 0===n,l=[{op:\"q1\",field:i.field,as:\"lower_box_\"+i.field},{op:\"q3\",field:i.field,as:\"upper_box_\"+i.field},{op:\"median\",field:i.field,as:\"mid_box_\"+i.field}],c=[];l.push({op:\"min\",field:i.field,as:(s?\"lower_whisker_\":\"min_\")+i.field}),l.push({op:\"max\",field:i.field,as:(s?\"upper_whisker_\":\"max_\")+i.field}),s||(c=[{calculate:\"datum.upper_box_\"+i.field+\" - datum.lower_box_\"+i.field,as:\"iqr_\"+i.field},{calculate:\"min(datum.upper_box_\"+i.field+\" + datum.iqr_\"+i.field+\" * \"+n+\", datum.max_\"+i.field+\")\",as:\"upper_whisker_\"+i.field},{calculate:\"max(datum.lower_box_\"+i.field+\" - datum.iqr_\"+i.field+\" * \"+n+\", datum.min_\"+i.field+\")\",as:\"lower_whisker_\"+i.field}]);var u=[],d=[],f=[],p={};return NB(o,function(e,t){if(t!==a)if(sB(e)){if(e.aggregate&&e.aggregate!==AB)l.push({op:e.aggregate,field:e.field,as:dB(e)});else if(void 0===e.aggregate){var n=dB(e),r=e.bin;if(r){var i=e.field;d.push({bin:r,field:i,as:n})}else if(e.timeUnit){var s=e.timeUnit;i=e.field,f.push({timeUnit:s,field:i,as:n})}u.push(n)}p[t]={field:dB(e),type:e.type}}else p[t]=o[t]}),{transform:[].concat(d,f,[{aggregate:l,groupby:u}],c),continuousAxisChannelDef:i,continuousAxis:a,encodingWithoutContinuousAxis:p}}(e,function(e){var t=e.mark,n=e.encoding;if(e.projection,TL(e,[\"mark\",\"encoding\",\"projection\"]),sB(n.x)&&fB(n.x)){if(sB(n.y)&&fB(n.y)){if(void 0===n.x.aggregate&&n.y.aggregate===AB)return\"vertical\";if(void 0===n.y.aggregate&&n.x.aggregate===AB)return\"horizontal\";if(n.x.aggregate===AB&&n.y.aggregate===AB)throw new Error(\"Both x and y cannot have aggregate\");return kB(t)&&t.orient?t.orient:\"vertical\"}return\"horizontal\"}if(sB(n.y)&&fB(n.y))return\"vertical\";throw new Error(\"Need a valid continuous axis for boxplots\")}(e),c),d=u.transform,f=u.continuousAxisChannelDef,p=u.continuousAxis,m=u.encodingWithoutContinuousAxis,g=(m.color,m.size),h=TL(m,[\"color\",\"size\"]),b=g?{size:g}:DB(t.box,\"size\"),v={};return f.scale&&(v.scale=f.scale),f.axis&&(v.axis=f.axis),NL({},l,{transform:d,layer:[{mark:{type:\"rule\",style:\"boxWhisker\"},encoding:NL((n={},n[p]=NL({field:\"lower_whisker_\"+f.field,type:f.type},v),n[p+\"2\"]={field:\"lower_box_\"+f.field,type:f.type},n),h,DB(t.boxWhisker,\"color\"))},{mark:{type:\"rule\",style:\"boxWhisker\"},encoding:NL((r={},r[p]={field:\"upper_box_\"+f.field,type:f.type},r[p+\"2\"]={field:\"upper_whisker_\"+f.field,type:f.type},r),h,DB(t.boxWhisker,\"color\"))},NL({},s?{selection:s}:{},{mark:{type:\"bar\",style:\"box\"},encoding:NL((i={},i[p]={field:\"lower_box_\"+f.field,type:f.type},i[p+\"2\"]={field:\"upper_box_\"+f.field,type:f.type},i),m,m.color?{}:DB(t.box,\"color\"),b)}),{mark:{type:\"tick\",style:\"boxMid\"},encoding:NL((a={},a[p]={field:\"mid_box_\"+f.field,type:f.type},a),h,DB(t.boxMid,\"color\"),b)}]})}),LB(\"error-bar\",function(e){e.mark,e.selection,e.projection;var t=e.encoding,n=TL(e,[\"mark\",\"selection\",\"projection\",\"encoding\"]),r=(t.size,TL(t,[\"size\"])),i=(t.x2,t.y2,TL(t,[\"x2\",\"y2\"])),a=(i.x,i.y,TL(i,[\"x\",\"y\"]));if(!t.x2&&!t.y2)throw new Error(\"Neither x2 or y2 provided\");return NL({},n,{layer:[{mark:\"rule\",encoding:r},{mark:\"tick\",encoding:i},{mark:\"tick\",encoding:t.x2?NL({x:t.x2,y:t.y},a):NL({x:t.x,y:t.y2},a)}]})});var BB,UB=[\"shortTimeLabels\"],jB={entryPadding:1,format:1,offset:1,orient:1,padding:1,tickCount:1,title:1,type:1,values:1,zindex:1},zB=NL({},jB,{opacity:1,shape:1,stroke:1,fill:1,size:1,encode:1}),qB=JL(jB),GB=JL(zB);!function(e){e.LINEAR=\"linear\",e.BIN_LINEAR=\"bin-linear\",e.LOG=\"log\",e.POW=\"pow\",e.SQRT=\"sqrt\",e.TIME=\"time\",e.UTC=\"utc\",e.SEQUENTIAL=\"sequential\",e.QUANTILE=\"quantile\",e.QUANTIZE=\"quantize\",e.THRESHOLD=\"threshold\",e.ORDINAL=\"ordinal\",e.BIN_ORDINAL=\"bin-ordinal\",e.POINT=\"point\",e.BAND=\"band\"}(BB||(BB={}));var $B={linear:\"numeric\",log:\"numeric\",pow:\"numeric\",sqrt:\"numeric\",\"bin-linear\":\"bin-linear\",time:\"time\",utc:\"time\",sequential:\"sequential\",ordinal:\"ordinal\",\"bin-ordinal\":\"bin-ordinal\",point:\"ordinal-position\",band:\"ordinal-position\"},HB=ZL($B);var WB={linear:0,log:1,pow:1,sqrt:1,time:0,utc:0,point:10,band:11,\"bin-linear\":0,sequential:0,ordinal:0,\"bin-ordinal\":0};function VB(e){return WB[e]}var KB=[\"linear\",\"bin-linear\",\"log\",\"pow\",\"sqrt\",\"time\",\"utc\"],QB=Object(Ee.Q)(KB),YB=KB.concat([\"sequential\"]),ZB=Object(Ee.Q)(YB),XB=Object(Ee.Q)([\"ordinal\",\"bin-ordinal\",\"point\",\"band\"]),JB=Object(Ee.Q)([\"bin-linear\",\"bin-ordinal\"]);function eU(e){return e in XB}function tU(e){return e in JB}function nU(e){return e in ZB}function rU(e){return e in QB}var iU={textXRangeStep:90,rangeStep:21,pointPadding:.5,bandPaddingInner:.1,facetSpacing:16,minBandSize:2,minFontSize:8,maxFontSize:40,minOpacity:.3,maxOpacity:.8,minSize:9,minStrokeWidth:1,maxStrokeWidth:4};function aU(e){return e&&e.selection}var oU={type:1,domain:1,range:1,rangeStep:1,scheme:1,reverse:1,round:1,clamp:1,nice:1,base:1,exponent:1,interpolate:1,zero:1,padding:1,paddingInner:1,paddingOuter:1},sU=(JL(oU),JL(TL(oU,[\"type\",\"domain\",\"range\",\"rangeStep\",\"scheme\"])));!function(){for(var e={},t=0,n=WP;t window:mousemove!\",encodings:[\"x\",\"y\"],translate:\"[mousedown, window:mouseup] > window:mousemove!\",zoom:\"wheel!\",mark:{fill:\"#333\",fillOpacity:.125,stroke:\"white\"},resolve:\"global\"}},style:{},title:{}};var hU=[\"view\"].concat(EF,PB),bU=[\"padding\",\"numberFormat\",\"timeFormat\",\"countTitle\",\"stack\",\"scale\",\"selection\",\"invalidValues\",\"overlay\"],vU=NL({view:[\"width\",\"height\"]},{area:[\"line\",\"point\"],bar:[\"binSpacing\",\"continuousBandSize\",\"discreteBandSize\"],line:[\"point\"],text:[\"shortTimeLabels\"],tick:[\"bandSize\",\"thickness\"]},FB);function _U(e,t,n){var r=\"title\"===t?mU(e.title).mark:e[t];\"view\"===t&&(n=\"cell\");var i=NL({},r,e.style[t]);ZL(i).length>0&&(e.style[n||t]=i),delete e[t]}var yU={zero:1,center:1,normalize:1};var xU=[cF,lF,hF,dF,vF,_F,uF,fF,pF],EU=[cF,lF];function SU(e,t,n){var r=SF(e)?e.type:e;if(!$L(xU,r))return null;var i=function(e){var t=e.x,n=e.y;if(sB(t)&&sB(n))if(\"quantitative\"===t.type&&\"quantitative\"===n.type){if(t.stack)return\"x\";if(n.stack)return\"y\";if(!!t.aggregate!=!!n.aggregate)return t.aggregate?\"x\":\"y\"}else{if(\"quantitative\"===t.type)return\"x\";if(\"quantitative\"===n.type)return\"y\"}else{if(sB(t)&&\"quantitative\"===t.type)return\"x\";if(sB(n)&&\"quantitative\"===n.type)return\"y\"}}(t);if(!i)return null;var a=t[i],o=lB(a)?dB(a,{}):void 0,s=\"x\"===i?\"y\":\"x\",l=t[s],c=lB(l)?dB(l,{}):void 0,u=YP.reduce(function(e,n){if(OB(t,n)){var r=t[n];(Object(Ee.u)(r)?r:[r]).forEach(function(t){var r=vB(t);if(!r.aggregate){var i=lB(r)?dB(r,{}):void 0;(!i||i!==c&&i!==o)&&e.push({channel:n,fieldDef:r})}})}return e},[]);if(0===u.length)return null;var d=void 0;return(d=void 0!==a.stack?a.stack:$L(EU,r)&&void 0===n?\"zero\":n)&&yU[d]?(a.scale&&a.scale.type&&a.scale.type!==BB.LINEAR&&kF(OF.cannotStackNonLinearScale(a.scale.type)),OB(t,i===_P?xP:EP)?(void 0!==a.stack&&kF(OF.cannotStackRangedMark(i)),null):(a.aggregate&&!$L(dP,a.aggregate)&&kF(OF.stackNonSummativeAggregate(a.aggregate)),{groupbyChannel:l?s:void 0,fieldChannel:i,impute:xF(r),stackBy:u,offset:d})):null}function wU(e){return void 0!==e.facet}function CU(e){return!!e.mark}function OU(e){return void 0!==e.layer}function MU(e){return void 0!==e.repeat}function NU(e){return TU(e)||DU(e)}function TU(e){return void 0!==e.vconcat}function DU(e){return void 0!==e.hconcat}function AU(e,t){if(wU(e))return function(e,t){var n=e.spec,r=TL(e,[\"spec\"]);return NL({},r,{spec:AU(n,t)})}(e,t);if(OU(e))return function e(t,n,r,i){var a=t.layer,o=t.encoding,s=t.projection,l=TL(t,[\"layer\",\"encoding\",\"projection\"]);var c=kU({parentEncoding:r,encoding:o});var u=RU({parentProjection:i,projection:s});return NL({},l,{layer:a.map(function(t){return OU(t)?e(t,n,c,u):IU(t,n,c,u)})})}(e,t);if(MU(e))return function(e,t){var n=e.spec,r=TL(e,[\"spec\"]);return NL({},r,{spec:AU(n,t)})}(e,t);if(TU(e))return function(e,t){var n=e.vconcat,r=TL(e,[\"vconcat\"]);return NL({},r,{vconcat:n.map(function(e){return AU(e,t)})})}(e,t);if(DU(e))return function(e,t){var n=e.hconcat,r=TL(e,[\"hconcat\"]);return NL({},r,{hconcat:n.map(function(e){return AU(e,t)})})}(e,t);if(CU(e)){var n=OB(e.encoding,MP),r=OB(e.encoding,NP);return n||r?function(e,t){var n=e.encoding,r=n.row,i=n.column,a=TL(n,[\"row\",\"column\"]),o=e.mark,s=e.width,l=e.projection,c=e.height,u=e.selection,d=(e.encoding,TL(e,[\"mark\",\"width\",\"projection\",\"height\",\"selection\",\"encoding\"]));return NL({},d,{facet:NL({},r?{row:r}:{},i?{column:i}:{}),spec:IU(NL({},l?{projection:l}:{},{mark:o},s?{width:s}:{},c?{height:c}:{},{encoding:a},u?{selection:u}:{}),t)})}(e,t):IU(e,t)}throw new Error(OF.INVALID_SPEC)}function kU(e){var t=e.parentEncoding,n=e.encoding;if(t&&n){var r=ZL(t).reduce(function(e,t){return n[t]&&e.push(t),e},[]);r.length>0&&kF(OF.encodingOverridden(r))}var i=NL({},t||{},n||{});return ZL(i).length>0?i:void 0}function RU(e){var t=e.parentProjection,n=e.projection;return t&&n&&kF(OF.projectionOverridden({parentProjection:t,projection:n})),n||t}function IU(e,t,n,r){var i=e.encoding,a=e.projection,o=SF(e.mark)?e.mark.type:e.mark;if(n||r){var s=RU({parentProjection:r,projection:a}),l=kU({parentEncoding:n,encoding:i});return IU(NL({},e,s?{projection:s}:{},l?{encoding:l}:{}),t)}return function(e){return CF(e.mark)}(e)?function(e){return e&&(!!e.x&&!!e.x2||!!e.y&&!!e.y2)}(i)?function(e){var t=OB(e.encoding,_P),n=OB(e.encoding,yP),r=OB(e.encoding,xP),i=OB(e.encoding,EP);if(r&&!t||i&&!n){var a=eP(e);return r&&!t&&(a.encoding.x=a.encoding.x2,delete a.encoding.x2),i&&!n&&(a.encoding.y=a.encoding.y2,delete a.encoding.y2),a}return e}(e):\"line\"===o&&(i.x2||i.y2)?(kF(OF.lineWithRange(!!i.x2,!!i.y2)),IU(NL({mark:\"rule\"},e),t,n,r)):xF(o)?function(e,t){void 0===t&&(t={});var n,r=e.selection,i=e.projection,a=e.encoding,o=e.mark,s=TL(e,[\"selection\",\"projection\",\"encoding\",\"mark\"]),l=SF(o)?o:{type:o},c=function(e,t,n){return\"transparent\"===e.point?{opacity:0}:e.point?Object(Ee.z)(e.point)?e.point:{}:void 0!==e.point?null:t.point||n.shape?Object(Ee.z)(t.point)?t.point:{}:null}(l,t[l.type],a),u=\"area\"===l.type&&function(e,t){return e.line?!0===e.line?{}:e.line:void 0!==e.line?null:t.line?!0===t.line?{}:t.line:null}(l,t[l.type]);if(!c&&!u)return NL({},e,{mark:LU(l)});var d=[NL({},r?{selection:r}:{},{mark:LU(NL({},l,\"area\"===l.type?{opacity:.7}:{})),encoding:function(e,t){for(var n=NL({},e),r=0,i=t;r1?t:t.type}function PU(e){return Object(Ee.B)(e)?{type:e}:e||{}}var FU=[\"background\",\"padding\",\"datasets\"];function BU(e){return FU.reduce(function(t,n){return e&&void 0!==e[n]&&(t[n]=e[n]),t},{})}function UU(e){return!!e.url}function jU(e){return!!e.values}var zU=\"main\",qU=\"raw\";function GU(e){return!!e.signal}function $U(e){return!!e.step}function HU(e){return!Object(Ee.u)(e)&&(\"field\"in e&&\"data\"in e)}var WU=JL({opacity:1,fill:1,fillOpacity:1,stroke:1,strokeCap:1,strokeWidth:1,strokeOpacity:1,strokeDash:1,strokeDashOffset:1,strokeJoin:1,strokeMiterLimit:1,size:1,shape:1,interpolate:1,tension:1,orient:1,align:1,baseline:1,text:1,dir:1,dx:1,dy:1,ellipsis:1,limit:1,radius:1,theta:1,angle:1,font:1,fontSize:1,fontWeight:1,fontStyle:1,cursor:1,href:1,tooltip:1,cornerRadius:1});function VU(e,t,n,r){void 0===r&&(r={header:!1});var i=e.combine(),a=i.orient,o=i.scale,s=i.title,l=i.zindex,c=TL(i,[\"orient\",\"scale\",\"title\",\"zindex\"]);if(ZL(c).forEach(function(e){var n=mP[e];n&&n!==t&&\"both\"!==n&&delete c[e]}),\"grid\"===t){if(!c.grid)return;if(c.encode){var u=c.encode.grid;c.encode=NL({},u?{grid:u}:{}),0===ZL(c.encode).length&&delete c.encode}return NL({scale:o,orient:a},c,{domain:!1,labels:!1,maxExtent:0,minExtent:0,ticks:!1,zindex:void 0!==l?l:0})}if(r.header||!e.mainExtracted){if(c.encode){for(var d=0,f=pP;d=0})}(r))return{scale:n,value:0};\"bar\"!==i&&\"area\"!==i||kF(OF.nonZeroScaleUsedWithLengthMark(i,t,{zeroFalse:!1===r.explicit.zero}))}}return\"zeroOrMin\"===e?\"x\"===t?{value:0}:{field:{group:\"height\"}}:\"x\"===t?{field:{group:\"width\"}}:{value:0}}return e}}function lj(e,t){var n,r;void 0===t&&(t={valueOnly:!1});var i=e.markDef,a=e.encoding,o=e.config,s=i.filled,l=i.type,c={fill:Ej(\"fill\",i,o),stroke:Ej(\"stroke\",i,o),color:Ej(\"color\",i,o)},u=$L([\"bar\",\"point\",\"circle\",\"square\",\"geoshape\"],l)?\"transparent\":void 0,d={fill:i.fill||c.fill||u,stroke:i.stroke||c.stroke},f=s?\"fill\":\"stroke\",p=NL({},d.fill?{fill:{value:d.fill}}:{},d.stroke?{stroke:{value:d.stroke}}:{});return a.fill||a.stroke?(i.color&&kF(OF.droppingColor(\"property\",{fill:\"fill\"in a,stroke:\"stroke\"in a})),NL({},fj(\"fill\",e,{defaultValue:d.fill||u}),fj(\"stroke\",e,{defaultValue:d.stroke}))):a.color?NL({},p,fj(\"color\",e,{vgChannel:f,defaultValue:i[f]||i.color||c[f]||c.color||(s?u:void 0)})):i.fill||i.stroke?(i.color&&kF(OF.droppingColor(\"property\",{fill:\"fill\"in i,stroke:\"stroke\"in i})),p):i.color?NL({},p,((n={})[f]={value:i.color},n)):c.fill||c.stroke?p:c.color?NL({},u?{fill:{value:\"transparent\"}}:{},((r={})[f]={value:c.color},r)):{}}function cj(e,t){return NL({},function(e,t){return WU.reduce(function(n,r){return void 0!==e[r]&&\"ignore\"!==t[r]&&(n[r]={value:e[r]}),n},{})}(e.markDef,t),lj(e),fj(\"opacity\",e),function(e){var t=e.encoding.tooltip;if(Object(Ee.u)(t)){var n=t.map(function(t){var n=void 0!==t.title?t.title:dB(t,{binSuffix:\"range\"}),r=aj(t,e.config).signal;return'\"'+n+'\": '+r});return{tooltip:{signal:\"{\"+n.join(\", \")+\"}\"}}}return gj(e,\"tooltip\",t)}(e),mj(e,\"href\"))}function uj(e){return e+\" !== null && !isNaN(\"+e+\")\"}function dj(e){if(\"filter\"===e.config.invalidValues){var t=[\"x\",\"y\"].map(function(t){var n=e.getScaleComponent(t);if(n&&nU(n.get(\"type\")))return e.vgField(t,{expr:\"datum\"})}).filter(function(e){return!!e}).map(uj);if(t.length>0)return{defined:{signal:t.join(\" && \")}}}return{}}function fj(e,t,n){void 0===n&&(n={});var r=n.defaultValue,i=n.vgChannel,a=n.defaultRef||(void 0!==r?{value:r}:void 0),o=t.encoding[e];return pj(t,o,i||e,function(n){return ij(e,n,t.scaleName(e),t.getScaleComponent(e),null,a)})}function pj(e,t,n,r){var i,a,o=t&&t.condition,s=r(t);if(o){var l=(Object(Ee.u)(o)?o:[o]).map(function(t){var n=r(t),i=function(e){return e.selection}(t)?Cq(e,t.selection):zq(e,t.test);return NL({test:i},n)});return(i={})[n]=l.concat(void 0!==s?[s]:[]),i}return void 0!==s?((a={})[n]=s,a):{}}function mj(e,t){return void 0===t&&(t=\"text\"),gj(e,t,e.encoding[t])}function gj(e,t,n){return pj(e,n,t,function(t){return aj(t,e.config)})}function hj(e,t,n){var r,i,a,o=n.scaleName(t),s=\"x\"===t?\"width\":\"height\";if(n.encoding.size||void 0!==n.markDef.size)if(n.markDef.orient){var l=((r={})[t+\"c\"]=nj(e,o,{},{band:.5}),r);if(vB(n.encoding.size))return NL({},l,fj(\"size\",n,{vgChannel:s}));if(cB(n.encoding.size))return NL({},l,fj(\"size\",n,{vgChannel:s}));if(void 0!==n.markDef.size)return NL({},l,((i={})[s]={value:n.markDef.size},i))}else kF(OF.cannotApplySizeToNonOrientedMark(n.markDef.type));return(a={})[t]=nj(e,o,{binSuffix:\"range\"}),a[s]=rj(o),a}function bj(e,t,n,r){var i=\"x\"===e?\"width\":\"height\";return NL({},_j(e,t,n,\"x\"===e?\"xc\":\"yc\"),fj(\"size\",t,{defaultRef:r,vgChannel:i}))}function vj(e,t,n,r,i){return\"x\"===t?{x2:tj(e,n,\"start\",i?0:r),x:tj(e,n,\"end\",i?r:0)}:{y2:tj(e,n,\"start\",i?r:0),y:tj(e,n,\"end\",i?0:r)}}function _j(e,t,n,r){var i,a=t.encoding,o=t.mark,s=t.stack,l=a[e],c=t.scaleName(e),u=t.getScaleComponent(e),d=ej(e,t.markDef),f=l||!a.latitude&&!a.longitude?NL({},function(e,t,n,r,i,a){return sB(t)&&i&&e===i.fieldChannel?nj(t,n,{suffix:\"end\"}):ij(e,t,n,r,i,a)}(e,a[e],c,u,s,sj(n,e,c,u,o)),d?{offset:d}:{}):{field:t.getName(e)};return(i={})[r||e]=f,i}function yj(e,t,n){var r,i=e.encoding,a=e.mark,o=e.stack,s=\"x2\"===n?\"x\":\"y\",l=i[s],c=e.scaleName(s),u=e.getScaleComponent(s),d=ej(n,e.markDef),f=l||!i.latitude&&!i.longitude?NL({},function(e,t,n,r,i,a,o){return sB(t)&&a&&e.charAt(0)===a.fieldChannel.charAt(0)?nj(t,r,{suffix:\"start\"}):ij(e,n,r,i,a,o)}(n,l,i[n],c,u,o,sj(t,s,c,u,a)),d?{offset:d}:{}):{field:e.getName(n)};return(r={})[n]=f,r}function xj(e){return[].concat(e.type,e.style||[])}function Ej(e,t,n){var r=n.mark[e],i=n[t.type];void 0!==i[e]&&(r=i[e]);for(var a=0,o=xj(t);a0&&l.push(i.join(\" \")),s.length>0&&l.push(s.join(\":\")),l.length>0&&(a&&(a+=\" + ' ' + \"),a+=r?\"utcFormat(\"+t+\", '\"+l.join(\" \")+\"')\":\"timeFormat(\"+t+\", '\"+l.join(\" \")+\"')\"),a||void 0}}(t,e,r,a)}function Dj(e,t){return(Object(Ee.u)(e)?e:[e]).reduce(function(e,n){return e.field.push(dB(n,t)),e.order.push(n.sort||\"ascending\"),e},{field:[],order:[]})}function Aj(e,t){var n=e.slice();return t.forEach(function(e){for(var t=0,r=n;t0?{encode:{update:m}}:{})}var g=i.axes,h=g&&g.length>0;if(s||h){var b=\"row\"===t?\"height\":\"width\";return NL({name:e.getName(t+\"_\"+n),type:\"group\",role:t+\"-\"+n},r.facetFieldDef?{from:{data:e.getName(t+\"_domain\")},sort:function(e,t){var n=e.sort;return XU(n)?{field:dB(n,{expr:\"datum\"}),order:n.order||\"ascending\"}:Object(Ee.u)(n)?{field:Uj(e,t,\"datum\"),order:\"ascending\"}:{field:dB(e,{expr:\"datum\"}),order:n||\"ascending\"}}(l,t)}:{},s?{title:s}:{},i.sizeSignal?{encode:{update:(a={},a[b]=i.sizeSignal,a)}}:{},h?{axes:g}:{})}}return null}function Hj(e,t,n,r){for(var i={},a=0,o=n;a0?t:a<0?n:tz(t,n,r,i)}}function tz(e,t,n,r){return e.explicit&&t.explicit&&kF(OF.mergeConflictingProperty(n,r,e.value,t.value)),e}function nz(e,t,n,r,i){return void 0===i&&(i=tz),void 0===e||void 0===e.value?t:e.explicit&&!t.explicit?e:t.explicit&&!e.explicit?t:qL(e.value)===qL(t.value)?e:i(e,t,n,r)}var rz=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return ML(t,e),t}(Zj);function iz(e,t,n,r,i){if(\"gradient\"!==i){var a=NL({},function(e,t,n){for(var r=0,i=n;r0?a:void 0}}function az(e,t,n,r,i){var a={};if(\"gradient\"===i){var o=sz(n.encoding.opacity)||n.markDef.opacity;o&&(a.opacity={value:o})}return a=NL({},a,t),ZL(a).length>0?a:void 0}function oz(e,t,n,r,i){var a=n.legend(r),o=n.config,s={};if(SB(e)){var l=n.getScaleComponent(r).get(\"type\")===BB.UTC,c=Tj(\"datum.value\",e.timeUnit,a.format,o.legend.shortTimeLabels,o.timeFormat,l);t=NL({},c?{text:{signal:c}}:{},t)}return s=NL({},s,t),ZL(s).length>0?s:void 0}function sz(e){return cz(e,function(e,t){return Math.max(e,t.value)})}function lz(e){return cz(e,function(e,t){return void 0!==e?e:t.value})}function cz(e,t){return function(e){return!!e&&!!e.condition&&(Object(Ee.u)(e.condition)||cB(e.condition))}(e)?(Object(Ee.u)(e.condition)?e.condition:[e.condition]).reduce(t,e.value):cB(e)?e.value:void 0}function uz(e){Yz(e)?e.component.legends=function(e){var t=e.encoding;return[AP,kP,RP,DP,TP,BP].reduce(function(n,r){var i=t[r];return!e.legend(r)||!e.getScaleComponent(r)||sB(i)&&r===TP&&i.type===rB||(n[r]=function(e,t){var n=e.fieldDef(t),r=e.legend(t),i=new rz({},function(e,t){var n;switch(t){case AP:var r=e.scaleName(AP);return e.markDef.filled?{fill:r}:{stroke:r};case kP:case RP:case DP:case TP:case BP:return(n={})[t]=e.scaleName(t),n}}(e,t));qB.forEach(function(n){var a=function(e,t,n,r){var i=r.fieldDef(n);switch(e){case\"format\":return Cj(i,t.format,r.config);case\"title\":var a=void 0!==i.title?i.title:t.title||(void 0===t.title?void 0:null);return wj(a,bB(i,r.config))||void 0;case\"values\":return function(e,t){var n=e.values;if(n)return CB(t,n)}(t,i);case\"type\":return wj(t.type,function(e,t,n){if($P(t)&&(\"quantitative\"===e&&!tU(n)||\"temporal\"===e&&$L([\"time\",\"utc\"],n)))return\"gradient\"}(i.type,n,r.getScaleComponent(n).get(\"type\")))}return t[e]}(n,r,t,e);if(void 0!==a){var o=\"values\"===n?!!r.values:\"title\"===n&&a===e.fieldDef(t).title||a===r[n];(o||void 0===e.config.legend[n])&&i.set(n,a,o)}});var a=r.encoding||{},o=[\"labels\",\"legend\",\"title\",\"symbols\",\"gradient\"].reduce(function(r,o){var s=Lj(a[o]||{},e),l=m[o]?m[o](n,s,e,t,i.get(\"type\")):s;return void 0!==l&&ZL(l).length>0&&(r[o]={update:l}),r},{});ZL(o).length>0&&i.set(\"encode\",o,!!r.encoding);return i}(e,r)),n},{})}(e):e.component.legends=function(e){for(var t=e.component,n=t.legends,r=t.resolve,i=function(t){uz(t),ZL(t.component.legends).forEach(function(i){r.legend[i]=Yj(e.component.resolve,i),\"shared\"===r.legend[i]&&(n[i]=dz(n[i],t.component.legends[i]),n[i]||(r.legend[i]=\"independent\",delete n[i]))})},a=0,o=e.children;a1?\"[\"+o.join(\", \")+\"]\":o[0]}},i)]}var gz=[\"type\",\"clipAngle\",\"clipExtent\",\"center\",\"rotate\",\"precision\",\"coefficient\",\"distance\",\"fraction\",\"lobes\",\"parallel\",\"radius\",\"ratio\",\"spacing\",\"tilt\"],hz=function(e){function t(t,n,r,i){var a=e.call(this,NL({},n),{name:t})||this;return a.specifiedProjection=n,a.size=r,a.data=i,a.merged=!1,a}return ML(t,e),t}(Zj);function bz(e){Yz(e)?e.component.projection=function(e){var t=e.specifiedProjection,n=e.config;if(e.hasProjection){var r=[];return[[CP,SP],[OP,wP]].forEach(function(t){(e.channelHasField(t[0])||e.channelHasField(t[1]))&&r.push({signal:e.getName(\"geojson_\"+r.length)})}),e.channelHasField(TP)&&e.fieldDef(TP).type===rB&&r.push({signal:e.getName(\"geojson_\"+r.length)}),0===r.length&&r.push(e.requestDataName(zU)),new hz(e.projectionName(!0),NL({},n.projection||{},t||{}),[e.getSizeSignalRef(\"width\"),e.getSizeSignalRef(\"height\")],r)}return}(e):e.component.projection=function(e){if(0===e.children.length)return;var t,n=WL(e.children,function(e){bz(e);var n=e.component.projection;if(n){if(t){var r=function(e,t){var n=WL(gz,function(n){return!e.explicit.hasOwnProperty(n)&&!t.explicit.hasOwnProperty(n)||!(!e.explicit.hasOwnProperty(n)||!t.explicit.hasOwnProperty(n)||qL(e.get(n))!==qL(t.get(n)))});if(qL(e.size)===qL(t.size)){if(n)return e;if(qL(e.explicit)===qL({}))return t;if(qL(t.explicit)===qL({}))return e}return null}(t,n);return r&&(t=r),!!r}return t=n,!0}return!0});if(t&&n){var r=e.projectionName(!0),i=new hz(r,t.specifiedProjection,t.size,eP(t.data));return e.children.forEach(function(e){e.component.projection&&(i.data=i.data.concat(e.component.projection.data),e.renameProjection(e.component.projection.get(\"name\"),r),e.component.projection.merged=!0)}),i}return}(e)}var vz=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.dimensions=n,i.measures=r,i}return ML(t,e),t.prototype.clone=function(){return new t(null,NL({},this.dimensions),eP(this.measures))},t.makeFromEncoding=function(e,n){var r=!1;n.forEachFieldDef(function(e){e.aggregate&&(r=!0)});var i={},a={};return r?(n.forEachFieldDef(function(e,t){var r=e.aggregate,o=e.field;r?\"count\"===r?(i[\"*\"]=i[\"*\"]||{},i[\"*\"].count=dB(e)):(i[o]=i[o]||{},i[o][r]=dB(e),rF(t)&&\"unaggregated\"===n.scaleDomain(t)&&(i[o].min=dB({field:o,aggregate:\"min\"}),i[o].max=dB({field:o,aggregate:\"max\"}))):function(e,t,n){n.bin?(e[dB(n,{})]=!0,e[dB(n,{binSuffix:\"end\"})]=!0,Ij(n,t)&&(e[dB(n,{binSuffix:\"range\"})]=!0)):e[dB(n)]=!0}(a,t,e)}),ZL(a).length+ZL(i).length===0?null:new t(e,a,i)):null},t.makeFromTransform=function(e,n){for(var r={},i={},a=0,o=n.aggregate;a0?{type:\"filter\",expr:t.join(\" && \")}:null},t}(Pj);var xz=function(e){function t(t,n){var r=e.call(this,t)||this;return r._parse=n,r}return ML(t,e),t.prototype.clone=function(){return new t(null,eP(this._parse))},t.makeExplicit=function(e,t,n){var r={},i=t.data;return i&&i.format&&i.format.parse&&(r=i.format.parse),this.makeWithAncestors(e,r,{},n)},t.makeImplicitFromFilterTransform=function(e,t,n){var r={};return function e(t,n){if(jL(t))e(t.not,n);else if(UL(t))for(var r=0,i=t.and;r1?e.field in r||(r[e.field]=\"flatten\"):uB(e)&&XU(e.sort)&&sP(e.sort.field)>1&&(e.sort.field in r||(r[e.sort.field]=\"flatten\")):uP(e.aggregate)||(r[e.field]=\"number\")}),this.makeWithAncestors(e,{},r,n)},t.makeWithAncestors=function(e,n,r,i){for(var a=0,o=ZL(r);a1}).map(function(e){var n,r=function(e,t){var n=aP(e);return\"number\"===t?\"toNumber(\"+n+\")\":\"boolean\"===t?\"toBoolean(\"+n+\")\":\"string\"===t?\"toString(\"+n+\")\":\"date\"===t?\"toDate(\"+n+\")\":\"flatten\"===t?n:0===t.indexOf(\"date:\")?\"timeParse(\"+n+\",\"+t.slice(5,t.length)+\")\":0===t.indexOf(\"utc:\")?\"utcParse(\"+n+\",\"+t.slice(4,t.length)+\")\":(kF(OF.unrecognizedParse(t)),null)}(e,t._parse[e]);return r?{type:\"formula\",expr:r,as:(n=e,\"\"+Object(Ee.L)(n).join(\".\"))}:null}).filter(function(e){return null!==e})},t}(Pj),Ez=function(e){function t(t){var n=e.call(this,null)||this;if(jU(t=t||{name:\"source\"}))n._data={values:t.values};else if(UU(t)){if(n._data={url:t.url},t.format||(t.format={}),!t.format||!t.format.type){var r=/(?:\\.([^.]+))?$/.exec(t.url)[1];$L([\"json\",\"csv\",\"tsv\",\"dsv\",\"topojson\"],r)||(r=\"json\"),t.format.type=r}}else(function(e){return!!e.name&&!UU(e)&&!jU(e)})(t)&&(n._data={});if(t.name&&(n._name=t.name),t.format){var i=t.format,a=(i.parse,TL(i,[\"parse\"]));n._data.format=a}return n}return ML(t,e),Object.defineProperty(t.prototype,\"data\",{get:function(){return this._data},enumerable:!0,configurable:!0}),t.prototype.hasName=function(){return!!this._name},Object.defineProperty(t.prototype,\"dataName\",{get:function(){return this._name},set:function(e){this._name=e},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,\"parent\",{set:function(e){throw new Error(\"Source nodes have to be roots.\")},enumerable:!0,configurable:!0}),t.prototype.remove=function(){throw new Error(\"Source nodes are roots and cannot be removed.\")},t.prototype.hash=function(){return jU(this._data)?(this._hash||(this._hash=GL(this._data)),this._hash):UU(this._data)?GL([this._data.url,this._data.format]):this._name},t.prototype.assemble=function(){return NL({name:this._name},this._data,{transform:[]})},t}(Pj),Sz=function(e){function t(t,n){var r=e.call(this,t)||this;return r.formula=n,r}return ML(t,e),t.prototype.clone=function(){return new t(null,eP(this.formula))},t.makeFromEncoding=function(e,n){var r=n.reduceFieldDef(function(e,t){if(t.timeUnit){var n=dB(t);e[n]={as:n,timeUnit:t.timeUnit,field:t.field}}return e},{});return 0===ZL(r).length?null:new t(e,r)},t.makeFromTransform=function(e,n){var r;return new t(e,((r={})[n.field]={as:n.as,timeUnit:n.timeUnit,field:n.field},r))},t.prototype.merge=function(e){this.formula=NL({},this.formula,e.formula),e.remove()},t.prototype.producedFields=function(){var e={};return XL(this.formula).forEach(function(t){e[t.as]=!0}),e},t.prototype.dependentFields=function(){var e={};return XL(this.formula).forEach(function(t){e[t.field]=!0}),e},t.prototype.assemble=function(){return XL(this.formula).map(function(e){return{type:\"formula\",as:e.as,expr:YF(e.timeUnit,e.field)}})},t}(Pj);function wz(e){return function t(n){if(!(n instanceof Ez)){var r=n.parent;e(n)&&t(r)}}}function Cz(e){var t=e.parent;if(e instanceof xz){if(t instanceof Ez)return!1;if(t.numChildren()>1)return!0;if(t instanceof xz)t.merge(e);else{if(function(e,t){for(var n in e)if(n in t)return!0;return!1}(t.producedFields(),e.dependentFields()))return!0;e.swapWithParent()}}return!0}function Oz(e){return!(e instanceof Fj||e.numChildren()>0||e instanceof _z)&&(e.remove(),!0)}function Mz(e){var t={};return wz(function(e){if(e instanceof Sz){var n=e.producedFields();ZL(n).every(function(e){return!!t[e]})?e.remove():t=NL({},t,n)}return!0})(e)}var Nz=function(e){function t(t,n){var r=e.call(this,t)||this;return r._stack=n,r}return ML(t,e),t.prototype.clone=function(){return new t(null,eP(this._stack))},t.makeFromTransform=function(e,n){var r=n.stack,i=n.groupby,a=n.as,o=n.offset,s=void 0===o?\"zero\":o,l=[],c=[];if(void 0!==n.sort)for(var u=0,d=n.sort;u1}(a)?a:Object(Ee.B)(a)?[a,a+\"_end\"]:[n.stack+\"_start\",n.stack+\"_end\"]})},t.makeFromEncoding=function(e,n){var r,i=n.stack;if(!i)return null;i.groupbyChannel&&(r=n.fieldDef(i.groupbyChannel));var a,o=function(e){return e.stack.stackBy.reduce(function(e,t){var n=dB(t.fieldDef);return n&&e.push(n),e},[])}(n),s=n.encoding.order;a=Object(Ee.u)(s)||sB(s)?Dj(s):o.reduce(function(e,t){return e.field.push(t),e.order.push(\"descending\"),e},{field:[],order:[]});var l=n.vgField(i.fieldChannel);return new t(e,{dimensionFieldDef:r,stackField:l,facetby:[],stackby:o,sort:a,offset:i.offset,impute:i.impute,as:[l+\"_start\",l+\"_end\"]})},Object.defineProperty(t.prototype,\"stack\",{get:function(){return this._stack},enumerable:!0,configurable:!0}),t.prototype.addDimensions=function(e){this._stack.facetby=this._stack.facetby.concat(e)},t.prototype.dependentFields=function(){var e={};e[this._stack.stackField]=!0,this.getGroupbyFields().forEach(function(t){return e[t]=!0}),this._stack.facetby.forEach(function(t){return e[t]=!0});var t=this._stack.sort.field;return Object(Ee.u)(t)?t.forEach(function(t){return e[t]=!0}):e[t]=!0,e},t.prototype.producedFields=function(){return this._stack.as.reduce(function(e,t){return e[t]=!0,e},{})},t.prototype.getGroupbyFields=function(){var e=this._stack,t=e.dimensionFieldDef,n=e.impute,r=e.groupby;return t?t.bin?n?[dB(t,{binSuffix:\"mid\"})]:[dB(t,{}),dB(t,{binSuffix:\"end\"})]:[dB(t)]:r||[]},t.prototype.assemble=function(){var e=[],t=this._stack,n=t.facetby,r=t.dimensionFieldDef,i=t.stackField,a=t.stackby,o=t.sort,s=t.offset,l=t.impute,c=t.as;if(l&&r){var u=r?dB(r,{binSuffix:\"mid\"}):void 0;r.bin&&e.push({type:\"formula\",expr:\"(\"+dB(r,{expr:\"datum\"})+\"+\"+dB(r,{expr:\"datum\",binSuffix:\"end\"})+\")/2\",as:u}),e.push({type:\"impute\",field:i,groupby:a,key:u,method:\"value\",value:0})}return e.push({type:\"stack\",groupby:this.getGroupbyFields().concat(n),field:i,sort:o,as:c,offset:s}),e},t}(Pj),Tz=\"scale_\";function Dz(e){if(e instanceof _z)if(1!==e.numChildren()||e.children[0]instanceof Fj){!function e(t){if(t instanceof Fj&&t.type===zU&&1===t.numChildren()){var n=t.children[0];n instanceof _z||(n.swapWithParent(),e(t))}}(e.model.component.data.main),VL(e.children.map((n=e,function e(t){if(!(t instanceof _z)){var r=t.clone();if(r instanceof Fj){var i=Tz+r.getSource();r.setSource(i),n.model.component.data.outputNodes[i]=r}else(r instanceof vz||r instanceof Nz)&&r.addDimensions(n.fields);return VL(t.children.map(e)).forEach(function(e){return e.parent=r}),[r]}return VL(t.children.map(e))}))).forEach(function(t){return t.parent=e.model.component.data.main})}else{var t=e.children[0];(t instanceof vz||t instanceof Nz)&&t.addDimensions(e.fields),t.swapWithParent(),Dz(e)}else e.children.forEach(Dz);var n}function Az(e){e instanceof yz&&WL(XL(e.filter),function(e){return null===e})&&e.remove(),e instanceof Fj&&!e.isRequired()&&e.remove(),e.children.forEach(Az)}function kz(e){var t=[];return e.forEach(function e(n){0===n.numChildren()?t.push(n):n.children.forEach(e)}),t}function Rz(e){Yz(e)?function(e){var t=e.specifiedScales,n=e.component.scales;ZL(n).forEach(function(r){var i=t[r],a=i?i.domain:void 0,o=function(e,t){var n=e.getScaleComponent(t).get(\"type\"),r=function(e,t,n,r){if(\"unaggregated\"===e){var i=Lz(t,n),a=i.valid,o=i.reason;if(!a)return void kF(o)}else if(void 0===e&&r.useUnaggregatedDomain){var a=Lz(t,n).valid;if(a)return\"unaggregated\"}return e}(e.scaleDomain(t),e.fieldDef(t),n,e.config.scale);r!==e.scaleDomain(t)&&(e.specifiedScales[t]=NL({},e.specifiedScales[t],{domain:r}));if(\"x\"===t&&e.channelHasField(\"x2\"))return e.channelHasField(\"x\")?Iz(n,r,e,\"x\").concat(Iz(n,r,e,\"x2\")):Iz(n,r,e,\"x2\");if(\"y\"===t&&e.channelHasField(\"y2\"))return e.channelHasField(\"y\")?Iz(n,r,e,\"y\").concat(Iz(n,r,e,\"y2\")):Iz(n,r,e,\"y2\");return Iz(n,r,e,t)}(e,r),s=n[r];if(s.domains=o,aU(a)&&s.set(\"domainRaw\",{signal:Sq+GL(a)},!0),e.component.data.isFaceted){for(var l=e;!Zz(l)&&l.parent;)l=l.parent;var c=l.component.resolve.scale[r];if(\"shared\"===c)for(var u=0,d=o;u0){var r=n[0];return n.length>1&&(kF(OF.MORE_THAN_ONE_SORT),r=!0),NL({},o,{sort:r})}return o}var i=YL(n.map(function(e){return!0===e?e:\"count\"===e.op?e:(kF(OF.domainSortDropped(e)),!0)}),GL),a=void 0;1===i.length?a=i[0]:i.length>1&&(kF(OF.MORE_THAN_ONE_SORT),a=!0);var o,s=YL(e.map(function(e){return HU(e)?e.data:null}),function(e){return e});return 1===s.length&&null!==s[0]?o=NL({data:s[0],fields:t.map(function(e){return e.field})},a?{sort:a}:{}):NL({fields:t},a?{sort:a}:{})}(e.component.scales[t].domains.map(function(t){return HU(t)&&(t.data=e.lookupDataSource(t.data)),t}))}function Bz(e){return ZL(e.component.scales).reduce(function(t,n){var r=e.component.scales[n];if(r.merged)return t;var i=r.combine(),a=i.domainRaw,o=i.range,s=i.name,l=i.type,c=(i.domainRaw,i.range,TL(i,[\"name\",\"type\",\"domainRaw\",\"range\"]));return o=function(e,t,n,r){if(\"x\"===r||\"y\"===r){if($U(e))return{step:{signal:t+\"_step\"}};if(Object(Ee.u)(e)&&2===e.length){var i=e[0],a=e[1];if(0===i&&GU(a))return[0,{signal:n.getSizeName(a.signal)}];if(GU(i)&&0===a)return[{signal:n.getSizeName(i.signal)},0]}}return e}(o,s,e,n),a&&function(e){return e.signal.indexOf(Sq)>=0}(a)&&(a=function(e,t){var n=JSON.parse(t.signal.replace(Sq,\"\")),r=nP(n.selection),i=e.component.selection&&e.component.selection[r];if(!i)return i=e.getSelectionComponent(r,n.selection),n.encoding||n.field||(n.field=i.project[0].field,i.project.length>1&&kF('A \"field\" or \"encoding\" must be specified when using a selection as a scale domain. Using \"field\": '+Object(Ee.M)(n.field)+\".\")),{signal:Mq(i.type).scaleDomain+\"(\"+Object(Ee.M)(r+yq)+\", \"+Object(Ee.M)(n.encoding||null)+\", \"+Object(Ee.M)(n.field||null)+(\"global\"===i.resolve?\")\":\", \"+Object(Ee.M)(i.resolve)+\")\")};kF('Use \"bind\": \"scales\" to setup a binding for scales and selections within the same view.');return{signal:\"null\"}}(e,a)),t.push(NL({name:s,type:l,domain:Fz(e,n)},a?{domainRaw:a}:{},{range:o},c)),t},[])}var Uz=function(e){function t(t,n){var r=e.call(this,{},{name:t})||this;return r.merged=!1,r.domains=[],r.setWithExplicit(\"type\",n),r}return ML(t,e),t}(Zj),jz=[\"range\",\"rangeStep\",\"scheme\"];function zz(e){Yz(e)?function(e){var t=e.component.scales;nF.forEach(function(n){var r=t[n];if(r){var i=e.getScaleComponent(n),a=e.specifiedScales[n],o=e.fieldDef(n),s=\"x\"===n?\"width\":\"y\"===n?\"height\":void 0,l=s?!!e.component.layoutSize.get(s):void 0,c=i.get(\"type\"),u=$L([\"point\",\"band\"],c)||!!a.rangeStep;s&&e.fit&&!l&&u&&(kF(OF.CANNOT_FIX_RANGE_STEP_WITH_FIT),l=!0);var d=function(e){var t=[],n=e.getScaleComponent(\"x\"),r=n&&n.get(\"range\");r&&$U(r)&&Object(Ee.y)(r.step)&&t.push(r.step);var i=e.getScaleComponent(\"y\"),a=i&&i.get(\"range\");a&&$U(a)&&Object(Ee.y)(a.step)&&t.push(a.step);return t}(e),f=function(e,t,n,r,i,a,o,s,l,c){for(var u=s||null===r.rangeStep,d=0,f=jz;d0?Math.min.apply(null,e):t.rangeStep?t.rangeStep:21}function $z(e,t){Yz(e)?function(e,t){var n=e.component.scales;ZL(n).forEach(function(r){var i=e.specifiedScales[r],a=n[r],o=e.getScaleComponent(r),s=e.fieldDef(r),l=e.config,c=i[t],u=o.get(\"type\"),d=lU(u,t),f=cU(r,t);if(void 0!==c&&(d?f&&kF(f):kF(OF.scalePropertyNotWorkWithScaleType(u,t,r))),d&&void 0===f)if(void 0!==c)a.copyKeyFromObject(t,i);else{var p=function(e,t,n,r,i,a,o,s,l){var c=l.scale;switch(e){case\"nice\":return function(e,t,n){if(n.bin||$L([BB.TIME,BB.UTC],e))return;return $L([_P,yP],t)}(r,t,n);case\"padding\":return function(e,t,n,r,i,a){if($L([_P,yP],e)){if(rU(t)){if(void 0!==n.continuousPadding)return n.continuousPadding;var o=i.type,s=i.orient;if(\"bar\"===o&&!r.bin&&(\"vertical\"===s&&\"x\"===e||\"horizontal\"===s&&\"y\"===e))return a.continuousBandSize}if(t===BB.POINT)return n.pointPadding}return}(t,r,c,n,s,l.bar);case\"paddingInner\":return function(e,t,n){if(void 0!==e)return;if($L([_P,yP],t))return n.bandPaddingInner;return}(i,t,c);case\"paddingOuter\":return function(e,t,n,r,i){if(void 0!==e)return;if($L([_P,yP],t)&&n===BB.BAND)return void 0!==i.bandPaddingOuter?i.bandPaddingOuter:r/2;return}(i,t,r,a,c);case\"reverse\":return function(e,t){if(nU(e)&&\"descending\"===t)return!0;return}(r,n.sort);case\"zero\":return function(e,t,n,r){if(n&&\"unaggregated\"!==n)return!1;if(\"size\"===e&&\"quantitative\"===t.type)return!0;if(!t.bin&&$L([_P,yP],e)){var i=r.orient,a=r.type;return!$L([\"bar\",\"area\",\"line\",\"trail\"],a)||!(\"horizontal\"===i&&\"y\"===e||\"vertical\"===i&&\"x\"===e)}return!1}(t,n,o,s)}return c[e]}(t,r,s,o.get(\"type\"),o.get(\"padding\"),o.get(\"paddingInner\"),i.domain,e.markDef,l);void 0!==p&&a.set(t,p,!1)}})}(e,t):Hz(e,t)}function Hz(e,t){for(var n=e.component.scales,r=0,i=e.children;r0?e:void 0},e.prototype.assembleGroup=function(e){void 0===e&&(e=[]);var t={};(e=e.concat(this.assembleSelectionSignals())).length>0&&(t.signals=e);var n=this.assembleLayout();n&&(t.layout=n),t.marks=[].concat(this.assembleHeaderMarks(),this.assembleMarks());var r=!this.parent||Zz(this.parent)?function e(t){return eq(t)||Jz(t)||Xz(t)?t.children.reduce(function(t,n){return t.concat(e(n))},Bz(t)):Bz(t)}(this):[];r.length>0&&(t.scales=r);var i=this.assembleAxes();i.length>0&&(t.axes=i);var a=this.assembleLegends();return a.length>0&&(t.legends=a),t},e.prototype.hasDescendantWithFieldOnChannel=function(e){for(var t=0,n=this.children;t=0&&(c=!0)}),c||n.splice(l+1,0,s),n}};function cq(e,t){var n=t.project,r=lq.has(t)?\"(item().isVoronoi ? datum.datum : datum)\":\"datum\",i=[],a=n.map(function(e){return Object(Ee.M)(e.channel)}).filter(function(e){return e}).join(\", \"),o=n.map(function(e){return Object(Ee.M)(e.field)}).join(\", \"),s=n.map(function(t){var n=t.channel,a=e.fieldDef(n);return a&&a.bin?(i.push(t.field),\"[\"+aP(e.vgField(n,{}),r)+\", \"+aP(e.vgField(n,{binSuffix:\"end\"}),r)+\"]\"):\"\"+aP(t.field,r)}).join(\", \");return[{name:t.name+xq,value:{},on:[{events:t.events,update:\"datum && item().mark.marktype !== 'group' ? {unit: \"+Tq(e)+\", encodings: [\"+a+\"], fields: [\"+o+\"], values: [\"+s+\"]\"+(i.length?\", \"+i.map(function(e){return Object(Ee.M)(\"bin_\"+e)+\": 1\"}).join(\", \"):\"\")+\"} : null\",force:!0}]}]}var uq={predicate:\"vlMulti\",scaleDomain:\"vlMultiDomain\",signals:cq,modifyExpr:function(e,t){return t.name+xq+\", \"+(\"global\"===t.resolve?\"null\":\"{unit: \"+Tq(e)+\"}\")}},dq={predicate:\"vlSingle\",scaleDomain:\"vlSingleDomain\",signals:cq,topLevelSignals:function(e,t,n){var r=n.filter(function(e){return e.name===t.name}),i=\"data(\"+Object(Ee.M)(t.name+yq)+\")\",a=i+\"[0].values\";return r.length?n:n.concat({name:t.name,update:i+\".length && {\"+t.project.map(function(e,t){return e.field+\": \"+a+\"[\"+t+\"]\"}).join(\", \")+\"}\"})},modifyExpr:function(e,t){return t.name+xq+\", \"+(\"global\"===t.resolve?\"true\":\"{unit: \"+Tq(e)+\"}\")}},fq=\"_translate_anchor\",pq=\"_translate_delta\";function mq(e,t,n,r,i){var a=t.name,o=rq.has(t),s=i.filter(function(e){return e.name===Aq(t,n,o?\"data\":\"visual\")})[0],l=a+fq,c=a+pq,u=e.getSizeSignalRef(r).signal,d=e.getScaleComponent(n),f=d.get(\"type\"),p=l+\".extent_\"+n,m=(o?\"log\"===f?\"panLog\":\"pow\"===f?\"panPow\":\"panLinear\":\"panLinear\")+\"(\"+p+\", \"+(\"\"+(o&&n===_P?\"-\":\"\")+c+\".\"+n+\" / \"+(o?\"\"+u:\"span(\"+p+\")\"))+(o&&\"pow\"===f?\", \"+(d.get(\"exponent\")||1):\"\")+\")\";s.on.push({events:{signal:c},update:o?m:\"clampRange(\"+m+\", 0, \"+u+\")\"})}var gq=\"_zoom_anchor\",hq=\"_zoom_delta\";function bq(e,t,n,r,i){var a=t.name,o=rq.has(t),s=i.filter(function(e){return e.name===Aq(t,n,o?\"data\":\"visual\")})[0],l=e.getSizeSignalRef(r).signal,c=e.getScaleComponent(n),u=c.get(\"type\"),d=o?iq(e,n):s.name,f=a+hq,p=(o?\"log\"===u?\"zoomLog\":\"pow\"===u?\"zoomPow\":\"zoomLinear\":\"zoomLinear\")+\"(\"+d+\", \"+(\"\"+a+gq+\".\"+n)+\", \"+f+(o&&\"pow\"===u?\", \"+(c.get(\"exponent\")||1):\"\")+\")\";s.on.push({events:{signal:f},update:o?p:\"clampRange(\"+p+\", 0, \"+l+\")\"})}var vq={project:{has:function(e){var t=e;return void 0!==t.fields||void 0!==t.encodings},parse:function(e,t,n){var r={},i={};(t.fields||[]).forEach(function(e){return r[e]=null}),(t.encodings||[]).forEach(function(t){var n=e.fieldDef(t);if(n)if(n.timeUnit){var a=e.vgField(t);r[a]=t,i[a]={as:a,field:n.field,timeUnit:n.timeUnit}}else r[n.field]=t;else kF(OF.cannotProjectOnChannelWithoutField(t))});var a=n.project||(n.project=[]);for(var o in r)r.hasOwnProperty(o)&&a.push({field:o,channel:r[o]});var s=n.fields||(n.fields={});a.filter(function(e){return e.channel}).forEach(function(e){return s[e.channel]=e.field}),ZL(i).length&&(n.timeUnit=new Sz(null,i))}},toggle:{has:function(e){return\"multi\"===e.type&&e.toggle},signals:function(e,t,n){return n.concat({name:t.name+\"_toggle\",value:!1,on:[{events:t.events,update:t.toggle}]})},modifyExpr:function(e,t,n){var r=t.name+xq,i=t.name+\"_toggle\";return i+\" ? null : \"+r+\", \"+(\"global\"===t.resolve?i+\" ? null : true, \":i+\" ? null : {unit: \"+Tq(e)+\"}, \")+i+\" ? \"+r+\" : null\"}},scales:rq,translate:{has:function(e){return\"interval\"===e.type&&e.translate},signals:function(e,t,n){var r=t.name,i=rq.has(t),a=r+fq,o=kq(t),s=o.x,l=o.y,c=VT(t.translate,\"scope\");return i||(c=c.map(function(e){return e.between[0].markname=r+\"_brush\",e})),n.push({name:a,value:{},on:[{events:c.map(function(e){return e.between[0]}),update:\"{x: x(unit), y: y(unit)\"+(null!==s?\", extent_x: \"+(i?iq(e,_P):\"slice(\"+Aq(t,\"x\",\"visual\")+\")\"):\"\")+(null!==l?\", extent_y: \"+(i?iq(e,yP):\"slice(\"+Aq(t,\"y\",\"visual\")+\")\"):\"\")+\"}\"}]},{name:r+pq,value:{},on:[{events:c,update:\"{x: \"+a+\".x - x(unit), y: \"+a+\".y - y(unit)}\"}]}),null!==s&&mq(e,t,_P,\"width\",n),null!==l&&mq(e,t,yP,\"height\",n),n}},zoom:{has:function(e){return\"interval\"===e.type&&e.zoom},signals:function(e,t,n){var r=t.name,i=rq.has(t),a=r+hq,o=kq(t),s=o.x,l=o.y,c=Object(Ee.M)(e.scaleName(_P)),u=Object(Ee.M)(e.scaleName(yP)),d=VT(t.zoom,\"scope\");return i||(d=d.map(function(e){return e.markname=r+\"_brush\",e})),n.push({name:r+gq,on:[{events:d,update:i?\"{\"+[c?\"x: invert(\"+c+\", x(unit))\":\"\",u?\"y: invert(\"+u+\", y(unit))\":\"\"].filter(function(e){return!!e}).join(\", \")+\"}\":\"{x: x(unit), y: y(unit)}\"}]},{name:a,on:[{events:d,force:!0,update:\"pow(1.001, event.deltaY * pow(16, event.deltaMode))\"}]}),null!==s&&bq(e,t,\"x\",\"width\",n),null!==l&&bq(e,t,\"y\",\"height\",n),n}},inputs:{has:function(e){return\"single\"===e.type&&\"global\"===e.resolve&&e.bind&&\"scales\"!==e.bind},topLevelSignals:function(e,t,n){var r=t.name,i=t.project,a=t.bind,o=lq.has(t)?\"(item().isVoronoi ? datum.datum : datum)\":\"datum\";return i.forEach(function(e){var i=nP(r+\"_\"+e.field);n.filter(function(e){return e.name===i}).length||n.unshift({name:i,value:\"\",on:[{events:t.events,update:\"datum && item().mark.marktype !== 'group' ? \"+aP(e.field,o)+\" : null\"}],bind:a[e.field]||a[e.channel]||a})}),n},signals:function(e,t,n){var r=t.name,i=t.project,a=n.filter(function(e){return e.name===r+xq})[0],o=i.map(function(e){return Object(Ee.M)(e.field)}).join(\", \"),s=i.map(function(e){return nP(r+\"_\"+e.field)});return s.length&&(a.update=s.join(\" && \")+\" ? {fields: [\"+o+\"], values: [\"+s.join(\", \")+\"]} : null\"),delete a.value,delete a.on,n}},nearest:lq};function _q(e,t){for(var n in vq)vq[n].has(e)&&t(vq[n])}var yq=\"_store\",xq=\"_tuple\",Eq=\"_modify\",Sq=\"_selection_domain_\";function wq(e,t){return Oq(e,function(n,r){t=r.marks?r.marks(e,n,t):t,_q(n,function(r){r.marks&&(t=r.marks(e,n,t))})}),t}function Cq(e,t,n){var r=[];var i=rP(t,function(t){var i=nP(t),a=e.getSelectionComponent(i,t),o=Object(Ee.M)(i+yq);if(a.timeUnit){var s=n||e.component.data.raw,l=a.timeUnit.clone();s.parent?l.insertAsParentOf(s):s.parent=l}return\"none\"!==a.empty&&r.push(o),Mq(a.type).predicate+\"(\"+o+\", datum\"+(\"global\"===a.resolve?\")\":\", \"+Object(Ee.M)(a.resolve)+\")\")});return(r.length?\"!(\"+r.map(function(e){return\"length(data(\"+e+\"))\"}).join(\" || \")+\") || \":\"\")+\"(\"+i+\")\"}function Oq(e,t){var n=e.component.selection;for(var r in n)if(n.hasOwnProperty(r)){var i=n[r];t(i,Mq(i.type))}}function Mq(e){switch(e){case\"single\":return dq;case\"multi\":return uq;case\"interval\":return oq}return null}function Nq(e){for(var t=e.parent;t&&!Zz(t);)t=t.parent;return t}function Tq(e){var t=Object(Ee.M)(e.name),n=Nq(e);return n&&(t+=(n.facet.row?\" + '_' + (\"+aP(n.vgField(\"row\"),\"facet\")+\")\":\"\")+(n.facet.column?\" + '_' + (\"+aP(n.vgField(\"column\"),\"facet\")+\")\":\"\")),t}function Dq(e){var t=!1;return Oq(e,function(e){t=t||e.project.some(function(e){return e.field===pU})}),t}function Aq(e,t,n){var r=e._signalNames||(e._signalNames={});if(r[t]&&r[t][n])return r[t][n];r[t]=r[t]||{};for(var i=nP(e.name+\"_\"+(\"visual\"===n?t:e.fields[t])),a=i,o=1;r[a];)a=i+\"_\"+o++;return r[a]=r[t][n]=a}function kq(e){var t=null,n=null,r=null,i=null;return e.project.forEach(function(e,a){e.channel===_P?(t=e,n=a):e.channel===yP&&(r=e,i=a)}),{x:t,xi:n,y:r,yi:i}}function Rq(e){return e&&!!e.field&&void 0!==e.equal}function Iq(e){return e&&!!e.field&&void 0!==e.lt}function Lq(e){return e&&!!e.field&&void 0!==e.lte}function Pq(e){return e&&!!e.field&&void 0!==e.gt}function Fq(e){return e&&!!e.field&&void 0!==e.gte}function Bq(e){return!!(e&&e.field&&Object(Ee.u)(e.range)&&2===e.range.length)}function Uq(e){return e&&!!e.field&&(Object(Ee.u)(e.oneOf)||Object(Ee.u)(e.in))}function jq(e){return Uq(e)||Rq(e)||Bq(e)||Iq(e)||Pq(e)||Lq(e)||Fq(e)}function zq(e,t,n){return rP(t,function(t){return Object(Ee.B)(t)?t:function(e){return e&&e.selection}(t)?Cq(e,t.selection,n):Gq(t)})}function qq(e,t){return wB(e,{timeUnit:t,time:!0})}function Gq(e,t){void 0===t&&(t=!0);var n=e.field,r=e.timeUnit,i=r?\"time(\"+YF(r,n)+\")\":dB(e,{expr:\"datum\"});if(Rq(e))return i+\"===\"+qq(e.equal,r);if(Iq(e))return i+\"<\"+qq(s=e.lt,r);if(Pq(e))return i+\">\"+qq(o=e.gt,r);if(Lq(e))return i+\"<=\"+qq(s=e.lte,r);if(Fq(e))return i+\">=\"+qq(o=e.gte,r);if(Uq(e)){var a=e.oneOf;return\"indexof([\"+function(e,t){return e.map(function(e){return qq(e,t)})}(a=a||e.in,r).join(\",\")+\"], \"+i+\") !== -1\"}if(Bq(e)){var o=e.range[0],s=e.range[1];if(null!==o&&null!==s&&t)return\"inrange(\"+i+\", [\"+qq(o,r)+\", \"+qq(s,r)+\"])\";var l=[];return null!==o&&l.push(i+\" >= \"+qq(o,r)),null!==s&&l.push(i+\" <= \"+qq(s,r)),l.length>0?l.join(\" && \"):\"true\"}throw new Error(\"Invalid field predicate: \"+JSON.stringify(e))}function $q(e){return jq(e)&&e.timeUnit?NL({},e,{timeUnit:ZF(e.timeUnit)}):e}function Hq(e){return void 0!==e.filter}function Wq(e,t){var n;n=function(e){return\"as\"in e}(e)?Object(Ee.B)(e.as)?[e.as,e.as+\"_end\"]:[e.as[0],e.as[1]]:[dB(e,{}),dB(e,{binSuffix:\"end\"})];var r=xB(e.bin,void 0)||{},i=function(e,t){return oF(e)+\"_\"+t}(r,e.field),a=function(e,t){return{signal:e.getName(t+\"_bins\"),extentSignal:e.getName(t+\"_extent\")}}(t,i),o=a.signal,s=a.extentSignal;return{key:i,binComponent:NL({bin:r,field:e.field,as:n},o?{signal:o}:{},s?{extentSignal:s}:{})}}var Vq=function(e){function t(t,n){var r=e.call(this,t)||this;return r.bins=n,r}return ML(t,e),t.prototype.clone=function(){return new t(null,eP(this.bins))},t.makeFromEncoding=function(e,n){var r=n.reduceFieldDef(function(e,t,r){if(t.bin){var i=Wq(t,n),a=i.key,o=i.binComponent;e[a]=NL({},o,e[a],function(e,t,n,r){if(Ij(t,n)){var i=Yz(e)&&(e.axis(n)||e.legend(n))||{},a=dB(t,{expr:\"datum\"}),o=dB(t,{expr:\"datum\",binSuffix:\"end\"});return{formulaAs:dB(t,{binSuffix:\"range\"}),formula:Nj(a,o,i.format,r)}}return{}}(n,t,r,n.config))}return e},{});return 0===ZL(r).length?null:new t(e,r)},t.makeFromTransform=function(e,n,r){var i,a=Wq(n,r),o=a.key,s=a.binComponent;return new t(e,((i={})[o]=s,i))},t.prototype.merge=function(e){this.bins=NL({},this.bins,e.bins),e.remove()},t.prototype.producedFields=function(){var e={};return XL(this.bins).forEach(function(t){t.as.forEach(function(t){return e[t]=!0})}),e},t.prototype.dependentFields=function(){var e={};return XL(this.bins).forEach(function(t){e[t.field]=!0}),e},t.prototype.assemble=function(){return VL(XL(this.bins).map(function(e){var t=[],n=NL({type:\"bin\",field:e.field,as:e.as,signal:e.signal},e.bin);return!e.bin.extent&&e.extentSignal&&(t.push({type:\"extent\",field:e.field,signal:e.extentSignal}),n.extent={signal:e.extentSignal}),t.push(n),e.formula&&t.push({type:\"formula\",expr:e.formula,as:e.formulaAs}),t}))},t}(Pj),Kq=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.model=n,i.filter=r,i.expr=zq(i.model,i.filter,i),i}return ML(t,e),t.prototype.clone=function(){return new t(null,this.model,eP(this.filter))},t.prototype.assemble=function(){return{type:\"filter\",expr:this.expr}},t}(Pj),Qq=function(e){function t(t,n,r,i){var a=e.call(this,t)||this;return a.fields=n,a.geojson=r,a.signal=i,a}return ML(t,e),t.prototype.clone=function(){return new t(null,eP(this.fields),this.geojson,this.signal)},t.parseAll=function(e,n){var r=0;if([[CP,SP],[OP,wP]].forEach(function(i){var a=i.map(function(e){return n.channelHasField(e)?n.fieldDef(e).field:void 0});(a[0]||a[1])&&(e=new t(e,a,null,n.getName(\"geojson_\"+r++)))}),n.channelHasField(TP)){var i=n.fieldDef(TP);i.type===rB&&(e=new t(e,null,i.field,n.getName(\"geojson_\"+r++)))}return e},t.prototype.assemble=function(){return NL({type:\"geojson\"},this.fields?{fields:this.fields}:{},this.geojson?{geojson:this.geojson}:{},{signal:this.signal})},t}(Pj),Yq=function(e){function t(t,n,r,i){var a=e.call(this,t)||this;return a.projection=n,a.fields=r,a.as=i,a}return ML(t,e),t.prototype.clone=function(){return new t(null,this.projection,eP(this.fields),eP(this.as))},t.parseAll=function(e,n){return n.projectionName()?([[CP,SP],[OP,wP]].forEach(function(r){var i=r.map(function(e){return n.channelHasField(e)?n.fieldDef(e).field:void 0}),a=r[0]===OP?\"2\":\"\";(i[0]||i[1])&&(e=new t(e,n.projectionName(),i,[n.getName(\"x\"+a),n.getName(\"y\"+a)]))}),e):e},t.prototype.assemble=function(){return{type:\"geopoint\",projection:this.projection,fields:this.fields,as:this.as}},t}(Pj),Zq=function(e){function t(t){return e.call(this,t)||this}return ML(t,e),t.prototype.clone=function(){return new t(null)},t.prototype.producedFields=function(){var e;return(e={})[pU]=!0,e},t.prototype.assemble=function(){return{type:\"identifier\",as:pU}},t}(Pj),Xq=function(e){function t(t,n,r){void 0===t&&(t={}),void 0===n&&(n={}),void 0===r&&(r=!1);var i=e.call(this,t,n)||this;return i.explicit=t,i.implicit=n,i.parseNothing=r,i}return ML(t,e),t.prototype.clone=function(){var t=e.prototype.clone.call(this);return t.parseNothing=this.parseNothing,t},t}(Zj),Jq=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.transform=n,i.secondary=r,i}return ML(t,e),t.make=function(e,n,r,i){var a=n.component.data.sources,o=new Ez(r.from.data),s=a[o.hash()];s||(a[o.hash()]=o,s=o);var l=n.getName(\"lookup_\"+i),c=new Fj(s,l,\"lookup\",n.component.data.outputNodeRefCounts);return n.component.data.outputNodes[l]=c,new t(e,r,c.getSource())},t.prototype.producedFields=function(){return Object(Ee.Q)(this.transform.from.fields||(this.transform.as instanceof Array?this.transform.as:[this.transform.as]))},t.prototype.assemble=function(){var e;if(this.transform.from.fields)e=NL({values:this.transform.from.fields},this.transform.as?{as:this.transform.as instanceof Array?this.transform.as:[this.transform.as]}:{});else{var t=this.transform.as;Object(Ee.B)(t)||(kF(OF.NO_FIELDS_NEEDS_AS),t=\"_lookup\"),e={as:[t]}}return NL({type:\"lookup\",from:this.secondary,key:this.transform.from.key,fields:[this.transform.lookup]},e,this.transform.default?{default:this.transform.default}:{})},t}(Pj);function eG(e){var t=0;return function n(r,i){r instanceof Ez&&(UU(r.data)||(e.push(i),i={name:null,source:i.name,transform:[]}));if(r instanceof xz&&(r.parent instanceof Ez&&!i.source?(i.format=NL({},i.format||{},{parse:r.assembleFormatParse()}),i.transform=i.transform.concat(r.assembleTransforms(!0))):i.transform=i.transform.concat(r.assembleTransforms())),r instanceof _z)return i.name||(i.name=\"data_\"+t++),!i.source||i.transform.length>0?(e.push(i),r.data=i.name):r.data=i.source,void r.assemble().forEach(function(t){return e.push(t)});(r instanceof Kq||r instanceof Bj||r instanceof Yq||r instanceof Qq||r instanceof vz||r instanceof Jq||r instanceof fG||r instanceof Zq)&&i.transform.push(r.assemble()),(r instanceof yz||r instanceof Vq||r instanceof Sz||r instanceof Nz)&&(i.transform=i.transform.concat(r.assemble())),r instanceof vz&&(i.name||(i.name=\"data_\"+t++)),r instanceof Fj&&(i.source&&0===i.transform.length?r.setSource(i.source):r.parent instanceof Fj?r.setSource(i.name):(i.name||(i.name=\"data_\"+t++),r.setSource(i.name),1===r.numChildren()&&(e.push(i),i={name:null,source:i.name,transform:[]})));switch(r.numChildren()){case 0:r instanceof Fj&&(!i.source||i.transform.length>0)&&e.push(i);break;case 1:n(r.children[0],i);break;default:i.name||(i.name=\"data_\"+t++);var a=i.name;!i.source||i.transform.length>0?e.push(i):a=i.source,r.children.forEach(function(e){n(e,{name:null,source:a,transform:[]})})}}}function tG(e){rG(e);var t=e.component.layoutSize;t.setWithExplicit(\"width\",iG(e,\"width\")),t.setWithExplicit(\"height\",iG(e,\"height\"))}var nG=tG;function rG(e){for(var t=0,n=e.children;t0?{data:t}:{},n?{encode:{update:n}}:{},e.assembleGroup())]},t.prototype.getMapping=function(){return this.facet},t}(nq),fG=function(e){function t(t,n){var r=e.call(this,t)||this;return r.transform=n,r}return ML(t,e),t.makeFromFacet=function(e,n){var r=n.row,i=n.column;if(r&&i){for(var a=null,o=0,s=[r,i];o0&&(t=function(e,t,n){var r=0;return t.transforms.forEach(function(i){if(function(e){return void 0!==e.calculate}(i))e=new Bj(e,i),n.set(i.as,\"derived\",!1);else if(Hq(i))e=xz.makeImplicitFromFilterTransform(e,i,n)||e,e=new Kq(e,t,i.filter);else if(function(e){return!!e.bin}(i))for(var a=e=Vq.makeFromTransform(e,i,t),o=0,s=ZL(a.producedFields());o0&&(n[a]={update:s}),n},{});ZL(a).length>0&&r.set(\"encode\",a,!!n.encoding||void 0!==n.labelAngle);return r}(n,e)]),t},{})}var yG={bottom:\"top\",top:\"bottom\",left:\"right\",right:\"left\"};function xG(e,t){if(!e)return t.map(function(e){return e.clone()});if(e.length===t.length){for(var n=e.length,r=0;r0?TG:\"\"});var r,i;return t.length>0?[{name:e.getName(\"pathgroup\"),type:\"group\",from:{facet:{name:TG+e.requestDataName(zU),data:e.requestDataName(zU),groupby:t}},encode:{update:{width:{field:{group:\"width\"}},height:{field:{group:\"height\"}}}},marks:n}]:n}(e):DG(e)}var TG=\"faceted_path_\";function DG(e,t){void 0===t&&(t={fromPrefix:\"\"});var n=e.mark,r=void 0!==e.markDef.clip?!!e.markDef.clip:function(e){var t=e.getScaleComponent(\"x\"),n=e.getScaleComponent(\"y\");return!!(t&&t.get(\"domainRaw\")||n&&n.get(\"domainRaw\"))}(e),i=xj(e.markDef),a=e.encoding.key,o=function(e){var t=e.encoding,n=e.stack,r=e.mark,i=e.markDef,a=t.order;if(Object(Ee.u)(a)||!cB(a)){if((Object(Ee.u)(a)||sB(a))&&!n)return Dj(a,{expr:\"datum\"});if(xF(r)){var o=t[\"horizontal\"===i.orient?\"y\":\"x\"];if(sB(o)){var s=o.sort;return{field:XU(s)?dB({aggregate:MB(e.encoding)?s.op:void 0,field:s.field},{expr:\"datum\"}):dB(o,{binSuffix:e.stack&&e.stack.impute?\"mid\":void 0,expr:\"datum\"}),order:\"descending\"}}}}}(e),s=MG[n].postEncodingTransform?MG[n].postEncodingTransform(e):null;return[NL({name:e.getName(\"marks\"),type:MG[n].vgMark},r?{clip:!0}:{},i?{style:i}:{},a?{key:{field:a.field}}:{},o?{sort:o}:{},{from:{data:t.fromPrefix+e.requestDataName(zU)},encode:{update:MG[n].encodeEntry(e)}},s?{transform:s}:{})]}var AG=function(e){function t(t,n,r,i,a,o,s){void 0===i&&(i={});var l=e.call(this,t,n,r,o,a,void 0)||this;l.fit=s,l.type=\"unit\",l.specifiedScales={},l.specifiedAxes={},l.specifiedLegends={},l.specifiedProjection={},l.selection={},l.children=[],l.initSize(NL({},i,t.width?{width:t.width}:{},t.height?{height:t.height}:{}));var c=SF(t.mark)?t.mark.type:t.mark,u=l.encoding=function(e,t){return ZL(e).reduce(function(n,r){var i;if(!VP(r))return kF(OF.invalidEncodingChannel(r)),n;if(!iF(r,t))return kF(OF.incompatibleChannel(r,t)),n;if(\"size\"===r&&\"line\"===t&&(o=vB(e[r]))&&o.aggregate)return kF(OF.LINE_WITH_VARYING_SIZE),n;if(\"color\"===r&&(\"fill\"in e||\"stroke\"in e))return kF(OF.droppingColor(\"encoding\",{fill:\"fill\"in e,stroke:\"stroke\"in e})),n;var a=e[r];if(\"detail\"===r||\"order\"===r&&!Object(Ee.u)(a)&&!cB(a)||\"tooltip\"===r&&Object(Ee.u)(a))a&&(n[r]=(Object(Ee.u)(a)?a:[a]).reduce(function(e,t){return sB(t)?e.push(yB(t,r)):kF(OF.emptyFieldDef(t,r)),e},[]));else{var o;if((o=vB(e[r]))&&$L([KF.LATITUDE,KF.LONGITUDE],o.type)){var s=r,l=(n[s],TL(n,[\"symbol\"==typeof s?s:s+\"\"])),c=\"x\"===r?\"longitude\":\"y\"===r?\"latitude\":\"x2\"===r?\"longitude2\":\"y2\"===r?\"latitude2\":void 0;return kF(OF.latLongDeprecated(r,o.type,c)),NL({},l,((i={})[c]=NL({},_B(o,r),{type:\"quantitative\"}),i))}if(!sB(a)&&!cB(a)&&!aB(a))return kF(OF.emptyFieldDef(a,r)),n;n[r]=_B(a,r)}return n},{})}(function(e,t){return cG(e,t)}(t.encoding||{},a),c);return l.markDef=wG(t.mark,u,o),l.stack=SU(c,u,l.config.stack),l.specifiedScales=l.initScales(c,u),l.specifiedAxes=l.initAxes(u),l.specifiedLegends=l.initLegend(u),l.specifiedProjection=t.projection,l.selection=t.selection,l}return ML(t,e),Object.defineProperty(t.prototype,\"hasProjection\",{get:function(){var e=this.encoding,t=this.mark===bF,n=e&&qP.some(function(t){return sB(e[t])});return t||n},enumerable:!0,configurable:!0}),t.prototype.scaleDomain=function(e){var t=this.specifiedScales[e];return t?t.domain:void 0},t.prototype.axis=function(e){return this.specifiedAxes[e]},t.prototype.legend=function(e){return this.specifiedLegends[e]},t.prototype.initScales=function(e,t){return nF.reduce(function(e,n){var r,i,a=t[n];return sB(a)?(r=a,i=a.scale):oB(a)?(r=a.condition,i=a.condition.scale):\"x\"===n?r=vB(t.x2):\"y\"===n&&(r=vB(t.y2)),r&&(e[n]=i||{}),e},{})},t.prototype.initAxes=function(e){return[_P,yP].reduce(function(t,n){var r=e[n];if(sB(r)||n===_P&&sB(e.x2)||n===yP&&sB(e.y2)){var i=sB(r)?r.axis:null;null!==i&&!1!==i&&(t[n]=NL({},i))}return t},{})},t.prototype.initLegend=function(e){return eF.reduce(function(t,n){var r=e[n];if(r){var i=sB(r)?r.legend:oB(r)?r.condition.legend:null;null!==i&&!1!==i&&(t[n]=NL({},i))}return t},{})},t.prototype.parseData=function(){this.component.data=pG(this)},t.prototype.parseLayoutSize=function(){!function(e){var t=e.component.layoutSize;if(!t.explicit.width){var n=aG(e,\"width\");t.set(\"width\",n,!1)}if(!t.explicit.height){var r=aG(e,\"height\");t.set(\"height\",r,!1)}}(this)},t.prototype.parseSelection=function(){this.component.selection=function(e,t){var n={},r=e.config.selection,i=function(i){if(!t.hasOwnProperty(i))return\"continue\";var a=t[i],o=r[a.type];for(var s in o)\"encodings\"===s&&a.fields||\"fields\"===s&&a.encodings||(\"mark\"===s&&(a[s]=NL({},o[s],a[s])),void 0!==a[s]&&!0!==a[s]||(a[s]=o[s]||a[s]));i=nP(i);var l=n[i]=NL({},a,{name:i,events:Object(Ee.B)(a.on)?VT(a.on,\"scope\"):a.on});_q(l,function(t){t.parse&&t.parse(e,a,l)})};for(var a in t)i(a);return n}(this,this.selection)},t.prototype.parseMarkGroup=function(){this.component.mark=NG(this)},t.prototype.parseAxisAndHeader=function(){this.component.axes=_G(this)},t.prototype.assembleSelectionTopLevelSignals=function(e){return function(e,t){var n=!1;return Oq(e,function(r,i){i.topLevelSignals&&(t=i.topLevelSignals(e,r,t)),_q(r,function(n){n.topLevelSignals&&(t=n.topLevelSignals(e,r,t))}),n=!0}),n&&(t.filter(function(e){return\"unit\"===e.name}).length||t.unshift({name:\"unit\",value:{},on:[{events:\"mousemove\",update:\"isTuple(group()) ? group() : unit\"}]})),t}(this,e)},t.prototype.assembleSelectionSignals=function(){return function(e,t){Oq(e,function(n,r){var i=n.name,a=r.modifyExpr(e,n);t.push.apply(t,r.signals(e,n)),_q(n,function(r){r.signals&&(t=r.signals(e,n,t)),r.modifyExpr&&(a=r.modifyExpr(e,n,a))}),t.push({name:i+Eq,on:[{events:{signal:i+xq},update:\"modify(\"+Object(Ee.M)(n.name+yq)+\", \"+a+\")\"}]})});var n=Nq(e);if(t.length&&n){var r=Object(Ee.M)(n.getName(\"cell\"));t.unshift({name:\"facet\",value:{},on:[{events:VT(\"mousemove\",\"scope\"),update:\"isTuple(facet) ? facet : group(\"+r+\").datum\"}]})}return t}(this,[])},t.prototype.assembleSelectionData=function(e){return function(e,t){return Oq(e,function(e){t.filter(function(t){return t.name===e.name+yq}).length||t.push({name:e.name+yq})}),t}(this,e)},t.prototype.assembleLayout=function(){return null},t.prototype.assembleLayoutSignals=function(){return Wj(this)},t.prototype.assembleMarks=function(){var e=this.component.mark||[];return this.parent&&eq(this.parent)||(e=wq(this,e)),e.map(this.correctDataNames)},t.prototype.assembleLayoutSize=function(){return{width:this.getSizeSignalRef(\"width\"),height:this.getSizeSignalRef(\"height\")}},t.prototype.getMapping=function(){return this.encoding},t.prototype.toSpec=function(e,t){var n,r=eP(this.encoding);return n={mark:this.markDef,encoding:r},e||(n.config=eP(this.config)),t||(n.data=eP(this.data)),n},Object.defineProperty(t.prototype,\"mark\",{get:function(){return this.markDef.type},enumerable:!0,configurable:!0}),t.prototype.channelHasField=function(e){return OB(this.encoding,e)},t.prototype.fieldDef=function(e){return vB(this.encoding[e])},t}(nq),kG=function(e){function t(n,r,i,a,o,s,l){var c=e.call(this,n,r,i,s,o,n.resolve)||this;c.type=\"layer\";var u=NL({},a,n.width?{width:n.width}:{},n.height?{height:n.height}:{});return c.initSize(u),c.children=n.layer.map(function(e,n){if(OU(e))return new t(e,c,c.getName(\"layer_\"+n),u,o,s,l);if(CU(e))return new AG(e,c,c.getName(\"layer_\"+n),u,o,s,l);throw new Error(OF.INVALID_SPEC)}),c}return ML(t,e),t.prototype.parseData=function(){this.component.data=pG(this);for(var e=0,t=this.children;e0&&!y){var x=yG[_];i[_]>i[x]&&b.set(\"orient\",x,!1)}i[_]++}}delete m.component.axes[c]}}}}(this)},t.prototype.assembleSelectionTopLevelSignals=function(e){return this.children.reduce(function(e,t){return t.assembleSelectionTopLevelSignals(e)},e)},t.prototype.assembleSelectionSignals=function(){return this.children.reduce(function(e,t){return e.concat(t.assembleSelectionSignals())},[])},t.prototype.assembleLayoutSignals=function(){return this.children.reduce(function(e,t){return e.concat(t.assembleLayoutSignals())},Wj(this))},t.prototype.assembleSelectionData=function(e){return this.children.reduce(function(e,t){return t.assembleSelectionData(e)},e)},t.prototype.assembleTitle=function(){var t=e.prototype.assembleTitle.call(this);if(t)return t;for(var n=0,r=this.children;n0})).forEach(wz(Oz)),kz(i=i.filter(function(e){return e.numChildren()>0})).forEach(wz(Cz)),kz(i).forEach(Mz),i.forEach(Dz),ZL(r.sources).forEach(function(e){0===r.sources[e].numChildren()&&delete r.sources[e]}),function(e,t){var n=e.config?function(e){e=eP(e);for(var t=0,n=bU;t0?e:void 0}(e.config):void 0,r=[].concat(e.assembleSelectionData([]),function(e,t){var n=XL(e.sources),r=[],i=eG(r),a=0;n.forEach(function(e){e.hasName()||(e.dataName=\"source_\"+a++);var t=e.assemble();i(e,t)}),r.forEach(function(e){0===e.transform.length&&delete e.transform});for(var o=0,s=0;s0?{projections:i}:{},e.assembleGroup(s.concat(e.assembleSelectionTopLevelSignals([]))),n?{config:n}:{})}}(l,function(e,t,n){return NL({autosize:1===ZL(n).length&&n.type?n.type:n},BU(t),BU(e))}(e,a,s))}finally{t.logger&&AF(),t.fieldTitle&&hB(mB)}}n(3),Object(Ee.Q)([\"row\",\"column\",\"x\",\"y\",\"size\",\"color\",\"fill\",\"stroke\",\"detail\"]),Object(Ee.Q)([\"row\",\"column\",\"x\",\"y\",\"color\",\"fill\",\"stroke\",\"color\",\"detail\"]),Object(Ee.Q)([\"row\",\"column\",\"x\",\"y\",\"color\",\"fill\",\"stroke\",\"color\",\"detail\",\"size\"]),Object(Ee.Q)([\"row\",\"column\",\"x\",\"y\",\"color\",\"fill\",\"stroke\",\"detail\"]),Object(Ee.Q)([\"row\",\"column\",\"x\",\"y\",\"color\",\"fill\",\"stroke\",\"detail\"]),Object(Ee.Q)([\"row\",\"column\",\"x\",\"y\",\"color\",\"fill\",\"stroke\",\"size\",\"detail\"]),Object(Ee.Q)([\"row\",\"column\",\"x\",\"y\",\"color\",\"fill\",\"stroke\",\"size\",\"detail\"]),Object(Ee.Q)([\"row\",\"column\",\"x\",\"y\",\"color\",\"fill\",\"stroke\",\"size\",\"detail\",\"shape\"]),Object(Ee.Q)([\"row\",\"column\",\"color\",\"fill\",\"stroke\",\"detail\",\"shape\"]),Object(Ee.Q)([\"row\",\"column\",\"size\",\"color\",\"fill\",\"stroke\",\"text\"]);n(5).version;n.d(t,\"embedExample\",function(){return BG}),window.runStreamingExample=function(e){var t,n,r=BG(e,{$schema:\"https://vega.github.io/schema/vega-lite/v2.json\",data:{name:\"table\"},autosize:{resize:!0},width:400,mark:\"line\",encoding:{x:{field:\"x\",type:\"quantitative\",scale:{zero:!1}},y:{field:\"y\",type:\"quantitative\"},color:{field:\"category\",type:\"nominal\"}}},!1,!1),i=(t=-1,n=[5,5,5,5],function(){t++;var e=n.map(function(e,n){return{x:t,y:e+Math.round(10*Math.random()-3*n),category:n}});return n=e.map(function(e){return e.y}),e}),a=-100;window.setInterval(function(){a++;var e=r.changeset().insert(i()).remove(function(e){return e.x'+n.replace(/^\\s+|\\s+$/g,\"\"))}),window.changeSpec=function(e,t){var n=document.getElementById(e);be(n).attr(\"data-name\",t),UG(n)},window.buildSpecOpts=function(e,t){var n=be(\"#\"+e).attr(\"data-name\"),r=be(\"select[name=\"+e+\"]\"),i=ye(\"input[name=\"+e+\"]:checked\"),a=r.empty()?e:r.property(\"value\"),o=i.nodes().map(function(e){return e.value}).sort().join(\"_\"),s=t+a+(o?\"_\"+o:\"\");n!==s&&window.changeSpec(e,s)},ye(\".vl-example\").each(function(){UG(this)});var jG=document.getElementById(\"carousel\");function zG(e,t,n,r){t[r].setAttribute(\"data-state\",\"\"),n[r].setAttribute(\"data-state\",\"\"),e[r].setAttribute(\"data-state\",\"\"),e[r].style.display=\"none\";var i=e[r].querySelector(\"video\");i&&i.pause()}function qG(e,t,n,r){return function(){for(var i=0;i=\"0\"&&r<=\"9\";)t+=r,l();if(\".\"===r)for(t+=\".\";l()&&r>=\"0\"&&r<=\"9\";)t+=r;if(\"e\"===r||\"E\"===r)for(t+=r,l(),\"-\"!==r&&\"+\"!==r||(t+=r,l());r>=\"0\"&&r<=\"9\";)t+=r,l();if(e=+t,isFinite(e))return e;s(\"Bad number\")},u=function(){var e,t,n,i=\"\";if('\"'===r)for(;l();){if('\"'===r)return l(),i;if(\"\\\\\"===r)if(l(),\"u\"===r){for(n=0,t=0;t<4&&(e=parseInt(l(),16),isFinite(e));t+=1)n=16*n+e;i+=String.fromCharCode(n)}else{if(\"string\"!=typeof o[r])break;i+=o[r]}else i+=r}s(\"Bad string\")},d=function(){for(;r&&r<=\" \";)l()};a=function(){switch(d(),r){case\"{\":return function(){var e,t={};if(\"{\"===r){if(l(\"{\"),d(),\"}\"===r)return l(\"}\"),t;for(;r;){if(e=u(),d(),l(\":\"),Object.hasOwnProperty.call(t,e)&&s('Duplicate key \"'+e+'\"'),t[e]=a(),d(),\"}\"===r)return l(\"}\"),t;l(\",\"),d()}}s(\"Bad object\")}();case\"[\":return function(){var e=[];if(\"[\"===r){if(l(\"[\"),d(),\"]\"===r)return l(\"]\"),e;for(;r;){if(e.push(a()),d(),\"]\"===r)return l(\"]\"),e;l(\",\"),d()}}s(\"Bad array\")}();case'\"':return u();case\"-\":return c();default:return r>=\"0\"&&r<=\"9\"?c():function(){switch(r){case\"t\":return l(\"t\"),l(\"r\"),l(\"u\"),l(\"e\"),!0;case\"f\":return l(\"f\"),l(\"a\"),l(\"l\"),l(\"s\"),l(\"e\"),!1;case\"n\":return l(\"n\"),l(\"u\"),l(\"l\"),l(\"l\"),null}s(\"Unexpected '\"+r+\"'\")}()}},e.exports=function(e,t){var o;return i=e,n=0,r=\" \",o=a(),d(),r&&s(\"Syntax error\"),\"function\"==typeof t?function e(n,r){var i,a,o=n[r];if(o&&\"object\"==typeof o)for(i in o)Object.prototype.hasOwnProperty.call(o,i)&&(void 0!==(a=e(o,i))?o[i]=a:delete o[i]);return t.call(n,r,o)}({\"\":o},\"\"):o}},function(e,t,n){t.parse=n(9),t.stringify=n(8)},function(e,t){var n={}.toString;e.exports=Array.isArray||function(e){return\"[object Array]\"==n.call(e)}},function(e,t){t.read=function(e,t,n,r,i){var a,o,s=8*i-r-1,l=(1<>1,u=-7,d=n?i-1:0,f=n?-1:1,p=e[t+d];for(d+=f,a=p&(1<<-u)-1,p>>=-u,u+=s;u>0;a=256*a+e[t+d],d+=f,u-=8);for(o=a&(1<<-u)-1,a>>=-u,u+=r;u>0;o=256*o+e[t+d],d+=f,u-=8);if(0===a)a=1-c;else{if(a===l)return o?NaN:1/0*(p?-1:1);o+=Math.pow(2,r),a-=c}return(p?-1:1)*o*Math.pow(2,a-r)},t.write=function(e,t,n,r,i,a){var o,s,l,c=8*a-i-1,u=(1<>1,f=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:a-1,m=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,o=u):(o=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-o))<1&&(o--,l*=2),(t+=o+d>=1?f/l:f*Math.pow(2,1-d))*l>=2&&(o++,l/=2),o+d>=u?(s=0,o=u):o+d>=1?(s=(t*l-1)*Math.pow(2,i),o+=d):(s=t*Math.pow(2,d-1)*Math.pow(2,i),o=0));i>=8;e[n+p]=255&s,p+=m,s/=256,i-=8);for(o=o<0;e[n+p]=255&o,p+=m,o/=256,c-=8);e[n+p-m]|=128*g}},function(e,t,n){\"use strict\";t.byteLength=function(e){var t=c(e),n=t[0],r=t[1];return 3*(n+r)/4-r},t.toByteArray=function(e){for(var t,n=c(e),r=n[0],o=n[1],s=new a(function(e,t,n){return 3*(t+n)/4-n}(0,r,o)),l=0,u=o>0?r-4:r,d=0;d>16&255,s[l++]=t>>8&255,s[l++]=255&t;2===o&&(t=i[e.charCodeAt(d)]<<2|i[e.charCodeAt(d+1)]>>4,s[l++]=255&t);1===o&&(t=i[e.charCodeAt(d)]<<10|i[e.charCodeAt(d+1)]<<4|i[e.charCodeAt(d+2)]>>2,s[l++]=t>>8&255,s[l++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,i=n%3,a=[],o=0,s=n-i;os?s:o+16383));1===i?(t=e[n-1],a.push(r[t>>2]+r[t<<4&63]+\"==\")):2===i&&(t=(e[n-2]<<8)+e[n-1],a.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+\"=\"));return a.join(\"\")};for(var r=[],i=[],a=\"undefined\"!=typeof Uint8Array?Uint8Array:Array,o=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",s=0,l=o.length;s0)throw new Error(\"Invalid string. Length must be a multiple of 4\");var n=e.indexOf(\"=\");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function u(e,t,n){for(var i,a,o=[],s=t;s>18&63]+r[a>>12&63]+r[a>>6&63]+r[63&a]);return o.join(\"\")}i[\"-\".charCodeAt(0)]=62,i[\"_\".charCodeAt(0)]=63},function(e,t){var n;n=function(){return this}();try{n=n||Function(\"return this\")()||(0,eval)(\"this\")}catch(e){\"object\"==typeof window&&(n=window)}e.exports=n},function(e,t,n){\"use strict\";(function(e){\n/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\nvar r=n(13),i=n(12),a=n(11);function o(){return l.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(o()=o())throw new RangeError(\"Attempt to allocate Buffer larger than maximum size: 0x\"+o().toString(16)+\" bytes\");return 0|e}function m(e,t){if(l.isBuffer(e))return e.length;if(\"undefined\"!=typeof ArrayBuffer&&\"function\"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;\"string\"!=typeof e&&(e=\"\"+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case\"ascii\":case\"latin1\":case\"binary\":return n;case\"utf8\":case\"utf-8\":case void 0:return j(e).length;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return 2*n;case\"hex\":return n>>>1;case\"base64\":return z(e).length;default:if(r)return j(e).length;t=(\"\"+t).toLowerCase(),r=!0}}function g(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function h(e,t,n,r,i){if(0===e.length)return-1;if(\"string\"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=i?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if(\"string\"==typeof t&&(t=l.from(t,r)),l.isBuffer(t))return 0===t.length?-1:b(e,t,n,r,i);if(\"number\"==typeof t)return t&=255,l.TYPED_ARRAY_SUPPORT&&\"function\"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):b(e,[t],n,r,i);throw new TypeError(\"val must be string, number or Buffer\")}function b(e,t,n,r,i){var a,o=1,s=e.length,l=t.length;if(void 0!==r&&(\"ucs2\"===(r=String(r).toLowerCase())||\"ucs-2\"===r||\"utf16le\"===r||\"utf-16le\"===r)){if(e.length<2||t.length<2)return-1;o=2,s/=2,l/=2,n/=2}function c(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}if(i){var u=-1;for(a=n;as&&(n=s-l),a=n;a>=0;a--){for(var d=!0,f=0;fi&&(r=i):r=i;var a=t.length;if(a%2!=0)throw new TypeError(\"Invalid hex string\");r>a/2&&(r=a/2);for(var o=0;o>8,i=n%256,a.push(i),a.push(r);return a}(t,e.length-n),e,n,r)}function w(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function C(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i239?4:c>223?3:c>191?2:1;if(i+d<=n)switch(d){case 1:c<128&&(u=c);break;case 2:128==(192&(a=e[i+1]))&&(l=(31&c)<<6|63&a)>127&&(u=l);break;case 3:a=e[i+1],o=e[i+2],128==(192&a)&&128==(192&o)&&(l=(15&c)<<12|(63&a)<<6|63&o)>2047&&(l<55296||l>57343)&&(u=l);break;case 4:a=e[i+1],o=e[i+2],s=e[i+3],128==(192&a)&&128==(192&o)&&128==(192&s)&&(l=(15&c)<<18|(63&a)<<12|(63&o)<<6|63&s)>65535&&l<1114112&&(u=l)}null===u?(u=65533,d=1):u>65535&&(u-=65536,r.push(u>>>10&1023|55296),u=56320|1023&u),r.push(u),i+=d}return function(e){var t=e.length;if(t<=O)return String.fromCharCode.apply(String,e);var n=\"\",r=0;for(;rthis.length)return\"\";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return\"\";if((n>>>=0)<=(t>>>=0))return\"\";for(e||(e=\"utf8\");;)switch(e){case\"hex\":return T(this,t,n);case\"utf8\":case\"utf-8\":return C(this,t,n);case\"ascii\":return M(this,t,n);case\"latin1\":case\"binary\":return N(this,t,n);case\"base64\":return w(this,t,n);case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return D(this,t,n);default:if(r)throw new TypeError(\"Unknown encoding: \"+e);e=(e+\"\").toLowerCase(),r=!0}}.apply(this,arguments)},l.prototype.equals=function(e){if(!l.isBuffer(e))throw new TypeError(\"Argument must be a Buffer\");return this===e||0===l.compare(this,e)},l.prototype.inspect=function(){var e=\"\",n=t.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString(\"hex\",0,n).match(/.{2}/g).join(\" \"),this.length>n&&(e+=\" ... \")),\"\"},l.prototype.compare=function(e,t,n,r,i){if(!l.isBuffer(e))throw new TypeError(\"Argument must be a Buffer\");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError(\"out of range index\");if(r>=i&&t>=n)return 0;if(r>=i)return-1;if(t>=n)return 1;if(t>>>=0,n>>>=0,r>>>=0,i>>>=0,this===e)return 0;for(var a=i-r,o=n-t,s=Math.min(a,o),c=this.slice(r,i),u=e.slice(t,n),d=0;di)&&(n=i),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError(\"Attempt to write outside buffer bounds\");r||(r=\"utf8\");for(var a=!1;;)switch(r){case\"hex\":return v(this,e,t,n);case\"utf8\":case\"utf-8\":return _(this,e,t,n);case\"ascii\":return y(this,e,t,n);case\"latin1\":case\"binary\":return x(this,e,t,n);case\"base64\":return E(this,e,t,n);case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return S(this,e,t,n);default:if(a)throw new TypeError(\"Unknown encoding: \"+r);r=(\"\"+r).toLowerCase(),a=!0}},l.prototype.toJSON=function(){return{type:\"Buffer\",data:Array.prototype.slice.call(this._arr||this,0)}};var O=4096;function M(e,t,n){var r=\"\";n=Math.min(e.length,n);for(var i=t;ir)&&(n=r);for(var i=\"\",a=t;an)throw new RangeError(\"Trying to access beyond buffer length\")}function k(e,t,n,r,i,a){if(!l.isBuffer(e))throw new TypeError('\"buffer\" argument must be a Buffer instance');if(t>i||te.length)throw new RangeError(\"Index out of range\")}function R(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,a=Math.min(e.length-n,2);i>>8*(r?i:1-i)}function I(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,a=Math.min(e.length-n,4);i>>8*(r?i:3-i)&255}function L(e,t,n,r,i,a){if(n+r>e.length)throw new RangeError(\"Index out of range\");if(n<0)throw new RangeError(\"Index out of range\")}function P(e,t,n,r,a){return a||L(e,0,n,4),i.write(e,t,n,r,23,4),n+4}function F(e,t,n,r,a){return a||L(e,0,n,8),i.write(e,t,n,r,52,8),n+8}l.prototype.slice=function(e,t){var n,r=this.length;if(e=~~e,t=void 0===t?r:~~t,e<0?(e+=r)<0&&(e=0):e>r&&(e=r),t<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(i*=256);)r+=this[e+--t]*i;return r},l.prototype.readUInt8=function(e,t){return t||A(e,1,this.length),this[e]},l.prototype.readUInt16LE=function(e,t){return t||A(e,2,this.length),this[e]|this[e+1]<<8},l.prototype.readUInt16BE=function(e,t){return t||A(e,2,this.length),this[e]<<8|this[e+1]},l.prototype.readUInt32LE=function(e,t){return t||A(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},l.prototype.readUInt32BE=function(e,t){return t||A(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},l.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||A(e,t,this.length);for(var r=this[e],i=1,a=0;++a=(i*=128)&&(r-=Math.pow(2,8*t)),r},l.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||A(e,t,this.length);for(var r=t,i=1,a=this[e+--r];r>0&&(i*=256);)a+=this[e+--r]*i;return a>=(i*=128)&&(a-=Math.pow(2,8*t)),a},l.prototype.readInt8=function(e,t){return t||A(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},l.prototype.readInt16LE=function(e,t){t||A(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},l.prototype.readInt16BE=function(e,t){t||A(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},l.prototype.readInt32LE=function(e,t){return t||A(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},l.prototype.readInt32BE=function(e,t){return t||A(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},l.prototype.readFloatLE=function(e,t){return t||A(e,4,this.length),i.read(this,e,!0,23,4)},l.prototype.readFloatBE=function(e,t){return t||A(e,4,this.length),i.read(this,e,!1,23,4)},l.prototype.readDoubleLE=function(e,t){return t||A(e,8,this.length),i.read(this,e,!0,52,8)},l.prototype.readDoubleBE=function(e,t){return t||A(e,8,this.length),i.read(this,e,!1,52,8)},l.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||k(this,e,t,n,Math.pow(2,8*n)-1,0);var i=1,a=0;for(this[t]=255&e;++a=0&&(a*=256);)this[t+i]=e/a&255;return t+n},l.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,1,255,0),l.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},l.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,2,65535,0),l.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):R(this,e,t,!0),t+2},l.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,2,65535,0),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):R(this,e,t,!1),t+2},l.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,4,4294967295,0),l.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):I(this,e,t,!0),t+4},l.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,4,4294967295,0),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):I(this,e,t,!1),t+4},l.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);k(this,e,t,n,i-1,-i)}var a=0,o=1,s=0;for(this[t]=255&e;++a>0)-s&255;return t+n},l.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);k(this,e,t,n,i-1,-i)}var a=n-1,o=1,s=0;for(this[t+a]=255&e;--a>=0&&(o*=256);)e<0&&0===s&&0!==this[t+a+1]&&(s=1),this[t+a]=(e/o>>0)-s&255;return t+n},l.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,1,127,-128),l.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},l.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,2,32767,-32768),l.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):R(this,e,t,!0),t+2},l.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,2,32767,-32768),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):R(this,e,t,!1),t+2},l.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,4,2147483647,-2147483648),l.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):I(this,e,t,!0),t+4},l.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||k(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):I(this,e,t,!1),t+4},l.prototype.writeFloatLE=function(e,t,n){return P(this,e,t,!0,n)},l.prototype.writeFloatBE=function(e,t,n){return P(this,e,t,!1,n)},l.prototype.writeDoubleLE=function(e,t,n){return F(this,e,t,!0,n)},l.prototype.writeDoubleBE=function(e,t,n){return F(this,e,t,!1,n)},l.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError(\"sourceStart out of bounds\");if(r<0)throw new RangeError(\"sourceEnd out of bounds\");r>this.length&&(r=this.length),e.length-t=0;--i)e[i+t]=this[i+n];else if(a<1e3||!l.TYPED_ARRAY_SUPPORT)for(i=0;i>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),\"number\"==typeof e)for(a=t;a55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(o+1===r){(t-=3)>-1&&a.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&a.push(239,191,189),i=n;continue}n=65536+(i-55296<<10|n-56320)}else i&&(t-=3)>-1&&a.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;a.push(n)}else if(n<2048){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error(\"Invalid code point\");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function z(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\\s+|\\s+$/g,\"\")}(e).replace(B,\"\")).length<2)return\"\";for(;e.length%4!=0;)e+=\"=\";return e}(e))}function q(e,t,n,r){for(var i=0;i=t.length||i>=e.length);++i)t[i+n]=e[i];return i}}).call(this,n(14))},function(e,t){},function(e,t){},function(e,t){e.exports=function(e){var t={className:\"string\",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:'b\"',end:'\"'},{begin:\"b'\",end:\"'\"},e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null})]},n={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]};return{aliases:[\"zep\"],case_insensitive:!0,keywords:\"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var let while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally int uint long ulong char uchar double float bool boolean stringlikely unlikely\",contains:[e.C_LINE_COMMENT_MODE,e.HASH_COMMENT_MODE,e.COMMENT(\"/\\\\*\",\"\\\\*/\",{contains:[{className:\"doctag\",begin:\"@[A-Za-z]+\"}]}),e.COMMENT(\"__halt_compiler.+?;\",!1,{endsWithParent:!0,keywords:\"__halt_compiler\",lexemes:e.UNDERSCORE_IDENT_RE}),{className:\"string\",begin:\"<<<['\\\"]?\\\\w+['\\\"]?$\",end:\"^\\\\w+;\",contains:[e.BACKSLASH_ESCAPE]},{begin:/(::|->)+[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*/},{className:\"function\",beginKeywords:\"function\",end:/[;{]/,excludeEnd:!0,illegal:\"\\\\$|\\\\[|%\",contains:[e.UNDERSCORE_TITLE_MODE,{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\",contains:[\"self\",e.C_BLOCK_COMMENT_MODE,t,n]}]},{className:\"class\",beginKeywords:\"class interface\",end:\"{\",excludeEnd:!0,illegal:/[:\\(\\$\"]/,contains:[{beginKeywords:\"extends implements\"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:\"namespace\",end:\";\",illegal:/[\\.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:\"use\",end:\";\",contains:[e.UNDERSCORE_TITLE_MODE]},{begin:\"=>\"},t,n]}}},function(e,t){e.exports=function(e){var t={begin:\"{\",end:\"}\"},n=[{begin:/\\$[a-zA-Z0-9\\-]+/},{className:\"string\",variants:[{begin:/\"/,end:/\"/,contains:[{begin:/\"\"/,relevance:0}]},{begin:/'/,end:/'/,contains:[{begin:/''/,relevance:0}]}]},{className:\"number\",begin:\"(\\\\b0[0-7_]+)|(\\\\b0x[0-9a-fA-F_]+)|(\\\\b[1-9][0-9_]*(\\\\.[0-9_]+)?)|[0_]\\\\b\",relevance:0},{className:\"comment\",begin:\"\\\\(:\",end:\":\\\\)\",relevance:10,contains:[{className:\"doctag\",begin:\"@\\\\w+\"}]},{className:\"meta\",begin:\"%\\\\w+\"},t];return t.contains=n,{aliases:[\"xpath\",\"xq\"],case_insensitive:!1,lexemes:/[a-zA-Z\\$][a-zA-Z0-9_:\\-]*/,illegal:/(proc)|(abstract)|(extends)|(until)|(#)/,keywords:{keyword:\"for let if while then else return where group by xquery encoding versionmodule namespace boundary-space preserve strip default collation base-uri orderingcopy-namespaces order declare import schema namespace function option in allowing emptyat tumbling window sliding window start when only end when previous next stable ascendingdescending empty greatest least some every satisfies switch case typeswitch try catch andor to union intersect instance of treat as castable cast map array delete insert intoreplace value rename copy modify update\",literal:\"false true xs:string xs:integer element item xs:date xs:datetime xs:float xs:double xs:decimal QName xs:anyURI xs:long xs:int xs:short xs:byte attribute\"},contains:n}}},function(e,t){e.exports=function(e){var t={keyword:\"if then else do while until for loop import with is as where when by data constant integer real text name boolean symbol infix prefix postfix block tree\",literal:\"true false nil\",built_in:\"in mod rem and or xor not abs sign floor ceil sqrt sin cos tan asin acos atan exp expm1 log log2 log10 log1p pi at text_length text_range text_find text_replace contains page slide basic_slide title_slide title subtitle fade_in fade_out fade_at clear_color color line_color line_width texture_wrap texture_transform texture scale_?x scale_?y scale_?z? translate_?x translate_?y translate_?z? rotate_?x rotate_?y rotate_?z? rectangle circle ellipse sphere path line_to move_to quad_to curve_to theme background contents locally time mouse_?x mouse_?y mouse_buttons ObjectLoader Animate MovieCredits Slides Filters Shading Materials LensFlare Mapping VLCAudioVideo StereoDecoder PointCloud NetworkAccess RemoteControl RegExp ChromaKey Snowfall NodeJS Speech Charts\"},n={className:\"string\",begin:'\"',end:'\"',illegal:\"\\\\n\"},r={beginKeywords:\"import\",end:\"$\",keywords:t,contains:[n]},i={className:\"function\",begin:/[a-z][^\\n]*->/,returnBegin:!0,end:/->/,contains:[e.inherit(e.TITLE_MODE,{starts:{endsWithParent:!0,keywords:t}})]};return{aliases:[\"tao\"],lexemes:/[a-zA-Z][a-zA-Z0-9_?]*/,keywords:t,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,{className:\"string\",begin:\"'\",end:\"'\",illegal:\"\\\\n\"},{className:\"string\",begin:\"<<\",end:\">>\"},i,r,{className:\"number\",begin:\"[0-9]+#[0-9A-Z_]+(\\\\.[0-9-A-Z_]+)?#?([Ee][+-]?[0-9]+)?\"},e.NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,lexemes:\"[.%]?\"+e.IDENT_RE,keywords:{keyword:\"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63\",built_in:\"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr\",meta:\"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__\"},contains:[e.COMMENT(\";\",\"$\",{relevance:0}),{className:\"number\",variants:[{begin:\"\\\\b(?:([0-9][0-9_]*)?\\\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\\\b\",relevance:0},{begin:\"\\\\$[0-9][0-9A-Fa-f]*\",relevance:0},{begin:\"\\\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\\\b\"},{begin:\"\\\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\\\b\"}]},e.QUOTE_STRING_MODE,{className:\"string\",variants:[{begin:\"'\",end:\"[^\\\\\\\\]'\"},{begin:\"`\",end:\"[^\\\\\\\\]`\"}],relevance:0},{className:\"symbol\",variants:[{begin:\"^\\\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\\\s+label)\"},{begin:\"^\\\\s*%%[A-Za-z0-9_$#@~.?]*:\"}],relevance:0},{className:\"subst\",begin:\"%[0-9]+\",relevance:0},{className:\"subst\",begin:\"%!S+\",relevance:0},{className:\"meta\",begin:/^\\s*\\.[\\w_-]+/}]}}},function(e,t){e.exports=function(e){return{lexemes:/[!#@\\w]+/,keywords:{keyword:\"N|0 P|0 X|0 a|0 ab abc abo al am an|0 ar arga argd arge argdo argg argl argu as au aug aun b|0 bN ba bad bd be bel bf bl bm bn bo bp br brea breaka breakd breakl bro bufdo buffers bun bw c|0 cN cNf ca cabc caddb cad caddf cal cat cb cc ccl cd ce cex cf cfir cgetb cgete cg changes chd che checkt cl cla clo cm cmapc cme cn cnew cnf cno cnorea cnoreme co col colo com comc comp con conf cope cp cpf cq cr cs cst cu cuna cunme cw delm deb debugg delc delf dif diffg diffo diffp diffpu diffs diffthis dig di dl dell dj dli do doautoa dp dr ds dsp e|0 ea ec echoe echoh echom echon el elsei em en endfo endf endt endw ene ex exe exi exu f|0 files filet fin fina fini fir fix fo foldc foldd folddoc foldo for fu go gr grepa gu gv ha helpf helpg helpt hi hid his ia iabc if ij il im imapc ime ino inorea inoreme int is isp iu iuna iunme j|0 ju k|0 keepa kee keepj lN lNf l|0 lad laddb laddf la lan lat lb lc lch lcl lcs le lefta let lex lf lfir lgetb lgete lg lgr lgrepa lh ll lla lli lmak lm lmapc lne lnew lnf ln loadk lo loc lockv lol lope lp lpf lr ls lt lu lua luad luaf lv lvimgrepa lw m|0 ma mak map mapc marks mat me menut mes mk mks mksp mkv mkvie mod mz mzf nbc nb nbs new nm nmapc nme nn nnoreme noa no noh norea noreme norm nu nun nunme ol o|0 om omapc ome on ono onoreme opt ou ounme ow p|0 profd prof pro promptr pc ped pe perld po popu pp pre prev ps pt ptN ptf ptj ptl ptn ptp ptr pts pu pw py3 python3 py3d py3f py pyd pyf quita qa rec red redi redr redraws reg res ret retu rew ri rightb rub rubyd rubyf rund ru rv sN san sa sal sav sb sbN sba sbf sbl sbm sbn sbp sbr scrip scripte scs se setf setg setl sf sfir sh sim sig sil sl sla sm smap smapc sme sn sni sno snor snoreme sor so spelld spe spelli spellr spellu spellw sp spr sre st sta startg startr star stopi stj sts sun sunm sunme sus sv sw sy synti sync tN tabN tabc tabdo tabe tabf tabfir tabl tabm tabnew tabn tabo tabp tabr tabs tab ta tags tc tcld tclf te tf th tj tl tm tn to tp tr try ts tu u|0 undoj undol una unh unl unlo unm unme uns up ve verb vert vim vimgrepa vi viu vie vm vmapc vme vne vn vnoreme vs vu vunme windo w|0 wN wa wh wi winc winp wn wp wq wqa ws wu wv x|0 xa xmapc xm xme xn xnoreme xu xunme y|0 z|0 ~ Next Print append abbreviate abclear aboveleft all amenu anoremenu args argadd argdelete argedit argglobal arglocal argument ascii autocmd augroup aunmenu buffer bNext ball badd bdelete behave belowright bfirst blast bmodified bnext botright bprevious brewind break breakadd breakdel breaklist browse bunload bwipeout change cNext cNfile cabbrev cabclear caddbuffer caddexpr caddfile call catch cbuffer cclose center cexpr cfile cfirst cgetbuffer cgetexpr cgetfile chdir checkpath checktime clist clast close cmap cmapclear cmenu cnext cnewer cnfile cnoremap cnoreabbrev cnoremenu copy colder colorscheme command comclear compiler continue confirm copen cprevious cpfile cquit crewind cscope cstag cunmap cunabbrev cunmenu cwindow delete delmarks debug debuggreedy delcommand delfunction diffupdate diffget diffoff diffpatch diffput diffsplit digraphs display deletel djump dlist doautocmd doautoall deletep drop dsearch dsplit edit earlier echo echoerr echohl echomsg else elseif emenu endif endfor endfunction endtry endwhile enew execute exit exusage file filetype find finally finish first fixdel fold foldclose folddoopen folddoclosed foldopen function global goto grep grepadd gui gvim hardcopy help helpfind helpgrep helptags highlight hide history insert iabbrev iabclear ijump ilist imap imapclear imenu inoremap inoreabbrev inoremenu intro isearch isplit iunmap iunabbrev iunmenu join jumps keepalt keepmarks keepjumps lNext lNfile list laddexpr laddbuffer laddfile last language later lbuffer lcd lchdir lclose lcscope left leftabove lexpr lfile lfirst lgetbuffer lgetexpr lgetfile lgrep lgrepadd lhelpgrep llast llist lmake lmap lmapclear lnext lnewer lnfile lnoremap loadkeymap loadview lockmarks lockvar lolder lopen lprevious lpfile lrewind ltag lunmap luado luafile lvimgrep lvimgrepadd lwindow move mark make mapclear match menu menutranslate messages mkexrc mksession mkspell mkvimrc mkview mode mzscheme mzfile nbclose nbkey nbsart next nmap nmapclear nmenu nnoremap nnoremenu noautocmd noremap nohlsearch noreabbrev noremenu normal number nunmap nunmenu oldfiles open omap omapclear omenu only onoremap onoremenu options ounmap ounmenu ownsyntax print profdel profile promptfind promptrepl pclose pedit perl perldo pop popup ppop preserve previous psearch ptag ptNext ptfirst ptjump ptlast ptnext ptprevious ptrewind ptselect put pwd py3do py3file python pydo pyfile quit quitall qall read recover redo redir redraw redrawstatus registers resize retab return rewind right rightbelow ruby rubydo rubyfile rundo runtime rviminfo substitute sNext sandbox sargument sall saveas sbuffer sbNext sball sbfirst sblast sbmodified sbnext sbprevious sbrewind scriptnames scriptencoding scscope set setfiletype setglobal setlocal sfind sfirst shell simalt sign silent sleep slast smagic smapclear smenu snext sniff snomagic snoremap snoremenu sort source spelldump spellgood spellinfo spellrepall spellundo spellwrong split sprevious srewind stop stag startgreplace startreplace startinsert stopinsert stjump stselect sunhide sunmap sunmenu suspend sview swapname syntax syntime syncbind tNext tabNext tabclose tabedit tabfind tabfirst tablast tabmove tabnext tabonly tabprevious tabrewind tag tcl tcldo tclfile tearoff tfirst throw tjump tlast tmenu tnext topleft tprevious trewind tselect tunmenu undo undojoin undolist unabbreviate unhide unlet unlockvar unmap unmenu unsilent update vglobal version verbose vertical vimgrep vimgrepadd visual viusage view vmap vmapclear vmenu vnew vnoremap vnoremenu vsplit vunmap vunmenu write wNext wall while winsize wincmd winpos wnext wprevious wqall wsverb wundo wviminfo xit xall xmapclear xmap xmenu xnoremap xnoremenu xunmap xunmenu yank\",built_in:\"synIDtrans atan2 range matcharg did_filetype asin feedkeys xor argv complete_check add getwinposx getqflist getwinposy screencol clearmatches empty extend getcmdpos mzeval garbagecollect setreg ceil sqrt diff_hlID inputsecret get getfperm getpid filewritable shiftwidth max sinh isdirectory synID system inputrestore winline atan visualmode inputlist tabpagewinnr round getregtype mapcheck hasmapto histdel argidx findfile sha256 exists toupper getcmdline taglist string getmatches bufnr strftime winwidth bufexists strtrans tabpagebuflist setcmdpos remote_read printf setloclist getpos getline bufwinnr float2nr len getcmdtype diff_filler luaeval resolve libcallnr foldclosedend reverse filter has_key bufname str2float strlen setline getcharmod setbufvar index searchpos shellescape undofile foldclosed setqflist buflisted strchars str2nr virtcol floor remove undotree remote_expr winheight gettabwinvar reltime cursor tabpagenr finddir localtime acos getloclist search tanh matchend rename gettabvar strdisplaywidth type abs py3eval setwinvar tolower wildmenumode log10 spellsuggest bufloaded synconcealed nextnonblank server2client complete settabwinvar executable input wincol setmatches getftype hlID inputsave searchpair or screenrow line settabvar histadd deepcopy strpart remote_peek and eval getftime submatch screenchar winsaveview matchadd mkdir screenattr getfontname libcall reltimestr getfsize winnr invert pow getbufline byte2line soundfold repeat fnameescape tagfiles sin strwidth spellbadword trunc maparg log lispindent hostname setpos globpath remote_foreground getchar synIDattr fnamemodify cscope_connection stridx winbufnr indent min complete_add nr2char searchpairpos inputdialog values matchlist items hlexists strridx browsedir expand fmod pathshorten line2byte argc count getwinvar glob foldtextresult getreg foreground cosh matchdelete has char2nr simplify histget searchdecl iconv winrestcmd pumvisible writefile foldlevel haslocaldir keys cos matchstr foldtext histnr tan tempname getcwd byteidx getbufvar islocked escape eventhandler remote_send serverlist winrestview synstack pyeval prevnonblank readfile cindent filereadable changenr exp\"},illegal:/;/,contains:[e.NUMBER_MODE,e.APOS_STRING_MODE,{className:\"string\",begin:/\"(\\\\\"|\\n\\\\|[^\"\\n])*\"/},e.COMMENT('\"',\"$\"),{className:\"variable\",begin:/[bwtglsav]:[\\w\\d_]*/},{className:\"function\",beginKeywords:\"function function!\",end:\"$\",relevance:0,contains:[e.TITLE_MODE,{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\"}]},{className:\"symbol\",begin:/<[\\w-]+>/}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,keywords:{keyword:\"abs access after alias all and architecture array assert assume assume_guarantee attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor\",built_in:\"boolean bit character integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_logic std_logic_vector unsigned signed boolean_vector integer_vector std_ulogic std_ulogic_vector unresolved_unsigned u_unsigned unresolved_signed u_signedreal_vector time_vector\",literal:\"false true note warning error failure line text side width\"},illegal:\"{\",contains:[e.C_BLOCK_COMMENT_MODE,e.COMMENT(\"--\",\"$\"),e.QUOTE_STRING_MODE,{className:\"number\",begin:\"\\\\b(\\\\d(_|\\\\d)*#\\\\w+(\\\\.\\\\w+)?#([eE][-+]?\\\\d(_|\\\\d)*)?|\\\\d(_|\\\\d)*(\\\\.\\\\d(_|\\\\d)*)?([eE][-+]?\\\\d(_|\\\\d)*)?)\",relevance:0},{className:\"string\",begin:\"'(U|X|0|1|Z|W|L|H|-)'\",contains:[e.BACKSLASH_ESCAPE]},{className:\"symbol\",begin:\"'[A-Za-z](_?[A-Za-z0-9])*\",contains:[e.BACKSLASH_ESCAPE]}]}}},function(e,t){e.exports=function(e){return{aliases:[\"v\",\"sv\",\"svh\"],case_insensitive:!1,keywords:{keyword:\"accept_on alias always always_comb always_ff always_latch and assert assign assume automatic before begin bind bins binsof bit break buf|0 bufif0 bufif1 byte case casex casez cell chandle checker class clocking cmos config const constraint context continue cover covergroup coverpoint cross deassign default defparam design disable dist do edge else end endcase endchecker endclass endclocking endconfig endfunction endgenerate endgroup endinterface endmodule endpackage endprimitive endprogram endproperty endspecify endsequence endtable endtask enum event eventually expect export extends extern final first_match for force foreach forever fork forkjoin function generate|5 genvar global highz0 highz1 if iff ifnone ignore_bins illegal_bins implements implies import incdir include initial inout input inside instance int integer interconnect interface intersect join join_any join_none large let liblist library local localparam logic longint macromodule matches medium modport module nand negedge nettype new nexttime nmos nor noshowcancelled not notif0 notif1 or output package packed parameter pmos posedge primitive priority program property protected pull0 pull1 pulldown pullup pulsestyle_ondetect pulsestyle_onevent pure rand randc randcase randsequence rcmos real realtime ref reg reject_on release repeat restrict return rnmos rpmos rtran rtranif0 rtranif1 s_always s_eventually s_nexttime s_until s_until_with scalared sequence shortint shortreal showcancelled signed small soft solve specify specparam static string strong strong0 strong1 struct super supply0 supply1 sync_accept_on sync_reject_on table tagged task this throughout time timeprecision timeunit tran tranif0 tranif1 tri tri0 tri1 triand trior trireg type typedef union unique unique0 unsigned until until_with untyped use uwire var vectored virtual void wait wait_order wand weak weak0 weak1 while wildcard wire with within wor xnor xor\",literal:\"null\",built_in:\"$finish $stop $exit $fatal $error $warning $info $realtime $time $printtimescale $bitstoreal $bitstoshortreal $itor $signed $cast $bits $stime $timeformat $realtobits $shortrealtobits $rtoi $unsigned $asserton $assertkill $assertpasson $assertfailon $assertnonvacuouson $assertoff $assertcontrol $assertpassoff $assertfailoff $assertvacuousoff $isunbounded $sampled $fell $changed $past_gclk $fell_gclk $changed_gclk $rising_gclk $steady_gclk $coverage_control $coverage_get $coverage_save $set_coverage_db_name $rose $stable $past $rose_gclk $stable_gclk $future_gclk $falling_gclk $changing_gclk $display $coverage_get_max $coverage_merge $get_coverage $load_coverage_db $typename $unpacked_dimensions $left $low $increment $clog2 $ln $log10 $exp $sqrt $pow $floor $ceil $sin $cos $tan $countbits $onehot $isunknown $fatal $warning $dimensions $right $high $size $asin $acos $atan $atan2 $hypot $sinh $cosh $tanh $asinh $acosh $atanh $countones $onehot0 $error $info $random $dist_chi_square $dist_erlang $dist_exponential $dist_normal $dist_poisson $dist_t $dist_uniform $q_initialize $q_remove $q_exam $async$and$array $async$nand$array $async$or$array $async$nor$array $sync$and$array $sync$nand$array $sync$or$array $sync$nor$array $q_add $q_full $psprintf $async$and$plane $async$nand$plane $async$or$plane $async$nor$plane $sync$and$plane $sync$nand$plane $sync$or$plane $sync$nor$plane $system $display $displayb $displayh $displayo $strobe $strobeb $strobeh $strobeo $write $readmemb $readmemh $writememh $value$plusargs $dumpvars $dumpon $dumplimit $dumpports $dumpportson $dumpportslimit $writeb $writeh $writeo $monitor $monitorb $monitorh $monitoro $writememb $dumpfile $dumpoff $dumpall $dumpflush $dumpportsoff $dumpportsall $dumpportsflush $fclose $fdisplay $fdisplayb $fdisplayh $fdisplayo $fstrobe $fstrobeb $fstrobeh $fstrobeo $swrite $swriteb $swriteh $swriteo $fscanf $fread $fseek $fflush $feof $fopen $fwrite $fwriteb $fwriteh $fwriteo $fmonitor $fmonitorb $fmonitorh $fmonitoro $sformat $sformatf $fgetc $ungetc $fgets $sscanf $rewind $ftell $ferror\"},lexemes:/[\\w\\$]+/,contains:[e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE,e.QUOTE_STRING_MODE,{className:\"number\",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:\"\\\\b((\\\\d+'(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)\"},{begin:\"\\\\B(('(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)\"},{begin:\"\\\\b([0-9_])+\",relevance:0}]},{className:\"variable\",variants:[{begin:\"#\\\\((?!parameter).+\\\\)\"},{begin:\"\\\\.\\\\w+\",relevance:0}]},{className:\"meta\",begin:\"`\",end:\"$\",keywords:{\"meta-keyword\":\"define __FILE__ __LINE__ begin_keywords celldefine default_nettype define else elsif end_keywords endcelldefine endif ifdef ifndef include line nounconnected_drive pragma resetall timescale unconnected_drive undef undefineall\"},relevance:0}]}}},function(e,t){e.exports=function(e){return{subLanguage:\"xml\",contains:[{begin:\"<%\",end:\"%>\",subLanguage:\"vbscript\"}]}}},function(e,t){e.exports=function(e){return{aliases:[\"vbs\"],case_insensitive:!0,keywords:{keyword:\"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto\",built_in:\"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err\",literal:\"true false null nothing empty\"},illegal:\"//\",contains:[e.inherit(e.QUOTE_STRING_MODE,{contains:[{begin:'\"\"'}]}),e.COMMENT(/'/,/$/,{relevance:0}),e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{aliases:[\"vb\"],case_insensitive:!0,keywords:{keyword:\"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor\",built_in:\"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort\",literal:\"true false nothing\"},illegal:\"//|{|}|endif|gosub|variant|wend\",contains:[e.inherit(e.QUOTE_STRING_MODE,{contains:[{begin:'\"\"'}]}),e.COMMENT(\"'\",\"$\",{returnBegin:!0,contains:[{className:\"doctag\",begin:\"'''|\\x3c!--|--\\x3e\",contains:[e.PHRASAL_WORDS_MODE]},{className:\"doctag\",begin:\"\",contains:[e.PHRASAL_WORDS_MODE]}]}),e.C_NUMBER_MODE,{className:\"meta\",begin:\"#\",end:\"$\",keywords:{\"meta-keyword\":\"if else elseif end region externalsource\"}}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:\"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override virtual delegate if while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var\",built_in:\"DBus GLib CCode Gee Object Gtk Posix\",literal:\"false true null\"},contains:[{className:\"class\",beginKeywords:\"class interface namespace\",end:\"{\",excludeEnd:!0,illegal:\"[^,:\\\\n\\\\s\\\\.]\",contains:[e.UNDERSCORE_TITLE_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:\"string\",begin:'\"\"\"',end:'\"\"\"',relevance:5},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,{className:\"meta\",begin:\"^#\",end:\"$\",relevance:2}]}}},function(e,t){e.exports=function(e){var t={keyword:\"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super static implements enum export import declare type namespace abstract as from extends async await\",literal:\"true false null undefined NaN Infinity\",built_in:\"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void Promise\"};return{aliases:[\"ts\"],keywords:t,contains:[{className:\"meta\",begin:/^\\s*['\"]use strict['\"]/},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:\"string\",begin:\"`\",end:\"`\",contains:[e.BACKSLASH_ESCAPE,{className:\"subst\",begin:\"\\\\$\\\\{\",end:\"\\\\}\"}]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:\"number\",variants:[{begin:\"\\\\b(0[bB][01]+)\"},{begin:\"\\\\b(0[oO][0-7]+)\"},{begin:e.C_NUMBER_RE}],relevance:0},{begin:\"(\"+e.RE_STARTERS_RE+\"|\\\\b(case|return|throw)\\\\b)\\\\s*\",keywords:\"return throw case\",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.REGEXP_MODE,{className:\"function\",begin:\"(\\\\(.*?\\\\)|\"+e.IDENT_RE+\")\\\\s*=>\",returnBegin:!0,end:\"\\\\s*=>\",contains:[{className:\"params\",variants:[{begin:e.IDENT_RE},{begin:/\\(\\s*\\)/},{begin:/\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:[\"self\",e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}]}]}],relevance:0},{className:\"function\",begin:\"function\",end:/[\\{;]/,excludeEnd:!0,keywords:t,contains:[\"self\",e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/}),{className:\"params\",begin:/\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],illegal:/[\"'\\(]/}],illegal:/%/,relevance:0},{beginKeywords:\"constructor\",end:/\\{/,excludeEnd:!0,contains:[\"self\",{className:\"params\",begin:/\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],illegal:/[\"'\\(]/}]},{begin:/module\\./,keywords:{built_in:\"module\"},relevance:0},{beginKeywords:\"module\",end:/\\{/,excludeEnd:!0},{beginKeywords:\"interface\",end:/\\{/,excludeEnd:!0,keywords:\"interface extends\"},{begin:/\\$[(.]/},{begin:\"\\\\.\"+e.IDENT_RE,relevance:0},{className:\"meta\",begin:\"@[A-Za-z]+\"}]}}},function(e,t){e.exports=function(e){var t=\"attribute block constant cycle date dump include max min parent random range source template_from_string\",n={beginKeywords:t,keywords:{name:t},relevance:0,contains:[{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\"}]},r={begin:/\\|[A-Za-z_]+:?/,keywords:\"abs batch capitalize convert_encoding date date_modify default escape first format join json_encode keys last length lower merge nl2br number_format raw replace reverse round slice sort split striptags title trim upper url_encode\",contains:[n]},i=\"autoescape block do embed extends filter flush for if import include macro sandbox set spaceless use verbatim\";return i=i+\" \"+i.split(\" \").map(function(e){return\"end\"+e}).join(\" \"),{aliases:[\"craftcms\"],case_insensitive:!0,subLanguage:\"xml\",contains:[e.COMMENT(/\\{#/,/#}/),{className:\"template-tag\",begin:/\\{%/,end:/%}/,contains:[{className:\"name\",begin:/\\w+/,keywords:i,starts:{endsWithParent:!0,contains:[r,n],relevance:0}}]},{className:\"template-variable\",begin:/\\{\\{/,end:/}}/,contains:[\"self\",r,n]}]}}},function(e,t){e.exports=function(e){var t={className:\"number\",begin:\"[1-9][0-9]*\",relevance:0},n={className:\"symbol\",begin:\":[^\\\\]]+\"};return{keywords:{keyword:\"ABORT ACC ADJUST AND AP_LD BREAK CALL CNT COL CONDITION CONFIG DA DB DIV DETECT ELSE END ENDFOR ERR_NUM ERROR_PROG FINE FOR GP GUARD INC IF JMP LINEAR_MAX_SPEED LOCK MOD MONITOR OFFSET Offset OR OVERRIDE PAUSE PREG PTH RT_LD RUN SELECT SKIP Skip TA TB TO TOOL_OFFSET Tool_Offset UF UT UFRAME_NUM UTOOL_NUM UNLOCK WAIT X Y Z W P R STRLEN SUBSTR FINDSTR VOFFSET PROG ATTR MN POS\",literal:\"ON OFF max_speed LPOS JPOS ENABLE DISABLE START STOP RESET\"},contains:[{className:\"built_in\",begin:\"(AR|P|PAYLOAD|PR|R|SR|RSR|LBL|VR|UALM|MESSAGE|UTOOL|UFRAME|TIMER| TIMER_OVERFLOW|JOINT_MAX_SPEED|RESUME_PROG|DIAG_REC)\\\\[\",end:\"\\\\]\",contains:[\"self\",t,n]},{className:\"built_in\",begin:\"(AI|AO|DI|DO|F|RI|RO|UI|UO|GI|GO|SI|SO)\\\\[\",end:\"\\\\]\",contains:[\"self\",t,e.QUOTE_STRING_MODE,n]},{className:\"keyword\",begin:\"/(PROG|ATTR|MN|POS|END)\\\\b\"},{className:\"keyword\",begin:\"(CALL|RUN|POINT_LOGIC|LBL)\\\\b\"},{className:\"keyword\",begin:\"\\\\b(ACC|CNT|Skip|Offset|PSPD|RT_LD|AP_LD|Tool_Offset)\"},{className:\"number\",begin:\"\\\\d+(sec|msec|mm/sec|cm/min|inch/min|deg/sec|mm|in|cm)?\\\\b\",relevance:0},e.COMMENT(\"//\",\"[;$]\"),e.COMMENT(\"!\",\"[;$]\"),e.COMMENT(\"--eg:\",\"$\"),e.QUOTE_STRING_MODE,{className:\"string\",begin:\"'\",end:\"'\"},e.C_NUMBER_MODE,{className:\"variable\",begin:\"\\\\$[A-Za-z0-9_]+\"}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:\"namespace const typedef struct enum service exception void oneway set list map required optional\",built_in:\"bool byte i16 i32 i64 double string binary\",literal:\"true false\"},contains:[e.QUOTE_STRING_MODE,e.NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:\"class\",beginKeywords:\"struct enum service exception\",end:/\\{/,illegal:/\\n/,contains:[e.inherit(e.TITLE_MODE,{starts:{endsWithParent:!0,excludeEnd:!0}})]},{begin:\"\\\\b(set|list|map)\\\\s*<\",end:\">\",keywords:\"bool byte i16 i32 i64 double string binary\",contains:[\"self\"]}]}}},function(e,t){e.exports=function(e){var t={className:\"tag\",begin:/\\\\/,relevance:0,contains:[{className:\"name\",variants:[{begin:/[a-zA-Zа-яА-я]+[*]?/},{begin:/[^a-zA-Zа-яА-я0-9]/}],starts:{endsWithParent:!0,relevance:0,contains:[{className:\"string\",variants:[{begin:/\\[/,end:/\\]/},{begin:/\\{/,end:/\\}/}]},{begin:/\\s*=\\s*/,endsWithParent:!0,relevance:0,contains:[{className:\"number\",begin:/-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?/}]}]}}]};return{contains:[t,{className:\"formula\",contains:[t],relevance:0,variants:[{begin:/\\$\\$/,end:/\\$\\$/},{begin:/\\$/,end:/\\$/}]},e.COMMENT(\"%\",\"$\",{relevance:0})]}}},function(e,t){e.exports=function(e){return{aliases:[\"tk\"],keywords:\"after append apply array auto_execok auto_import auto_load auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror binary break catch cd chan clock close concat continue dde dict encoding eof error eval exec exit expr fblocked fconfigure fcopy file fileevent filename flush for foreach format gets glob global history http if incr info interp join lappend|10 lassign|10 lindex|10 linsert|10 list llength|10 load lrange|10 lrepeat|10 lreplace|10 lreverse|10 lsearch|10 lset|10 lsort|10 mathfunc mathop memory msgcat namespace open package parray pid pkg::create pkg_mkIndex platform platform::shell proc puts pwd read refchan regexp registry regsub|10 rename return safe scan seek set socket source split string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord tcl_wordBreakAfter tcl_wordBreakBefore tcltest tclvars tell time tm trace unknown unload unset update uplevel upvar variable vwait while\",contains:[e.COMMENT(\";[ \\\\t]*#\",\"$\"),e.COMMENT(\"^[ \\\\t]*#\",\"$\"),{beginKeywords:\"proc\",end:\"[\\\\{]\",excludeEnd:!0,contains:[{className:\"title\",begin:\"[ \\\\t\\\\n\\\\r]+(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\",end:\"[ \\\\t\\\\n\\\\r]\",endsWithParent:!0,excludeEnd:!0}]},{excludeEnd:!0,variants:[{begin:\"\\\\$(\\\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\\\\(([a-zA-Z0-9_])*\\\\)\",end:\"[^a-zA-Z0-9_\\\\}\\\\$]\"},{begin:\"\\\\$(\\\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\",end:\"(\\\\))?[^a-zA-Z0-9_\\\\}\\\\$]\"}]},{className:\"string\",contains:[e.BACKSLASH_ESCAPE],variants:[e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null})]},{className:\"number\",variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,contains:[e.HASH_COMMENT_MODE,{className:\"meta\",variants:[{begin:\"^TAP version (\\\\d+)$\"},{begin:\"^1\\\\.\\\\.(\\\\d+)$\"}]},{begin:\"(s+)?---$\",end:\"\\\\.\\\\.\\\\.$\",subLanguage:\"yaml\",relevance:0},{className:\"number\",begin:\" (\\\\d+) \"},{className:\"symbol\",variants:[{begin:\"^ok\"},{begin:\"^not ok\"}]}]}}},function(e,t){e.exports=function(e){var t=\"[a-zA-Z_][\\\\w\\\\-]*\",n={className:\"attr\",variants:[{begin:\"^[ \\\\-]*\"+t+\":\"},{begin:'^[ \\\\-]*\"'+t+'\":'},{begin:\"^[ \\\\-]*'\"+t+\"':\"}]},r={className:\"string\",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/\"/,end:/\"/},{begin:/\\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:\"template-variable\",variants:[{begin:\"{{\",end:\"}}\"},{begin:\"%{\",end:\"}\"}]}]};return{case_insensitive:!0,aliases:[\"yml\",\"YAML\",\"yaml\"],contains:[n,{className:\"meta\",begin:\"^---s*$\",relevance:10},{className:\"string\",begin:\"[\\\\|>] *$\",returnEnd:!0,contains:r.contains,end:n.variants[0].begin},{begin:\"<%[%=-]?\",end:\"[%-]?%>\",subLanguage:\"ruby\",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:\"type\",begin:\"!!\"+e.UNDERSCORE_IDENT_RE},{className:\"meta\",begin:\"&\"+e.UNDERSCORE_IDENT_RE+\"$\"},{className:\"meta\",begin:\"\\\\*\"+e.UNDERSCORE_IDENT_RE+\"$\"},{className:\"bullet\",begin:\"^ *-\",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:\"true false yes no null\",keywords:{literal:\"true false yes no null\"}},e.C_NUMBER_MODE,r]}}},function(e,t){e.exports=function(e){return{contains:[{className:\"comment\",begin:/\\$noop\\(/,end:/\\)/,contains:[{begin:/\\(/,end:/\\)/,contains:[\"self\",{begin:/\\\\./}]}],relevance:10},{className:\"keyword\",begin:/\\$(?!noop)[a-zA-Z][_a-zA-Z0-9]*/,end:/\\(/,excludeEnd:!0},{className:\"variable\",begin:/%[_a-zA-Z0-9:]*/,end:\"%\"},{className:\"symbol\",begin:/\\\\./}]}}},function(e,t){e.exports=function(e){var t={keyword:\"__COLUMN__ __FILE__ __FUNCTION__ __LINE__ as as! as? associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet\",literal:\"true false nil\",built_in:\"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip\"},n=e.COMMENT(\"/\\\\*\",\"\\\\*/\",{contains:[\"self\"]}),r={className:\"subst\",begin:/\\\\\\(/,end:\"\\\\)\",keywords:t,contains:[]},i={className:\"number\",begin:\"\\\\b([\\\\d_]+(\\\\.[\\\\deE_]+)?|0x[a-fA-F0-9_]+(\\\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\\\b\",relevance:0},a=e.inherit(e.QUOTE_STRING_MODE,{contains:[r,e.BACKSLASH_ESCAPE]});return r.contains=[i],{keywords:t,contains:[a,e.C_LINE_COMMENT_MODE,n,{className:\"type\",begin:\"\\\\b[A-Z][\\\\wÀ-ʸ']*\",relevance:0},i,{className:\"function\",beginKeywords:\"func\",end:\"{\",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/}),{begin://},{className:\"params\",begin:/\\(/,end:/\\)/,endsParent:!0,keywords:t,contains:[\"self\",i,a,e.C_BLOCK_COMMENT_MODE,{begin:\":\"}],illegal:/[\"']/}],illegal:/\\[|%/},{className:\"class\",beginKeywords:\"struct protocol class extension enum\",keywords:t,end:\"\\\\{\",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][\\u00C0-\\u02B80-9A-Za-z$_]*/})]},{className:\"meta\",begin:\"(@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain)\"},{beginKeywords:\"import\",end:/$/,contains:[e.C_LINE_COMMENT_MODE,n]}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,contains:[{className:\"string\",begin:\"\\\\[\\n(multipart)?\",end:\"\\\\]\\n\"},{className:\"string\",begin:\"\\\\d{4}-\\\\d{2}-\\\\d{2}(\\\\s+)\\\\d{2}:\\\\d{2}:\\\\d{2}.\\\\d+Z\"},{className:\"string\",begin:\"(\\\\+|-)\\\\d+\"},{className:\"keyword\",relevance:10,variants:[{begin:\"^(test|testing|success|successful|failure|error|skip|xfail|uxsuccess)(:?)\\\\s+(test)?\"},{begin:\"^progress(:?)(\\\\s+)?(pop|push)?\"},{begin:\"^tags:\"},{begin:\"^time:\"}]}]}}},function(e,t){e.exports=function(e){var t={className:\"variable\",begin:\"\\\\$\"+e.IDENT_RE},n={className:\"number\",begin:\"#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})\"},r=\"[\\\\.\\\\s\\\\n\\\\[\\\\:,]\";return{aliases:[\"styl\"],case_insensitive:!1,keywords:\"if else for in\",illegal:\"(\"+[\"\\\\?\",\"(\\\\bReturn\\\\b)\",\"(\\\\bEnd\\\\b)\",\"(\\\\bend\\\\b)\",\"(\\\\bdef\\\\b)\",\";\",\"#\\\\s\",\"\\\\*\\\\s\",\"===\\\\s\",\"\\\\|\",\"%\"].join(\"|\")+\")\",contains:[e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,{begin:\"\\\\.[a-zA-Z][a-zA-Z0-9_-]*\"+r,returnBegin:!0,contains:[{className:\"selector-class\",begin:\"\\\\.[a-zA-Z][a-zA-Z0-9_-]*\"}]},{begin:\"\\\\#[a-zA-Z][a-zA-Z0-9_-]*\"+r,returnBegin:!0,contains:[{className:\"selector-id\",begin:\"\\\\#[a-zA-Z][a-zA-Z0-9_-]*\"}]},{begin:\"\\\\b(\"+[\"a\",\"abbr\",\"address\",\"article\",\"aside\",\"audio\",\"b\",\"blockquote\",\"body\",\"button\",\"canvas\",\"caption\",\"cite\",\"code\",\"dd\",\"del\",\"details\",\"dfn\",\"div\",\"dl\",\"dt\",\"em\",\"fieldset\",\"figcaption\",\"figure\",\"footer\",\"form\",\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\",\"header\",\"hgroup\",\"html\",\"i\",\"iframe\",\"img\",\"input\",\"ins\",\"kbd\",\"label\",\"legend\",\"li\",\"mark\",\"menu\",\"nav\",\"object\",\"ol\",\"p\",\"q\",\"quote\",\"samp\",\"section\",\"span\",\"strong\",\"summary\",\"sup\",\"table\",\"tbody\",\"td\",\"textarea\",\"tfoot\",\"th\",\"thead\",\"time\",\"tr\",\"ul\",\"var\",\"video\"].join(\"|\")+\")\"+r,returnBegin:!0,contains:[{className:\"selector-tag\",begin:\"\\\\b[a-zA-Z][a-zA-Z0-9_-]*\"}]},{begin:\"&?:?:\\\\b(\"+[\"after\",\"before\",\"first-letter\",\"first-line\",\"active\",\"first-child\",\"focus\",\"hover\",\"lang\",\"link\",\"visited\"].join(\"|\")+\")\"+r},{begin:\"@(\"+[\"charset\",\"css\",\"debug\",\"extend\",\"font-face\",\"for\",\"import\",\"include\",\"media\",\"mixin\",\"page\",\"warn\",\"while\"].join(\"|\")+\")\\\\b\"},t,e.CSS_NUMBER_MODE,e.NUMBER_MODE,{className:\"function\",begin:\"^[a-zA-Z][a-zA-Z0-9_-]*\\\\(.*\\\\)\",illegal:\"[\\\\n]\",returnBegin:!0,contains:[{className:\"title\",begin:\"\\\\b[a-zA-Z][a-zA-Z0-9_-]*\"},{className:\"params\",begin:/\\(/,end:/\\)/,contains:[n,t,e.APOS_STRING_MODE,e.CSS_NUMBER_MODE,e.NUMBER_MODE,e.QUOTE_STRING_MODE]}]},{className:\"attribute\",begin:\"\\\\b(\"+[\"align-content\",\"align-items\",\"align-self\",\"animation\",\"animation-delay\",\"animation-direction\",\"animation-duration\",\"animation-fill-mode\",\"animation-iteration-count\",\"animation-name\",\"animation-play-state\",\"animation-timing-function\",\"auto\",\"backface-visibility\",\"background\",\"background-attachment\",\"background-clip\",\"background-color\",\"background-image\",\"background-origin\",\"background-position\",\"background-repeat\",\"background-size\",\"border\",\"border-bottom\",\"border-bottom-color\",\"border-bottom-left-radius\",\"border-bottom-right-radius\",\"border-bottom-style\",\"border-bottom-width\",\"border-collapse\",\"border-color\",\"border-image\",\"border-image-outset\",\"border-image-repeat\",\"border-image-slice\",\"border-image-source\",\"border-image-width\",\"border-left\",\"border-left-color\",\"border-left-style\",\"border-left-width\",\"border-radius\",\"border-right\",\"border-right-color\",\"border-right-style\",\"border-right-width\",\"border-spacing\",\"border-style\",\"border-top\",\"border-top-color\",\"border-top-left-radius\",\"border-top-right-radius\",\"border-top-style\",\"border-top-width\",\"border-width\",\"bottom\",\"box-decoration-break\",\"box-shadow\",\"box-sizing\",\"break-after\",\"break-before\",\"break-inside\",\"caption-side\",\"clear\",\"clip\",\"clip-path\",\"color\",\"column-count\",\"column-fill\",\"column-gap\",\"column-rule\",\"column-rule-color\",\"column-rule-style\",\"column-rule-width\",\"column-span\",\"column-width\",\"columns\",\"content\",\"counter-increment\",\"counter-reset\",\"cursor\",\"direction\",\"display\",\"empty-cells\",\"filter\",\"flex\",\"flex-basis\",\"flex-direction\",\"flex-flow\",\"flex-grow\",\"flex-shrink\",\"flex-wrap\",\"float\",\"font\",\"font-family\",\"font-feature-settings\",\"font-kerning\",\"font-language-override\",\"font-size\",\"font-size-adjust\",\"font-stretch\",\"font-style\",\"font-variant\",\"font-variant-ligatures\",\"font-weight\",\"height\",\"hyphens\",\"icon\",\"image-orientation\",\"image-rendering\",\"image-resolution\",\"ime-mode\",\"inherit\",\"initial\",\"justify-content\",\"left\",\"letter-spacing\",\"line-height\",\"list-style\",\"list-style-image\",\"list-style-position\",\"list-style-type\",\"margin\",\"margin-bottom\",\"margin-left\",\"margin-right\",\"margin-top\",\"marks\",\"mask\",\"max-height\",\"max-width\",\"min-height\",\"min-width\",\"nav-down\",\"nav-index\",\"nav-left\",\"nav-right\",\"nav-up\",\"none\",\"normal\",\"object-fit\",\"object-position\",\"opacity\",\"order\",\"orphans\",\"outline\",\"outline-color\",\"outline-offset\",\"outline-style\",\"outline-width\",\"overflow\",\"overflow-wrap\",\"overflow-x\",\"overflow-y\",\"padding\",\"padding-bottom\",\"padding-left\",\"padding-right\",\"padding-top\",\"page-break-after\",\"page-break-before\",\"page-break-inside\",\"perspective\",\"perspective-origin\",\"pointer-events\",\"position\",\"quotes\",\"resize\",\"right\",\"tab-size\",\"table-layout\",\"text-align\",\"text-align-last\",\"text-decoration\",\"text-decoration-color\",\"text-decoration-line\",\"text-decoration-style\",\"text-indent\",\"text-overflow\",\"text-rendering\",\"text-shadow\",\"text-transform\",\"text-underline-position\",\"top\",\"transform\",\"transform-origin\",\"transform-style\",\"transition\",\"transition-delay\",\"transition-duration\",\"transition-property\",\"transition-timing-function\",\"unicode-bidi\",\"vertical-align\",\"visibility\",\"white-space\",\"widows\",\"width\",\"word-break\",\"word-spacing\",\"word-wrap\",\"z-index\"].reverse().join(\"|\")+\")\\\\b\",starts:{end:/;|$/,contains:[n,t,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE,e.NUMBER_MODE,e.C_BLOCK_COMMENT_MODE],illegal:/\\./,relevance:0}}]}}},function(e,t){e.exports=function(e){return{aliases:[\"p21\",\"step\",\"stp\"],case_insensitive:!0,lexemes:\"[A-Z_][A-Z0-9_.]*\",keywords:{keyword:\"HEADER ENDSEC DATA\"},contains:[{className:\"meta\",begin:\"ISO-10303-21;\",relevance:10},{className:\"meta\",begin:\"END-ISO-10303-21;\",relevance:10},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.COMMENT(\"/\\\\*\\\\*!\",\"\\\\*/\"),e.C_NUMBER_MODE,e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),{className:\"string\",begin:\"'\",end:\"'\"},{className:\"symbol\",variants:[{begin:\"#\",end:\"\\\\d+\",illegal:\"\\\\W\"}]}]}}},function(e,t){e.exports=function(e){return{aliases:[\"do\",\"ado\"],case_insensitive:!0,keywords:\"if else in foreach for forv forva forval forvalu forvalue forvalues by bys bysort xi quietly qui capture about ac ac_7 acprplot acprplot_7 adjust ado adopath adoupdate alpha ameans an ano anov anova anova_estat anova_terms anovadef aorder ap app appe appen append arch arch_dr arch_estat arch_p archlm areg areg_p args arima arima_dr arima_estat arima_p as asmprobit asmprobit_estat asmprobit_lf asmprobit_mfx__dlg asmprobit_p ass asse asser assert avplot avplot_7 avplots avplots_7 bcskew0 bgodfrey binreg bip0_lf biplot bipp_lf bipr_lf bipr_p biprobit bitest bitesti bitowt blogit bmemsize boot bootsamp bootstrap bootstrap_8 boxco_l boxco_p boxcox boxcox_6 boxcox_p bprobit br break brier bro brow brows browse brr brrstat bs bs_7 bsampl_w bsample bsample_7 bsqreg bstat bstat_7 bstat_8 bstrap bstrap_7 ca ca_estat ca_p cabiplot camat canon canon_8 canon_8_p canon_estat canon_p cap caprojection capt captu captur capture cat cc cchart cchart_7 cci cd censobs_table centile cf char chdir checkdlgfiles checkestimationsample checkhlpfiles checksum chelp ci cii cl class classutil clear cli clis clist clo clog clog_lf clog_p clogi clogi_sw clogit clogit_lf clogit_p clogitp clogl_sw cloglog clonevar clslistarray cluster cluster_measures cluster_stop cluster_tree cluster_tree_8 clustermat cmdlog cnr cnre cnreg cnreg_p cnreg_sw cnsreg codebook collaps4 collapse colormult_nb colormult_nw compare compress conf confi confir confirm conren cons const constr constra constrai constrain constraint continue contract copy copyright copysource cor corc corr corr2data corr_anti corr_kmo corr_smc corre correl correla correlat correlate corrgram cou coun count cox cox_p cox_sw coxbase coxhaz coxvar cprplot cprplot_7 crc cret cretu cretur creturn cross cs cscript cscript_log csi ct ct_is ctset ctst_5 ctst_st cttost cumsp cumsp_7 cumul cusum cusum_7 cutil d|0 datasig datasign datasigna datasignat datasignatu datasignatur datasignature datetof db dbeta de dec deco decod decode deff des desc descr descri describ describe destring dfbeta dfgls dfuller di di_g dir dirstats dis discard disp disp_res disp_s displ displa display distinct do doe doed doedi doedit dotplot dotplot_7 dprobit drawnorm drop ds ds_util dstdize duplicates durbina dwstat dydx e|0 ed edi edit egen eivreg emdef en enc enco encod encode eq erase ereg ereg_lf ereg_p ereg_sw ereghet ereghet_glf ereghet_glf_sh ereghet_gp ereghet_ilf ereghet_ilf_sh ereghet_ip eret eretu eretur ereturn err erro error est est_cfexist est_cfname est_clickable est_expand est_hold est_table est_unhold est_unholdok estat estat_default estat_summ estat_vce_only esti estimates etodow etof etomdy ex exi exit expand expandcl fac fact facto factor factor_estat factor_p factor_pca_rotated factor_rotate factormat fcast fcast_compute fcast_graph fdades fdadesc fdadescr fdadescri fdadescrib fdadescribe fdasav fdasave fdause fh_st file open file read file close file filefilter fillin find_hlp_file findfile findit findit_7 fit fl fli flis flist for5_0 form forma format fpredict frac_154 frac_adj frac_chk frac_cox frac_ddp frac_dis frac_dv frac_in frac_mun frac_pp frac_pq frac_pv frac_wgt frac_xo fracgen fracplot fracplot_7 fracpoly fracpred fron_ex fron_hn fron_p fron_tn fron_tn2 frontier ftodate ftoe ftomdy ftowdate g|0 gamhet_glf gamhet_gp gamhet_ilf gamhet_ip gamma gamma_d2 gamma_p gamma_sw gammahet gdi_hexagon gdi_spokes ge gen gene gener genera generat generate genrank genstd genvmean gettoken gl gladder gladder_7 glim_l01 glim_l02 glim_l03 glim_l04 glim_l05 glim_l06 glim_l07 glim_l08 glim_l09 glim_l10 glim_l11 glim_l12 glim_lf glim_mu glim_nw1 glim_nw2 glim_nw3 glim_p glim_v1 glim_v2 glim_v3 glim_v4 glim_v5 glim_v6 glim_v7 glm glm_6 glm_p glm_sw glmpred glo glob globa global glogit glogit_8 glogit_p gmeans gnbre_lf gnbreg gnbreg_5 gnbreg_p gomp_lf gompe_sw gomper_p gompertz gompertzhet gomphet_glf gomphet_glf_sh gomphet_gp gomphet_ilf gomphet_ilf_sh gomphet_ip gphdot gphpen gphprint gprefs gprobi_p gprobit gprobit_8 gr gr7 gr_copy gr_current gr_db gr_describe gr_dir gr_draw gr_draw_replay gr_drop gr_edit gr_editviewopts gr_example gr_example2 gr_export gr_print gr_qscheme gr_query gr_read gr_rename gr_replay gr_save gr_set gr_setscheme gr_table gr_undo gr_use graph graph7 grebar greigen greigen_7 greigen_8 grmeanby grmeanby_7 gs_fileinfo gs_filetype gs_graphinfo gs_stat gsort gwood h|0 hadimvo hareg hausman haver he heck_d2 heckma_p heckman heckp_lf heckpr_p heckprob hel help hereg hetpr_lf hetpr_p hetprob hettest hexdump hilite hist hist_7 histogram hlogit hlu hmeans hotel hotelling hprobit hreg hsearch icd9 icd9_ff icd9p iis impute imtest inbase include inf infi infil infile infix inp inpu input ins insheet insp inspe inspec inspect integ inten intreg intreg_7 intreg_p intrg2_ll intrg_ll intrg_ll2 ipolate iqreg ir irf irf_create irfm iri is_svy is_svysum isid istdize ivprob_1_lf ivprob_lf ivprobit ivprobit_p ivreg ivreg_footnote ivtob_1_lf ivtob_lf ivtobit ivtobit_p jackknife jacknife jknife jknife_6 jknife_8 jkstat joinby kalarma1 kap kap_3 kapmeier kappa kapwgt kdensity kdensity_7 keep ksm ksmirnov ktau kwallis l|0 la lab labe label labelbook ladder levels levelsof leverage lfit lfit_p li lincom line linktest lis list lloghet_glf lloghet_glf_sh lloghet_gp lloghet_ilf lloghet_ilf_sh lloghet_ip llogi_sw llogis_p llogist llogistic llogistichet lnorm_lf lnorm_sw lnorma_p lnormal lnormalhet lnormhet_glf lnormhet_glf_sh lnormhet_gp lnormhet_ilf lnormhet_ilf_sh lnormhet_ip lnskew0 loadingplot loc loca local log logi logis_lf logistic logistic_p logit logit_estat logit_p loglogs logrank loneway lookfor lookup lowess lowess_7 lpredict lrecomp lroc lroc_7 lrtest ls lsens lsens_7 lsens_x lstat ltable ltable_7 ltriang lv lvr2plot lvr2plot_7 m|0 ma mac macr macro makecns man manova manova_estat manova_p manovatest mantel mark markin markout marksample mat mat_capp mat_order mat_put_rr mat_rapp mata mata_clear mata_describe mata_drop mata_matdescribe mata_matsave mata_matuse mata_memory mata_mlib mata_mosave mata_rename mata_which matalabel matcproc matlist matname matr matri matrix matrix_input__dlg matstrik mcc mcci md0_ md1_ md1debug_ md2_ md2debug_ mds mds_estat mds_p mdsconfig mdslong mdsmat mdsshepard mdytoe mdytof me_derd mean means median memory memsize meqparse mer merg merge mfp mfx mhelp mhodds minbound mixed_ll mixed_ll_reparm mkassert mkdir mkmat mkspline ml ml_5 ml_adjs ml_bhhhs ml_c_d ml_check ml_clear ml_cnt ml_debug ml_defd ml_e0 ml_e0_bfgs ml_e0_cycle ml_e0_dfp ml_e0i ml_e1 ml_e1_bfgs ml_e1_bhhh ml_e1_cycle ml_e1_dfp ml_e2 ml_e2_cycle ml_ebfg0 ml_ebfr0 ml_ebfr1 ml_ebh0q ml_ebhh0 ml_ebhr0 ml_ebr0i ml_ecr0i ml_edfp0 ml_edfr0 ml_edfr1 ml_edr0i ml_eds ml_eer0i ml_egr0i ml_elf ml_elf_bfgs ml_elf_bhhh ml_elf_cycle ml_elf_dfp ml_elfi ml_elfs ml_enr0i ml_enrr0 ml_erdu0 ml_erdu0_bfgs ml_erdu0_bhhh ml_erdu0_bhhhq ml_erdu0_cycle ml_erdu0_dfp ml_erdu0_nrbfgs ml_exde ml_footnote ml_geqnr ml_grad0 ml_graph ml_hbhhh ml_hd0 ml_hold ml_init ml_inv ml_log ml_max ml_mlout ml_mlout_8 ml_model ml_nb0 ml_opt ml_p ml_plot ml_query ml_rdgrd ml_repor ml_s_e ml_score ml_searc ml_technique ml_unhold mleval mlf_ mlmatbysum mlmatsum mlog mlogi mlogit mlogit_footnote mlogit_p mlopts mlsum mlvecsum mnl0_ mor more mov move mprobit mprobit_lf mprobit_p mrdu0_ mrdu1_ mvdecode mvencode mvreg mvreg_estat n|0 nbreg nbreg_al nbreg_lf nbreg_p nbreg_sw nestreg net newey newey_7 newey_p news nl nl_7 nl_9 nl_9_p nl_p nl_p_7 nlcom nlcom_p nlexp2 nlexp2_7 nlexp2a nlexp2a_7 nlexp3 nlexp3_7 nlgom3 nlgom3_7 nlgom4 nlgom4_7 nlinit nllog3 nllog3_7 nllog4 nllog4_7 nlog_rd nlogit nlogit_p nlogitgen nlogittree nlpred no nobreak noi nois noisi noisil noisily note notes notes_dlg nptrend numlabel numlist odbc old_ver olo olog ologi ologi_sw ologit ologit_p ologitp on one onew onewa oneway op_colnm op_comp op_diff op_inv op_str opr opro oprob oprob_sw oprobi oprobi_p oprobit oprobitp opts_exclusive order orthog orthpoly ou out outf outfi outfil outfile outs outsh outshe outshee outsheet ovtest pac pac_7 palette parse parse_dissim pause pca pca_8 pca_display pca_estat pca_p pca_rotate pcamat pchart pchart_7 pchi pchi_7 pcorr pctile pentium pergram pergram_7 permute permute_8 personal peto_st pkcollapse pkcross pkequiv pkexamine pkexamine_7 pkshape pksumm pksumm_7 pl plo plot plugin pnorm pnorm_7 poisgof poiss_lf poiss_sw poisso_p poisson poisson_estat post postclose postfile postutil pperron pr prais prais_e prais_e2 prais_p predict predictnl preserve print pro prob probi probit probit_estat probit_p proc_time procoverlay procrustes procrustes_estat procrustes_p profiler prog progr progra program prop proportion prtest prtesti pwcorr pwd q\\\\s qby qbys qchi qchi_7 qladder qladder_7 qnorm qnorm_7 qqplot qqplot_7 qreg qreg_c qreg_p qreg_sw qu quadchk quantile quantile_7 que quer query range ranksum ratio rchart rchart_7 rcof recast reclink recode reg reg3 reg3_p regdw regr regre regre_p2 regres regres_p regress regress_estat regriv_p remap ren rena renam rename renpfix repeat replace report reshape restore ret retu retur return rm rmdir robvar roccomp roccomp_7 roccomp_8 rocf_lf rocfit rocfit_8 rocgold rocplot rocplot_7 roctab roctab_7 rolling rologit rologit_p rot rota rotat rotate rotatemat rreg rreg_p ru run runtest rvfplot rvfplot_7 rvpplot rvpplot_7 sa safesum sample sampsi sav save savedresults saveold sc sca scal scala scalar scatter scm_mine sco scob_lf scob_p scobi_sw scobit scor score scoreplot scoreplot_help scree screeplot screeplot_help sdtest sdtesti se search separate seperate serrbar serrbar_7 serset set set_defaults sfrancia sh she shel shell shewhart shewhart_7 signestimationsample signrank signtest simul simul_7 simulate simulate_8 sktest sleep slogit slogit_d2 slogit_p smooth snapspan so sor sort spearman spikeplot spikeplot_7 spikeplt spline_x split sqreg sqreg_p sret sretu sretur sreturn ssc st st_ct st_hc st_hcd st_hcd_sh st_is st_issys st_note st_promo st_set st_show st_smpl st_subid stack statsby statsby_8 stbase stci stci_7 stcox stcox_estat stcox_fr stcox_fr_ll stcox_p stcox_sw stcoxkm stcoxkm_7 stcstat stcurv stcurve stcurve_7 stdes stem stepwise stereg stfill stgen stir stjoin stmc stmh stphplot stphplot_7 stphtest stphtest_7 stptime strate strate_7 streg streg_sw streset sts sts_7 stset stsplit stsum sttocc sttoct stvary stweib su suest suest_8 sum summ summa summar summari summariz summarize sunflower sureg survcurv survsum svar svar_p svmat svy svy_disp svy_dreg svy_est svy_est_7 svy_estat svy_get svy_gnbreg_p svy_head svy_header svy_heckman_p svy_heckprob_p svy_intreg_p svy_ivreg_p svy_logistic_p svy_logit_p svy_mlogit_p svy_nbreg_p svy_ologit_p svy_oprobit_p svy_poisson_p svy_probit_p svy_regress_p svy_sub svy_sub_7 svy_x svy_x_7 svy_x_p svydes svydes_8 svygen svygnbreg svyheckman svyheckprob svyintreg svyintreg_7 svyintrg svyivreg svylc svylog_p svylogit svymarkout svymarkout_8 svymean svymlog svymlogit svynbreg svyolog svyologit svyoprob svyoprobit svyopts svypois svypois_7 svypoisson svyprobit svyprobt svyprop svyprop_7 svyratio svyreg svyreg_p svyregress svyset svyset_7 svyset_8 svytab svytab_7 svytest svytotal sw sw_8 swcnreg swcox swereg swilk swlogis swlogit swologit swoprbt swpois swprobit swqreg swtobit swweib symmetry symmi symplot symplot_7 syntax sysdescribe sysdir sysuse szroeter ta tab tab1 tab2 tab_or tabd tabdi tabdis tabdisp tabi table tabodds tabodds_7 tabstat tabu tabul tabula tabulat tabulate te tempfile tempname tempvar tes test testnl testparm teststd tetrachoric time_it timer tis tob tobi tobit tobit_p tobit_sw token tokeni tokeniz tokenize tostring total translate translator transmap treat_ll treatr_p treatreg trim trnb_cons trnb_mean trpoiss_d2 trunc_ll truncr_p truncreg tsappend tset tsfill tsline tsline_ex tsreport tsrevar tsrline tsset tssmooth tsunab ttest ttesti tut_chk tut_wait tutorial tw tware_st two twoway twoway__fpfit_serset twoway__function_gen twoway__histogram_gen twoway__ipoint_serset twoway__ipoints_serset twoway__kdensity_gen twoway__lfit_serset twoway__normgen_gen twoway__pci_serset twoway__qfit_serset twoway__scatteri_serset twoway__sunflower_gen twoway_ksm_serset ty typ type typeof u|0 unab unabbrev unabcmd update us use uselabel var var_mkcompanion var_p varbasic varfcast vargranger varirf varirf_add varirf_cgraph varirf_create varirf_ctable varirf_describe varirf_dir varirf_drop varirf_erase varirf_graph varirf_ograph varirf_rename varirf_set varirf_table varlist varlmar varnorm varsoc varstable varstable_w varstable_w2 varwle vce vec vec_fevd vec_mkphi vec_p vec_p_w vecirf_create veclmar veclmar_w vecnorm vecnorm_w vecrank vecstable verinst vers versi versio version view viewsource vif vwls wdatetof webdescribe webseek webuse weib1_lf weib2_lf weib_lf weib_lf0 weibhet_glf weibhet_glf_sh weibhet_glfa weibhet_glfa_sh weibhet_gp weibhet_ilf weibhet_ilf_sh weibhet_ilfa weibhet_ilfa_sh weibhet_ip weibu_sw weibul_p weibull weibull_c weibull_s weibullhet wh whelp whi which whil while wilc_st wilcoxon win wind windo window winexec wntestb wntestb_7 wntestq xchart xchart_7 xcorr xcorr_7 xi xi_6 xmlsav xmlsave xmluse xpose xsh xshe xshel xshell xt_iis xt_tis xtab_p xtabond xtbin_p xtclog xtcloglog xtcloglog_8 xtcloglog_d2 xtcloglog_pa_p xtcloglog_re_p xtcnt_p xtcorr xtdata xtdes xtfront_p xtfrontier xtgee xtgee_elink xtgee_estat xtgee_makeivar xtgee_p xtgee_plink xtgls xtgls_p xthaus xthausman xtht_p xthtaylor xtile xtint_p xtintreg xtintreg_8 xtintreg_d2 xtintreg_p xtivp_1 xtivp_2 xtivreg xtline xtline_ex xtlogit xtlogit_8 xtlogit_d2 xtlogit_fe_p xtlogit_pa_p xtlogit_re_p xtmixed xtmixed_estat xtmixed_p xtnb_fe xtnb_lf xtnbreg xtnbreg_pa_p xtnbreg_refe_p xtpcse xtpcse_p xtpois xtpoisson xtpoisson_d2 xtpoisson_pa_p xtpoisson_refe_p xtpred xtprobit xtprobit_8 xtprobit_d2 xtprobit_re_p xtps_fe xtps_lf xtps_ren xtps_ren_8 xtrar_p xtrc xtrc_p xtrchh xtrefe_p xtreg xtreg_be xtreg_fe xtreg_ml xtreg_pa_p xtreg_re xtregar xtrere_p xtset xtsf_ll xtsf_llti xtsum xttab xttest0 xttobit xttobit_8 xttobit_p xttrans yx yxview__barlike_draw yxview_area_draw yxview_bar_draw yxview_dot_draw yxview_dropline_draw yxview_function_draw yxview_iarrow_draw yxview_ilabels_draw yxview_normal_draw yxview_pcarrow_draw yxview_pcbarrow_draw yxview_pccapsym_draw yxview_pcscatter_draw yxview_pcspike_draw yxview_rarea_draw yxview_rbar_draw yxview_rbarm_draw yxview_rcap_draw yxview_rcapsym_draw yxview_rconnected_draw yxview_rline_draw yxview_rscatter_draw yxview_rspike_draw yxview_spike_draw yxview_sunflower_draw zap_s zinb zinb_llf zinb_plf zip zip_llf zip_p zip_plf zt_ct_5 zt_hc_5 zt_hcd_5 zt_is_5 zt_iss_5 zt_sho_5 zt_smp_5 ztbase_5 ztcox_5 ztdes_5 ztereg_5 ztfill_5 ztgen_5 ztir_5 ztjoin_5 ztnb ztnb_p ztp ztp_p zts_5 ztset_5 ztspli_5 ztsum_5 zttoct_5 ztvary_5 ztweib_5\",contains:[{className:\"symbol\",begin:/`[a-zA-Z0-9_]+'/},{className:\"variable\",begin:/\\$\\{?[a-zA-Z0-9_]+\\}?/},{className:\"string\",variants:[{begin:'`\"[^\\r\\n]*?\"\\''},{begin:'\"[^\\r\\n\"]*\"'}]},{className:\"built_in\",variants:[{begin:\"\\\\b(abs|acos|asin|atan|atan2|atanh|ceil|cloglog|comb|cos|digamma|exp|floor|invcloglog|invlogit|ln|lnfact|lnfactorial|lngamma|log|log10|max|min|mod|reldif|round|sign|sin|sqrt|sum|tan|tanh|trigamma|trunc|betaden|Binomial|binorm|binormal|chi2|chi2tail|dgammapda|dgammapdada|dgammapdadx|dgammapdx|dgammapdxdx|F|Fden|Ftail|gammaden|gammap|ibeta|invbinomial|invchi2|invchi2tail|invF|invFtail|invgammap|invibeta|invnchi2|invnFtail|invnibeta|invnorm|invnormal|invttail|nbetaden|nchi2|nFden|nFtail|nibeta|norm|normal|normalden|normd|npnchi2|tden|ttail|uniform|abbrev|char|index|indexnot|length|lower|ltrim|match|plural|proper|real|regexm|regexr|regexs|reverse|rtrim|string|strlen|strlower|strltrim|strmatch|strofreal|strpos|strproper|strreverse|strrtrim|strtrim|strupper|subinstr|subinword|substr|trim|upper|word|wordcount|_caller|autocode|byteorder|chop|clip|cond|e|epsdouble|epsfloat|group|inlist|inrange|irecode|matrix|maxbyte|maxdouble|maxfloat|maxint|maxlong|mi|minbyte|mindouble|minfloat|minint|minlong|missing|r|recode|replay|return|s|scalar|d|date|day|dow|doy|halfyear|mdy|month|quarter|week|year|d|daily|dofd|dofh|dofm|dofq|dofw|dofy|h|halfyearly|hofd|m|mofd|monthly|q|qofd|quarterly|tin|twithin|w|weekly|wofd|y|yearly|yh|ym|yofd|yq|yw|cholesky|colnumb|colsof|corr|det|diag|diag0cnt|el|get|hadamard|I|inv|invsym|issym|issymmetric|J|matmissing|matuniform|mreldif|nullmat|rownumb|rowsof|sweep|syminv|trace|vec|vecdiag)(?=\\\\(|$)\"}]},e.COMMENT(\"^[ \\t]*\\\\*.*$\",!1),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}}},function(e,t){e.exports=function(e){return{contains:[e.HASH_COMMENT_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:e.UNDERSCORE_IDENT_RE,lexemes:e.UNDERSCORE_IDENT_RE,keywords:{name:\"for in while repeat until if then else\",symbol:\"bernoulli bernoulli_logit binomial binomial_logit beta_binomial hypergeometric categorical categorical_logit ordered_logistic neg_binomial neg_binomial_2 neg_binomial_2_log poisson poisson_log multinomial normal exp_mod_normal skew_normal student_t cauchy double_exponential logistic gumbel lognormal chi_square inv_chi_square scaled_inv_chi_square exponential inv_gamma weibull frechet rayleigh wiener pareto pareto_type_2 von_mises uniform multi_normal multi_normal_prec multi_normal_cholesky multi_gp multi_gp_cholesky multi_student_t gaussian_dlm_obs dirichlet lkj_corr lkj_corr_cholesky wishart inv_wishart\",\"selector-tag\":\"int real vector simplex unit_vector ordered positive_ordered row_vector matrix cholesky_factor_corr cholesky_factor_cov corr_matrix cov_matrix\",title:\"functions model data parameters quantities transformed generated\",literal:\"true false\"},relevance:0},{className:\"number\",begin:\"0[xX][0-9a-fA-F]+[Li]?\\\\b\",relevance:0},{className:\"number\",begin:\"0[xX][0-9a-fA-F]+[Li]?\\\\b\",relevance:0},{className:\"number\",begin:\"\\\\d+(?:[eE][+\\\\-]?\\\\d*)?L\\\\b\",relevance:0},{className:\"number\",begin:\"\\\\d+\\\\.(?!\\\\d)(?:i\\\\b)?\",relevance:0},{className:\"number\",begin:\"\\\\d+(?:\\\\.\\\\d*)?(?:[eE][+\\\\-]?\\\\d*)?i?\\\\b\",relevance:0},{className:\"number\",begin:\"\\\\.\\\\d+(?:[eE][+\\\\-]?\\\\d*)?i?\\\\b\",relevance:0}]}}},function(e,t){e.exports=function(e){var t=e.COMMENT(\"--\",\"$\");return{case_insensitive:!0,illegal:/[<>{}*#]/,contains:[{beginKeywords:\"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment\",end:/;/,endsWithParent:!0,lexemes:/[\\w\\.]+/,keywords:{keyword:\"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek\",literal:\"true false null\",built_in:\"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void\"},contains:[{className:\"string\",begin:\"'\",end:\"'\",contains:[e.BACKSLASH_ESCAPE,{begin:\"''\"}]},{className:\"string\",begin:'\"',end:'\"',contains:[e.BACKSLASH_ESCAPE,{begin:'\"\"'}]},{className:\"string\",begin:\"`\",end:\"`\",contains:[e.BACKSLASH_ESCAPE]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t]},e.C_BLOCK_COMMENT_MODE,t]}}},function(e,t){e.exports=function(e){var t=e.getLanguage(\"cpp\").exports;return{aliases:[\"sqf\"],case_insensitive:!0,keywords:{keyword:\"case catch default do else exit exitWith for forEach from if switch then throw to try waitUntil while with\",built_in:\"abs accTime acos action actionIDs actionKeys actionKeysImages actionKeysNames actionKeysNamesArray actionName actionParams activateAddons activatedAddons activateKey add3DENConnection add3DENEventHandler add3DENLayer addAction addBackpack addBackpackCargo addBackpackCargoGlobal addBackpackGlobal addCamShake addCuratorAddons addCuratorCameraArea addCuratorEditableObjects addCuratorEditingArea addCuratorPoints addEditorObject addEventHandler addGoggles addGroupIcon addHandgunItem addHeadgear addItem addItemCargo addItemCargoGlobal addItemPool addItemToBackpack addItemToUniform addItemToVest addLiveStats addMagazine addMagazineAmmoCargo addMagazineCargo addMagazineCargoGlobal addMagazineGlobal addMagazinePool addMagazines addMagazineTurret addMenu addMenuItem addMissionEventHandler addMPEventHandler addMusicEventHandler addOwnedMine addPlayerScores addPrimaryWeaponItem addPublicVariableEventHandler addRating addResources addScore addScoreSide addSecondaryWeaponItem addSwitchableUnit addTeamMember addToRemainsCollector addUniform addVehicle addVest addWaypoint addWeapon addWeaponCargo addWeaponCargoGlobal addWeaponGlobal addWeaponItem addWeaponPool addWeaponTurret agent agents AGLToASL aimedAtTarget aimPos airDensityRTD airportSide AISFinishHeal alive all3DENEntities allControls allCurators allCutLayers allDead allDeadMen allDisplays allGroups allMapMarkers allMines allMissionObjects allow3DMode allowCrewInImmobile allowCuratorLogicIgnoreAreas allowDamage allowDammage allowFileOperations allowFleeing allowGetIn allowSprint allPlayers allSites allTurrets allUnits allUnitsUAV allVariables ammo and animate animateDoor animateSource animationNames animationPhase animationSourcePhase animationState append apply armoryPoints arrayIntersect asin ASLToAGL ASLToATL assert assignAsCargo assignAsCargoIndex assignAsCommander assignAsDriver assignAsGunner assignAsTurret assignCurator assignedCargo assignedCommander assignedDriver assignedGunner assignedItems assignedTarget assignedTeam assignedVehicle assignedVehicleRole assignItem assignTeam assignToAirport atan atan2 atg ATLToASL attachedObject attachedObjects attachedTo attachObject attachTo attackEnabled backpack backpackCargo backpackContainer backpackItems backpackMagazines backpackSpaceFor behaviour benchmark binocular blufor boundingBox boundingBoxReal boundingCenter breakOut breakTo briefingName buildingExit buildingPos buttonAction buttonSetAction cadetMode call callExtension camCommand camCommit camCommitPrepared camCommitted camConstuctionSetParams camCreate camDestroy cameraEffect cameraEffectEnableHUD cameraInterest cameraOn cameraView campaignConfigFile camPreload camPreloaded camPrepareBank camPrepareDir camPrepareDive camPrepareFocus camPrepareFov camPrepareFovRange camPreparePos camPrepareRelPos camPrepareTarget camSetBank camSetDir camSetDive camSetFocus camSetFov camSetFovRange camSetPos camSetRelPos camSetTarget camTarget camUseNVG canAdd canAddItemToBackpack canAddItemToUniform canAddItemToVest cancelSimpleTaskDestination canFire canMove canSlingLoad canStand canSuspend canUnloadInCombat canVehicleCargo captive captiveNum cbChecked cbSetChecked ceil channelEnabled cheatsEnabled checkAIFeature checkVisibility civilian className clearAllItemsFromBackpack clearBackpackCargo clearBackpackCargoGlobal clearGroupIcons clearItemCargo clearItemCargoGlobal clearItemPool clearMagazineCargo clearMagazineCargoGlobal clearMagazinePool clearOverlay clearRadio clearWeaponCargo clearWeaponCargoGlobal clearWeaponPool clientOwner closeDialog closeDisplay closeOverlay collapseObjectTree collect3DENHistory combatMode commandArtilleryFire commandChat commander commandFire commandFollow commandFSM commandGetOut commandingMenu commandMove commandRadio commandStop commandSuppressiveFire commandTarget commandWatch comment commitOverlay compile compileFinal completedFSM composeText configClasses configFile configHierarchy configName configNull configProperties configSourceAddonList configSourceMod configSourceModList connectTerminalToUAV controlNull controlsGroupCtrl copyFromClipboard copyToClipboard copyWaypoints cos count countEnemy countFriendly countSide countType countUnknown create3DENComposition create3DENEntity createAgent createCenter createDialog createDiaryLink createDiaryRecord createDiarySubject createDisplay createGearDialog createGroup createGuardedPoint createLocation createMarker createMarkerLocal createMenu createMine createMissionDisplay createMPCampaignDisplay createSimpleObject createSimpleTask createSite createSoundSource createTask createTeam createTrigger createUnit createVehicle createVehicleCrew createVehicleLocal crew ctrlActivate ctrlAddEventHandler ctrlAngle ctrlAutoScrollDelay ctrlAutoScrollRewind ctrlAutoScrollSpeed ctrlChecked ctrlClassName ctrlCommit ctrlCommitted ctrlCreate ctrlDelete ctrlEnable ctrlEnabled ctrlFade ctrlHTMLLoaded ctrlIDC ctrlIDD ctrlMapAnimAdd ctrlMapAnimClear ctrlMapAnimCommit ctrlMapAnimDone ctrlMapCursor ctrlMapMouseOver ctrlMapScale ctrlMapScreenToWorld ctrlMapWorldToScreen ctrlModel ctrlModelDirAndUp ctrlModelScale ctrlParent ctrlParentControlsGroup ctrlPosition ctrlRemoveAllEventHandlers ctrlRemoveEventHandler ctrlScale ctrlSetActiveColor ctrlSetAngle ctrlSetAutoScrollDelay ctrlSetAutoScrollRewind ctrlSetAutoScrollSpeed ctrlSetBackgroundColor ctrlSetChecked ctrlSetEventHandler ctrlSetFade ctrlSetFocus ctrlSetFont ctrlSetFontH1 ctrlSetFontH1B ctrlSetFontH2 ctrlSetFontH2B ctrlSetFontH3 ctrlSetFontH3B ctrlSetFontH4 ctrlSetFontH4B ctrlSetFontH5 ctrlSetFontH5B ctrlSetFontH6 ctrlSetFontH6B ctrlSetFontHeight ctrlSetFontHeightH1 ctrlSetFontHeightH2 ctrlSetFontHeightH3 ctrlSetFontHeightH4 ctrlSetFontHeightH5 ctrlSetFontHeightH6 ctrlSetFontHeightSecondary ctrlSetFontP ctrlSetFontPB ctrlSetFontSecondary ctrlSetForegroundColor ctrlSetModel ctrlSetModelDirAndUp ctrlSetModelScale ctrlSetPosition ctrlSetScale ctrlSetStructuredText ctrlSetText ctrlSetTextColor ctrlSetTooltip ctrlSetTooltipColorBox ctrlSetTooltipColorShade ctrlSetTooltipColorText ctrlShow ctrlShown ctrlText ctrlTextHeight ctrlType ctrlVisible curatorAddons curatorCamera curatorCameraArea curatorCameraAreaCeiling curatorCoef curatorEditableObjects curatorEditingArea curatorEditingAreaType curatorMouseOver curatorPoints curatorRegisteredObjects curatorSelected curatorWaypointCost current3DENOperation currentChannel currentCommand currentMagazine currentMagazineDetail currentMagazineDetailTurret currentMagazineTurret currentMuzzle currentNamespace currentTask currentTasks currentThrowable currentVisionMode currentWaypoint currentWeapon currentWeaponMode currentWeaponTurret currentZeroing cursorObject cursorTarget customChat customRadio cutFadeOut cutObj cutRsc cutText damage date dateToNumber daytime deActivateKey debriefingText debugFSM debugLog deg delete3DENEntities deleteAt deleteCenter deleteCollection deleteEditorObject deleteGroup deleteIdentity deleteLocation deleteMarker deleteMarkerLocal deleteRange deleteResources deleteSite deleteStatus deleteTeam deleteVehicle deleteVehicleCrew deleteWaypoint detach detectedMines diag_activeMissionFSMs diag_activeScripts diag_activeSQFScripts diag_activeSQSScripts diag_captureFrame diag_captureSlowFrame diag_codePerformance diag_drawMode diag_enable diag_enabled diag_fps diag_fpsMin diag_frameNo diag_list diag_log diag_logSlowFrame diag_mergeConfigFile diag_recordTurretLimits diag_tickTime diag_toggle dialog diarySubjectExists didJIP didJIPOwner difficulty difficultyEnabled difficultyEnabledRTD difficultyOption direction directSay disableAI disableCollisionWith disableConversation disableDebriefingStats disableNVGEquipment disableRemoteSensors disableSerialization disableTIEquipment disableUAVConnectability disableUserInput displayAddEventHandler displayCtrl displayNull displayParent displayRemoveAllEventHandlers displayRemoveEventHandler displaySetEventHandler dissolveTeam distance distance2D distanceSqr distributionRegion do3DENAction doArtilleryFire doFire doFollow doFSM doGetOut doMove doorPhase doStop doSuppressiveFire doTarget doWatch drawArrow drawEllipse drawIcon drawIcon3D drawLine drawLine3D drawLink drawLocation drawPolygon drawRectangle driver drop east echo edit3DENMissionAttributes editObject editorSetEventHandler effectiveCommander emptyPositions enableAI enableAIFeature enableAimPrecision enableAttack enableAudioFeature enableCamShake enableCaustics enableChannel enableCollisionWith enableCopilot enableDebriefingStats enableDiagLegend enableEndDialog enableEngineArtillery enableEnvironment enableFatigue enableGunLights enableIRLasers enableMimics enablePersonTurret enableRadio enableReload enableRopeAttach enableSatNormalOnDetail enableSaving enableSentences enableSimulation enableSimulationGlobal enableStamina enableTeamSwitch enableUAVConnectability enableUAVWaypoints enableVehicleCargo endLoadingScreen endMission engineOn enginesIsOnRTD enginesRpmRTD enginesTorqueRTD entities estimatedEndServerTime estimatedTimeLeft evalObjectArgument everyBackpack everyContainer exec execEditorScript execFSM execVM exp expectedDestination exportJIPMessages eyeDirection eyePos face faction fadeMusic fadeRadio fadeSound fadeSpeech failMission fillWeaponsFromPool find findCover findDisplay findEditorObject findEmptyPosition findEmptyPositionReady findNearestEnemy finishMissionInit finite fire fireAtTarget firstBackpack flag flagOwner flagSide flagTexture fleeing floor flyInHeight flyInHeightASL fog fogForecast fogParams forceAddUniform forcedMap forceEnd forceMap forceRespawn forceSpeed forceWalk forceWeaponFire forceWeatherChange forEachMember forEachMemberAgent forEachMemberTeam format formation formationDirection formationLeader formationMembers formationPosition formationTask formatText formLeader freeLook fromEditor fuel fullCrew gearIDCAmmoCount gearSlotAmmoCount gearSlotData get3DENActionState get3DENAttribute get3DENCamera get3DENConnections get3DENEntity get3DENEntityID get3DENGrid get3DENIconsVisible get3DENLayerEntities get3DENLinesVisible get3DENMissionAttribute get3DENMouseOver get3DENSelected getAimingCoef getAllHitPointsDamage getAllOwnedMines getAmmoCargo getAnimAimPrecision getAnimSpeedCoef getArray getArtilleryAmmo getArtilleryComputerSettings getArtilleryETA getAssignedCuratorLogic getAssignedCuratorUnit getBackpackCargo getBleedingRemaining getBurningValue getCameraViewDirection getCargoIndex getCenterOfMass getClientState getClientStateNumber getConnectedUAV getCustomAimingCoef getDammage getDescription getDir getDirVisual getDLCs getEditorCamera getEditorMode getEditorObjectScope getElevationOffset getFatigue getFriend getFSMVariable getFuelCargo getGroupIcon getGroupIconParams getGroupIcons getHideFrom getHit getHitIndex getHitPointDamage getItemCargo getMagazineCargo getMarkerColor getMarkerPos getMarkerSize getMarkerType getMass getMissionConfig getMissionConfigValue getMissionDLCs getMissionLayerEntities getModelInfo getMousePosition getNumber getObjectArgument getObjectChildren getObjectDLC getObjectMaterials getObjectProxy getObjectTextures getObjectType getObjectViewDistance getOxygenRemaining getPersonUsedDLCs getPilotCameraDirection getPilotCameraPosition getPilotCameraRotation getPilotCameraTarget getPlayerChannel getPlayerScores getPlayerUID getPos getPosASL getPosASLVisual getPosASLW getPosATL getPosATLVisual getPosVisual getPosWorld getRelDir getRelPos getRemoteSensorsDisabled getRepairCargo getResolution getShadowDistance getShotParents getSlingLoad getSpeed getStamina getStatValue getSuppression getTerrainHeightASL getText getUnitLoadout getUnitTrait getVariable getVehicleCargo getWeaponCargo getWeaponSway getWPPos glanceAt globalChat globalRadio goggles goto group groupChat groupFromNetId groupIconSelectable groupIconsVisible groupId groupOwner groupRadio groupSelectedUnits groupSelectUnit grpNull gunner gusts halt handgunItems handgunMagazine handgunWeapon handsHit hasInterface hasPilotCamera hasWeapon hcAllGroups hcGroupParams hcLeader hcRemoveAllGroups hcRemoveGroup hcSelected hcSelectGroup hcSetGroup hcShowBar hcShownBar headgear hideBody hideObject hideObjectGlobal hideSelection hint hintC hintCadet hintSilent hmd hostMission htmlLoad HUDMovementLevels humidity image importAllGroups importance in inArea inAreaArray incapacitatedState independent inflame inflamed inGameUISetEventHandler inheritsFrom initAmbientLife inPolygon inputAction inRangeOfArtillery insertEditorObject intersect is3DEN is3DENMultiplayer isAbleToBreathe isAgent isArray isAutoHoverOn isAutonomous isAutotest isBleeding isBurning isClass isCollisionLightOn isCopilotEnabled isDedicated isDLCAvailable isEngineOn isEqualTo isEqualType isEqualTypeAll isEqualTypeAny isEqualTypeArray isEqualTypeParams isFilePatchingEnabled isFlashlightOn isFlatEmpty isForcedWalk isFormationLeader isHidden isInRemainsCollector isInstructorFigureEnabled isIRLaserOn isKeyActive isKindOf isLightOn isLocalized isManualFire isMarkedForCollection isMultiplayer isMultiplayerSolo isNil isNull isNumber isObjectHidden isObjectRTD isOnRoad isPipEnabled isPlayer isRealTime isRemoteExecuted isRemoteExecutedJIP isServer isShowing3DIcons isSprintAllowed isStaminaEnabled isSteamMission isStreamFriendlyUIEnabled isText isTouchingGround isTurnedOut isTutHintsEnabled isUAVConnectable isUAVConnected isUniformAllowed isVehicleCargo isWalking isWeaponDeployed isWeaponRested itemCargo items itemsWithMagazines join joinAs joinAsSilent joinSilent joinString kbAddDatabase kbAddDatabaseTargets kbAddTopic kbHasTopic kbReact kbRemoveTopic kbTell kbWasSaid keyImage keyName knowsAbout land landAt landResult language laserTarget lbAdd lbClear lbColor lbCurSel lbData lbDelete lbIsSelected lbPicture lbSelection lbSetColor lbSetCurSel lbSetData lbSetPicture lbSetPictureColor lbSetPictureColorDisabled lbSetPictureColorSelected lbSetSelectColor lbSetSelectColorRight lbSetSelected lbSetTooltip lbSetValue lbSize lbSort lbSortByValue lbText lbValue leader leaderboardDeInit leaderboardGetRows leaderboardInit leaveVehicle libraryCredits libraryDisclaimers lifeState lightAttachObject lightDetachObject lightIsOn lightnings limitSpeed linearConversion lineBreak lineIntersects lineIntersectsObjs lineIntersectsSurfaces lineIntersectsWith linkItem list listObjects ln lnbAddArray lnbAddColumn lnbAddRow lnbClear lnbColor lnbCurSelRow lnbData lnbDeleteColumn lnbDeleteRow lnbGetColumnsPosition lnbPicture lnbSetColor lnbSetColumnsPos lnbSetCurSelRow lnbSetData lnbSetPicture lnbSetText lnbSetValue lnbSize lnbText lnbValue load loadAbs loadBackpack loadFile loadGame loadIdentity loadMagazine loadOverlay loadStatus loadUniform loadVest local localize locationNull locationPosition lock lockCameraTo lockCargo lockDriver locked lockedCargo lockedDriver lockedTurret lockIdentity lockTurret lockWP log logEntities logNetwork logNetworkTerminate lookAt lookAtPos magazineCargo magazines magazinesAllTurrets magazinesAmmo magazinesAmmoCargo magazinesAmmoFull magazinesDetail magazinesDetailBackpack magazinesDetailUniform magazinesDetailVest magazinesTurret magazineTurretAmmo mapAnimAdd mapAnimClear mapAnimCommit mapAnimDone mapCenterOnCamera mapGridPosition markAsFinishedOnSteam markerAlpha markerBrush markerColor markerDir markerPos markerShape markerSize markerText markerType max members menuAction menuAdd menuChecked menuClear menuCollapse menuData menuDelete menuEnable menuEnabled menuExpand menuHover menuPicture menuSetAction menuSetCheck menuSetData menuSetPicture menuSetValue menuShortcut menuShortcutText menuSize menuSort menuText menuURL menuValue min mineActive mineDetectedBy missionConfigFile missionDifficulty missionName missionNamespace missionStart missionVersion mod modelToWorld modelToWorldVisual modParams moonIntensity moonPhase morale move move3DENCamera moveInAny moveInCargo moveInCommander moveInDriver moveInGunner moveInTurret moveObjectToEnd moveOut moveTime moveTo moveToCompleted moveToFailed musicVolume name nameSound nearEntities nearestBuilding nearestLocation nearestLocations nearestLocationWithDubbing nearestObject nearestObjects nearestTerrainObjects nearObjects nearObjectsReady nearRoads nearSupplies nearTargets needReload netId netObjNull newOverlay nextMenuItemIndex nextWeatherChange nMenuItems not numberToDate objectCurators objectFromNetId objectParent objNull objStatus onBriefingGroup onBriefingNotes onBriefingPlan onBriefingTeamSwitch onCommandModeChanged onDoubleClick onEachFrame onGroupIconClick onGroupIconOverEnter onGroupIconOverLeave onHCGroupSelectionChanged onMapSingleClick onPlayerConnected onPlayerDisconnected onPreloadFinished onPreloadStarted onShowNewObject onTeamSwitch openCuratorInterface openDLCPage openMap openYoutubeVideo opfor or orderGetIn overcast overcastForecast owner param params parseNumber parseText parsingNamespace particlesQuality pi pickWeaponPool pitch pixelGrid pixelGridBase pixelGridNoUIScale pixelH pixelW playableSlotsNumber playableUnits playAction playActionNow player playerRespawnTime playerSide playersNumber playGesture playMission playMove playMoveNow playMusic playScriptedMission playSound playSound3D position positionCameraToWorld posScreenToWorld posWorldToScreen ppEffectAdjust ppEffectCommit ppEffectCommitted ppEffectCreate ppEffectDestroy ppEffectEnable ppEffectEnabled ppEffectForceInNVG precision preloadCamera preloadObject preloadSound preloadTitleObj preloadTitleRsc preprocessFile preprocessFileLineNumbers primaryWeapon primaryWeaponItems primaryWeaponMagazine priority private processDiaryLink productVersion profileName profileNamespace profileNameSteam progressLoadingScreen progressPosition progressSetPosition publicVariable publicVariableClient publicVariableServer pushBack pushBackUnique putWeaponPool queryItemsPool queryMagazinePool queryWeaponPool rad radioChannelAdd radioChannelCreate radioChannelRemove radioChannelSetCallSign radioChannelSetLabel radioVolume rain rainbow random rank rankId rating rectangular registeredTasks registerTask reload reloadEnabled remoteControl remoteExec remoteExecCall remove3DENConnection remove3DENEventHandler remove3DENLayer removeAction removeAll3DENEventHandlers removeAllActions removeAllAssignedItems removeAllContainers removeAllCuratorAddons removeAllCuratorCameraAreas removeAllCuratorEditingAreas removeAllEventHandlers removeAllHandgunItems removeAllItems removeAllItemsWithMagazines removeAllMissionEventHandlers removeAllMPEventHandlers removeAllMusicEventHandlers removeAllOwnedMines removeAllPrimaryWeaponItems removeAllWeapons removeBackpack removeBackpackGlobal removeCuratorAddons removeCuratorCameraArea removeCuratorEditableObjects removeCuratorEditingArea removeDrawIcon removeDrawLinks removeEventHandler removeFromRemainsCollector removeGoggles removeGroupIcon removeHandgunItem removeHeadgear removeItem removeItemFromBackpack removeItemFromUniform removeItemFromVest removeItems removeMagazine removeMagazineGlobal removeMagazines removeMagazinesTurret removeMagazineTurret removeMenuItem removeMissionEventHandler removeMPEventHandler removeMusicEventHandler removeOwnedMine removePrimaryWeaponItem removeSecondaryWeaponItem removeSimpleTask removeSwitchableUnit removeTeamMember removeUniform removeVest removeWeapon removeWeaponGlobal removeWeaponTurret requiredVersion resetCamShake resetSubgroupDirection resistance resize resources respawnVehicle restartEditorCamera reveal revealMine reverse reversedMouseY roadAt roadsConnectedTo roleDescription ropeAttachedObjects ropeAttachedTo ropeAttachEnabled ropeAttachTo ropeCreate ropeCut ropeDestroy ropeDetach ropeEndPosition ropeLength ropes ropeUnwind ropeUnwound rotorsForcesRTD rotorsRpmRTD round runInitScript safeZoneH safeZoneW safeZoneWAbs safeZoneX safeZoneXAbs safeZoneY save3DENInventory saveGame saveIdentity saveJoysticks saveOverlay saveProfileNamespace saveStatus saveVar savingEnabled say say2D say3D scopeName score scoreSide screenshot screenToWorld scriptDone scriptName scriptNull scudState secondaryWeapon secondaryWeaponItems secondaryWeaponMagazine select selectBestPlaces selectDiarySubject selectedEditorObjects selectEditorObject selectionNames selectionPosition selectLeader selectMax selectMin selectNoPlayer selectPlayer selectRandom selectWeapon selectWeaponTurret sendAUMessage sendSimpleCommand sendTask sendTaskResult sendUDPMessage serverCommand serverCommandAvailable serverCommandExecutable serverName serverTime set set3DENAttribute set3DENAttributes set3DENGrid set3DENIconsVisible set3DENLayer set3DENLinesVisible set3DENMissionAttributes set3DENModelsVisible set3DENObjectType set3DENSelected setAccTime setAirportSide setAmmo setAmmoCargo setAnimSpeedCoef setAperture setApertureNew setArmoryPoints setAttributes setAutonomous setBehaviour setBleedingRemaining setCameraInterest setCamShakeDefParams setCamShakeParams setCamUseTi setCaptive setCenterOfMass setCollisionLight setCombatMode setCompassOscillation setCuratorCameraAreaCeiling setCuratorCoef setCuratorEditingAreaType setCuratorWaypointCost setCurrentChannel setCurrentTask setCurrentWaypoint setCustomAimCoef setDamage setDammage setDate setDebriefingText setDefaultCamera setDestination setDetailMapBlendPars setDir setDirection setDrawIcon setDropInterval setEditorMode setEditorObjectScope setEffectCondition setFace setFaceAnimation setFatigue setFlagOwner setFlagSide setFlagTexture setFog setFormation setFormationTask setFormDir setFriend setFromEditor setFSMVariable setFuel setFuelCargo setGroupIcon setGroupIconParams setGroupIconsSelectable setGroupIconsVisible setGroupId setGroupIdGlobal setGroupOwner setGusts setHideBehind setHit setHitIndex setHitPointDamage setHorizonParallaxCoef setHUDMovementLevels setIdentity setImportance setLeader setLightAmbient setLightAttenuation setLightBrightness setLightColor setLightDayLight setLightFlareMaxDistance setLightFlareSize setLightIntensity setLightnings setLightUseFlare setLocalWindParams setMagazineTurretAmmo setMarkerAlpha setMarkerAlphaLocal setMarkerBrush setMarkerBrushLocal setMarkerColor setMarkerColorLocal setMarkerDir setMarkerDirLocal setMarkerPos setMarkerPosLocal setMarkerShape setMarkerShapeLocal setMarkerSize setMarkerSizeLocal setMarkerText setMarkerTextLocal setMarkerType setMarkerTypeLocal setMass setMimic setMousePosition setMusicEffect setMusicEventHandler setName setNameSound setObjectArguments setObjectMaterial setObjectMaterialGlobal setObjectProxy setObjectTexture setObjectTextureGlobal setObjectViewDistance setOvercast setOwner setOxygenRemaining setParticleCircle setParticleClass setParticleFire setParticleParams setParticleRandom setPilotCameraDirection setPilotCameraRotation setPilotCameraTarget setPilotLight setPiPEffect setPitch setPlayable setPlayerRespawnTime setPos setPosASL setPosASL2 setPosASLW setPosATL setPosition setPosWorld setRadioMsg setRain setRainbow setRandomLip setRank setRectangular setRepairCargo setShadowDistance setShotParents setSide setSimpleTaskAlwaysVisible setSimpleTaskCustomData setSimpleTaskDescription setSimpleTaskDestination setSimpleTaskTarget setSimpleTaskType setSimulWeatherLayers setSize setSkill setSlingLoad setSoundEffect setSpeaker setSpeech setSpeedMode setStamina setStaminaScheme setStatValue setSuppression setSystemOfUnits setTargetAge setTaskResult setTaskState setTerrainGrid setText setTimeMultiplier setTitleEffect setTriggerActivation setTriggerArea setTriggerStatements setTriggerText setTriggerTimeout setTriggerType setType setUnconscious setUnitAbility setUnitLoadout setUnitPos setUnitPosWeak setUnitRank setUnitRecoilCoefficient setUnitTrait setUnloadInCombat setUserActionText setVariable setVectorDir setVectorDirAndUp setVectorUp setVehicleAmmo setVehicleAmmoDef setVehicleArmor setVehicleCargo setVehicleId setVehicleLock setVehiclePosition setVehicleTiPars setVehicleVarName setVelocity setVelocityTransformation setViewDistance setVisibleIfTreeCollapsed setWaves setWaypointBehaviour setWaypointCombatMode setWaypointCompletionRadius setWaypointDescription setWaypointForceBehaviour setWaypointFormation setWaypointHousePosition setWaypointLoiterRadius setWaypointLoiterType setWaypointName setWaypointPosition setWaypointScript setWaypointSpeed setWaypointStatements setWaypointTimeout setWaypointType setWaypointVisible setWeaponReloadingTime setWind setWindDir setWindForce setWindStr setWPPos show3DIcons showChat showCinemaBorder showCommandingMenu showCompass showCuratorCompass showGPS showHUD showLegend showMap shownArtilleryComputer shownChat shownCompass shownCuratorCompass showNewEditorObject shownGPS shownHUD shownMap shownPad shownRadio shownScoretable shownUAVFeed shownWarrant shownWatch showPad showRadio showScoretable showSubtitles showUAVFeed showWarrant showWatch showWaypoint showWaypoints side sideAmbientLife sideChat sideEmpty sideEnemy sideFriendly sideLogic sideRadio sideUnknown simpleTasks simulationEnabled simulCloudDensity simulCloudOcclusion simulInClouds simulWeatherSync sin size sizeOf skill skillFinal skipTime sleep sliderPosition sliderRange sliderSetPosition sliderSetRange sliderSetSpeed sliderSpeed slingLoadAssistantShown soldierMagazines someAmmo sort soundVolume spawn speaker speed speedMode splitString sqrt squadParams stance startLoadingScreen step stop stopEngineRTD stopped str sunOrMoon supportInfo suppressFor surfaceIsWater surfaceNormal surfaceType swimInDepth switchableUnits switchAction switchCamera switchGesture switchLight switchMove synchronizedObjects synchronizedTriggers synchronizedWaypoints synchronizeObjectsAdd synchronizeObjectsRemove synchronizeTrigger synchronizeWaypoint systemChat systemOfUnits tan targetKnowledge targetsAggregate targetsQuery taskAlwaysVisible taskChildren taskCompleted taskCustomData taskDescription taskDestination taskHint taskMarkerOffset taskNull taskParent taskResult taskState taskType teamMember teamMemberNull teamName teams teamSwitch teamSwitchEnabled teamType terminate terrainIntersect terrainIntersectASL text textLog textLogFormat tg time timeMultiplier titleCut titleFadeOut titleObj titleRsc titleText toArray toFixed toLower toString toUpper triggerActivated triggerActivation triggerArea triggerAttachedVehicle triggerAttachObject triggerAttachVehicle triggerStatements triggerText triggerTimeout triggerTimeoutCurrent triggerType turretLocal turretOwner turretUnit tvAdd tvClear tvCollapse tvCount tvCurSel tvData tvDelete tvExpand tvPicture tvSetCurSel tvSetData tvSetPicture tvSetPictureColor tvSetPictureColorDisabled tvSetPictureColorSelected tvSetPictureRight tvSetPictureRightColor tvSetPictureRightColorDisabled tvSetPictureRightColorSelected tvSetText tvSetTooltip tvSetValue tvSort tvSortByValue tvText tvTooltip tvValue type typeName typeOf UAVControl uiNamespace uiSleep unassignCurator unassignItem unassignTeam unassignVehicle underwater uniform uniformContainer uniformItems uniformMagazines unitAddons unitAimPosition unitAimPositionVisual unitBackpack unitIsUAV unitPos unitReady unitRecoilCoefficient units unitsBelowHeight unlinkItem unlockAchievement unregisterTask updateDrawIcon updateMenuItem updateObjectTree useAISteeringComponent useAudioTimeForMoves vectorAdd vectorCos vectorCrossProduct vectorDiff vectorDir vectorDirVisual vectorDistance vectorDistanceSqr vectorDotProduct vectorFromTo vectorMagnitude vectorMagnitudeSqr vectorMultiply vectorNormalized vectorUp vectorUpVisual vehicle vehicleCargoEnabled vehicleChat vehicleRadio vehicles vehicleVarName velocity velocityModelSpace verifySignature vest vestContainer vestItems vestMagazines viewDistance visibleCompass visibleGPS visibleMap visiblePosition visiblePositionASL visibleScoretable visibleWatch waves waypointAttachedObject waypointAttachedVehicle waypointAttachObject waypointAttachVehicle waypointBehaviour waypointCombatMode waypointCompletionRadius waypointDescription waypointForceBehaviour waypointFormation waypointHousePosition waypointLoiterRadius waypointLoiterType waypointName waypointPosition waypoints waypointScript waypointsEnabledUAV waypointShow waypointSpeed waypointStatements waypointTimeout waypointTimeoutCurrent waypointType waypointVisible weaponAccessories weaponAccessoriesCargo weaponCargo weaponDirection weaponInertia weaponLowered weapons weaponsItems weaponsItemsCargo weaponState weaponsTurret weightRTD west WFSideText wind\",literal:\"true false nil\"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.NUMBER_MODE,{className:\"variable\",begin:/\\b_+[a-zA-Z_]\\w*/},{className:\"title\",begin:/[a-zA-Z][a-zA-Z0-9]+_fnc_\\w*/},{className:\"string\",variants:[{begin:'\"',end:'\"',contains:[{begin:'\"\"',relevance:0}]},{begin:\"'\",end:\"'\",contains:[{begin:\"''\",relevance:0}]}]},t.preprocessor],illegal:/#/}}},function(e,t){e.exports=function(e){return{aliases:[\"ml\"],keywords:{keyword:\"abstype and andalso as case datatype do else end eqtype exception fn fun functor handle if in include infix infixr let local nonfix of op open orelse raise rec sharing sig signature struct structure then type val with withtype where while\",built_in:\"array bool char exn int list option order real ref string substring vector unit word\",literal:\"true false NONE SOME LESS EQUAL GREATER nil\"},illegal:/\\/\\/|>>/,lexemes:\"[a-z_]\\\\w*!?\",contains:[{className:\"literal\",begin:/\\[(\\|\\|)?\\]|\\(\\)/,relevance:0},e.COMMENT(\"\\\\(\\\\*\",\"\\\\*\\\\)\",{contains:[\"self\"]}),{className:\"symbol\",begin:\"'[A-Za-z_](?!')[\\\\w']*\"},{className:\"type\",begin:\"`[A-Z][\\\\w']*\"},{className:\"type\",begin:\"\\\\b[A-Z][\\\\w']*\",relevance:0},{begin:\"[a-z_]\\\\w*'[\\\\w']*\"},e.inherit(e.APOS_STRING_MODE,{className:\"string\",relevance:0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),{className:\"number\",begin:\"\\\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)\",relevance:0},{begin:/[-=]>/}]}}},function(e,t){e.exports=function(e){var t={className:\"string\",begin:\"\\\\$.{1}\"},n={className:\"symbol\",begin:\"#\"+e.UNDERSCORE_IDENT_RE};return{aliases:[\"st\"],keywords:\"self super nil true false thisContext\",contains:[e.COMMENT('\"','\"'),e.APOS_STRING_MODE,{className:\"type\",begin:\"\\\\b[A-Z][A-Za-z0-9_]*\",relevance:0},{begin:\"[a-z][a-zA-Z0-9_]*:\",relevance:0},e.C_NUMBER_MODE,n,t,{begin:\"\\\\|[ ]*[a-z][a-zA-Z0-9_]*([ ]+[a-z][a-zA-Z0-9_]*)*[ ]*\\\\|\",returnBegin:!0,end:/\\|/,illegal:/\\S/,contains:[{begin:\"(\\\\|[ ]*)?[a-z][a-zA-Z0-9_]*\"}]},{begin:\"\\\\#\\\\(\",end:\"\\\\)\",contains:[e.APOS_STRING_MODE,t,e.C_NUMBER_MODE,n]}]}}},function(e,t){e.exports=function(e){var t=[\"add\",\"and\",\"cmp\",\"cmpg\",\"cmpl\",\"const\",\"div\",\"double\",\"float\",\"goto\",\"if\",\"int\",\"long\",\"move\",\"mul\",\"neg\",\"new\",\"nop\",\"not\",\"or\",\"rem\",\"return\",\"shl\",\"shr\",\"sput\",\"sub\",\"throw\",\"ushr\",\"xor\"];return{aliases:[\"smali\"],contains:[{className:\"string\",begin:'\"',end:'\"',relevance:0},e.COMMENT(\"#\",\"$\",{relevance:0}),{className:\"keyword\",variants:[{begin:\"\\\\s*\\\\.end\\\\s[a-zA-Z0-9]*\"},{begin:\"^[ ]*\\\\.[a-zA-Z]*\",relevance:0},{begin:\"\\\\s:[a-zA-Z_0-9]*\",relevance:0},{begin:\"\\\\s(\"+[\"transient\",\"constructor\",\"abstract\",\"final\",\"synthetic\",\"public\",\"private\",\"protected\",\"static\",\"bridge\",\"system\"].join(\"|\")+\")\"}]},{className:\"built_in\",variants:[{begin:\"\\\\s(\"+t.join(\"|\")+\")\\\\s\"},{begin:\"\\\\s(\"+t.join(\"|\")+\")((\\\\-|/)[a-zA-Z0-9]+)+\\\\s\",relevance:10},{begin:\"\\\\s(\"+[\"aget\",\"aput\",\"array\",\"check\",\"execute\",\"fill\",\"filled\",\"goto/16\",\"goto/32\",\"iget\",\"instance\",\"invoke\",\"iput\",\"monitor\",\"packed\",\"sget\",\"sparse\"].join(\"|\")+\")((\\\\-|/)[a-zA-Z0-9]+)*\\\\s\",relevance:10}]},{className:\"class\",begin:\"L[^(;:\\n]*;\",relevance:0},{begin:\"[vp][0-9]+\"}]}}},function(e,t){e.exports=function(e){return{aliases:[\"console\"],contains:[{className:\"meta\",begin:\"^\\\\s{0,3}[\\\\w\\\\d\\\\[\\\\]()@-]*[>%$#]\",starts:{end:\"$\",subLanguage:\"bash\"}}]}}},function(e,t){e.exports=function(e){var t={className:\"variable\",begin:\"(\\\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\\\b\"},n={className:\"number\",begin:\"#[0-9A-Fa-f]+\"};e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE;return{case_insensitive:!0,illegal:\"[=/|']\",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:\"selector-id\",begin:\"\\\\#[A-Za-z0-9_-]+\",relevance:0},{className:\"selector-class\",begin:\"\\\\.[A-Za-z0-9_-]+\",relevance:0},{className:\"selector-attr\",begin:\"\\\\[\",end:\"\\\\]\",illegal:\"$\"},{className:\"selector-tag\",begin:\"\\\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\\\b\",relevance:0},{begin:\":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)\"},{begin:\"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)\"},t,{className:\"attribute\",begin:\"\\\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\\\b\",illegal:\"[^\\\\s]\"},{begin:\"\\\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\\\b\"},{begin:\":\",end:\";\",contains:[t,n,e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{className:\"meta\",begin:\"!important\"}]},{begin:\"@\",end:\"[{;]\",keywords:\"mixin include extend for if else each while charset import debug media page content font-face namespace warn\",contains:[t,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n,e.CSS_NUMBER_MODE,{begin:\"\\\\s[A-Za-z0-9_.-]+\",relevance:0}]}]}}},function(e,t){e.exports=function(e){var t=[e.C_NUMBER_MODE,{className:\"string\",begin:\"'|\\\"\",end:\"'|\\\"\",contains:[e.BACKSLASH_ESCAPE,{begin:\"''\"}]}];return{aliases:[\"sci\"],lexemes:/%?\\w+/,keywords:{keyword:\"abort break case clear catch continue do elseif else endfunction end for function global if pause return resume select try then while\",literal:\"%f %F %t %T %pi %eps %inf %nan %e %i %z %s\",built_in:\"abs and acos asin atan ceil cd chdir clearglobal cosh cos cumprod deff disp error exec execstr exists exp eye gettext floor fprintf fread fsolve imag isdef isempty isinfisnan isvector lasterror length load linspace list listfiles log10 log2 log max min msprintf mclose mopen ones or pathconvert poly printf prod pwd rand real round sinh sin size gsort sprintf sqrt strcat strcmps tring sum system tanh tan type typename warning zeros matrix\"},illegal:'(\"|#|/\\\\*|\\\\s+/\\\\w+)',contains:[{className:\"function\",beginKeywords:\"function\",end:\"$\",contains:[e.UNDERSCORE_TITLE_MODE,{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\"}]},{begin:\"[a-zA-Z_][a-zA-Z_0-9]*('+[\\\\.']*|[\\\\.']+)\",end:\"\",relevance:0},{begin:\"\\\\[\",end:\"\\\\]'*[\\\\.']*\",relevance:0,contains:t},e.COMMENT(\"//\",\"$\")].concat(t)}}},function(e,t){e.exports=function(e){var t=\"[^\\\\(\\\\)\\\\[\\\\]\\\\{\\\\}\\\",'`;#|\\\\\\\\\\\\s]+\",n={className:\"literal\",begin:\"(#t|#f|#\\\\\\\\\"+t+\"|#\\\\\\\\.)\"},r={className:\"number\",variants:[{begin:\"(\\\\-|\\\\+)?\\\\d+([./]\\\\d+)?\",relevance:0},{begin:\"(\\\\-|\\\\+)?\\\\d+([./]\\\\d+)?[+\\\\-](\\\\-|\\\\+)?\\\\d+([./]\\\\d+)?i\",relevance:0},{begin:\"#b[0-1]+(/[0-1]+)?\"},{begin:\"#o[0-7]+(/[0-7]+)?\"},{begin:\"#x[0-9a-f]+(/[0-9a-f]+)?\"}]},i=e.QUOTE_STRING_MODE,a=[e.COMMENT(\";\",\"$\",{relevance:0}),e.COMMENT(\"#\\\\|\",\"\\\\|#\")],o={begin:t,relevance:0},s={className:\"symbol\",begin:\"'\"+t},l={endsWithParent:!0,relevance:0},c={variants:[{begin:/'/},{begin:\"`\"}],contains:[{begin:\"\\\\(\",end:\"\\\\)\",contains:[\"self\",n,i,r,o,s]}]},u={className:\"name\",begin:t,lexemes:t,keywords:{\"builtin-name\":\"case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules ' * + , ,@ - ... / ; < <= = => > >= ` abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string=? string>? string? substring symbol->string symbol? tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?\"}},d={variants:[{begin:\"\\\\(\",end:\"\\\\)\"},{begin:\"\\\\[\",end:\"\\\\]\"}],contains:[{begin:/lambda/,endsWithParent:!0,returnBegin:!0,contains:[u,{begin:/\\(/,end:/\\)/,endsParent:!0,contains:[o]}]},u,l]};return l.contains=[n,r,i,o,s,c,d].concat(a),{illegal:/\\S/,contains:[{className:\"meta\",begin:\"^#!\",end:\"$\"},r,i,s,c,d].concat(a)}}},function(e,t){e.exports=function(e){var t={className:\"subst\",variants:[{begin:\"\\\\$[A-Za-z0-9_]+\"},{begin:\"\\\\${\",end:\"}\"}]},n={className:\"string\",variants:[{begin:'\"',end:'\"',illegal:\"\\\\n\",contains:[e.BACKSLASH_ESCAPE]},{begin:'\"\"\"',end:'\"\"\"',relevance:10},{begin:'[a-z]+\"',end:'\"',illegal:\"\\\\n\",contains:[e.BACKSLASH_ESCAPE,t]},{className:\"string\",begin:'[a-z]+\"\"\"',end:'\"\"\"',contains:[t],relevance:10}]},r={className:\"type\",begin:\"\\\\b[A-Z][A-Za-z0-9_]*\",relevance:0},i={className:\"title\",begin:/[^0-9\\n\\t \"'(),.`{}\\[\\]:;][^\\n\\t \"'(),.`{}\\[\\]:;]+|[^0-9\\n\\t \"'(),.`{}\\[\\]:;=]/,relevance:0},a={className:\"class\",beginKeywords:\"class object trait type\",end:/[:={\\[\\n;]/,excludeEnd:!0,contains:[{beginKeywords:\"extends with\",relevance:10},{begin:/\\[/,end:/\\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[r]},{className:\"params\",begin:/\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[r]},i]},o={className:\"function\",beginKeywords:\"def\",end:/[:={\\[(\\n;]/,excludeEnd:!0,contains:[i]};return{keywords:{literal:\"true false null\",keyword:\"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit\"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,{className:\"symbol\",begin:\"'\\\\w[\\\\w\\\\d_]*(?!')\"},r,o,a,e.C_NUMBER_MODE,{className:\"meta\",begin:\"@[A-Za-z]+\"}]}}},function(e,t){e.exports=function(e){var t=\"([ui](8|16|32|64|128|size)|f(32|64))?\",n=\"drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!\";return{aliases:[\"rs\"],keywords:{keyword:\"alignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self Self sizeof static struct super trait true type typeof unsafe unsized use virtual while where yield move default\",literal:\"true false Some None Ok Err\",built_in:n},lexemes:e.IDENT_RE+\"!?\",illegal:\"\"}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:\"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN SAVE_UPDATE DETERMINANT LABEL REPORT REVENUE EACH IN FROM TOTAL CHARGE BLOCK AND OR CSV_FILE RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM NUMDAYS READ_DATE STAGING\",built_in:\"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME\"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,{className:\"literal\",variants:[{begin:\"#\\\\s+[a-zA-Z\\\\ \\\\.]*\",relevance:0},{begin:\"#[a-zA-Z\\\\ \\\\.]+\"}]}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:\"float color point normal vector matrix while for if do return else break extern continue\",built_in:\"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp\"},illegal:\"\\]$/},{begin:/<\\//,end:/>/},{begin:/^facet /,end:/\\}/},{begin:\"^1\\\\.\\\\.(\\\\d+)$\",end:/$/}],illegal:/./},e.COMMENT(\"^#\",\"$\"),i,a,r,{begin:/[\\w-]+\\=([^\\s\\{\\}\\[\\]\\(\\)]+)/,relevance:0,returnBegin:!0,contains:[{className:\"attribute\",begin:/[^=]+/},{begin:/=/,endsWithParent:!0,relevance:0,contains:[i,a,r,{className:\"literal\",begin:\"\\\\b(\"+n.split(\" \").join(\"|\")+\")\\\\b\"},{begin:/(\"[^\"]*\"|[^\\s\\{\\}\\[\\]]+)/}]}]},{className:\"number\",begin:/\\*[0-9a-fA-F]+/},{begin:\"\\\\b(\"+\"add remove enable disable set get print export edit find run debug error info warning\".split(\" \").join(\"|\")+\")([\\\\s[(]|])\",returnBegin:!0,contains:[{className:\"builtin-name\",begin:/\\w+/}]},{className:\"built_in\",variants:[{begin:\"(\\\\.\\\\./|/|\\\\s)((\"+\"traffic-flow traffic-generator firewall scheduler aaa accounting address-list address align area bandwidth-server bfd bgp bridge client clock community config connection console customer default dhcp-client dhcp-server discovery dns e-mail ethernet filter firewall firmware gps graphing group hardware health hotspot identity igmp-proxy incoming instance interface ip ipsec ipv6 irq l2tp-server lcd ldp logging mac-server mac-winbox mangle manual mirror mme mpls nat nd neighbor network note ntp ospf ospf-v3 ovpn-server page peer pim ping policy pool port ppp pppoe-client pptp-server prefix profile proposal proxy queue radius resource rip ripng route routing screen script security-profiles server service service-port settings shares smb sms sniffer snmp snooper socks sstp-server system tool tracking type upgrade upnp user-manager users user vlan secret vrrp watchdog web-access wireless pptp pppoe lan wan layer7-protocol lease simple raw\".split(\" \").join(\"|\")+\");?\\\\s)+\",relevance:10},{begin:/\\.\\./}]}]}}},function(e,t){e.exports=function(e){var t=\"[a-zA-Z-_][^\\\\n{]+\\\\{\",n={className:\"attribute\",begin:/[a-zA-Z-_]+/,end:/\\s*:/,excludeEnd:!0,starts:{end:\";\",relevance:0,contains:[{className:\"variable\",begin:/\\.[a-zA-Z-_]+/},{className:\"keyword\",begin:/\\(optional\\)/}]}};return{aliases:[\"graph\",\"instances\"],case_insensitive:!0,keywords:\"import\",contains:[{begin:\"^facet \"+t,end:\"}\",keywords:\"facet\",contains:[n,e.HASH_COMMENT_MODE]},{begin:\"^\\\\s*instance of \"+t,end:\"}\",keywords:\"name count channels instance-data instance-state instance of\",illegal:/\\S/,contains:[\"self\",n,e.HASH_COMMENT_MODE]},{begin:\"^\"+t,end:\"}\",contains:[n,e.HASH_COMMENT_MODE]},e.HASH_COMMENT_MODE]}}},function(e,t){e.exports=function(e){return{keywords:\"ArchiveRecord AreaLightSource Atmosphere Attribute AttributeBegin AttributeEnd Basis Begin Blobby Bound Clipping ClippingPlane Color ColorSamples ConcatTransform Cone CoordinateSystem CoordSysTransform CropWindow Curves Cylinder DepthOfField Detail DetailRange Disk Displacement Display End ErrorHandler Exposure Exterior Format FrameAspectRatio FrameBegin FrameEnd GeneralPolygon GeometricApproximation Geometry Hider Hyperboloid Identity Illuminate Imager Interior LightSource MakeCubeFaceEnvironment MakeLatLongEnvironment MakeShadow MakeTexture Matte MotionBegin MotionEnd NuPatch ObjectBegin ObjectEnd ObjectInstance Opacity Option Orientation Paraboloid Patch PatchMesh Perspective PixelFilter PixelSamples PixelVariance Points PointsGeneralPolygons PointsPolygons Polygon Procedural Projection Quantize ReadArchive RelativeDetail ReverseOrientation Rotate Scale ScreenWindow ShadingInterpolation ShadingRate Shutter Sides Skew SolidBegin SolidEnd Sphere SubdivisionMesh Surface TextureCoordinates Torus Transform TransformBegin TransformEnd TransformPoints Translate TrimCurve WorldBegin WorldEnd\",illegal:\"\\s*[);\\]]/,relevance:0,subLanguage:\"xml\"}],relevance:0},{className:\"keyword\",begin:\"\\\\bsignal\\\\b\",starts:{className:\"string\",end:\"(\\\\(|:|=|;|,|//|/\\\\*|$)\",returnEnd:!0}},{className:\"keyword\",begin:\"\\\\bproperty\\\\b\",starts:{className:\"string\",end:\"(:|=|;|,|//|/\\\\*|$)\",returnEnd:!0}},{className:\"function\",beginKeywords:\"function\",end:/\\{/,excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/}),{className:\"params\",begin:/\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}],illegal:/\\[|%/},{begin:\"\\\\.\"+e.IDENT_RE,relevance:0},n,r,i],illegal:/#/}}},function(e,t){e.exports=function(e){return{aliases:[\"k\",\"kdb\"],keywords:{keyword:\"do while select delete by update from\",literal:\"0b 1b\",built_in:\"neg not null string reciprocal floor ceiling signum mod xbar xlog and or each scan over prior mmu lsq inv md5 ltime gtime count first var dev med cov cor all any rand sums prds mins maxs fills deltas ratios avgs differ prev next rank reverse iasc idesc asc desc msum mcount mavg mdev xrank mmin mmax xprev rotate distinct group where flip type key til get value attr cut set upsert raze union inter except cross sv vs sublist enlist read0 read1 hopen hclose hdel hsym hcount peach system ltrim rtrim trim lower upper ssr view tables views cols xcols keys xkey xcol xasc xdesc fkeys meta lj aj aj0 ij pj asof uj ww wj wj1 fby xgroup ungroup ej save load rsave rload show csv parse eval min max avg wavg wsum sin cos tan sum\",type:\"`float `double int `timestamp `timespan `datetime `time `boolean `symbol `char `byte `short `long `real `month `date `minute `second `guid\"},lexemes:/(`?)[A-Za-z0-9_]+\\b/,contains:[e.C_LINE_COMMENT_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t={keyword:\"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False\",built_in:\"Ellipsis NotImplemented\"},n={className:\"meta\",begin:/^(>>>|\\.\\.\\.) /},r={className:\"subst\",begin:/\\{/,end:/\\}/,keywords:t,illegal:/#/},i={className:\"string\",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/(u|b)?r?'''/,end:/'''/,contains:[n],relevance:10},{begin:/(u|b)?r?\"\"\"/,end:/\"\"\"/,contains:[n],relevance:10},{begin:/(fr|rf|f)'''/,end:/'''/,contains:[n,r]},{begin:/(fr|rf|f)\"\"\"/,end:/\"\"\"/,contains:[n,r]},{begin:/(u|r|ur)'/,end:/'/,relevance:10},{begin:/(u|r|ur)\"/,end:/\"/,relevance:10},{begin:/(b|br)'/,end:/'/},{begin:/(b|br)\"/,end:/\"/},{begin:/(fr|rf|f)'/,end:/'/,contains:[r]},{begin:/(fr|rf|f)\"/,end:/\"/,contains:[r]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},a={className:\"number\",relevance:0,variants:[{begin:e.BINARY_NUMBER_RE+\"[lLjJ]?\"},{begin:\"\\\\b(0o[0-7]+)[lLjJ]?\"},{begin:e.C_NUMBER_RE+\"[lLjJ]?\"}]},o={className:\"params\",begin:/\\(/,end:/\\)/,contains:[\"self\",n,a,i]};return r.contains=[i,a,n],{aliases:[\"py\",\"gyp\"],keywords:t,illegal:/(<\\/|->|\\?)|=>/,contains:[n,a,i,e.HASH_COMMENT_MODE,{variants:[{className:\"function\",beginKeywords:\"def\"},{className:\"class\",beginKeywords:\"class\"}],end:/:/,illegal:/[${=;\\n,]/,contains:[e.UNDERSCORE_TITLE_MODE,o,{begin:/->/,endsWithParent:!0,keywords:\"None\"}]},{className:\"meta\",begin:/^[\\t ]*@/,end:/$/},{begin:/\\b(print|exec)\\(/}]}}},function(e,t){e.exports=function(e){return{aliases:[\"pb\",\"pbi\"],keywords:\"And As Break CallDebugger Case CompilerCase CompilerDefault CompilerElse CompilerEndIf CompilerEndSelect CompilerError CompilerIf CompilerSelect Continue Data DataSection EndDataSection Debug DebugLevel Default Define Dim DisableASM DisableDebugger DisableExplicit Else ElseIf EnableASM EnableDebugger EnableExplicit End EndEnumeration EndIf EndImport EndInterface EndMacro EndProcedure EndSelect EndStructure EndStructureUnion EndWith Enumeration Extends FakeReturn For Next ForEach ForEver Global Gosub Goto If Import ImportC IncludeBinary IncludeFile IncludePath Interface Macro NewList Not Or ProcedureReturn Protected Prototype PrototypeC Read ReDim Repeat Until Restore Return Select Shared Static Step Structure StructureUnion Swap To Wend While With XIncludeFile XOr Procedure ProcedureC ProcedureCDLL ProcedureDLL Declare DeclareC DeclareCDLL DeclareDLL\",contains:[e.COMMENT(\";\",\"$\",{relevance:0}),{className:\"function\",begin:\"\\\\b(Procedure|Declare)(C|CDLL|DLL)?\\\\b\",end:\"\\\\(\",excludeEnd:!0,returnBegin:!0,contains:[{className:\"keyword\",begin:\"(Procedure|Declare)(C|CDLL|DLL)?\",excludeEnd:!0},{className:\"type\",begin:\"\\\\.\\\\w*\"},e.UNDERSCORE_TITLE_MODE]},{className:\"string\",begin:'(~)?\"',end:'\"',illegal:\"\\\\n\"},{className:\"symbol\",begin:\"#[a-zA-Z_]\\\\w*\\\\$?\"}]}}},function(e,t){e.exports=function(e){var t=e.COMMENT(\"#\",\"$\"),n=e.inherit(e.TITLE_MODE,{begin:\"([A-Za-z_]|::)(\\\\w|::)*\"}),r={className:\"variable\",begin:\"\\\\$([A-Za-z_]|::)(\\\\w|::)*\"},i={className:\"string\",contains:[e.BACKSLASH_ESCAPE,r],variants:[{begin:/'/,end:/'/},{begin:/\"/,end:/\"/}]};return{aliases:[\"pp\"],contains:[t,r,i,{beginKeywords:\"class\",end:\"\\\\{|;\",illegal:/=/,contains:[n,t]},{beginKeywords:\"define\",end:/\\{/,contains:[{className:\"section\",begin:e.IDENT_RE,endsParent:!0}]},{begin:e.IDENT_RE+\"\\\\s+\\\\{\",returnBegin:!0,end:/\\S/,contains:[{className:\"keyword\",begin:e.IDENT_RE},{begin:/\\{/,end:/\\}/,keywords:{keyword:\"and case default else elsif false if in import enherits node or true undef unless main settings $string \",literal:\"alias audit before loglevel noop require subscribe tag owner ensure group mode name|0 changes context force incl lens load_path onlyif provider returns root show_diff type_check en_address ip_address realname command environment hour monute month monthday special target weekday creates cwd ogoutput refresh refreshonly tries try_sleep umask backup checksum content ctime force ignore links mtime purge recurse recurselimit replace selinux_ignore_defaults selrange selrole seltype seluser source souirce_permissions sourceselect validate_cmd validate_replacement allowdupe attribute_membership auth_membership forcelocal gid ia_load_module members system host_aliases ip allowed_trunk_vlans description device_url duplex encapsulation etherchannel native_vlan speed principals allow_root auth_class auth_type authenticate_user k_of_n mechanisms rule session_owner shared options device fstype enable hasrestart directory present absent link atboot blockdevice device dump pass remounts poller_tag use message withpath adminfile allow_virtual allowcdrom category configfiles flavor install_options instance package_settings platform responsefile status uninstall_options vendor unless_system_user unless_uid binary control flags hasstatus manifest pattern restart running start stop allowdupe auths expiry gid groups home iterations key_membership keys managehome membership password password_max_age password_min_age profile_membership profiles project purge_ssh_keys role_membership roles salt shell uid baseurl cost descr enabled enablegroups exclude failovermethod gpgcheck gpgkey http_caching include includepkgs keepalive metadata_expire metalink mirrorlist priority protect proxy proxy_password proxy_username repo_gpgcheck s3_enabled skip_if_unavailable sslcacert sslclientcert sslclientkey sslverify mounted\",built_in:\"architecture augeasversion blockdevices boardmanufacturer boardproductname boardserialnumber cfkey dhcp_servers domain ec2_ ec2_userdata facterversion filesystems ldom fqdn gid hardwareisa hardwaremodel hostname id|0 interfaces ipaddress ipaddress_ ipaddress6 ipaddress6_ iphostnumber is_virtual kernel kernelmajversion kernelrelease kernelversion kernelrelease kernelversion lsbdistcodename lsbdistdescription lsbdistid lsbdistrelease lsbmajdistrelease lsbminordistrelease lsbrelease macaddress macaddress_ macosx_buildversion macosx_productname macosx_productversion macosx_productverson_major macosx_productversion_minor manufacturer memoryfree memorysize netmask metmask_ network_ operatingsystem operatingsystemmajrelease operatingsystemrelease osfamily partitions path physicalprocessorcount processor processorcount productname ps puppetversion rubysitedir rubyversion selinux selinux_config_mode selinux_config_policy selinux_current_mode selinux_current_mode selinux_enforced selinux_policyversion serialnumber sp_ sshdsakey sshecdsakey sshrsakey swapencrypted swapfree swapsize timezone type uniqueid uptime uptime_days uptime_hours uptime_seconds uuid virtual vlans xendomains zfs_version zonenae zones zpool_version\"},relevance:0,contains:[i,t,{begin:\"[a-zA-Z_]+\\\\s*=>\",returnBegin:!0,end:\"=>\",contains:[{className:\"attr\",begin:e.IDENT_RE}]},{className:\"number\",begin:\"(\\\\b0[0-7_]+)|(\\\\b0x[0-9a-fA-F_]+)|(\\\\b[1-9][0-9_]*(\\\\.[0-9_]+)?)|[0_]\\\\b\",relevance:0},r]}],relevance:0}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:\"package import option optional required repeated group\",built_in:\"double float int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64 bool string bytes\",literal:\"true false\"},contains:[e.QUOTE_STRING_MODE,e.NUMBER_MODE,e.C_LINE_COMMENT_MODE,{className:\"class\",beginKeywords:\"message enum service\",end:/\\{/,illegal:/\\n/,contains:[e.inherit(e.TITLE_MODE,{starts:{endsWithParent:!0,excludeEnd:!0}})]},{className:\"function\",beginKeywords:\"rpc\",end:/;/,excludeEnd:!0,keywords:\"rpc returns\"},{begin:/^\\s*[A-Z_]+/,end:/\\s*=/,excludeEnd:!0}]}}},function(e,t){e.exports=function(e){var t={begin:/\\(/,end:/\\)/,relevance:0},n={begin:/\\[/,end:/\\]/},r={className:\"comment\",begin:/%/,end:/$/,contains:[e.PHRASAL_WORDS_MODE]},i={className:\"string\",begin:/`/,end:/`/,contains:[e.BACKSLASH_ESCAPE]},a=[{begin:/[a-z][A-Za-z0-9_]*/,relevance:0},{className:\"symbol\",variants:[{begin:/[A-Z][a-zA-Z0-9_]*/},{begin:/_[A-Za-z0-9_]*/}],relevance:0},t,{begin:/:-/},n,r,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,i,{className:\"string\",begin:/0\\'(\\\\\\'|.)/},{className:\"string\",begin:/0\\'\\\\s/},e.C_NUMBER_MODE];return t.contains=a,n.contains=a,{contains:a.concat([{begin:/\\.$/}])}}},function(e,t){e.exports=function(e){return{contains:[e.C_NUMBER_MODE,{begin:\"[a-zA-Z_][\\\\da-zA-Z_]+\\\\.[\\\\da-zA-Z_]{1,3}\",end:\":\",excludeEnd:!0},{begin:\"(ncalls|tottime|cumtime)\",end:\"$\",keywords:\"ncalls tottime|10 cumtime|10 filename\",relevance:10},{begin:\"function calls\",end:\"$\",contains:[e.C_NUMBER_MODE],relevance:10},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:\"string\",begin:\"\\\\(\",end:\"\\\\)$\",excludeBegin:!0,excludeEnd:!0,relevance:0}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:\"BufferedReader PVector PFont PImage PGraphics HashMap boolean byte char color double float int long String Array FloatDict FloatList IntDict IntList JSONArray JSONObject Object StringDict StringList Table TableRow XML false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private\",literal:\"P2D P3D HALF_PI PI QUARTER_PI TAU TWO_PI\",title:\"setup draw\",built_in:\"displayHeight displayWidth mouseY mouseX mousePressed pmouseX pmouseY key keyCode pixels focused frameCount frameRate height width size createGraphics beginDraw createShape loadShape PShape arc ellipse line point quad rect triangle bezier bezierDetail bezierPoint bezierTangent curve curveDetail curvePoint curveTangent curveTightness shape shapeMode beginContour beginShape bezierVertex curveVertex endContour endShape quadraticVertex vertex ellipseMode noSmooth rectMode smooth strokeCap strokeJoin strokeWeight mouseClicked mouseDragged mouseMoved mousePressed mouseReleased mouseWheel keyPressed keyPressedkeyReleased keyTyped print println save saveFrame day hour millis minute month second year background clear colorMode fill noFill noStroke stroke alpha blue brightness color green hue lerpColor red saturation modelX modelY modelZ screenX screenY screenZ ambient emissive shininess specular add createImage beginCamera camera endCamera frustum ortho perspective printCamera printProjection cursor frameRate noCursor exit loop noLoop popStyle pushStyle redraw binary boolean byte char float hex int str unbinary unhex join match matchAll nf nfc nfp nfs split splitTokens trim append arrayCopy concat expand reverse shorten sort splice subset box sphere sphereDetail createInput createReader loadBytes loadJSONArray loadJSONObject loadStrings loadTable loadXML open parseXML saveTable selectFolder selectInput beginRaw beginRecord createOutput createWriter endRaw endRecord PrintWritersaveBytes saveJSONArray saveJSONObject saveStream saveStrings saveXML selectOutput popMatrix printMatrix pushMatrix resetMatrix rotate rotateX rotateY rotateZ scale shearX shearY translate ambientLight directionalLight lightFalloff lights lightSpecular noLights normal pointLight spotLight image imageMode loadImage noTint requestImage tint texture textureMode textureWrap blend copy filter get loadPixels set updatePixels blendMode loadShader PShaderresetShader shader createFont loadFont text textFont textAlign textLeading textMode textSize textWidth textAscent textDescent abs ceil constrain dist exp floor lerp log mag map max min norm pow round sq sqrt acos asin atan atan2 cos degrees radians sin tan noise noiseDetail noiseSeed random randomGaussian randomSeed\"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t={begin:\"`[\\\\s\\\\S]\",relevance:0},n={className:\"variable\",variants:[{begin:/\\$[\\w\\d][\\w\\d_:]*/}]},r={className:\"string\",variants:[{begin:/\"/,end:/\"/},{begin:/@\"/,end:/^\"@/}],contains:[t,n,{className:\"variable\",begin:/\\$[A-z]/,end:/[^A-z]/}]},i=e.inherit(e.COMMENT(null,null),{variants:[{begin:/#/,end:/$/},{begin:/<#/,end:/#>/}],contains:[{className:\"doctag\",variants:[{begin:/\\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{begin:/\\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\\s+\\S+/}]}]});return{aliases:[\"ps\"],lexemes:/-?[A-z\\.\\-]+/,case_insensitive:!0,keywords:{keyword:\"if else foreach return function do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch\",built_in:\"Add-Computer Add-Content Add-History Add-JobTrigger Add-Member Add-PSSnapin Add-Type Checkpoint-Computer Clear-Content Clear-EventLog Clear-History Clear-Host Clear-Item Clear-ItemProperty Clear-Variable Compare-Object Complete-Transaction Connect-PSSession Connect-WSMan Convert-Path ConvertFrom-Csv ConvertFrom-Json ConvertFrom-SecureString ConvertFrom-StringData ConvertTo-Csv ConvertTo-Html ConvertTo-Json ConvertTo-SecureString ConvertTo-Xml Copy-Item Copy-ItemProperty Debug-Process Disable-ComputerRestore Disable-JobTrigger Disable-PSBreakpoint Disable-PSRemoting Disable-PSSessionConfiguration Disable-WSManCredSSP Disconnect-PSSession Disconnect-WSMan Disable-ScheduledJob Enable-ComputerRestore Enable-JobTrigger Enable-PSBreakpoint Enable-PSRemoting Enable-PSSessionConfiguration Enable-ScheduledJob Enable-WSManCredSSP Enter-PSSession Exit-PSSession Export-Alias Export-Clixml Export-Console Export-Counter Export-Csv Export-FormatData Export-ModuleMember Export-PSSession ForEach-Object Format-Custom Format-List Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-ComputerRestorePoint Get-Content Get-ControlPanelItem Get-Counter Get-Credential Get-Culture Get-Date Get-Event Get-EventLog Get-EventSubscriber Get-ExecutionPolicy Get-FormatData Get-Host Get-HotFix Get-Help Get-History Get-IseSnippet Get-Item Get-ItemProperty Get-Job Get-JobTrigger Get-Location Get-Member Get-Module Get-PfxCertificate Get-Process Get-PSBreakpoint Get-PSCallStack Get-PSDrive Get-PSProvider Get-PSSession Get-PSSessionConfiguration Get-PSSnapin Get-Random Get-ScheduledJob Get-ScheduledJobOption Get-Service Get-TraceSource Get-Transaction Get-TypeData Get-UICulture Get-Unique Get-Variable Get-Verb Get-WinEvent Get-WmiObject Get-WSManCredSSP Get-WSManInstance Group-Object Import-Alias Import-Clixml Import-Counter Import-Csv Import-IseSnippet Import-LocalizedData Import-PSSession Import-Module Invoke-AsWorkflow Invoke-Command Invoke-Expression Invoke-History Invoke-Item Invoke-RestMethod Invoke-WebRequest Invoke-WmiMethod Invoke-WSManAction Join-Path Limit-EventLog Measure-Command Measure-Object Move-Item Move-ItemProperty New-Alias New-Event New-EventLog New-IseSnippet New-Item New-ItemProperty New-JobTrigger New-Object New-Module New-ModuleManifest New-PSDrive New-PSSession New-PSSessionConfigurationFile New-PSSessionOption New-PSTransportOption New-PSWorkflowExecutionOption New-PSWorkflowSession New-ScheduledJobOption New-Service New-TimeSpan New-Variable New-WebServiceProxy New-WinEvent New-WSManInstance New-WSManSessionOption Out-Default Out-File Out-GridView Out-Host Out-Null Out-Printer Out-String Pop-Location Push-Location Read-Host Receive-Job Register-EngineEvent Register-ObjectEvent Register-PSSessionConfiguration Register-ScheduledJob Register-WmiEvent Remove-Computer Remove-Event Remove-EventLog Remove-Item Remove-ItemProperty Remove-Job Remove-JobTrigger Remove-Module Remove-PSBreakpoint Remove-PSDrive Remove-PSSession Remove-PSSnapin Remove-TypeData Remove-Variable Remove-WmiObject Remove-WSManInstance Rename-Computer Rename-Item Rename-ItemProperty Reset-ComputerMachinePassword Resolve-Path Restart-Computer Restart-Service Restore-Computer Resume-Job Resume-Service Save-Help Select-Object Select-String Select-Xml Send-MailMessage Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-JobTrigger Set-Location Set-PSBreakpoint Set-PSDebug Set-PSSessionConfiguration Set-ScheduledJob Set-ScheduledJobOption Set-Service Set-StrictMode Set-TraceSource Set-Variable Set-WmiInstance Set-WSManInstance Set-WSManQuickConfig Show-Command Show-ControlPanelItem Show-EventLog Sort-Object Split-Path Start-Job Start-Process Start-Service Start-Sleep Start-Transaction Start-Transcript Stop-Computer Stop-Job Stop-Process Stop-Service Stop-Transcript Suspend-Job Suspend-Service Tee-Object Test-ComputerSecureChannel Test-Connection Test-ModuleManifest Test-Path Test-PSSessionConfigurationFile Trace-Command Unblock-File Undo-Transaction Unregister-Event Unregister-PSSessionConfiguration Unregister-ScheduledJob Update-FormatData Update-Help Update-List Update-TypeData Use-Transaction Wait-Event Wait-Job Wait-Process Where-Object Write-Debug Write-Error Write-EventLog Write-Host Write-Output Write-Progress Write-Verbose Write-Warning Add-MDTPersistentDrive Disable-MDTMonitorService Enable-MDTMonitorService Get-MDTDeploymentShareStatistics Get-MDTMonitorData Get-MDTOperatingSystemCatalog Get-MDTPersistentDrive Import-MDTApplication Import-MDTDriver Import-MDTOperatingSystem Import-MDTPackage Import-MDTTaskSequence New-MDTDatabase Remove-MDTMonitorData Remove-MDTPersistentDrive Restore-MDTPersistentDrive Set-MDTMonitorData Test-MDTDeploymentShare Test-MDTMonitorData Update-MDTDatabaseSchema Update-MDTDeploymentShare Update-MDTLinkedDS Update-MDTMedia Update-MDTMedia Add-VamtProductKey Export-VamtData Find-VamtManagedMachine Get-VamtConfirmationId Get-VamtProduct Get-VamtProductKey Import-VamtData Initialize-VamtData Install-VamtConfirmationId Install-VamtProductActivation Install-VamtProductKey Update-VamtProduct\",nomarkup:\"-ne -eq -lt -gt -ge -le -not -like -notlike -match -notmatch -contains -notcontains -in -notin -replace\"},contains:[t,e.NUMBER_MODE,r,{className:\"string\",variants:[{begin:/'/,end:/'/},{begin:/@'/,end:/^'@/}]},{className:\"literal\",begin:/\\$(null|true|false)\\b/},n,i]}}},function(e,t){e.exports=function(e){var t={className:\"string\",begin:'\"',end:'\"',contains:[e.BACKSLASH_ESCAPE]},n={className:\"string\",begin:\"'\",end:\"'\",contains:[e.BACKSLASH_ESCAPE],relevance:0},r={className:\"type\",begin:\"\\\\b_?[A-Z][\\\\w]*\",relevance:0},i={begin:e.IDENT_RE+\"'\",relevance:0};return{keywords:{keyword:\"actor addressof and as be break class compile_error compile_intrinsicconsume continue delegate digestof do else elseif embed end errorfor fun if ifdef in interface is isnt lambda let match new not objector primitive recover repeat return struct then trait try type until use var where while with xor\",meta:\"iso val tag trn box ref\",literal:\"this false true\"},contains:[{className:\"class\",beginKeywords:\"class actor\",end:\"$\",contains:[e.TITLE_MODE,e.C_LINE_COMMENT_MODE]},{className:\"function\",beginKeywords:\"new fun\",end:\"=>\",contains:[e.TITLE_MODE,{begin:/\\(/,end:/\\)/,contains:[r,i,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},{begin:/:/,endsWithParent:!0,contains:[r]},e.C_LINE_COMMENT_MODE]},r,{className:\"string\",begin:'\"\"\"',end:'\"\"\"',relevance:10},t,n,i,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}}},function(e,t){e.exports=function(e){var t={begin:\"\\\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*\"},n={className:\"meta\",begin:/<\\?(php)?|\\?>/},r={className:\"string\",contains:[e.BACKSLASH_ESCAPE,n],variants:[{begin:'b\"',end:'\"'},{begin:\"b'\",end:\"'\"},e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null})]},i={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]};return{aliases:[\"php3\",\"php4\",\"php5\",\"php6\"],case_insensitive:!0,keywords:\"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally\",contains:[e.HASH_COMMENT_MODE,e.COMMENT(\"//\",\"$\",{contains:[n]}),e.COMMENT(\"/\\\\*\",\"\\\\*/\",{contains:[{className:\"doctag\",begin:\"@[A-Za-z]+\"}]}),e.COMMENT(\"__halt_compiler.+?;\",!1,{endsWithParent:!0,keywords:\"__halt_compiler\",lexemes:e.UNDERSCORE_IDENT_RE}),{className:\"string\",begin:/<<<['\"]?\\w+['\"]?$/,end:/^\\w+;?$/,contains:[e.BACKSLASH_ESCAPE,{className:\"subst\",variants:[{begin:/\\$\\w+/},{begin:/\\{\\$/,end:/\\}/}]}]},n,{className:\"keyword\",begin:/\\$this\\b/},t,{begin:/(::|->)+[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*/},{className:\"function\",beginKeywords:\"function\",end:/[;{]/,excludeEnd:!0,illegal:\"\\\\$|\\\\[|%\",contains:[e.UNDERSCORE_TITLE_MODE,{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\",contains:[\"self\",t,e.C_BLOCK_COMMENT_MODE,r,i]}]},{className:\"class\",beginKeywords:\"class interface\",end:\"{\",excludeEnd:!0,illegal:/[:\\(\\$\"]/,contains:[{beginKeywords:\"extends implements\"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:\"namespace\",end:\";\",illegal:/[\\.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:\"use\",end:\";\",contains:[e.UNDERSCORE_TITLE_MODE]},{begin:\"=>\"},r,i]}}},function(e,t){e.exports=function(e){return{aliases:[\"pf.conf\"],lexemes:/[a-z0-9_<>-]+/,keywords:{built_in:\"block match pass load anchor|5 antispoof|10 set table\",keyword:\"in out log quick on rdomain inet inet6 proto from port os to routeallow-opts divert-packet divert-reply divert-to flags group icmp-typeicmp6-type label once probability recieved-on rtable prio queuetos tag tagged user keep fragment for os dropaf-to|10 binat-to|10 nat-to|10 rdr-to|10 bitmask least-stats random round-robinsource-hash static-portdup-to reply-to route-toparent bandwidth default min max qlimitblock-policy debug fingerprints hostid limit loginterface optimizationreassemble ruleset-optimization basic none profile skip state-defaultsstate-policy timeoutconst counters persistno modulate synproxy state|5 floating if-bound no-sync pflow|10 sloppysource-track global rule max-src-nodes max-src-states max-src-connmax-src-conn-rate overload flushscrub|5 max-mss min-ttl no-df|10 random-id\",literal:\"all any no-route self urpf-failed egress|5 unknown\"},contains:[e.HASH_COMMENT_MODE,e.NUMBER_MODE,e.QUOTE_STRING_MODE,{className:\"variable\",begin:/\\$[\\w\\d#@][\\w\\d_]*/},{className:\"variable\",begin:/<(?!\\/)/,end:/>/}]}}},function(e,t){e.exports=function(e){var t=e.COMMENT(\"{\",\"}\",{contains:[\"self\"]});return{subLanguage:\"xml\",relevance:0,contains:[e.COMMENT(\"^#\",\"$\"),e.COMMENT(\"\\\\^rem{\",\"}\",{relevance:10,contains:[t]}),{className:\"meta\",begin:\"^@(?:BASE|USE|CLASS|OPTIONS)$\",relevance:10},{className:\"title\",begin:\"@[\\\\w\\\\-]+\\\\[[\\\\w^;\\\\-]*\\\\](?:\\\\[[\\\\w^;\\\\-]*\\\\])?(?:.*)$\"},{className:\"variable\",begin:\"\\\\$\\\\{?[\\\\w\\\\-\\\\.\\\\:]+\\\\}?\"},{className:\"keyword\",begin:\"\\\\^[\\\\w\\\\-\\\\.\\\\:]+\"},{className:\"number\",begin:\"\\\\^#[0-9a-fA-F]+\"},e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t=\"abstract add and array as asc aspect assembly async begin break block by case class concat const copy constructor continue create default delegate desc distinct div do downto dynamic each else empty end ensure enum equals event except exit extension external false final finalize finalizer finally flags for forward from function future global group has if implementation implements implies in index inherited inline interface into invariants is iterator join locked locking loop matching method mod module namespace nested new nil not notify nullable of old on operator or order out override parallel params partial pinned private procedure property protected public queryable raise read readonly record reintroduce remove repeat require result reverse sealed select self sequence set shl shr skip static step soft take then to true try tuple type union unit unsafe until uses using var virtual raises volatile where while with write xor yield await mapped deprecated stdcall cdecl pascal register safecall overload library platform reference packed strict published autoreleasepool selector strong weak unretained\",n=e.COMMENT(\"{\",\"}\",{relevance:0}),r=e.COMMENT(\"\\\\(\\\\*\",\"\\\\*\\\\)\",{relevance:10}),i={className:\"string\",begin:\"'\",end:\"'\",contains:[{begin:\"''\"}]},a={className:\"string\",begin:\"(#\\\\d+)+\"},o={className:\"function\",beginKeywords:\"function constructor destructor procedure method\",end:\"[:;]\",keywords:\"function constructor|10 destructor|10 procedure|10 method|10\",contains:[e.TITLE_MODE,{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\",keywords:t,contains:[i,a]},n,r]};return{case_insensitive:!0,lexemes:/\\.?\\w+/,keywords:t,illegal:'(\"|\\\\$[G-Zg-z]|\\\\/\\\\*||->)',contains:[n,r,e.C_LINE_COMMENT_MODE,i,a,e.NUMBER_MODE,o,{className:\"class\",begin:\"=\\\\bclass\\\\b\",end:\"end;\",keywords:t,contains:[i,a,n,r,e.C_LINE_COMMENT_MODE,o]}]}}},function(e,t){e.exports=function(e){var t={className:\"keyword\",begin:\"\\\\$(f[asn]|t|vp[rtd]|children)\"},n={className:\"number\",begin:\"\\\\b\\\\d+(\\\\.\\\\d+)?(e-?\\\\d+)?\",relevance:0},r=e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),i={className:\"function\",beginKeywords:\"module function\",end:\"\\\\=|\\\\{\",contains:[{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\",contains:[\"self\",n,r,t,{className:\"literal\",begin:\"false|true|PI|undef\"}]},e.UNDERSCORE_TITLE_MODE]};return{aliases:[\"scad\"],keywords:{keyword:\"function module include use for intersection_for if else \\\\%\",literal:\"false true PI undef\",built_in:\"circle square polygon text sphere cube cylinder polyhedron translate rotate scale resize mirror multmatrix color offset hull minkowski union difference intersection abs sign sin cos tan acos asin atan atan2 floor round ceil ln log pow sqrt exp rands min max concat lookup str chr search version version_num norm cross parent_module echo import import_dxf dxf_linear_extrude linear_extrude rotate_extrude surface projection render children dxf_cross dxf_dim let assign\"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,{className:\"meta\",keywords:{\"meta-keyword\":\"include use\"},begin:\"include|use <\",end:\">\"},r,t,{begin:\"[*!#%]\",relevance:0},i]}}},function(e,t){e.exports=function(e){return{aliases:[\"ml\"],keywords:{keyword:\"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value\",built_in:\"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref\",literal:\"true false\"},illegal:/\\/\\/|>>/,lexemes:\"[a-z_]\\\\w*!?\",contains:[{className:\"literal\",begin:\"\\\\[(\\\\|\\\\|)?\\\\]|\\\\(\\\\)\",relevance:0},e.COMMENT(\"\\\\(\\\\*\",\"\\\\*\\\\)\",{contains:[\"self\"]}),{className:\"symbol\",begin:\"'[A-Za-z_](?!')[\\\\w']*\"},{className:\"type\",begin:\"`[A-Z][\\\\w']*\"},{className:\"type\",begin:\"\\\\b[A-Z][\\\\w']*\",relevance:0},{begin:\"[a-z_]\\\\w*'[\\\\w']*\",relevance:0},e.inherit(e.APOS_STRING_MODE,{className:\"string\",relevance:0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),{className:\"number\",begin:\"\\\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)\",relevance:0},{begin:/[-=]>/}]}}},function(e,t){e.exports=function(e){var t=/[a-zA-Z@][a-zA-Z0-9_]*/,n=\"@interface @class @protocol @implementation\";return{aliases:[\"mm\",\"objc\",\"obj-c\"],keywords:{keyword:\"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN\",literal:\"false true FALSE TRUE nil YES NO NULL\",built_in:\"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once\"},lexemes:t,illegal:\"\"}]}]},{className:\"class\",begin:\"(\"+n.split(\" \").join(\"|\")+\")\\\\b\",end:\"({|$)\",excludeEnd:!0,keywords:n,lexemes:t,contains:[e.UNDERSCORE_TITLE_MODE]},{begin:\"\\\\.\"+e.UNDERSCORE_IDENT_RE,relevance:0}]}}},function(e,t){e.exports=function(e){var t={className:\"variable\",begin:/\\$+{[\\w\\.:-]+}/},n={className:\"variable\",begin:/\\$+\\w+/,illegal:/\\(\\){}/},r={className:\"variable\",begin:/\\$+\\([\\w\\^\\.:-]+\\)/},i={className:\"string\",variants:[{begin:'\"',end:'\"'},{begin:\"'\",end:\"'\"},{begin:\"`\",end:\"`\"}],illegal:/\\n/,contains:[{className:\"subst\",begin:/\\$(\\\\[nrt]|\\$)/},{className:\"variable\",begin:/\\$(ADMINTOOLS|APPDATA|CDBURN_AREA|CMDLINE|COMMONFILES32|COMMONFILES64|COMMONFILES|COOKIES|DESKTOP|DOCUMENTS|EXEDIR|EXEFILE|EXEPATH|FAVORITES|FONTS|HISTORY|HWNDPARENT|INSTDIR|INTERNET_CACHE|LANGUAGE|LOCALAPPDATA|MUSIC|NETHOOD|OUTDIR|PICTURES|PLUGINSDIR|PRINTHOOD|PROFILE|PROGRAMFILES32|PROGRAMFILES64|PROGRAMFILES|QUICKLAUNCH|RECENT|RESOURCES_LOCALIZED|RESOURCES|SENDTO|SMPROGRAMS|SMSTARTUP|STARTMENU|SYSDIR|TEMP|TEMPLATES|VIDEOS|WINDIR)/},t,n,r]};return{case_insensitive:!1,keywords:{keyword:\"Abort AddBrandingImage AddSize AllowRootDirInstall AllowSkipFiles AutoCloseWindow BGFont BGGradient BrandingText BringToFront Call CallInstDLL Caption ChangeUI CheckBitmap ClearErrors CompletedText ComponentText CopyFiles CRCCheck CreateDirectory CreateFont CreateShortCut Delete DeleteINISec DeleteINIStr DeleteRegKey DeleteRegValue DetailPrint DetailsButtonText DirText DirVar DirVerify EnableWindow EnumRegKey EnumRegValue Exch Exec ExecShell ExecWait ExpandEnvStrings File FileBufSize FileClose FileErrorText FileOpen FileRead FileReadByte FileReadUTF16LE FileReadWord FileSeek FileWrite FileWriteByte FileWriteUTF16LE FileWriteWord FindClose FindFirst FindNext FindWindow FlushINI FunctionEnd GetCurInstType GetCurrentAddress GetDlgItem GetDLLVersion GetDLLVersionLocal GetErrorLevel GetFileTime GetFileTimeLocal GetFullPathName GetFunctionAddress GetInstDirError GetLabelAddress GetTempFileName Goto HideWindow Icon IfAbort IfErrors IfFileExists IfRebootFlag IfSilent InitPluginsDir InstallButtonText InstallColors InstallDir InstallDirRegKey InstProgressFlags InstType InstTypeGetText InstTypeSetText IntCmp IntCmpU IntFmt IntOp IsWindow LangString LicenseBkColor LicenseData LicenseForceSelection LicenseLangString LicenseText LoadLanguageFile LockWindow LogSet LogText ManifestDPIAware ManifestSupportedOS MessageBox MiscButtonText Name Nop OutFile Page PageCallbacks PageExEnd Pop Push Quit ReadEnvStr ReadINIStr ReadRegDWORD ReadRegStr Reboot RegDLL Rename RequestExecutionLevel ReserveFile Return RMDir SearchPath SectionEnd SectionGetFlags SectionGetInstTypes SectionGetSize SectionGetText SectionGroupEnd SectionIn SectionSetFlags SectionSetInstTypes SectionSetSize SectionSetText SendMessage SetAutoClose SetBrandingImage SetCompress SetCompressor SetCompressorDictSize SetCtlColors SetCurInstType SetDatablockOptimize SetDateSave SetDetailsPrint SetDetailsView SetErrorLevel SetErrors SetFileAttributes SetFont SetOutPath SetOverwrite SetRebootFlag SetRegView SetShellVarContext SetSilent ShowInstDetails ShowUninstDetails ShowWindow SilentInstall SilentUnInstall Sleep SpaceTexts StrCmp StrCmpS StrCpy StrLen SubCaption Unicode UninstallButtonText UninstallCaption UninstallIcon UninstallSubCaption UninstallText UninstPage UnRegDLL Var VIAddVersionKey VIFileVersion VIProductVersion WindowIcon WriteINIStr WriteRegBin WriteRegDWORD WriteRegExpandStr WriteRegStr WriteUninstaller XPStyle\",literal:\"admin all auto both bottom bzip2 colored components current custom directory false force hide highest ifdiff ifnewer instfiles lastused leave left license listonly lzma nevershow none normal notset off on open print right show silent silentlog smooth textonly top true try un.components un.custom un.directory un.instfiles un.license uninstConfirm user Win10 Win7 Win8 WinVista zlib\"},contains:[e.HASH_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.COMMENT(\";\",\"$\",{relevance:0}),{className:\"function\",beginKeywords:\"Function PageEx Section SectionGroup\",end:\"$\"},i,{className:\"keyword\",begin:/\\!(addincludedir|addplugindir|appendfile|cd|define|delfile|echo|else|endif|error|execute|finalize|getdllversionsystem|ifdef|ifmacrodef|ifmacrondef|ifndef|if|include|insertmacro|macroend|macro|makensis|packhdr|searchparse|searchreplace|tempfile|undef|verbose|warning)/},t,n,r,{className:\"params\",begin:\"(ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HKCR|HKCU|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM|HKPD|HKU|IDABORT|IDCANCEL|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)\"},{className:\"class\",begin:/\\w+\\:\\:\\w+/},e.NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t={keyword:\"rec with let in inherit assert if else then\",literal:\"true false or and null\",built_in:\"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation\"},n={className:\"subst\",begin:/\\$\\{/,end:/}/,keywords:t},r={className:\"string\",contains:[n],variants:[{begin:\"''\",end:\"''\"},{begin:'\"',end:'\"'}]},i=[e.NUMBER_MODE,e.HASH_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,r,{begin:/[a-zA-Z0-9-_]+(\\s*=)/,returnBegin:!0,relevance:0,contains:[{className:\"attr\",begin:/\\S+/}]}];return n.contains=i,{aliases:[\"nixos\"],keywords:t,contains:i}}},function(e,t){e.exports=function(e){return{aliases:[\"nim\"],keywords:{keyword:\"addr and as asm bind block break case cast const continue converter discard distinct div do elif else end enum except export finally for from generic if import in include interface is isnot iterator let macro method mixin mod nil not notin object of or out proc ptr raise ref return shl shr static template try tuple type using var when while with without xor yield\",literal:\"shared guarded stdin stdout stderr result true false\",built_in:\"int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 bool char string cstring pointer expr stmt void auto any range array openarray varargs seq set clong culong cchar cschar cshort cint csize clonglong cfloat cdouble clongdouble cuchar cushort cuint culonglong cstringarray semistatic\"},contains:[{className:\"meta\",begin:/{\\./,end:/\\.}/,relevance:10},{className:\"string\",begin:/[a-zA-Z]\\w*\"/,end:/\"/,contains:[{begin:/\"\"/}]},{className:\"string\",begin:/([a-zA-Z]\\w*)?\"\"\"/,end:/\"\"\"/},e.QUOTE_STRING_MODE,{className:\"type\",begin:/\\b[A-Z]\\w+\\b/,relevance:0},{className:\"number\",relevance:0,variants:[{begin:/\\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?/},{begin:/\\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?/},{begin:/\\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?/},{begin:/\\b(\\d[_\\d]*)('?[iIuUfF](8|16|32|64))?/}]},e.HASH_COMMENT_MODE]}}},function(e,t){e.exports=function(e){var t={className:\"variable\",variants:[{begin:/\\$\\d+/},{begin:/\\$\\{/,end:/}/},{begin:\"[\\\\$\\\\@]\"+e.UNDERSCORE_IDENT_RE}]},n={endsWithParent:!0,lexemes:\"[a-z/_]+\",keywords:{literal:\"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll\"},relevance:0,illegal:\"=>\",contains:[e.HASH_COMMENT_MODE,{className:\"string\",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:/\"/,end:/\"/},{begin:/'/,end:/'/}]},{begin:\"([a-z]+):/\",end:\"\\\\s\",endsWithParent:!0,excludeEnd:!0,contains:[t]},{className:\"regexp\",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:\"\\\\s\\\\^\",end:\"\\\\s|{|;\",returnEnd:!0},{begin:\"~\\\\*?\\\\s+\",end:\"\\\\s|{|;\",returnEnd:!0},{begin:\"\\\\*(\\\\.[a-z\\\\-]+)+\"},{begin:\"([a-z\\\\-]+\\\\.)+\\\\*\"}]},{className:\"number\",begin:\"\\\\b\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}(:\\\\d{1,5})?\\\\b\"},{className:\"number\",begin:\"\\\\b\\\\d+[kKmMgGdshdwy]*\\\\b\",relevance:0},t]};return{aliases:[\"nginxconf\"],contains:[e.HASH_COMMENT_MODE,{begin:e.UNDERSCORE_IDENT_RE+\"\\\\s+{\",returnBegin:!0,end:\"{\",contains:[{className:\"section\",begin:e.UNDERSCORE_IDENT_RE}],relevance:0},{begin:e.UNDERSCORE_IDENT_RE+\"\\\\s\",end:\";|{\",returnBegin:!0,contains:[{className:\"attribute\",begin:e.UNDERSCORE_IDENT_RE,starts:n}],relevance:0}],illegal:\"[^\\\\s\\\\}]\"}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,contains:[{beginKeywords:\"build create index delete drop explain infer|10 insert merge prepare select update upsert|10\",end:/;/,endsWithParent:!0,keywords:{keyword:\"all alter analyze and any array as asc begin between binary boolean break bucket build by call case cast cluster collate collection commit connect continue correlate cover create database dataset datastore declare decrement delete derived desc describe distinct do drop each element else end every except exclude execute exists explain fetch first flatten for force from function grant group gsi having if ignore ilike in include increment index infer inline inner insert intersect into is join key keys keyspace known last left let letting like limit lsm map mapping matched materialized merge minus namespace nest not number object offset on option or order outer over parse partition password path pool prepare primary private privilege procedure public raw realm reduce rename return returning revoke right role rollback satisfies schema select self semi set show some start statistics string system then to transaction trigger truncate under union unique unknown unnest unset update upsert use user using validate value valued values via view when where while with within work xor\",literal:\"true false null missing|5\",built_in:\"array_agg array_append array_concat array_contains array_count array_distinct array_ifnull array_length array_max array_min array_position array_prepend array_put array_range array_remove array_repeat array_replace array_reverse array_sort array_sum avg count max min sum greatest least ifmissing ifmissingornull ifnull missingif nullif ifinf ifnan ifnanorinf naninf neginfif posinfif clock_millis clock_str date_add_millis date_add_str date_diff_millis date_diff_str date_part_millis date_part_str date_trunc_millis date_trunc_str duration_to_str millis str_to_millis millis_to_str millis_to_utc millis_to_zone_name now_millis now_str str_to_duration str_to_utc str_to_zone_name decode_json encode_json encoded_size poly_length base64 base64_encode base64_decode meta uuid abs acos asin atan atan2 ceil cos degrees e exp ln log floor pi power radians random round sign sin sqrt tan trunc object_length object_names object_pairs object_inner_pairs object_values object_inner_values object_add object_put object_remove object_unwrap regexp_contains regexp_like regexp_position regexp_replace contains initcap length lower ltrim position repeat replace rtrim split substr title trim upper isarray isatom isboolean isnumber isobject isstring type toarray toatom toboolean tonumber toobject tostring\"},contains:[{className:\"string\",begin:\"'\",end:\"'\",contains:[e.BACKSLASH_ESCAPE],relevance:0},{className:\"string\",begin:'\"',end:'\"',contains:[e.BACKSLASH_ESCAPE],relevance:0},{className:\"symbol\",begin:\"`\",end:\"`\",contains:[e.BACKSLASH_ESCAPE],relevance:2},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_BLOCK_COMMENT_MODE]}}},function(e,t){e.exports=function(e){var t={keyword:\"if then not for in while do return else elseif break continue switch and or unless when class extends super local import export from using\",literal:\"true false nil\",built_in:\"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table\"},n=\"[A-Za-z$_][0-9A-Za-z$_]*\",r={className:\"subst\",begin:/#\\{/,end:/}/,keywords:t},i=[e.inherit(e.C_NUMBER_MODE,{starts:{end:\"(\\\\s*/)?\",relevance:0}}),{className:\"string\",variants:[{begin:/'/,end:/'/,contains:[e.BACKSLASH_ESCAPE]},{begin:/\"/,end:/\"/,contains:[e.BACKSLASH_ESCAPE,r]}]},{className:\"built_in\",begin:\"@__\"+e.IDENT_RE},{begin:\"@\"+e.IDENT_RE},{begin:e.IDENT_RE+\"\\\\\\\\\"+e.IDENT_RE}];r.contains=i;var a=e.inherit(e.TITLE_MODE,{begin:n}),o={className:\"params\",begin:\"\\\\([^\\\\(]\",returnBegin:!0,contains:[{begin:/\\(/,end:/\\)/,keywords:t,contains:[\"self\"].concat(i)}]};return{aliases:[\"moon\"],keywords:t,illegal:/\\/\\*/,contains:i.concat([e.COMMENT(\"--\",\"$\"),{className:\"function\",begin:\"^\\\\s*\"+n+\"\\\\s*=\\\\s*(\\\\(.*\\\\))?\\\\s*\\\\B[-=]>\",end:\"[-=]>\",returnBegin:!0,contains:[a,o]},{begin:/[\\(,:=]\\s*/,relevance:0,contains:[{className:\"function\",begin:\"(\\\\(.*\\\\))?\\\\s*\\\\B[-=]>\",end:\"[-=]>\",returnBegin:!0,contains:[o]}]},{className:\"class\",beginKeywords:\"class\",end:\"$\",illegal:/[:=\"\\[\\]]/,contains:[{beginKeywords:\"extends\",endsWithParent:!0,illegal:/[:=\"\\[\\]]/,contains:[a]},a]},{className:\"name\",begin:n+\":\",end:\":\",returnBegin:!0,returnEnd:!0,relevance:0}])}}},function(e,t){e.exports=function(e){var t={className:\"number\",relevance:0,variants:[{begin:\"[$][a-fA-F0-9]+\"},e.NUMBER_MODE]};return{case_insensitive:!0,keywords:{keyword:\"public private property continue exit extern new try catch eachin not abstract final select case default const local global field end if then else elseif endif while wend repeat until forever for to step next return module inline throw import\",built_in:\"DebugLog DebugStop Error Print ACos ACosr ASin ASinr ATan ATan2 ATan2r ATanr Abs Abs Ceil Clamp Clamp Cos Cosr Exp Floor Log Max Max Min Min Pow Sgn Sgn Sin Sinr Sqrt Tan Tanr Seed PI HALFPI TWOPI\",literal:\"true false null and or shl shr mod\"},illegal:/\\/\\*/,contains:[e.COMMENT(\"#rem\",\"#end\"),e.COMMENT(\"'\",\"$\",{relevance:0}),{className:\"function\",beginKeywords:\"function method\",end:\"[(=:]|$\",illegal:/\\n/,contains:[e.UNDERSCORE_TITLE_MODE]},{className:\"class\",beginKeywords:\"class interface\",end:\"$\",contains:[{beginKeywords:\"extends implements\"},e.UNDERSCORE_TITLE_MODE]},{className:\"built_in\",begin:\"\\\\b(self|super)\\\\b\"},{className:\"meta\",begin:\"\\\\s*#\",end:\"$\",keywords:{\"meta-keyword\":\"if else elseif endif end then\"}},{className:\"meta\",begin:\"^\\\\s*strict\\\\b\"},{beginKeywords:\"alias\",end:\"=\",contains:[e.UNDERSCORE_TITLE_MODE]},e.QUOTE_STRING_MODE,t]}}},function(e,t){e.exports=function(e){return{subLanguage:\"xml\",contains:[{className:\"meta\",begin:\"^__(END|DATA)__$\"},{begin:\"^\\\\s*%{1,2}={0,2}\",end:\"$\",subLanguage:\"perl\"},{begin:\"<%{1,2}={0,2}\",end:\"={0,1}%>\",subLanguage:\"perl\",excludeBegin:!0,excludeEnd:!0}]}}},function(e,t){e.exports=function(e){var t=\"getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when\",n={className:\"subst\",begin:\"[$@]\\\\{\",end:\"\\\\}\",keywords:t},r={begin:\"->{\",end:\"}\"},i={variants:[{begin:/\\$\\d/},{begin:/[\\$%@](\\^\\w\\b|#\\w+(::\\w+)*|{\\w+}|\\w+(::\\w*)*)/},{begin:/[\\$%@][^\\s\\w{]/,relevance:0}]},a=[e.BACKSLASH_ESCAPE,n,i],o=[i,e.HASH_COMMENT_MODE,e.COMMENT(\"^\\\\=\\\\w\",\"\\\\=cut\",{endsWithParent:!0}),r,{className:\"string\",contains:a,variants:[{begin:\"q[qwxr]?\\\\s*\\\\(\",end:\"\\\\)\",relevance:5},{begin:\"q[qwxr]?\\\\s*\\\\[\",end:\"\\\\]\",relevance:5},{begin:\"q[qwxr]?\\\\s*\\\\{\",end:\"\\\\}\",relevance:5},{begin:\"q[qwxr]?\\\\s*\\\\|\",end:\"\\\\|\",relevance:5},{begin:\"q[qwxr]?\\\\s*\\\\<\",end:\"\\\\>\",relevance:5},{begin:\"qw\\\\s+q\",end:\"q\",relevance:5},{begin:\"'\",end:\"'\",contains:[e.BACKSLASH_ESCAPE]},{begin:'\"',end:'\"'},{begin:\"`\",end:\"`\",contains:[e.BACKSLASH_ESCAPE]},{begin:\"{\\\\w+}\",contains:[],relevance:0},{begin:\"-?\\\\w+\\\\s*\\\\=\\\\>\",contains:[],relevance:0}]},{className:\"number\",begin:\"(\\\\b0[0-7_]+)|(\\\\b0x[0-9a-fA-F_]+)|(\\\\b[1-9][0-9_]*(\\\\.[0-9_]+)?)|[0_]\\\\b\",relevance:0},{begin:\"(\\\\/\\\\/|\"+e.RE_STARTERS_RE+\"|\\\\b(split|return|print|reverse|grep)\\\\b)\\\\s*\",keywords:\"split return print reverse grep\",relevance:0,contains:[e.HASH_COMMENT_MODE,{className:\"regexp\",begin:\"(s|tr|y)/(\\\\\\\\.|[^/])*/(\\\\\\\\.|[^/])*/[a-z]*\",relevance:10},{className:\"regexp\",begin:\"(m|qr)?/\",end:\"/[a-z]*\",contains:[e.BACKSLASH_ESCAPE],relevance:0}]},{className:\"function\",beginKeywords:\"sub\",end:\"(\\\\s*\\\\(.*?\\\\))?[;{]\",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{begin:\"-\\\\w\\\\b\",relevance:0},{begin:\"^__DATA__$\",end:\"^__END__$\",subLanguage:\"mojolicious\",contains:[{begin:\"^@@.*\",end:\"$\",className:\"comment\"}]}];return n.contains=o,r.contains=o,{aliases:[\"pl\",\"pm\"],lexemes:/[\\w\\.]+/,keywords:t,contains:o}}},function(e,t){e.exports=function(e){return{keywords:\"environ vocabularies notations constructors definitions registrations theorems schemes requirements begin end definition registration cluster existence pred func defpred deffunc theorem proof let take assume then thus hence ex for st holds consider reconsider such that and in provided of as from be being by means equals implies iff redefine define now not or attr is mode suppose per cases set thesis contradiction scheme reserve struct correctness compatibility coherence symmetry assymetry reflexivity irreflexivity connectedness uniqueness commutativity idempotence involutiveness projectivity\",contains:[e.COMMENT(\"::\",\"$\")]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,aliases:[\"mips\"],lexemes:\"\\\\.?\"+e.IDENT_RE,keywords:{meta:\".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .ltorg \",built_in:\"$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 $17 $18 $19 $20 $21 $22 $23 $24 $25 $26 $27 $28 $29 $30 $31 zero at v0 v1 a0 a1 a2 a3 a4 a5 a6 a7 t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 s0 s1 s2 s3 s4 s5 s6 s7 s8 k0 k1 gp sp fp ra $f0 $f1 $f2 $f2 $f4 $f5 $f6 $f7 $f8 $f9 $f10 $f11 $f12 $f13 $f14 $f15 $f16 $f17 $f18 $f19 $f20 $f21 $f22 $f23 $f24 $f25 $f26 $f27 $f28 $f29 $f30 $f31 Context Random EntryLo0 EntryLo1 Context PageMask Wired EntryHi HWREna BadVAddr Count Compare SR IntCtl SRSCtl SRSMap Cause EPC PRId EBase Config Config1 Config2 Config3 LLAddr Debug DEPC DESAVE CacheErr ECC ErrorEPC TagLo DataLo TagHi DataHi WatchLo WatchHi PerfCtl PerfCnt \"},contains:[{className:\"keyword\",begin:\"\\\\b(addi?u?|andi?|b(al)?|beql?|bgez(al)?l?|bgtzl?|blezl?|bltz(al)?l?|bnel?|cl[oz]|divu?|ext|ins|j(al)?|jalr(.hb)?|jr(.hb)?|lbu?|lhu?|ll|lui|lw[lr]?|maddu?|mfhi|mflo|movn|movz|move|msubu?|mthi|mtlo|mul|multu?|nop|nor|ori?|rotrv?|sb|sc|se[bh]|sh|sllv?|slti?u?|srav?|srlv?|subu?|sw[lr]?|xori?|wsbh|abs.[sd]|add.[sd]|alnv.ps|bc1[ft]l?|c.(s?f|un|u?eq|[ou]lt|[ou]le|ngle?|seq|l[et]|ng[et]).[sd]|(ceil|floor|round|trunc).[lw].[sd]|cfc1|cvt.d.[lsw]|cvt.l.[dsw]|cvt.ps.s|cvt.s.[dlw]|cvt.s.p[lu]|cvt.w.[dls]|div.[ds]|ldx?c1|luxc1|lwx?c1|madd.[sd]|mfc1|mov[fntz]?.[ds]|msub.[sd]|mth?c1|mul.[ds]|neg.[ds]|nmadd.[ds]|nmsub.[ds]|p[lu][lu].ps|recip.fmt|r?sqrt.[ds]|sdx?c1|sub.[ds]|suxc1|swx?c1|break|cache|d?eret|[de]i|ehb|mfc0|mtc0|pause|prefx?|rdhwr|rdpgpr|sdbbp|ssnop|synci?|syscall|teqi?|tgei?u?|tlb(p|r|w[ir])|tlti?u?|tnei?|wait|wrpgpr)\",end:\"\\\\s\"},e.COMMENT(\"[;#]\",\"$\"),e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,{className:\"string\",begin:\"'\",end:\"[^\\\\\\\\]'\",relevance:0},{className:\"title\",begin:\"\\\\|\",end:\"\\\\|\",illegal:\"\\\\n\",relevance:0},{className:\"number\",variants:[{begin:\"0x[0-9a-f]+\"},{begin:\"\\\\b-?\\\\d+\"}],relevance:0},{className:\"symbol\",variants:[{begin:\"^\\\\s*[a-z_\\\\.\\\\$][a-z0-9_\\\\.\\\\$]+:\"},{begin:\"^\\\\s*[0-9]+:\"},{begin:\"[0-9]+[bf]\"}],relevance:0}],illegal:\"/\"}}},function(e,t){e.exports=function(e){var t=e.COMMENT(\"%\",\"$\"),n=e.inherit(e.APOS_STRING_MODE,{relevance:0}),r=e.inherit(e.QUOTE_STRING_MODE,{relevance:0});r.contains.push({className:\"subst\",begin:\"\\\\\\\\[abfnrtv]\\\\|\\\\\\\\x[0-9a-fA-F]*\\\\\\\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]\",relevance:0});return{aliases:[\"m\",\"moo\"],keywords:{keyword:\"module use_module import_module include_module end_module initialise mutable initialize finalize finalise interface implementation pred mode func type inst solver any_pred any_func is semidet det nondet multi erroneous failure cc_nondet cc_multi typeclass instance where pragma promise external trace atomic or_else require_complete_switch require_det require_semidet require_multi require_nondet require_cc_multi require_cc_nondet require_erroneous require_failure\",meta:\"inline no_inline type_spec source_file fact_table obsolete memo loop_check minimal_model terminates does_not_terminate check_termination promise_equivalent_clauses foreign_proc foreign_decl foreign_code foreign_type foreign_import_module foreign_export_enum foreign_export foreign_enum may_call_mercury will_not_call_mercury thread_safe not_thread_safe maybe_thread_safe promise_pure promise_semipure tabled_for_io local untrailed trailed attach_to_io_state can_pass_as_mercury_type stable will_not_throw_exception may_modify_trail will_not_modify_trail may_duplicate may_not_duplicate affects_liveness does_not_affect_liveness doesnt_affect_liveness no_sharing unknown_sharing sharing\",built_in:\"some all not if then else true fail false try catch catch_any semidet_true semidet_false semidet_fail impure_true impure semipure\"},contains:[{className:\"built_in\",variants:[{begin:\"<=>\"},{begin:\"<=\",relevance:0},{begin:\"=>\",relevance:0},{begin:\"/\\\\\\\\\"},{begin:\"\\\\\\\\/\"}]},{className:\"built_in\",variants:[{begin:\":-\\\\|--\\x3e\"},{begin:\"=\",relevance:0}]},t,e.C_BLOCK_COMMENT_MODE,{className:\"number\",begin:\"0'.\\\\|0[box][0-9a-fA-F]*\"},e.NUMBER_MODE,n,r,{begin:/:-/}]}}},function(e,t){e.exports=function(e){return{keywords:\"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform\",illegal:\"\\\\*?\",end:\"\\\\->\\\\*?\"},{begin:\"(\"+n+\"\\\\s*(?:=|:=)\\\\s*)?!?(\\\\(.*\\\\))?\\\\s*\\\\B[-~]{1,2}>\\\\*?\",end:\"[-~]{1,2}>\\\\*?\"},{begin:\"(\"+n+\"\\\\s*(?:=|:=)\\\\s*)?(\\\\(.*\\\\))?\\\\s*\\\\B!?[-~]{1,2}>\\\\*?\",end:\"!?[-~]{1,2}>\\\\*?\"}]},{className:\"class\",beginKeywords:\"class\",end:\"$\",illegal:/[:=\"\\[\\]]/,contains:[{beginKeywords:\"extends\",endsWithParent:!0,illegal:/[:=\"\\[\\]]/,contains:[r]},r]},{begin:n+\":\",end:\":\",returnBegin:!0,returnEnd:!0,relevance:0}])}}},function(e,t){e.exports=function(e){var t={begin:\"\\\\b[gtps][A-Z]+[A-Za-z0-9_\\\\-]*\\\\b|\\\\$_[A-Z]+\",relevance:0},n=[e.C_BLOCK_COMMENT_MODE,e.HASH_COMMENT_MODE,e.COMMENT(\"--\",\"$\"),e.COMMENT(\"[^:]//\",\"$\")],r=e.inherit(e.TITLE_MODE,{variants:[{begin:\"\\\\b_*rig[A-Z]+[A-Za-z0-9_\\\\-]*\"},{begin:\"\\\\b_[a-z0-9\\\\-]+\"}]}),i=e.inherit(e.TITLE_MODE,{begin:\"\\\\b([A-Za-z0-9_\\\\-]+)\\\\b\"});return{case_insensitive:!1,keywords:{keyword:\"$_COOKIE $_FILES $_GET $_GET_BINARY $_GET_RAW $_POST $_POST_BINARY $_POST_RAW $_SESSION $_SERVER codepoint codepoints segment segments codeunit codeunits sentence sentences trueWord trueWords paragraph after byte bytes english the until http forever descending using line real8 with seventh for stdout finally element word words fourth before black ninth sixth characters chars stderr uInt1 uInt1s uInt2 uInt2s stdin string lines relative rel any fifth items from middle mid at else of catch then third it file milliseconds seconds second secs sec int1 int1s int4 int4s internet int2 int2s normal text item last long detailed effective uInt4 uInt4s repeat end repeat URL in try into switch to words https token binfile each tenth as ticks tick system real4 by dateItems without char character ascending eighth whole dateTime numeric short first ftp integer abbreviated abbr abbrev private case while if div mod wrap and or bitAnd bitNot bitOr bitXor among not in a an within contains ends with begins the keys of keys\",literal:\"SIX TEN FORMFEED NINE ZERO NONE SPACE FOUR FALSE COLON CRLF PI COMMA ENDOFFILE EOF EIGHT FIVE QUOTE EMPTY ONE TRUE RETURN CR LINEFEED RIGHT BACKSLASH NULL SEVEN TAB THREE TWO six ten formfeed nine zero none space four false colon crlf pi comma endoffile eof eight five quote empty one true return cr linefeed right backslash null seven tab three two RIVERSION RISTATE FILE_READ_MODE FILE_WRITE_MODE FILE_WRITE_MODE DIR_WRITE_MODE FILE_READ_UMASK FILE_WRITE_UMASK DIR_READ_UMASK DIR_WRITE_UMASK\",built_in:\"put abs acos aliasReference annuity arrayDecode arrayEncode asin atan atan2 average avg avgDev base64Decode base64Encode baseConvert binaryDecode binaryEncode byteOffset byteToNum cachedURL cachedURLs charToNum cipherNames codepointOffset codepointProperty codepointToNum codeunitOffset commandNames compound compress constantNames cos date dateFormat decompress directories diskSpace DNSServers exp exp1 exp2 exp10 extents files flushEvents folders format functionNames geometricMean global globals hasMemory harmonicMean hostAddress hostAddressToName hostName hostNameToAddress isNumber ISOToMac itemOffset keys len length libURLErrorData libUrlFormData libURLftpCommand libURLLastHTTPHeaders libURLLastRHHeaders libUrlMultipartFormAddPart libUrlMultipartFormData libURLVersion lineOffset ln ln1 localNames log log2 log10 longFilePath lower macToISO matchChunk matchText matrixMultiply max md5Digest median merge millisec millisecs millisecond milliseconds min monthNames nativeCharToNum normalizeText num number numToByte numToChar numToCodepoint numToNativeChar offset open openfiles openProcesses openProcessIDs openSockets paragraphOffset paramCount param params peerAddress pendingMessages platform popStdDev populationStandardDeviation populationVariance popVariance processID random randomBytes replaceText result revCreateXMLTree revCreateXMLTreeFromFile revCurrentRecord revCurrentRecordIsFirst revCurrentRecordIsLast revDatabaseColumnCount revDatabaseColumnIsNull revDatabaseColumnLengths revDatabaseColumnNames revDatabaseColumnNamed revDatabaseColumnNumbered revDatabaseColumnTypes revDatabaseConnectResult revDatabaseCursors revDatabaseID revDatabaseTableNames revDatabaseType revDataFromQuery revdb_closeCursor revdb_columnbynumber revdb_columncount revdb_columnisnull revdb_columnlengths revdb_columnnames revdb_columntypes revdb_commit revdb_connect revdb_connections revdb_connectionerr revdb_currentrecord revdb_cursorconnection revdb_cursorerr revdb_cursors revdb_dbtype revdb_disconnect revdb_execute revdb_iseof revdb_isbof revdb_movefirst revdb_movelast revdb_movenext revdb_moveprev revdb_query revdb_querylist revdb_recordcount revdb_rollback revdb_tablenames revGetDatabaseDriverPath revNumberOfRecords revOpenDatabase revOpenDatabases revQueryDatabase revQueryDatabaseBlob revQueryResult revQueryIsAtStart revQueryIsAtEnd revUnixFromMacPath revXMLAttribute revXMLAttributes revXMLAttributeValues revXMLChildContents revXMLChildNames revXMLCreateTreeFromFileWithNamespaces revXMLCreateTreeWithNamespaces revXMLDataFromXPathQuery revXMLEvaluateXPath revXMLFirstChild revXMLMatchingNode revXMLNextSibling revXMLNodeContents revXMLNumberOfChildren revXMLParent revXMLPreviousSibling revXMLRootNode revXMLRPC_CreateRequest revXMLRPC_Documents revXMLRPC_Error revXMLRPC_GetHost revXMLRPC_GetMethod revXMLRPC_GetParam revXMLText revXMLRPC_Execute revXMLRPC_GetParamCount revXMLRPC_GetParamNode revXMLRPC_GetParamType revXMLRPC_GetPath revXMLRPC_GetPort revXMLRPC_GetProtocol revXMLRPC_GetRequest revXMLRPC_GetResponse revXMLRPC_GetSocket revXMLTree revXMLTrees revXMLValidateDTD revZipDescribeItem revZipEnumerateItems revZipOpenArchives round sampVariance sec secs seconds sentenceOffset sha1Digest shell shortFilePath sin specialFolderPath sqrt standardDeviation statRound stdDev sum sysError systemVersion tan tempName textDecode textEncode tick ticks time to tokenOffset toLower toUpper transpose truewordOffset trunc uniDecode uniEncode upper URLDecode URLEncode URLStatus uuid value variableNames variance version waitDepth weekdayNames wordOffset xsltApplyStylesheet xsltApplyStylesheetFromFile xsltLoadStylesheet xsltLoadStylesheetFromFile add breakpoint cancel clear local variable file word line folder directory URL close socket process combine constant convert create new alias folder directory decrypt delete variable word line folder directory URL dispatch divide do encrypt filter get include intersect kill libURLDownloadToFile libURLFollowHttpRedirects libURLftpUpload libURLftpUploadFile libURLresetAll libUrlSetAuthCallback libURLSetCustomHTTPHeaders libUrlSetExpect100 libURLSetFTPListCommand libURLSetFTPMode libURLSetFTPStopTime libURLSetStatusCallback load multiply socket prepare process post seek rel relative read from process rename replace require resetAll resolve revAddXMLNode revAppendXML revCloseCursor revCloseDatabase revCommitDatabase revCopyFile revCopyFolder revCopyXMLNode revDeleteFolder revDeleteXMLNode revDeleteAllXMLTrees revDeleteXMLTree revExecuteSQL revGoURL revInsertXMLNode revMoveFolder revMoveToFirstRecord revMoveToLastRecord revMoveToNextRecord revMoveToPreviousRecord revMoveToRecord revMoveXMLNode revPutIntoXMLNode revRollBackDatabase revSetDatabaseDriverPath revSetXMLAttribute revXMLRPC_AddParam revXMLRPC_DeleteAllDocuments revXMLAddDTD revXMLRPC_Free revXMLRPC_FreeAll revXMLRPC_DeleteDocument revXMLRPC_DeleteParam revXMLRPC_SetHost revXMLRPC_SetMethod revXMLRPC_SetPort revXMLRPC_SetProtocol revXMLRPC_SetSocket revZipAddItemWithData revZipAddItemWithFile revZipAddUncompressedItemWithData revZipAddUncompressedItemWithFile revZipCancel revZipCloseArchive revZipDeleteItem revZipExtractItemToFile revZipExtractItemToVariable revZipSetProgressCallback revZipRenameItem revZipReplaceItemWithData revZipReplaceItemWithFile revZipOpenArchive send set sort split start stop subtract union unload wait write\"},contains:[t,{className:\"keyword\",begin:\"\\\\bend\\\\sif\\\\b\"},{className:\"function\",beginKeywords:\"function\",end:\"$\",contains:[t,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE,r]},{className:\"function\",begin:\"\\\\bend\\\\s+\",end:\"$\",keywords:\"end\",contains:[i,r],relevance:0},{beginKeywords:\"command on\",end:\"$\",contains:[t,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE,r]},{className:\"meta\",variants:[{begin:\"<\\\\?(rev|lc|livecode)\",relevance:10},{begin:\"<\\\\?\"},{begin:\"\\\\?>\"}]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE,r].concat(n),illegal:\";$|^\\\\[|^=|&|{\"}}},function(e,t){e.exports=function(e){var t=\"[a-zA-Z_\\\\-\\\\+\\\\*\\\\/\\\\<\\\\=\\\\>\\\\&\\\\#][a-zA-Z0-9_\\\\-\\\\+\\\\*\\\\/\\\\<\\\\=\\\\>\\\\&\\\\#!]*\",n=\"(\\\\-|\\\\+)?\\\\d+(\\\\.\\\\d+|\\\\/\\\\d+)?((d|e|f|l|s|D|E|F|L|S)(\\\\+|\\\\-)?\\\\d+)?\",r={className:\"literal\",begin:\"\\\\b(t{1}|nil)\\\\b\"},i={className:\"number\",variants:[{begin:n,relevance:0},{begin:\"#(b|B)[0-1]+(/[0-1]+)?\"},{begin:\"#(o|O)[0-7]+(/[0-7]+)?\"},{begin:\"#(x|X)[0-9a-fA-F]+(/[0-9a-fA-F]+)?\"},{begin:\"#(c|C)\\\\(\"+n+\" +\"+n,end:\"\\\\)\"}]},a=e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),o=e.COMMENT(\";\",\"$\",{relevance:0}),s={begin:\"\\\\*\",end:\"\\\\*\"},l={className:\"symbol\",begin:\"[:&]\"+t},c={begin:t,relevance:0},u={begin:\"\\\\|[^]*?\\\\|\"},d={contains:[i,a,s,l,{begin:\"\\\\(\",end:\"\\\\)\",contains:[\"self\",r,a,i,c]},c],variants:[{begin:\"['`]\\\\(\",end:\"\\\\)\"},{begin:\"\\\\(quote \",end:\"\\\\)\",keywords:{name:\"quote\"}},{begin:\"'\\\\|[^]*?\\\\|\"}]},f={variants:[{begin:\"'\"+t},{begin:\"#'\"+t+\"(::\"+t+\")*\"}]},p={begin:\"\\\\(\\\\s*\",end:\"\\\\)\"},m={endsWithParent:!0,relevance:0};return p.contains=[{className:\"name\",variants:[{begin:t},{begin:\"\\\\|[^]*?\\\\|\"}]},m],m.contains=[d,f,p,r,i,a,o,s,l,u,c],{illegal:/\\S/,contains:[i,{className:\"meta\",begin:\"^#!\",end:\"$\"},r,a,o,d,f,p,c]}}},function(e,t){e.exports=function(e){var t=\"([\\\\w-]+|@{[\\\\w-]+})\",n=[],r=[],i=function(e){return{className:\"string\",begin:\"~?\"+e+\".*?\"+e}},a=function(e,t,n){return{className:e,begin:t,relevance:n}},o={begin:\"\\\\(\",end:\"\\\\)\",contains:r,relevance:0};r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,i(\"'\"),i('\"'),e.CSS_NUMBER_MODE,{begin:\"(url|data-uri)\\\\(\",starts:{className:\"string\",end:\"[\\\\)\\\\n]\",excludeEnd:!0}},a(\"number\",\"#[0-9A-Fa-f]+\\\\b\"),o,a(\"variable\",\"@@?[\\\\w-]+\",10),a(\"variable\",\"@{[\\\\w-]+}\"),a(\"built_in\",\"~?`[^`]*?`\"),{className:\"attribute\",begin:\"[\\\\w-]+\\\\s*:\",end:\":\",returnBegin:!0,excludeEnd:!0},{className:\"meta\",begin:\"!important\"});var s=r.concat({begin:\"{\",end:\"}\",contains:n}),l={beginKeywords:\"when\",endsWithParent:!0,contains:[{beginKeywords:\"and not\"}].concat(r)},c={begin:t+\"\\\\s*:\",returnBegin:!0,end:\"[;}]\",relevance:0,contains:[{className:\"attribute\",begin:t,end:\":\",excludeEnd:!0,starts:{endsWithParent:!0,illegal:\"[<=$]\",relevance:0,contains:r}}]},u={className:\"keyword\",begin:\"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\\\b\",starts:{end:\"[;{}]\",returnEnd:!0,contains:r,relevance:0}},d={className:\"variable\",variants:[{begin:\"@[\\\\w-]+\\\\s*:\",relevance:15},{begin:\"@[\\\\w-]+\"}],starts:{end:\"[;}]\",returnEnd:!0,contains:s}},f={variants:[{begin:\"[\\\\.#:&\\\\[>]\",end:\"[;{}]\"},{begin:t,end:\"{\"}],returnBegin:!0,returnEnd:!0,illegal:\"[<='$\\\"]\",relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,l,a(\"keyword\",\"all\\\\b\"),a(\"variable\",\"@{[\\\\w-]+}\"),a(\"selector-tag\",t+\"%?\",0),a(\"selector-id\",\"#\"+t),a(\"selector-class\",\"\\\\.\"+t,0),a(\"selector-tag\",\"&\",0),{className:\"selector-attr\",begin:\"\\\\[\",end:\"\\\\]\"},{className:\"selector-pseudo\",begin:/:(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\"'.]+/},{begin:\"\\\\(\",end:\"\\\\)\",contains:s},{begin:\"!important\"}]};return n.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,u,d,c,f),{case_insensitive:!0,illegal:\"[=>'/<($\\\"]\",contains:n}}},function(e,t){e.exports=function(e){return{contains:[{className:\"function\",begin:\"#+[A-Za-z_0-9]*\\\\(\",end:\" {\",returnBegin:!0,excludeEnd:!0,contains:[{className:\"keyword\",begin:\"#+\"},{className:\"title\",begin:\"[A-Za-z_][A-Za-z_0-9]*\"},{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\",endsParent:!0,contains:[{className:\"string\",begin:'\"',end:'\"'},{className:\"variable\",begin:\"[A-Za-z_][A-Za-z_0-9]*\"}]}]}]}}},function(e,t){e.exports=function(e){return{contains:[{className:\"attribute\",begin:\"^dn\",end:\": \",excludeEnd:!0,starts:{end:\"$\",relevance:0},relevance:10},{className:\"attribute\",begin:\"^\\\\w\",end:\": \",excludeEnd:!0,starts:{end:\"$\",relevance:0}},{className:\"literal\",begin:\"^-\",end:\"$\"},e.HASH_COMMENT_MODE]}}},function(e,t){e.exports=function(e){var t=\"\\\\]|\\\\?>\",n={literal:\"true false none minimal full all void and or not bw nbw ew new cn ncn lt lte gt gte eq neq rx nrx ft\",built_in:\"array date decimal duration integer map pair string tag xml null boolean bytes keyword list locale queue set stack staticarray local var variable global data self inherited currentcapture givenblock\",keyword:\"cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else fail_if fail_ifnot fail if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require returnhome skip split_thread sum take thread to trait type where with yield yieldhome\"},r=e.COMMENT(\"\\x3c!--\",\"--\\x3e\",{relevance:0}),i={className:\"meta\",begin:\"\\\\[noprocess\\\\]\",starts:{end:\"\\\\[/noprocess\\\\]\",returnEnd:!0,contains:[r]}},a={className:\"meta\",begin:\"\\\\[/noprocess|<\\\\?(lasso(script)?|=)\"},o={className:\"symbol\",begin:\"'[a-zA-Z_][\\\\w.]*'\"},s=[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.inherit(e.C_NUMBER_MODE,{begin:e.C_NUMBER_RE+\"|(-?infinity|NaN)\\\\b\"}),e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),{className:\"string\",begin:\"`\",end:\"`\"},{variants:[{begin:\"[#$][a-zA-Z_][\\\\w.]*\"},{begin:\"#\",end:\"\\\\d+\",illegal:\"\\\\W\"}]},{className:\"type\",begin:\"::\\\\s*\",end:\"[a-zA-Z_][\\\\w.]*\",illegal:\"\\\\W\"},{className:\"params\",variants:[{begin:\"-(?!infinity)[a-zA-Z_][\\\\w.]*\",relevance:0},{begin:\"(\\\\.\\\\.\\\\.)\"}]},{begin:/(->|\\.)\\s*/,relevance:0,contains:[o]},{className:\"class\",beginKeywords:\"define\",returnEnd:!0,end:\"\\\\(|=>\",contains:[e.inherit(e.TITLE_MODE,{begin:\"[a-zA-Z_][\\\\w.]*(=(?!>))?|[-+*/%](?!>)\"})]}];return{aliases:[\"ls\",\"lassoscript\"],case_insensitive:!0,lexemes:\"[a-zA-Z_][\\\\w.]*|&[lg]t;\",keywords:n,contains:[{className:\"meta\",begin:t,relevance:0,starts:{end:\"\\\\[|<\\\\?(lasso(script)?|=)\",returnEnd:!0,relevance:0,contains:[r]}},i,a,{className:\"meta\",begin:\"\\\\[no_square_brackets\",starts:{end:\"\\\\[/no_square_brackets\\\\]\",lexemes:\"[a-zA-Z_][\\\\w.]*|&[lg]t;\",keywords:n,contains:[{className:\"meta\",begin:t,relevance:0,starts:{end:\"\\\\[noprocess\\\\]|<\\\\?(lasso(script)?|=)\",returnEnd:!0,contains:[r]}},i,a].concat(s)}},{className:\"meta\",begin:\"\\\\[\",relevance:0},{className:\"meta\",begin:\"^#!\",end:\"lasso9$\",relevance:10}].concat(s)}}},function(e,t){e.exports=function(e){var t={keyword:\"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit initinterface annotation data sealed internal infix operator out by constructor super trait volatile transient native default\",built_in:\"Byte Short Char Int Long Boolean Float Double Void Unit Nothing\",literal:\"true false null\"},n={className:\"symbol\",begin:e.UNDERSCORE_IDENT_RE+\"@\"},r={className:\"subst\",begin:\"\\\\${\",end:\"}\",contains:[e.APOS_STRING_MODE,e.C_NUMBER_MODE]},i={className:\"variable\",begin:\"\\\\$\"+e.UNDERSCORE_IDENT_RE},a={className:\"string\",variants:[{begin:'\"\"\"',end:'\"\"\"',contains:[i,r]},{begin:\"'\",end:\"'\",illegal:/\\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'\"',end:'\"',illegal:/\\n/,contains:[e.BACKSLASH_ESCAPE,i,r]}]},o={className:\"meta\",begin:\"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\\\s*:(?:\\\\s*\"+e.UNDERSCORE_IDENT_RE+\")?\"},s={className:\"meta\",begin:\"@\"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\\(/,end:/\\)/,contains:[e.inherit(a,{className:\"meta-string\"})]}]};return{keywords:t,contains:[e.COMMENT(\"/\\\\*\\\\*\",\"\\\\*/\",{relevance:0,contains:[{className:\"doctag\",begin:\"@[A-Za-z]+\"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:\"keyword\",begin:/\\b(break|continue|return|this)\\b/,starts:{contains:[{className:\"symbol\",begin:/@\\w+/}]}},n,o,s,{className:\"function\",beginKeywords:\"fun\",end:\"[(]|$\",returnBegin:!0,excludeEnd:!0,keywords:t,illegal:/fun\\s+(<.*>)?[^\\s\\(]+(\\s+[^\\s\\(]+)\\s*=/,relevance:5,contains:[{begin:e.UNDERSCORE_IDENT_RE+\"\\\\s*\\\\(\",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:\"type\",begin://,keywords:\"reified\",relevance:0},{className:\"params\",begin:/\\(/,end:/\\)/,endsParent:!0,keywords:t,relevance:0,contains:[{begin:/:/,end:/[=,\\/]/,endsWithParent:!0,contains:[{className:\"type\",begin:e.UNDERSCORE_IDENT_RE},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],relevance:0},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,o,s,a,e.C_NUMBER_MODE]},e.C_BLOCK_COMMENT_MODE]},{className:\"class\",beginKeywords:\"class interface trait\",end:/[:\\{(]|$/,excludeEnd:!0,illegal:\"extends implements\",contains:[{beginKeywords:\"public protected internal private constructor\"},e.UNDERSCORE_TITLE_MODE,{className:\"type\",begin://,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:\"type\",begin:/[,:]\\s*/,end:/[<\\(,]|$/,excludeBegin:!0,returnEnd:!0},o,s]},a,{className:\"meta\",begin:\"^#!/usr/bin/env\",end:\"$\",illegal:\"\\n\"},e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{contains:[{className:\"meta\",begin:/^julia>/,relevance:10,starts:{end:/^(?![ ]{6})/,subLanguage:\"julia\"},aliases:[\"jldoctest\"]}]}}},function(e,t){e.exports=function(e){var t={keyword:\"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias \",literal:\"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ \",built_in:\"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool \"},n=\"[A-Za-z_\\\\u00A1-\\\\uFFFF][A-Za-z_0-9\\\\u00A1-\\\\uFFFF]*\",r={lexemes:n,keywords:t,illegal:/<\\//},i={className:\"subst\",begin:/\\$\\(/,end:/\\)/,keywords:t},a={className:\"variable\",begin:\"\\\\$\"+n},o={className:\"string\",contains:[e.BACKSLASH_ESCAPE,i,a],variants:[{begin:/\\w*\"\"\"/,end:/\"\"\"\\w*/,relevance:10},{begin:/\\w*\"/,end:/\"\\w*/}]},s={className:\"string\",contains:[e.BACKSLASH_ESCAPE,i,a],begin:\"`\",end:\"`\"},l={className:\"meta\",begin:\"@\"+n};return r.contains=[{className:\"number\",begin:/(\\b0x[\\d_]*(\\.[\\d_]*)?|0x\\.\\d[\\d_]*)p[-+]?\\d+|\\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\\b\\d[\\d_]*(\\.[\\d_]*)?|\\.\\d[\\d_]*)([eEfF][-+]?\\d+)?/,relevance:0},{className:\"string\",begin:/'(.|\\\\[xXuU][a-zA-Z0-9]+)'/},o,s,l,{className:\"comment\",variants:[{begin:\"#=\",end:\"=#\",relevance:10},{begin:\"#\",end:\"$\"}]},e.HASH_COMMENT_MODE,{className:\"keyword\",begin:\"\\\\b(((abstract|primitive)\\\\s+)type|(mutable\\\\s+)?struct)\\\\b\"},{begin:/<:/}],i.contains=r.contains,r}},function(e,t){e.exports=function(e){var t={literal:\"true false null\"},n=[e.QUOTE_STRING_MODE,e.C_NUMBER_MODE],r={end:\",\",endsWithParent:!0,excludeEnd:!0,contains:n,keywords:t},i={begin:\"{\",end:\"}\",contains:[{className:\"attr\",begin:/\"/,end:/\"/,contains:[e.BACKSLASH_ESCAPE],illegal:\"\\\\n\"},e.inherit(r,{begin:/:/})],illegal:\"\\\\S\"},a={begin:\"\\\\[\",end:\"\\\\]\",contains:[e.inherit(r)],illegal:\"\\\\S\"};return n.splice(n.length,0,i,a),{contains:n,keywords:t,illegal:\"\\\\S\"}}},function(e,t){e.exports=function(e){var t={className:\"params\",begin:/\\(/,end:/\\)/,contains:[{begin:/[\\w-]+ *=/,returnBegin:!0,relevance:0,contains:[{className:\"attr\",begin:/[\\w-]+/}]}],relevance:0};return{aliases:[\"wildfly-cli\"],lexemes:\"[a-z-]+\",keywords:{keyword:\"alias batch cd clear command connect connection-factory connection-info data-source deploy deployment-info deployment-overlay echo echo-dmr help history if jdbc-driver-info jms-queue|20 jms-topic|20 ls patch pwd quit read-attribute read-operation reload rollout-plan run-batch set shutdown try unalias undeploy unset version xa-data-source\",literal:\"true false\"},contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,{className:\"params\",begin:/--[\\w\\-=\\/]+/},{className:\"function\",begin:/:[\\w\\-.]+/,relevance:0},{className:\"string\",begin:/\\B(([\\/.])[\\w\\-.\\/=]+)+/},t]}}},function(e,t){e.exports=function(e){var t=\"[A-Za-z$_][0-9A-Za-z$_]*\",n={keyword:\"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as\",literal:\"true false null undefined NaN Infinity\",built_in:\"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise\"},r={className:\"number\",variants:[{begin:\"\\\\b(0[bB][01]+)\"},{begin:\"\\\\b(0[oO][0-7]+)\"},{begin:e.C_NUMBER_RE}],relevance:0},i={className:\"subst\",begin:\"\\\\$\\\\{\",end:\"\\\\}\",keywords:n,contains:[]},a={className:\"string\",begin:\"`\",end:\"`\",contains:[e.BACKSLASH_ESCAPE,i]};i.contains=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,r,e.REGEXP_MODE];var o=i.contains.concat([e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE]);return{aliases:[\"js\",\"jsx\"],keywords:n,contains:[{className:\"meta\",relevance:10,begin:/^\\s*['\"]use (strict|asm)['\"]/},{className:\"meta\",begin:/^#!/,end:/$/},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,r,{begin:/[{,]\\s*/,relevance:0,contains:[{begin:t+\"\\\\s*:\",returnBegin:!0,relevance:0,contains:[{className:\"attr\",begin:t,relevance:0}]}]},{begin:\"(\"+e.RE_STARTERS_RE+\"|\\\\b(case|return|throw)\\\\b)\\\\s*\",keywords:\"return throw case\",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.REGEXP_MODE,{className:\"function\",begin:\"(\\\\(.*?\\\\)|\"+t+\")\\\\s*=>\",returnBegin:!0,end:\"\\\\s*=>\",contains:[{className:\"params\",variants:[{begin:t},{begin:/\\(\\s*\\)/},{begin:/\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,contains:o}]}]},{begin://,subLanguage:\"xml\",contains:[{begin:/<\\w+\\s*\\/>/,skip:!0},{begin:/<\\w+/,end:/(\\/\\w+|\\w+\\/)>/,skip:!0,contains:[{begin:/<\\w+\\s*\\/>/,skip:!0},\"self\"]}]}],relevance:0},{className:\"function\",beginKeywords:\"function\",end:/\\{/,excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:t}),{className:\"params\",begin:/\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0,contains:o}],illegal:/\\[|%/},{begin:/\\$[(.]/},e.METHOD_GUARD,{className:\"class\",beginKeywords:\"class\",end:/[{;=]/,excludeEnd:!0,illegal:/[:\"\\[\\]]/,contains:[{beginKeywords:\"extends\"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:\"constructor\",end:/\\{/,excludeEnd:!0}],illegal:/#(?!!)/}}},function(e,t){e.exports=function(e){var t=\"false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do\",n={className:\"number\",begin:\"\\\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+)(\\\\.([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+))?|\\\\.([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+))([eE][-+]?\\\\d+)?)[lLfF]?\",relevance:0};return{aliases:[\"jsp\"],keywords:t,illegal:/<\\/|#/,contains:[e.COMMENT(\"/\\\\*\\\\*\",\"\\\\*/\",{relevance:0,contains:[{begin:/\\w+@/,relevance:0},{className:\"doctag\",begin:\"@[A-Za-z]+\"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:\"class\",beginKeywords:\"class interface\",end:/[{;=]/,excludeEnd:!0,keywords:\"class interface\",illegal:/[:\"\\[\\]]/,contains:[{beginKeywords:\"extends implements\"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:\"new throw return else\",relevance:0},{className:\"function\",begin:\"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\\\s*,\\\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\\\s+)+\"+e.UNDERSCORE_IDENT_RE+\"\\\\s*\\\\(\",returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:t,contains:[{begin:e.UNDERSCORE_IDENT_RE+\"\\\\s*\\\\(\",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:\"params\",begin:/\\(/,end:/\\)/,keywords:t,relevance:0,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},n,{className:\"meta\",begin:\"@[A-Za-z]+\"}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,keywords:{literal:\".False. .True.\",keyword:\"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data begin_provider &begin_provider end_provider begin_shell end_shell begin_template end_template subst assert touch soft_touch provide no_dep free irp_if irp_else irp_endif irp_write irp_read\",built_in:\"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image IRP_ALIGN irp_here\"},illegal:/\\/\\*/,contains:[e.inherit(e.APOS_STRING_MODE,{className:\"string\",relevance:0}),e.inherit(e.QUOTE_STRING_MODE,{className:\"string\",relevance:0}),{className:\"function\",beginKeywords:\"subroutine function program\",illegal:\"[${=\\\\n]\",contains:[e.UNDERSCORE_TITLE_MODE,{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\"}]},e.COMMENT(\"!\",\"$\",{relevance:0}),e.COMMENT(\"begin_doc\",\"end_doc\",{relevance:10}),{className:\"number\",begin:\"(?=\\\\b|\\\\+|\\\\-|\\\\.)(?=\\\\.\\\\d|\\\\d)(?:\\\\d+)?(?:\\\\.?\\\\d*)(?:[de][+-]?\\\\d+)?\\\\b\\\\.?\",relevance:0}]}}},function(e,t){e.exports=function(e){var t={className:\"string\",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:\"'''\",end:\"'''\",relevance:10},{begin:'\"\"\"',end:'\"\"\"',relevance:10},{begin:'\"',end:'\"'},{begin:\"'\",end:\"'\"}]};return{aliases:[\"toml\"],case_insensitive:!0,illegal:/\\S/,contains:[e.COMMENT(\";\",\"$\"),e.HASH_COMMENT_MODE,{className:\"section\",begin:/^\\s*\\[+/,end:/\\]+/},{begin:/^[a-z0-9\\[\\]_-]+\\s*=\\s*/,end:\"$\",returnBegin:!0,contains:[{className:\"attr\",begin:/[a-z0-9\\[\\]_-]+/},{begin:/=/,endsWithParent:!0,relevance:0,contains:[{className:\"literal\",begin:/\\bon|off|true|false|yes|no\\b/},{className:\"variable\",variants:[{begin:/\\$[\\w\\d\"][\\w\\d_]*/},{begin:/\\$\\{(.*?)}/}]},t,{className:\"number\",begin:/([\\+\\-]+)?[\\d]+_[\\d_]+/},e.NUMBER_MODE]}]}]}}},function(e,t){e.exports=function(e){return{aliases:[\"i7\"],case_insensitive:!0,keywords:{keyword:\"thing room person man woman animal container supporter backdrop door scenery open closed locked inside gender is are say understand kind of rule\"},contains:[{className:\"string\",begin:'\"',end:'\"',relevance:0,contains:[{className:\"subst\",begin:\"\\\\[\",end:\"\\\\]\"}]},{className:\"section\",begin:/^(Volume|Book|Part|Chapter|Section|Table)\\b/,end:\"$\"},{begin:/^(Check|Carry out|Report|Instead of|To|Rule|When|Before|After)\\b/,end:\":\",contains:[{begin:\"\\\\(This\",end:\"\\\\)\"}]},{className:\"comment\",begin:\"\\\\[\",end:\"\\\\]\",contains:[\"self\"]}]}}},function(e,t){e.exports=function(e){var t=\"[a-zA-Z_\\\\-!.?+*=<>&#'][a-zA-Z_\\\\-!.?+*=<>&#'0-9/;:]*\",n={begin:t,relevance:0},r={className:\"number\",begin:\"[-+]?\\\\d+(\\\\.\\\\d+)?\",relevance:0},i=e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),a=e.COMMENT(\";\",\"$\",{relevance:0}),o={className:\"literal\",begin:/\\b([Tt]rue|[Ff]alse|nil|None)\\b/},s={begin:\"[\\\\[\\\\{]\",end:\"[\\\\]\\\\}]\"},l={className:\"comment\",begin:\"\\\\^\"+t},c=e.COMMENT(\"\\\\^\\\\{\",\"\\\\}\"),u={className:\"symbol\",begin:\"[:]{1,2}\"+t},d={begin:\"\\\\(\",end:\"\\\\)\"},f={endsWithParent:!0,relevance:0},p={keywords:{\"builtin-name\":\"!= % %= & &= * ** **= *= *map + += , --build-class-- --import-- -= . / // //= /= < << <<= <= = > >= >> >>= @ @= ^ ^= abs accumulate all and any ap-compose ap-dotimes ap-each ap-each-while ap-filter ap-first ap-if ap-last ap-map ap-map-when ap-pipe ap-reduce ap-reject apply as-> ascii assert assoc bin break butlast callable calling-module-name car case cdr chain chr coll? combinations compile compress cond cons cons? continue count curry cut cycle dec def default-method defclass defmacro defmacro-alias defmacro/g! defmain defmethod defmulti defn defn-alias defnc defnr defreader defseq del delattr delete-route dict-comp dir disassemble dispatch-reader-macro distinct divmod do doto drop drop-last drop-while empty? end-sequence eval eval-and-compile eval-when-compile even? every? except exec filter first flatten float? fn fnc fnr for for* format fraction genexpr gensym get getattr global globals group-by hasattr hash hex id identity if if* if-not if-python2 import in inc input instance? integer integer-char? integer? interleave interpose is is-coll is-cons is-empty is-even is-every is-float is-instance is-integer is-integer-char is-iterable is-iterator is-keyword is-neg is-none is-not is-numeric is-odd is-pos is-string is-symbol is-zero isinstance islice issubclass iter iterable? iterate iterator? keyword keyword? lambda last len let lif lif-not list* list-comp locals loop macro-error macroexpand macroexpand-1 macroexpand-all map max merge-with method-decorator min multi-decorator multicombinations name neg? next none? nonlocal not not-in not? nth numeric? oct odd? open or ord partition permutations pos? post-route postwalk pow prewalk print product profile/calls profile/cpu put-route quasiquote quote raise range read read-str recursive-replace reduce remove repeat repeatedly repr require rest round route route-with-methods rwm second seq set-comp setattr setv some sorted string string? sum switch symbol? take take-nth take-while tee try unless unquote unquote-splicing vars walk when while with with* with-decorator with-gensyms xi xor yield yield-from zero? zip zip-longest | |= ~\"},lexemes:t,className:\"name\",begin:t,starts:f},m=[d,i,l,c,a,u,s,r,o,n];return d.contains=[e.COMMENT(\"comment\",\"\"),p,f],f.contains=m,s.contains=m,{aliases:[\"hylang\"],illegal:/\\S/,contains:[{className:\"meta\",begin:\"^#!\",end:\"$\"},d,i,l,c,a,u,s,r,o]}}},function(e,t){e.exports=function(e){var t=\"HTTP/[0-9\\\\.]+\";return{aliases:[\"https\"],illegal:\"\\\\S\",contains:[{begin:\"^\"+t,end:\"$\",contains:[{className:\"number\",begin:\"\\\\b\\\\d{3}\\\\b\"}]},{begin:\"^[A-Z]+ (.*?) \"+t+\"$\",returnBegin:!0,end:\"$\",contains:[{className:\"string\",begin:\" \",end:\" \",excludeBegin:!0,excludeEnd:!0},{begin:t},{className:\"keyword\",begin:\"[A-Z]+\"}]},{className:\"attribute\",begin:\"^\\\\w\",end:\": \",excludeEnd:!0,illegal:\"\\\\n|\\\\s|=\",starts:{end:\"$\",relevance:0}},{begin:\"\\\\n\\\\n\",starts:{subLanguage:[],endsWithParent:!0}}]}}},function(e,t){e.exports=function(e){var t=\"action collection component concat debugger each each-in else get hash if input link-to loc log mut outlet partial query-params render textarea unbound unless with yield view\",n=(e.QUOTE_STRING_MODE,{endsWithParent:!0,relevance:0,keywords:{keyword:\"as\",built_in:t},contains:[e.QUOTE_STRING_MODE,{illegal:/\\}\\}/,begin:/[a-zA-Z0-9_]+=/,returnBegin:!0,relevance:0,contains:[{className:\"attr\",begin:/[a-zA-Z0-9_]+/}]},e.NUMBER_MODE]});return{case_insensitive:!0,subLanguage:\"xml\",contains:[e.COMMENT(\"{{!(--)?\",\"(--)?}}\"),{className:\"template-tag\",begin:/\\{\\{[#\\/]/,end:/\\}\\}/,contains:[{className:\"name\",begin:/[a-zA-Z\\.\\-]+/,keywords:{\"builtin-name\":t},starts:n}]},{className:\"template-variable\",begin:/\\{\\{[a-zA-Z][a-zA-Z\\-]+/,end:/\\}\\}/,keywords:{keyword:\"as\",built_in:t},contains:[e.QUOTE_STRING_MODE]}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,lexemes:/[\\w\\._]+/,keywords:\"goto gosub return break repeat loop continue wait await dim sdim foreach dimtype dup dupptr end stop newmod delmod mref run exgoto on mcall assert logmes newlab resume yield onexit onerror onkey onclick oncmd exist delete mkdir chdir dirlist bload bsave bcopy memfile if else poke wpoke lpoke getstr chdpm memexpand memcpy memset notesel noteadd notedel noteload notesave randomize noteunsel noteget split strrep setease button chgdisp exec dialog mmload mmplay mmstop mci pset pget syscolor mes print title pos circle cls font sysfont objsize picload color palcolor palette redraw width gsel gcopy gzoom gmode bmpsave hsvcolor getkey listbox chkbox combox input mesbox buffer screen bgscr mouse objsel groll line clrobj boxf objprm objmode stick grect grotate gsquare gradf objimage objskip objenable celload celdiv celput newcom querycom delcom cnvstow comres axobj winobj sendmsg comevent comevarg sarrayconv callfunc cnvwtos comevdisp libptr system hspstat hspver stat cnt err strsize looplev sublev iparam wparam lparam refstr refdval int rnd strlen length length2 length3 length4 vartype gettime peek wpeek lpeek varptr varuse noteinfo instr abs limit getease str strmid strf getpath strtrim sin cos tan atan sqrt double absf expf logf limitf powf geteasef mousex mousey mousew hwnd hinstance hdc ginfo objinfo dirinfo sysinfo thismod __hspver__ __hsp30__ __date__ __time__ __line__ __file__ _debug __hspdef__ and or xor not screen_normal screen_palette screen_hide screen_fixedsize screen_tool screen_frame gmode_gdi gmode_mem gmode_rgb0 gmode_alpha gmode_rgb0alpha gmode_add gmode_sub gmode_pixela ginfo_mx ginfo_my ginfo_act ginfo_sel ginfo_wx1 ginfo_wy1 ginfo_wx2 ginfo_wy2 ginfo_vx ginfo_vy ginfo_sizex ginfo_sizey ginfo_winx ginfo_winy ginfo_mesx ginfo_mesy ginfo_r ginfo_g ginfo_b ginfo_paluse ginfo_dispx ginfo_dispy ginfo_cx ginfo_cy ginfo_intid ginfo_newid ginfo_sx ginfo_sy objinfo_mode objinfo_bmscr objinfo_hwnd notemax notesize dir_cur dir_exe dir_win dir_sys dir_cmdline dir_desktop dir_mydoc dir_tv font_normal font_bold font_italic font_underline font_strikeout font_antialias objmode_normal objmode_guifont objmode_usefont gsquare_grad msgothic msmincho do until while wend for next _break _continue switch case default swbreak swend ddim ldim alloc m_pi rad2deg deg2rad ease_linear ease_quad_in ease_quad_out ease_quad_inout ease_cubic_in ease_cubic_out ease_cubic_inout ease_quartic_in ease_quartic_out ease_quartic_inout ease_bounce_in ease_bounce_out ease_bounce_inout ease_shake_in ease_shake_out ease_shake_inout ease_loop\",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{className:\"string\",begin:'{\"',end:'\"}',contains:[e.BACKSLASH_ESCAPE]},e.COMMENT(\";\",\"$\",{relevance:0}),{className:\"meta\",begin:\"#\",end:\"$\",keywords:{\"meta-keyword\":\"addion cfunc cmd cmpopt comfunc const defcfunc deffunc define else endif enum epack func global if ifdef ifndef include modcfunc modfunc modinit modterm module pack packopt regcmd runtime undef usecom uselib\"},contains:[e.inherit(e.QUOTE_STRING_MODE,{className:\"meta-string\"}),e.NUMBER_MODE,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:\"symbol\",begin:\"^\\\\*(\\\\w+|@)\"},e.NUMBER_MODE,e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{aliases:[\"hx\"],keywords:{keyword:\"break case cast catch continue default do dynamic else enum extern for function here if import in inline never new override package private get set public return static super switch this throw trace try typedef untyped using var while Int Float String Bool Dynamic Void Array \",built_in:\"trace this\",literal:\"true false null _\"},contains:[{className:\"string\",begin:\"'\",end:\"'\",contains:[e.BACKSLASH_ESCAPE,{className:\"subst\",begin:\"\\\\$\\\\{\",end:\"\\\\}\"},{className:\"subst\",begin:\"\\\\$\",end:\"\\\\W}\"}]},e.QUOTE_STRING_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.C_NUMBER_MODE,{className:\"meta\",begin:\"@:\",end:\"$\"},{className:\"meta\",begin:\"#\",end:\"$\",keywords:{\"meta-keyword\":\"if else elseif end error\"}},{className:\"type\",begin:\":[ \\t]*\",end:\"[^A-Za-z0-9_ \\t\\\\->]\",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:\"type\",begin:\":[ \\t]*\",end:\"\\\\W\",excludeBegin:!0,excludeEnd:!0},{className:\"type\",begin:\"new *\",end:\"\\\\W\",excludeBegin:!0,excludeEnd:!0},{className:\"class\",beginKeywords:\"enum\",end:\"\\\\{\",contains:[e.TITLE_MODE]},{className:\"class\",beginKeywords:\"abstract\",end:\"[\\\\{$]\",contains:[{className:\"type\",begin:\"\\\\(\",end:\"\\\\)\",excludeBegin:!0,excludeEnd:!0},{className:\"type\",begin:\"from +\",end:\"\\\\W\",excludeBegin:!0,excludeEnd:!0},{className:\"type\",begin:\"to +\",end:\"\\\\W\",excludeBegin:!0,excludeEnd:!0},e.TITLE_MODE],keywords:{keyword:\"abstract from to\"}},{className:\"class\",begin:\"\\\\b(class|interface) +\",end:\"[\\\\{$]\",excludeEnd:!0,keywords:\"class interface\",contains:[{className:\"keyword\",begin:\"\\\\b(extends|implements) +\",keywords:\"extends implements\",contains:[{className:\"type\",begin:e.IDENT_RE,relevance:0}]},e.TITLE_MODE]},{className:\"function\",beginKeywords:\"function\",end:\"\\\\(\",excludeEnd:!0,illegal:\"\\\\S\",contains:[e.TITLE_MODE]}],illegal:/<\\//}}},function(e,t){e.exports=function(e){var t={variants:[e.COMMENT(\"--\",\"$\"),e.COMMENT(\"{-\",\"-}\",{contains:[\"self\"]})]},n={className:\"meta\",begin:\"{-#\",end:\"#-}\"},r={className:\"meta\",begin:\"^#\",end:\"$\"},i={className:\"type\",begin:\"\\\\b[A-Z][\\\\w']*\",relevance:0},a={begin:\"\\\\(\",end:\"\\\\)\",illegal:'\"',contains:[n,r,{className:\"type\",begin:\"\\\\b[A-Z][\\\\w]*(\\\\((\\\\.\\\\.|,|\\\\w+)\\\\))?\"},e.inherit(e.TITLE_MODE,{begin:\"[_a-z][\\\\w']*\"}),t]};return{aliases:[\"hs\"],keywords:\"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec\",contains:[{beginKeywords:\"module\",end:\"where\",keywords:\"module where\",contains:[a,t],illegal:\"\\\\W\\\\.|;\"},{begin:\"\\\\bimport\\\\b\",end:\"$\",keywords:\"import qualified as hiding\",contains:[a,t],illegal:\"\\\\W\\\\.|;\"},{className:\"class\",begin:\"^(\\\\s*)?(class|instance)\\\\b\",end:\"where\",keywords:\"class family instance where\",contains:[i,a,t]},{className:\"class\",begin:\"\\\\b(data|(new)?type)\\\\b\",end:\"$\",keywords:\"data family type newtype deriving\",contains:[n,i,a,{begin:\"{\",end:\"}\",contains:a.contains},t]},{beginKeywords:\"default\",end:\"$\",contains:[i,a,t]},{beginKeywords:\"infix infixl infixr\",end:\"$\",contains:[e.C_NUMBER_MODE,t]},{begin:\"\\\\bforeign\\\\b\",end:\"$\",keywords:\"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe\",contains:[i,e.QUOTE_STRING_MODE,t]},{className:\"meta\",begin:\"#!\\\\/usr\\\\/bin\\\\/env runhaskell\",end:\"$\"},n,r,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,i,e.inherit(e.TITLE_MODE,{begin:\"^[_a-z][\\\\w']*\"}),t,{begin:\"->|<-\"}]}}},function(e,t){e.exports=function(e){var t={\"builtin-name\":\"each in with if else unless bindattr action collection debugger log outlet template unbound view yield\"};return{aliases:[\"hbs\",\"html.hbs\",\"html.handlebars\"],case_insensitive:!0,subLanguage:\"xml\",contains:[e.COMMENT(\"{{!(--)?\",\"(--)?}}\"),{className:\"template-tag\",begin:/\\{\\{[#\\/]/,end:/\\}\\}/,contains:[{className:\"name\",begin:/[a-zA-Z\\.-]+/,keywords:t,starts:{endsWithParent:!0,relevance:0,contains:[e.QUOTE_STRING_MODE]}}]},{className:\"template-variable\",begin:/\\{\\{/,end:/\\}\\}/,keywords:t}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,contains:[{className:\"meta\",begin:\"^!!!( (5|1\\\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\\\b.*))?$\",relevance:10},e.COMMENT(\"^\\\\s*(!=#|=#|-#|/).*$\",!1,{relevance:0}),{begin:\"^\\\\s*(-|=|!=)(?!#)\",starts:{end:\"\\\\n\",subLanguage:\"ruby\"}},{className:\"tag\",begin:\"^\\\\s*%\",contains:[{className:\"selector-tag\",begin:\"\\\\w+\"},{className:\"selector-id\",begin:\"#[\\\\w-]+\"},{className:\"selector-class\",begin:\"\\\\.[\\\\w-]+\"},{begin:\"{\\\\s*\",end:\"\\\\s*}\",contains:[{begin:\":\\\\w+\\\\s*=>\",end:\",\\\\s+\",returnBegin:!0,endsWithParent:!0,contains:[{className:\"attr\",begin:\":\\\\w+\"},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{begin:\"\\\\w+\",relevance:0}]}]},{begin:\"\\\\(\\\\s*\",end:\"\\\\s*\\\\)\",excludeEnd:!0,contains:[{begin:\"\\\\w+\\\\s*=\",end:\"\\\\s+\",returnBegin:!0,endsWithParent:!0,contains:[{className:\"attr\",begin:\"\\\\w+\",relevance:0},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{begin:\"\\\\w+\",relevance:0}]}]}]},{begin:\"^\\\\s*[=~]\\\\s*\"},{begin:\"#{\",starts:{end:\"}\",subLanguage:\"ruby\"}}]}}},function(e,t){e.exports=function(e){return{keywords:{literal:\"true false null\",keyword:\"byte short char int long boolean float double void def as in assert trait super this abstract static volatile transient public private protected synchronized final class interface enum if else for while switch case break default continue throw throws try catch finally implements extends new import package return instanceof\"},contains:[e.COMMENT(\"/\\\\*\\\\*\",\"\\\\*/\",{relevance:0,contains:[{begin:/\\w+@/,relevance:0},{className:\"doctag\",begin:\"@[A-Za-z]+\"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:\"string\",begin:'\"\"\"',end:'\"\"\"'},{className:\"string\",begin:\"'''\",end:\"'''\"},{className:\"string\",begin:\"\\\\$/\",end:\"/\\\\$\",relevance:10},e.APOS_STRING_MODE,{className:\"regexp\",begin:/~?\\/[^\\/\\n]+\\//,contains:[e.BACKSLASH_ESCAPE]},e.QUOTE_STRING_MODE,{className:\"meta\",begin:\"^#!/usr/bin/env\",end:\"$\",illegal:\"\\n\"},e.BINARY_NUMBER_MODE,{className:\"class\",beginKeywords:\"class interface trait enum\",end:\"{\",illegal:\":\",contains:[{beginKeywords:\"extends implements\"},e.UNDERSCORE_TITLE_MODE]},e.C_NUMBER_MODE,{className:\"meta\",begin:\"@[A-Za-z]+\"},{className:\"string\",begin:/[^\\?]{0}[A-Za-z0-9_$]+ *:/},{begin:/\\?/,end:/\\:/},{className:\"symbol\",begin:\"^\\\\s*[A-Za-z0-9_$]+:\",relevance:0}],illegal:/#|<\\//}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,keywords:{keyword:\"task project allprojects subprojects artifacts buildscript configurations dependencies repositories sourceSets description delete from into include exclude source classpath destinationDir includes options sourceCompatibility targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant def abstract break case catch continue default do else extends final finally for if implements instanceof native new private protected public return static switch synchronized throw throws transient try volatile while strictfp package import false null super this true antlrtask checkstyle codenarc copy boolean byte char class double float int interface long short void compile runTime file fileTree abs any append asList asWritable call collect compareTo count div dump each eachByte eachFile eachLine every find findAll flatten getAt getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter newReader newWriter next plus pop power previous print println push putAt read readBytes readLines reverse reverseEach round size sort splitEachLine step subMap times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader withStream withWriter withWriterAppend write writeLine\"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,e.REGEXP_MODE]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:\"println readln print import module function local return let var while for foreach times in case when match with break continue augment augmentation each find filter reduce if then else otherwise try catch finally raise throw orIfNull DynamicObject|10 DynamicVariable struct Observable map set vector list array\",literal:\"true false null\"},contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,{className:\"meta\",begin:\"@[A-Za-z]+\"}]}}},function(e,t){e.exports=function(e){var t={keyword:\"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune\",literal:\"true false iota nil\",built_in:\"append cap close complex copy imag len make new panic print println real recover delete\"};return{aliases:[\"golang\"],keywords:t,illegal:\"\"},e.HASH_COMMENT_MODE,{className:\"string\",begin:'\"\"\"',end:'\"\"\"'},e.QUOTE_STRING_MODE]}}},function(e,t){e.exports=function(e){var t=[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.COMMENT(/\\(/,/\\)/),e.inherit(e.C_NUMBER_MODE,{begin:\"([-+]?([0-9]*\\\\.?[0-9]+\\\\.?))|\"+e.C_NUMBER_RE}),e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),{className:\"name\",begin:\"([G])([0-9]+\\\\.?[0-9]?)\"},{className:\"name\",begin:\"([M])([0-9]+\\\\.?[0-9]?)\"},{className:\"attr\",begin:\"(VC|VS|#)\",end:\"(\\\\d+)\"},{className:\"attr\",begin:\"(VZOFX|VZOFY|VZOFZ)\"},{className:\"built_in\",begin:\"(ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN)(\\\\[)\",end:\"([-+]?([0-9]*\\\\.?[0-9]+\\\\.?))(\\\\])\"},{className:\"symbol\",variants:[{begin:\"N\",end:\"\\\\d+\",illegal:\"\\\\W\"}]}];return{aliases:[\"nc\"],case_insensitive:!0,lexemes:\"[A-Z_][A-Z0-9_.]*\",keywords:\"IF DO WHILE ENDWHILE CALL ENDIF SUB ENDSUB GOTO REPEAT ENDREPEAT EQ LT GT NE GE LE OR XOR\",contains:[{className:\"meta\",begin:\"\\\\%\"},{className:\"meta\",begin:\"([O])([0-9]+)\"}].concat(t)}}},function(e,t){e.exports=function(e){var t={keyword:\"and bool break call callexe checkinterrupt clear clearg closeall cls comlog compile continue create debug declare delete disable dlibrary dllcall do dos ed edit else elseif enable end endfor endif endp endo errorlog errorlogat expr external fn for format goto gosub graph if keyword let lib library line load loadarray loadexe loadf loadk loadm loadp loads loadx local locate loopnextindex lprint lpwidth lshow matrix msym ndpclex new not open or output outwidth plot plotsym pop prcsn print printdos proc push retp return rndcon rndmod rndmult rndseed run save saveall screen scroll setarray show sparse stop string struct system trace trap threadfor threadendfor threadbegin threadjoin threadstat threadend until use while winprint\",built_in:\"abs acf aconcat aeye amax amean AmericanBinomCall AmericanBinomCall_Greeks AmericanBinomCall_ImpVol AmericanBinomPut AmericanBinomPut_Greeks AmericanBinomPut_ImpVol AmericanBSCall AmericanBSCall_Greeks AmericanBSCall_ImpVol AmericanBSPut AmericanBSPut_Greeks AmericanBSPut_ImpVol amin amult annotationGetDefaults annotationSetBkd annotationSetFont annotationSetLineColor annotationSetLineStyle annotationSetLineThickness annualTradingDays arccos arcsin areshape arrayalloc arrayindex arrayinit arraytomat asciiload asclabel astd astds asum atan atan2 atranspose axmargin balance band bandchol bandcholsol bandltsol bandrv bandsolpd bar base10 begwind besselj bessely beta box boxcox cdfBeta cdfBetaInv cdfBinomial cdfBinomialInv cdfBvn cdfBvn2 cdfBvn2e cdfCauchy cdfCauchyInv cdfChic cdfChii cdfChinc cdfChincInv cdfExp cdfExpInv cdfFc cdfFnc cdfFncInv cdfGam cdfGenPareto cdfHyperGeo cdfLaplace cdfLaplaceInv cdfLogistic cdfLogisticInv cdfmControlCreate cdfMvn cdfMvn2e cdfMvnce cdfMvne cdfMvt2e cdfMvtce cdfMvte cdfN cdfN2 cdfNc cdfNegBinomial cdfNegBinomialInv cdfNi cdfPoisson cdfPoissonInv cdfRayleigh cdfRayleighInv cdfTc cdfTci cdfTnc cdfTvn cdfWeibull cdfWeibullInv cdir ceil ChangeDir chdir chiBarSquare chol choldn cholsol cholup chrs close code cols colsf combinate combinated complex con cond conj cons ConScore contour conv convertsatostr convertstrtosa corrm corrms corrvc corrx corrxs cos cosh counts countwts crossprd crout croutp csrcol csrlin csvReadM csvReadSA cumprodc cumsumc curve cvtos datacreate datacreatecomplex datalist dataload dataloop dataopen datasave date datestr datestring datestrymd dayinyr dayofweek dbAddDatabase dbClose dbCommit dbCreateQuery dbExecQuery dbGetConnectOptions dbGetDatabaseName dbGetDriverName dbGetDrivers dbGetHostName dbGetLastErrorNum dbGetLastErrorText dbGetNumericalPrecPolicy dbGetPassword dbGetPort dbGetTableHeaders dbGetTables dbGetUserName dbHasFeature dbIsDriverAvailable dbIsOpen dbIsOpenError dbOpen dbQueryBindValue dbQueryClear dbQueryCols dbQueryExecPrepared dbQueryFetchAllM dbQueryFetchAllSA dbQueryFetchOneM dbQueryFetchOneSA dbQueryFinish dbQueryGetBoundValue dbQueryGetBoundValues dbQueryGetField dbQueryGetLastErrorNum dbQueryGetLastErrorText dbQueryGetLastInsertID dbQueryGetLastQuery dbQueryGetPosition dbQueryIsActive dbQueryIsForwardOnly dbQueryIsNull dbQueryIsSelect dbQueryIsValid dbQueryPrepare dbQueryRows dbQuerySeek dbQuerySeekFirst dbQuerySeekLast dbQuerySeekNext dbQuerySeekPrevious dbQuerySetForwardOnly dbRemoveDatabase dbRollback dbSetConnectOptions dbSetDatabaseName dbSetHostName dbSetNumericalPrecPolicy dbSetPort dbSetUserName dbTransaction DeleteFile delif delrows denseToSp denseToSpRE denToZero design det detl dfft dffti diag diagrv digamma doswin DOSWinCloseall DOSWinOpen dotfeq dotfeqmt dotfge dotfgemt dotfgt dotfgtmt dotfle dotflemt dotflt dotfltmt dotfne dotfnemt draw drop dsCreate dstat dstatmt dstatmtControlCreate dtdate dtday dttime dttodtv dttostr dttoutc dtvnormal dtvtodt dtvtoutc dummy dummybr dummydn eig eigh eighv eigv elapsedTradingDays endwind envget eof eqSolve eqSolvemt eqSolvemtControlCreate eqSolvemtOutCreate eqSolveset erf erfc erfccplx erfcplx error etdays ethsec etstr EuropeanBinomCall EuropeanBinomCall_Greeks EuropeanBinomCall_ImpVol EuropeanBinomPut EuropeanBinomPut_Greeks EuropeanBinomPut_ImpVol EuropeanBSCall EuropeanBSCall_Greeks EuropeanBSCall_ImpVol EuropeanBSPut EuropeanBSPut_Greeks EuropeanBSPut_ImpVol exctsmpl exec execbg exp extern eye fcheckerr fclearerr feq feqmt fflush fft ffti fftm fftmi fftn fge fgemt fgets fgetsa fgetsat fgetst fgt fgtmt fileinfo filesa fle flemt floor flt fltmt fmod fne fnemt fonts fopen formatcv formatnv fputs fputst fseek fstrerror ftell ftocv ftos ftostrC gamma gammacplx gammaii gausset gdaAppend gdaCreate gdaDStat gdaDStatMat gdaGetIndex gdaGetName gdaGetNames gdaGetOrders gdaGetType gdaGetTypes gdaGetVarInfo gdaIsCplx gdaLoad gdaPack gdaRead gdaReadByIndex gdaReadSome gdaReadSparse gdaReadStruct gdaReportVarInfo gdaSave gdaUpdate gdaUpdateAndPack gdaVars gdaWrite gdaWrite32 gdaWriteSome getarray getdims getf getGAUSShome getmatrix getmatrix4D getname getnamef getNextTradingDay getNextWeekDay getnr getorders getpath getPreviousTradingDay getPreviousWeekDay getRow getscalar3D getscalar4D getTrRow getwind glm gradcplx gradMT gradMTm gradMTT gradMTTm gradp graphprt graphset hasimag header headermt hess hessMT hessMTg hessMTgw hessMTm hessMTmw hessMTT hessMTTg hessMTTgw hessMTTm hessMTw hessp hist histf histp hsec imag indcv indexcat indices indices2 indicesf indicesfn indnv indsav integrate1d integrateControlCreate intgrat2 intgrat3 inthp1 inthp2 inthp3 inthp4 inthpControlCreate intquad1 intquad2 intquad3 intrleav intrleavsa intrsect intsimp inv invpd invswp iscplx iscplxf isden isinfnanmiss ismiss key keyav keyw lag lag1 lagn lapEighb lapEighi lapEighvb lapEighvi lapgEig lapgEigh lapgEighv lapgEigv lapgSchur lapgSvdcst lapgSvds lapgSvdst lapSvdcusv lapSvds lapSvdusv ldlp ldlsol linSolve listwise ln lncdfbvn lncdfbvn2 lncdfmvn lncdfn lncdfn2 lncdfnc lnfact lngammacplx lnpdfmvn lnpdfmvt lnpdfn lnpdft loadd loadstruct loadwind loess loessmt loessmtControlCreate log loglog logx logy lower lowmat lowmat1 ltrisol lu lusol machEpsilon make makevars makewind margin matalloc matinit mattoarray maxbytes maxc maxindc maxv maxvec mbesselei mbesselei0 mbesselei1 mbesseli mbesseli0 mbesseli1 meanc median mergeby mergevar minc minindc minv miss missex missrv moment momentd movingave movingaveExpwgt movingaveWgt nextindex nextn nextnevn nextwind ntos null null1 numCombinations ols olsmt olsmtControlCreate olsqr olsqr2 olsqrmt ones optn optnevn orth outtyp pacf packedToSp packr parse pause pdfCauchy pdfChi pdfExp pdfGenPareto pdfHyperGeo pdfLaplace pdfLogistic pdfn pdfPoisson pdfRayleigh pdfWeibull pi pinv pinvmt plotAddArrow plotAddBar plotAddBox plotAddHist plotAddHistF plotAddHistP plotAddPolar plotAddScatter plotAddShape plotAddTextbox plotAddTS plotAddXY plotArea plotBar plotBox plotClearLayout plotContour plotCustomLayout plotGetDefaults plotHist plotHistF plotHistP plotLayout plotLogLog plotLogX plotLogY plotOpenWindow plotPolar plotSave plotScatter plotSetAxesPen plotSetBar plotSetBarFill plotSetBarStacked plotSetBkdColor plotSetFill plotSetGrid plotSetLegend plotSetLineColor plotSetLineStyle plotSetLineSymbol plotSetLineThickness plotSetNewWindow plotSetTitle plotSetWhichYAxis plotSetXAxisShow plotSetXLabel plotSetXRange plotSetXTicInterval plotSetXTicLabel plotSetYAxisShow plotSetYLabel plotSetYRange plotSetZAxisShow plotSetZLabel plotSurface plotTS plotXY polar polychar polyeval polygamma polyint polymake polymat polymroot polymult polyroot pqgwin previousindex princomp printfm printfmt prodc psi putarray putf putvals pvCreate pvGetIndex pvGetParNames pvGetParVector pvLength pvList pvPack pvPacki pvPackm pvPackmi pvPacks pvPacksi pvPacksm pvPacksmi pvPutParVector pvTest pvUnpack QNewton QNewtonmt QNewtonmtControlCreate QNewtonmtOutCreate QNewtonSet QProg QProgmt QProgmtInCreate qqr qqre qqrep qr qre qrep qrsol qrtsol qtyr qtyre qtyrep quantile quantiled qyr qyre qyrep qz rank rankindx readr real reclassify reclassifyCuts recode recserar recsercp recserrc rerun rescale reshape rets rev rfft rffti rfftip rfftn rfftnp rfftp rndBernoulli rndBeta rndBinomial rndCauchy rndChiSquare rndCon rndCreateState rndExp rndGamma rndGeo rndGumbel rndHyperGeo rndi rndKMbeta rndKMgam rndKMi rndKMn rndKMnb rndKMp rndKMu rndKMvm rndLaplace rndLCbeta rndLCgam rndLCi rndLCn rndLCnb rndLCp rndLCu rndLCvm rndLogNorm rndMTu rndMVn rndMVt rndn rndnb rndNegBinomial rndp rndPoisson rndRayleigh rndStateSkip rndu rndvm rndWeibull rndWishart rotater round rows rowsf rref sampleData satostrC saved saveStruct savewind scale scale3d scalerr scalinfnanmiss scalmiss schtoc schur searchsourcepath seekr select selif seqa seqm setdif setdifsa setvars setvwrmode setwind shell shiftr sin singleindex sinh sleep solpd sortc sortcc sortd sorthc sorthcc sortind sortindc sortmc sortr sortrc spBiconjGradSol spChol spConjGradSol spCreate spDenseSubmat spDiagRvMat spEigv spEye spLDL spline spLU spNumNZE spOnes spreadSheetReadM spreadSheetReadSA spreadSheetWrite spScale spSubmat spToDense spTrTDense spTScalar spZeros sqpSolve sqpSolveMT sqpSolveMTControlCreate sqpSolveMTlagrangeCreate sqpSolveMToutCreate sqpSolveSet sqrt statements stdc stdsc stocv stof strcombine strindx strlen strput strrindx strsect strsplit strsplitPad strtodt strtof strtofcplx strtriml strtrimr strtrunc strtruncl strtruncpad strtruncr submat subscat substute subvec sumc sumr surface svd svd1 svd2 svdcusv svds svdusv sysstate tab tan tanh tempname threadBegin threadEnd threadEndFor threadFor threadJoin threadStat time timedt timestr timeutc title tkf2eps tkf2ps tocart todaydt toeplitz token topolar trapchk trigamma trimr trunc type typecv typef union unionsa uniqindx uniqindxsa unique uniquesa upmat upmat1 upper utctodt utctodtv utrisol vals varCovMS varCovXS varget vargetl varmall varmares varput varputl vartypef vcm vcms vcx vcxs vec vech vecr vector vget view viewxyz vlist vnamecv volume vput vread vtypecv wait waitc walkindex where window writer xlabel xlsGetSheetCount xlsGetSheetSize xlsGetSheetTypes xlsMakeRange xlsReadM xlsReadSA xlsWrite xlsWriteM xlsWriteSA xpnd xtics xy xyz ylabel ytics zeros zeta zlabel ztics cdfEmpirical dot h5create h5open h5read h5readAttribute h5write h5writeAttribute ldl plotAddErrorBar plotAddSurface plotCDFEmpirical plotSetColormap plotSetContourLabels plotSetLegendFont plotSetTextInterpreter plotSetXTicCount plotSetYTicCount plotSetZLevels powerm strjoin strtrim sylvester\",literal:\"DB_AFTER_LAST_ROW DB_ALL_TABLES DB_BATCH_OPERATIONS DB_BEFORE_FIRST_ROW DB_BLOB DB_EVENT_NOTIFICATIONS DB_FINISH_QUERY DB_HIGH_PRECISION DB_LAST_INSERT_ID DB_LOW_PRECISION_DOUBLE DB_LOW_PRECISION_INT32 DB_LOW_PRECISION_INT64 DB_LOW_PRECISION_NUMBERS DB_MULTIPLE_RESULT_SETS DB_NAMED_PLACEHOLDERS DB_POSITIONAL_PLACEHOLDERS DB_PREPARED_QUERIES DB_QUERY_SIZE DB_SIMPLE_LOCKING DB_SYSTEM_TABLES DB_TABLES DB_TRANSACTIONS DB_UNICODE DB_VIEWS\"},n={className:\"meta\",begin:\"#\",end:\"$\",keywords:{\"meta-keyword\":\"define definecs|10 undef ifdef ifndef iflight ifdllcall ifmac ifos2win ifunix else endif lineson linesoff srcfile srcline\"},contains:[{begin:/\\\\\\n/,relevance:0},{beginKeywords:\"include\",end:\"$\",keywords:{\"meta-keyword\":\"include\"},contains:[{className:\"meta-string\",begin:'\"',end:'\"',illegal:\"\\\\n\"}]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},r=e.UNDERSCORE_IDENT_RE+\"\\\\s*\\\\(?\",i=[{className:\"params\",begin:/\\(/,end:/\\)/,keywords:t,relevance:0,contains:[e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}];return{aliases:[\"gss\"],case_insensitive:!0,keywords:t,illegal:\"(\\\\{[%#]|[%#]\\\\})\",contains:[e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.COMMENT(\"@\",\"@\"),n,{className:\"string\",begin:'\"',end:'\"',contains:[e.BACKSLASH_ESCAPE]},{className:\"function\",beginKeywords:\"proc keyword\",end:\";\",excludeEnd:!0,keywords:t,contains:[{begin:r,returnBegin:!0,contains:[e.UNDERSCORE_TITLE_MODE],relevance:0},e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n].concat(i)},{className:\"function\",beginKeywords:\"fn\",end:\";\",excludeEnd:!0,keywords:t,contains:[{begin:r+e.IDENT_RE+\"\\\\)?\\\\s*\\\\=\\\\s*\",returnBegin:!0,contains:[e.UNDERSCORE_TITLE_MODE],relevance:0},e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE].concat(i)},{className:\"function\",begin:\"\\\\bexternal (proc|keyword|fn)\\\\s+\",end:\";\",excludeEnd:!0,keywords:t,contains:[{begin:r,returnBegin:!0,contains:[e.UNDERSCORE_TITLE_MODE],relevance:0},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:\"function\",begin:\"\\\\bexternal (matrix|string|array|sparse matrix|struct \"+e.IDENT_RE+\")\\\\s+\",end:\";\",excludeEnd:!0,keywords:t,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}]}}},function(e,t){e.exports=function(e){var t={keyword:\"abort acronym acronyms alias all and assign binary card diag display else eq file files for free ge gt if integer le loop lt maximizing minimizing model models ne negative no not option options or ord positive prod put putpage puttl repeat sameas semicont semiint smax smin solve sos1 sos2 sum system table then until using while xor yes\",literal:\"eps inf na\",\"built-in\":\"abs arccos arcsin arctan arctan2 Beta betaReg binomial ceil centropy cos cosh cvPower div div0 eDist entropy errorf execSeed exp fact floor frac gamma gammaReg log logBeta logGamma log10 log2 mapVal max min mod ncpCM ncpF ncpVUpow ncpVUsin normal pi poly power randBinomial randLinear randTriangle round rPower sigmoid sign signPower sin sinh slexp sllog10 slrec sqexp sqlog10 sqr sqrec sqrt tan tanh trunc uniform uniformInt vcPower bool_and bool_eqv bool_imp bool_not bool_or bool_xor ifThen rel_eq rel_ge rel_gt rel_le rel_lt rel_ne gday gdow ghour gleap gmillisec gminute gmonth gsecond gyear jdate jnow jstart jtime errorLevel execError gamsRelease gamsVersion handleCollect handleDelete handleStatus handleSubmit heapFree heapLimit heapSize jobHandle jobKill jobStatus jobTerminate licenseLevel licenseStatus maxExecError sleep timeClose timeComp timeElapsed timeExec timeStart\"},n={className:\"symbol\",variants:[{begin:/\\=[lgenxc]=/},{begin:/\\$/}]},r={className:\"comment\",variants:[{begin:\"'\",end:\"'\"},{begin:'\"',end:'\"'}],illegal:\"\\\\n\",contains:[e.BACKSLASH_ESCAPE]},i={begin:\"/\",end:\"/\",keywords:t,contains:[r,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_NUMBER_MODE]},a={begin:/[a-z][a-z0-9_]*(\\([a-z0-9_, ]*\\))?[ \\t]+/,excludeBegin:!0,end:\"$\",endsWithParent:!0,contains:[r,i,{className:\"comment\",begin:/([ ]*[a-z0-9&#*=?@>\\\\<:\\-,()$\\[\\]_.{}!+%^]+)+/,relevance:0}]};return{aliases:[\"gms\"],case_insensitive:!0,keywords:t,contains:[e.COMMENT(/^\\$ontext/,/^\\$offtext/),{className:\"meta\",begin:\"^\\\\$[a-z0-9]+\",end:\"$\",returnBegin:!0,contains:[{className:\"meta-keyword\",begin:\"^\\\\$[a-z0-9]+\"}]},e.COMMENT(\"^\\\\*\",\"$\"),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{beginKeywords:\"set sets parameter parameters variable variables scalar scalars equation equations\",end:\";\",contains:[e.COMMENT(\"^\\\\*\",\"$\"),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,i,a]},{beginKeywords:\"table\",end:\";\",returnBegin:!0,contains:[{beginKeywords:\"table\",end:\"$\",contains:[a]},e.COMMENT(\"^\\\\*\",\"$\"),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_NUMBER_MODE]},{className:\"function\",begin:/^[a-z][a-z0-9_,\\-+' ()$]+\\.{2}/,returnBegin:!0,contains:[{className:\"title\",begin:/^[a-z0-9_]+/},{className:\"params\",begin:/\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0},n]},e.C_NUMBER_MODE,n]}}},function(e,t){e.exports=function(e){var t={begin:\"<\",end:\">\",contains:[e.inherit(e.TITLE_MODE,{begin:/'[a-zA-Z0-9_]+/})]};return{aliases:[\"fs\"],keywords:\"abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield\",illegal:/\\/\\*/,contains:[{className:\"keyword\",begin:/\\b(yield|return|let|do)!/},{className:\"string\",begin:'@\"',end:'\"',contains:[{begin:'\"\"'}]},{className:\"string\",begin:'\"\"\"',end:'\"\"\"'},e.COMMENT(\"\\\\(\\\\*\",\"\\\\*\\\\)\"),{className:\"class\",beginKeywords:\"type\",end:\"\\\\(|=|$\",excludeEnd:!0,contains:[e.UNDERSCORE_TITLE_MODE,t]},{className:\"meta\",begin:\"\\\\[<\",end:\">\\\\]\",relevance:10},{className:\"symbol\",begin:\"\\\\B('[A-Za-z])\\\\b\",contains:[e.BACKSLASH_ESCAPE]},e.C_LINE_COMMENT_MODE,e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,aliases:[\"f90\",\"f95\"],keywords:{literal:\".False. .True.\",keyword:\"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data\",built_in:\"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image\"},illegal:/\\/\\*/,contains:[e.inherit(e.APOS_STRING_MODE,{className:\"string\",relevance:0}),e.inherit(e.QUOTE_STRING_MODE,{className:\"string\",relevance:0}),{className:\"function\",beginKeywords:\"subroutine function program\",illegal:\"[${=\\\\n]\",contains:[e.UNDERSCORE_TITLE_MODE,{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\"}]},e.COMMENT(\"!\",\"$\",{relevance:0}),{className:\"number\",begin:\"(?=\\\\b|\\\\+|\\\\-|\\\\.)(?=\\\\.\\\\d|\\\\d)(?:\\\\d+)?(?:\\\\.?\\\\d*)(?:[de][+-]?\\\\d+)?\\\\b\\\\.?\",relevance:0}]}}},function(e,t){e.exports=function(e){var t={className:\"function\",beginKeywords:\"def\",end:/[:={\\[(\\n;]/,excludeEnd:!0,contains:[{className:\"title\",begin:/[^0-9\\n\\t \"'(),.`{}\\[\\]:;][^\\n\\t \"'(),.`{}\\[\\]:;]+|[^0-9\\n\\t \"'(),.`{}\\[\\]:;=]/}]};return{keywords:{literal:\"true false\",keyword:\"case class def else enum if impl import in lat rel index let match namespace switch type yield with\"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:\"string\",begin:/'(.|\\\\[xXuU][a-zA-Z0-9]+)'/},{className:\"string\",variants:[{begin:'\"',end:'\"'}]},t,e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{contains:[{begin:/[^\\u2401\\u0001]+/,end:/[\\u2401\\u0001]/,excludeEnd:!0,returnBegin:!0,returnEnd:!1,contains:[{begin:/([^\\u2401\\u0001=]+)/,end:/=([^\\u2401\\u0001=]+)/,returnEnd:!0,returnBegin:!1,className:\"attr\"},{begin:/=/,end:/([\\u2401\\u0001])/,excludeEnd:!0,excludeBegin:!0,className:\"string\"}]}],case_insensitive:!0}}},function(e,t){e.exports=function(e){return{aliases:[\"xlsx\",\"xls\"],case_insensitive:!0,lexemes:/[a-zA-Z][\\w\\.]*/,keywords:{built_in:\"ABS ACCRINT ACCRINTM ACOS ACOSH ACOT ACOTH AGGREGATE ADDRESS AMORDEGRC AMORLINC AND ARABIC AREAS ASC ASIN ASINH ATAN ATAN2 ATANH AVEDEV AVERAGE AVERAGEA AVERAGEIF AVERAGEIFS BAHTTEXT BASE BESSELI BESSELJ BESSELK BESSELY BETADIST BETA.DIST BETAINV BETA.INV BIN2DEC BIN2HEX BIN2OCT BINOMDIST BINOM.DIST BINOM.DIST.RANGE BINOM.INV BITAND BITLSHIFT BITOR BITRSHIFT BITXOR CALL CEILING CEILING.MATH CEILING.PRECISE CELL CHAR CHIDIST CHIINV CHITEST CHISQ.DIST CHISQ.DIST.RT CHISQ.INV CHISQ.INV.RT CHISQ.TEST CHOOSE CLEAN CODE COLUMN COLUMNS COMBIN COMBINA COMPLEX CONCAT CONCATENATE CONFIDENCE CONFIDENCE.NORM CONFIDENCE.T CONVERT CORREL COS COSH COT COTH COUNT COUNTA COUNTBLANK COUNTIF COUNTIFS COUPDAYBS COUPDAYS COUPDAYSNC COUPNCD COUPNUM COUPPCD COVAR COVARIANCE.P COVARIANCE.S CRITBINOM CSC CSCH CUBEKPIMEMBER CUBEMEMBER CUBEMEMBERPROPERTY CUBERANKEDMEMBER CUBESET CUBESETCOUNT CUBEVALUE CUMIPMT CUMPRINC DATE DATEDIF DATEVALUE DAVERAGE DAY DAYS DAYS360 DB DBCS DCOUNT DCOUNTA DDB DEC2BIN DEC2HEX DEC2OCT DECIMAL DEGREES DELTA DEVSQ DGET DISC DMAX DMIN DOLLAR DOLLARDE DOLLARFR DPRODUCT DSTDEV DSTDEVP DSUM DURATION DVAR DVARP EDATE EFFECT ENCODEURL EOMONTH ERF ERF.PRECISE ERFC ERFC.PRECISE ERROR.TYPE EUROCONVERT EVEN EXACT EXP EXPON.DIST EXPONDIST FACT FACTDOUBLE FALSE|0 F.DIST FDIST F.DIST.RT FILTERXML FIND FINDB F.INV F.INV.RT FINV FISHER FISHERINV FIXED FLOOR FLOOR.MATH FLOOR.PRECISE FORECAST FORECAST.ETS FORECAST.ETS.CONFINT FORECAST.ETS.SEASONALITY FORECAST.ETS.STAT FORECAST.LINEAR FORMULATEXT FREQUENCY F.TEST FTEST FV FVSCHEDULE GAMMA GAMMA.DIST GAMMADIST GAMMA.INV GAMMAINV GAMMALN GAMMALN.PRECISE GAUSS GCD GEOMEAN GESTEP GETPIVOTDATA GROWTH HARMEAN HEX2BIN HEX2DEC HEX2OCT HLOOKUP HOUR HYPERLINK HYPGEOM.DIST HYPGEOMDIST IF|0 IFERROR IFNA IFS IMABS IMAGINARY IMARGUMENT IMCONJUGATE IMCOS IMCOSH IMCOT IMCSC IMCSCH IMDIV IMEXP IMLN IMLOG10 IMLOG2 IMPOWER IMPRODUCT IMREAL IMSEC IMSECH IMSIN IMSINH IMSQRT IMSUB IMSUM IMTAN INDEX INDIRECT INFO INT INTERCEPT INTRATE IPMT IRR ISBLANK ISERR ISERROR ISEVEN ISFORMULA ISLOGICAL ISNA ISNONTEXT ISNUMBER ISODD ISREF ISTEXT ISO.CEILING ISOWEEKNUM ISPMT JIS KURT LARGE LCM LEFT LEFTB LEN LENB LINEST LN LOG LOG10 LOGEST LOGINV LOGNORM.DIST LOGNORMDIST LOGNORM.INV LOOKUP LOWER MATCH MAX MAXA MAXIFS MDETERM MDURATION MEDIAN MID MIDBs MIN MINIFS MINA MINUTE MINVERSE MIRR MMULT MOD MODE MODE.MULT MODE.SNGL MONTH MROUND MULTINOMIAL MUNIT N NA NEGBINOM.DIST NEGBINOMDIST NETWORKDAYS NETWORKDAYS.INTL NOMINAL NORM.DIST NORMDIST NORMINV NORM.INV NORM.S.DIST NORMSDIST NORM.S.INV NORMSINV NOT NOW NPER NPV NUMBERVALUE OCT2BIN OCT2DEC OCT2HEX ODD ODDFPRICE ODDFYIELD ODDLPRICE ODDLYIELD OFFSET OR PDURATION PEARSON PERCENTILE.EXC PERCENTILE.INC PERCENTILE PERCENTRANK.EXC PERCENTRANK.INC PERCENTRANK PERMUT PERMUTATIONA PHI PHONETIC PI PMT POISSON.DIST POISSON POWER PPMT PRICE PRICEDISC PRICEMAT PROB PRODUCT PROPER PV QUARTILE QUARTILE.EXC QUARTILE.INC QUOTIENT RADIANS RAND RANDBETWEEN RANK.AVG RANK.EQ RANK RATE RECEIVED REGISTER.ID REPLACE REPLACEB REPT RIGHT RIGHTB ROMAN ROUND ROUNDDOWN ROUNDUP ROW ROWS RRI RSQ RTD SEARCH SEARCHB SEC SECH SECOND SERIESSUM SHEET SHEETS SIGN SIN SINH SKEW SKEW.P SLN SLOPE SMALL SQL.REQUEST SQRT SQRTPI STANDARDIZE STDEV STDEV.P STDEV.S STDEVA STDEVP STDEVPA STEYX SUBSTITUTE SUBTOTAL SUM SUMIF SUMIFS SUMPRODUCT SUMSQ SUMX2MY2 SUMX2PY2 SUMXMY2 SWITCH SYD T TAN TANH TBILLEQ TBILLPRICE TBILLYIELD T.DIST T.DIST.2T T.DIST.RT TDIST TEXT TEXTJOIN TIME TIMEVALUE T.INV T.INV.2T TINV TODAY TRANSPOSE TREND TRIM TRIMMEAN TRUE|0 TRUNC T.TEST TTEST TYPE UNICHAR UNICODE UPPER VALUE VAR VAR.P VAR.S VARA VARP VARPA VDB VLOOKUP WEBSERVICE WEEKDAY WEEKNUM WEIBULL WEIBULL.DIST WORKDAY WORKDAY.INTL XIRR XNPV XOR YEAR YEARFRAC YIELD YIELDDISC YIELDMAT Z.TEST ZTEST\"},contains:[{begin:/^=/,end:/[^=]/,returnEnd:!0,illegal:/=/,relevance:10},{className:\"symbol\",begin:/\\b[A-Z]{1,2}\\d+\\b/,end:/[^\\d]/,excludeEnd:!0,relevance:0},{className:\"symbol\",begin:/[A-Z]{0,2}\\d*:[A-Z]{0,2}\\d*/,relevance:0},e.BACKSLASH_ESCAPE,e.QUOTE_STRING_MODE,{className:\"number\",begin:e.NUMBER_RE+\"(%)?\",relevance:0},e.COMMENT(/\\bN\\(/,/\\)/,{excludeBegin:!0,excludeEnd:!0,illegal:/\\n/})]}}},function(e,t){e.exports=function(e){var t=\"[a-z'][a-zA-Z0-9_']*\",n=\"(\"+t+\":\"+t+\"|\"+t+\")\",r={keyword:\"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor\",literal:\"false true\"},i=e.COMMENT(\"%\",\"$\"),a={className:\"number\",begin:\"\\\\b(\\\\d+#[a-fA-F0-9]+|\\\\d+(\\\\.\\\\d+)?([eE][-+]?\\\\d+)?)\",relevance:0},o={begin:\"fun\\\\s+\"+t+\"/\\\\d+\"},s={begin:n+\"\\\\(\",end:\"\\\\)\",returnBegin:!0,relevance:0,contains:[{begin:n,relevance:0},{begin:\"\\\\(\",end:\"\\\\)\",endsWithParent:!0,returnEnd:!0,relevance:0}]},l={begin:\"{\",end:\"}\",relevance:0},c={begin:\"\\\\b_([A-Z][A-Za-z0-9_]*)?\",relevance:0},u={begin:\"[A-Z][a-zA-Z0-9_]*\",relevance:0},d={begin:\"#\"+e.UNDERSCORE_IDENT_RE,relevance:0,returnBegin:!0,contains:[{begin:\"#\"+e.UNDERSCORE_IDENT_RE,relevance:0},{begin:\"{\",end:\"}\",relevance:0}]},f={beginKeywords:\"fun receive if try case\",end:\"end\",keywords:r};f.contains=[i,o,e.inherit(e.APOS_STRING_MODE,{className:\"\"}),f,s,e.QUOTE_STRING_MODE,a,l,c,u,d];var p=[i,o,f,s,e.QUOTE_STRING_MODE,a,l,c,u,d];s.contains[1].contains=p,l.contains=p,d.contains[1].contains=p;var m={className:\"params\",begin:\"\\\\(\",end:\"\\\\)\",contains:p};return{aliases:[\"erl\"],keywords:r,illegal:\"(\",returnBegin:!0,illegal:\"\\\\(|#|//|/\\\\*|\\\\\\\\|:|;\",contains:[m,e.inherit(e.TITLE_MODE,{begin:t})],starts:{end:\";|\\\\.\",keywords:r,contains:p}},i,{begin:\"^-\",end:\"\\\\.\",relevance:0,excludeEnd:!0,returnBegin:!0,lexemes:\"-\"+e.IDENT_RE,keywords:\"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec\",contains:[m]},a,e.QUOTE_STRING_MODE,d,c,u,l,{begin:/\\.$/}]}}},function(e,t){e.exports=function(e){return{keywords:{built_in:\"spawn spawn_link self\",keyword:\"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor\"},contains:[{className:\"meta\",begin:\"^[0-9]+> \",relevance:10},e.COMMENT(\"%\",\"$\"),{className:\"number\",begin:\"\\\\b(\\\\d+#[a-fA-F0-9]+|\\\\d+(\\\\.\\\\d+)?([eE][-+]?\\\\d+)?)\",relevance:0},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{begin:\"\\\\?(::)?([A-Z]\\\\w*(::)?)+\"},{begin:\"->\"},{begin:\"ok\"},{begin:\"!\"},{begin:\"(\\\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\\\b[a-z'][a-zA-Z0-9_']*)\",relevance:0},{begin:\"[A-Z][a-zA-Z0-9_']*\",relevance:0}]}}},function(e,t){e.exports=function(e){return{subLanguage:\"xml\",contains:[e.COMMENT(\"<%#\",\"%>\"),{begin:\"<%[%=-]?\",end:\"[%-]?%>\",subLanguage:\"ruby\",excludeBegin:!0,excludeEnd:!0}]}}},function(e,t){e.exports=function(e){var t=\"[a-zA-Z_]\\\\w*[!?=]?|[-+~]\\\\@|<<|>>|=~|===?|<=>|[<>]=?|\\\\*\\\\*|[-/+%^&*~`|]|\\\\[\\\\]=?\",n={keyword:\"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor\",literal:\"true false nil\"},r={className:\"doctag\",begin:\"@[A-Za-z]+\"},i={begin:\"#<\",end:\">\"},a=[e.COMMENT(\"#\",\"$\",{contains:[r]}),e.COMMENT(\"^\\\\=begin\",\"^\\\\=end\",{contains:[r],relevance:10}),e.COMMENT(\"^__END__\",\"\\\\n$\")],o={className:\"subst\",begin:\"#\\\\{\",end:\"}\",keywords:n},s={className:\"string\",contains:[e.BACKSLASH_ESCAPE,o],variants:[{begin:/'/,end:/'/},{begin:/\"/,end:/\"/},{begin:/`/,end:/`/},{begin:\"%[qQwWx]?\\\\(\",end:\"\\\\)\"},{begin:\"%[qQwWx]?\\\\[\",end:\"\\\\]\"},{begin:\"%[qQwWx]?{\",end:\"}\"},{begin:\"%[qQwWx]?<\",end:\">\"},{begin:\"%[qQwWx]?/\",end:\"/\"},{begin:\"%[qQwWx]?%\",end:\"%\"},{begin:\"%[qQwWx]?-\",end:\"-\"},{begin:\"%[qQwWx]?\\\\|\",end:\"\\\\|\"},{begin:/\\B\\?(\\\\\\d{1,3}|\\\\x[A-Fa-f0-9]{1,2}|\\\\u[A-Fa-f0-9]{4}|\\\\?\\S)\\b/},{begin:/<<(-?)\\w+$/,end:/^\\s*\\w+$/}]},l={className:\"params\",begin:\"\\\\(\",end:\"\\\\)\",endsParent:!0,keywords:n},c=[s,i,{className:\"class\",beginKeywords:\"class module\",end:\"$|;\",illegal:/=/,contains:[e.inherit(e.TITLE_MODE,{begin:\"[A-Za-z_]\\\\w*(::\\\\w+)*(\\\\?|\\\\!)?\"}),{begin:\"<\\\\s*\",contains:[{begin:\"(\"+e.IDENT_RE+\"::)?\"+e.IDENT_RE}]}].concat(a)},{className:\"function\",beginKeywords:\"def\",end:\"$|;\",contains:[e.inherit(e.TITLE_MODE,{begin:t}),l].concat(a)},{begin:e.IDENT_RE+\"::\"},{className:\"symbol\",begin:e.UNDERSCORE_IDENT_RE+\"(\\\\!|\\\\?)?:\",relevance:0},{className:\"symbol\",begin:\":(?!\\\\s)\",contains:[s,{begin:t}],relevance:0},{className:\"number\",begin:\"(\\\\b0[0-7_]+)|(\\\\b0x[0-9a-fA-F_]+)|(\\\\b[1-9][0-9_]*(\\\\.[0-9_]+)?)|[0_]\\\\b\",relevance:0},{begin:\"(\\\\$\\\\W)|((\\\\$|\\\\@\\\\@?)(\\\\w+))\"},{className:\"params\",begin:/\\|/,end:/\\|/,keywords:n},{begin:\"(\"+e.RE_STARTERS_RE+\"|unless)\\\\s*\",keywords:\"unless\",contains:[i,{className:\"regexp\",contains:[e.BACKSLASH_ESCAPE,o],illegal:/\\n/,variants:[{begin:\"/\",end:\"/[a-z]*\"},{begin:\"%r{\",end:\"}[a-z]*\"},{begin:\"%r\\\\(\",end:\"\\\\)[a-z]*\"},{begin:\"%r!\",end:\"![a-z]*\"},{begin:\"%r\\\\[\",end:\"\\\\][a-z]*\"}]}].concat(a),relevance:0}].concat(a);o.contains=c,l.contains=c;var u=[{begin:/^\\s*=>/,starts:{end:\"$\",contains:c}},{className:\"meta\",begin:\"^([>?]>|[\\\\w#]+\\\\(\\\\w+\\\\):\\\\d+:\\\\d+>|(\\\\w+-)?\\\\d+\\\\.\\\\d+\\\\.\\\\d(p\\\\d+)?[^>]+>)\",starts:{end:\"$\",contains:c}}];return{aliases:[\"rb\",\"gemspec\",\"podspec\",\"thor\",\"irb\"],keywords:n,illegal:/\\/\\*/,contains:a.concat(u).concat(c)}}},function(e,t){e.exports=function(e){var t={variants:[e.COMMENT(\"--\",\"$\"),e.COMMENT(\"{-\",\"-}\",{contains:[\"self\"]})]},n={className:\"type\",begin:\"\\\\b[A-Z][\\\\w']*\",relevance:0},r={begin:\"\\\\(\",end:\"\\\\)\",illegal:'\"',contains:[{className:\"type\",begin:\"\\\\b[A-Z][\\\\w]*(\\\\((\\\\.\\\\.|,|\\\\w+)\\\\))?\"},t]};return{keywords:\"let in if then else case of where module import exposing type alias as infix infixl infixr port effect command subscription\",contains:[{beginKeywords:\"port effect module\",end:\"exposing\",keywords:\"port effect module where command subscription exposing\",contains:[r,t],illegal:\"\\\\W\\\\.|;\"},{begin:\"import\",end:\"$\",keywords:\"import as exposing\",contains:[r,t],illegal:\"\\\\W\\\\.|;\"},{begin:\"type\",end:\"$\",keywords:\"type alias\",contains:[n,r,{begin:\"{\",end:\"}\",contains:r.contains},t]},{beginKeywords:\"infix infixl infixr\",end:\"$\",contains:[e.C_NUMBER_MODE,t]},{begin:\"port\",end:\"$\",keywords:\"port\",contains:[t]},e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,n,e.inherit(e.TITLE_MODE,{begin:\"^[_a-z][\\\\w']*\"}),t,{begin:\"->|<-\"}],illegal:/;/}}},function(e,t){e.exports=function(e){var t=\"[a-zA-Z_][a-zA-Z0-9_]*(\\\\!|\\\\?)?\",n=\"and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote\",r={className:\"subst\",begin:\"#\\\\{\",end:\"}\",lexemes:t,keywords:n},i={className:\"string\",contains:[e.BACKSLASH_ESCAPE,r],variants:[{begin:/'/,end:/'/},{begin:/\"/,end:/\"/}]},a={className:\"function\",beginKeywords:\"def defp defmacro\",end:/\\B\\b/,contains:[e.inherit(e.TITLE_MODE,{begin:t,endsParent:!0})]},o=e.inherit(a,{className:\"class\",beginKeywords:\"defimpl defmodule defprotocol defrecord\",end:/\\bdo\\b|$|;/}),s=[i,e.HASH_COMMENT_MODE,o,a,{className:\"symbol\",begin:\":(?!\\\\s)\",contains:[i,{begin:\"[a-zA-Z_]\\\\w*[!?=]?|[-+~]\\\\@|<<|>>|=~|===?|<=>|[<>]=?|\\\\*\\\\*|[-/+%^&*~`|]|\\\\[\\\\]=?\"}],relevance:0},{className:\"symbol\",begin:t+\":\",relevance:0},{className:\"number\",begin:\"(\\\\b0[0-7_]+)|(\\\\b0x[0-9a-fA-F_]+)|(\\\\b[1-9][0-9_]*(\\\\.[0-9_]+)?)|[0_]\\\\b\",relevance:0},{className:\"variable\",begin:\"(\\\\$\\\\W)|((\\\\$|\\\\@\\\\@?)(\\\\w+))\"},{begin:\"->\"},{begin:\"(\"+e.RE_STARTERS_RE+\")\\\\s*\",contains:[e.HASH_COMMENT_MODE,{className:\"regexp\",illegal:\"\\\\n\",contains:[e.BACKSLASH_ESCAPE,r],variants:[{begin:\"/\",end:\"/[a-z]*\"},{begin:\"%r\\\\[\",end:\"\\\\][a-z]*\"}]}],relevance:0}];return r.contains=s,{lexemes:t,keywords:n,contains:s}}},function(e,t){e.exports=function(e){var t=e.COMMENT(/\\(\\*/,/\\*\\)/);return{illegal:/\\S/,contains:[t,{className:\"attribute\",begin:/^[ ]*[a-zA-Z][a-zA-Z-]*([\\s-]+[a-zA-Z][a-zA-Z]*)*/},{begin:/=/,end:/;/,contains:[t,{className:\"meta\",begin:/\\?.*\\?/},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]}]}}},function(e,t){e.exports=function(e){return{aliases:[\"dst\"],case_insensitive:!0,subLanguage:\"xml\",contains:[{className:\"template-tag\",begin:/\\{[#\\/]/,end:/\\}/,illegal:/;/,contains:[{className:\"name\",begin:/[a-zA-Z\\.-]+/,starts:{endsWithParent:!0,relevance:0,contains:[e.QUOTE_STRING_MODE]}}]},{className:\"template-variable\",begin:/\\{/,end:/\\}/,illegal:/;/,keywords:\"if eq ne lt lte gt gte select default math sep\"}]}}},function(e,t){e.exports=function(e){var t={className:\"string\",variants:[e.inherit(e.QUOTE_STRING_MODE,{begin:'((u8?|U)|L)?\"'}),{begin:'(u8?|U)?R\"',end:'\"',contains:[e.BACKSLASH_ESCAPE]},{begin:\"'\\\\\\\\?.\",end:\"'\",illegal:\".\"}]},n={className:\"number\",variants:[{begin:\"\\\\b(\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)(u|U|l|L|ul|UL|f|F)\"},{begin:e.C_NUMBER_RE}],relevance:0},r={className:\"meta\",begin:\"#\",end:\"$\",keywords:{\"meta-keyword\":\"if else elif endif define undef ifdef ifndef\"},contains:[{begin:/\\\\\\n/,relevance:0},{beginKeywords:\"include\",end:\"$\",keywords:{\"meta-keyword\":\"include\"},contains:[e.inherit(t,{className:\"meta-string\"}),{className:\"meta-string\",begin:\"<\",end:\">\",illegal:\"\\\\n\"}]},t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},i={className:\"variable\",begin:\"\\\\&[a-z\\\\d_]*\\\\b\"},a={className:\"meta-keyword\",begin:\"/[a-z][a-z\\\\d-]*/\"},o={className:\"symbol\",begin:\"^\\\\s*[a-zA-Z_][a-zA-Z\\\\d_]*:\"},s={className:\"params\",begin:\"<\",end:\">\",contains:[n,i]},l={className:\"class\",begin:/[a-zA-Z_][a-zA-Z\\d_@]*\\s{/,end:/[{;=]/,returnBegin:!0,excludeEnd:!0};return{keywords:\"\",contains:[{className:\"class\",begin:\"/\\\\s*{\",end:\"};\",relevance:10,contains:[i,a,o,l,s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,t]},i,a,o,l,s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,t,r,{begin:e.IDENT_RE+\"::\",keywords:\"\"}]}}},function(e,t){e.exports=function(e){return{keywords:\"dsconfig\",contains:[{className:\"keyword\",begin:\"^dsconfig\",end:\"\\\\s\",excludeEnd:!0,relevance:10},{className:\"built_in\",begin:\"(list|create|get|set|delete)-(\\\\w+)\",end:\"\\\\s\",excludeEnd:!0,illegal:\"!@#$%^&*()\",relevance:10},{className:\"built_in\",begin:\"--(\\\\w+)\",end:\"\\\\s\",excludeEnd:!0},{className:\"string\",begin:/\"/,end:/\"/},{className:\"string\",begin:/'/,end:/'/},{className:\"string\",begin:\"[\\\\w-?]+:\\\\w+\",end:\"\\\\W\",relevance:0},{className:\"string\",begin:\"\\\\w+-?\\\\w+\",end:\"\\\\W\",relevance:0},e.HASH_COMMENT_MODE]}}},function(e,t){e.exports=function(e){var t=e.COMMENT(/^\\s*@?rem\\b/,/$/,{relevance:10});return{aliases:[\"bat\",\"cmd\"],case_insensitive:!0,illegal:/\\/\\*/,keywords:{keyword:\"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq\",built_in:\"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux shift cd dir echo setlocal endlocal set pause copy append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color comp compact convert date dir diskcomp diskcopy doskey erase fs find findstr format ftype graftabl help keyb label md mkdir mode more move path pause print popd pushd promt rd recover rem rename replace restore rmdir shiftsort start subst time title tree type ver verify vol ping net ipconfig taskkill xcopy ren del\"},contains:[{className:\"variable\",begin:/%%[^ ]|%[^ ]+?%|![^ ]+?!/},{className:\"function\",begin:\"^\\\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\\\s+label)\",end:\"goto:eof\",contains:[e.inherit(e.TITLE_MODE,{begin:\"([_a-zA-Z]\\\\w*\\\\.)*([_a-zA-Z]\\\\w*:)?[_a-zA-Z]\\\\w*\"}),t]},{className:\"number\",begin:\"\\\\b\\\\d+\",relevance:0},t]}}},function(e,t){e.exports=function(e){return{aliases:[\"docker\"],case_insensitive:!0,keywords:\"from maintainer expose env arg user onbuild stopsignal\",contains:[e.HASH_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{beginKeywords:\"run cmd entrypoint volume add copy workdir label healthcheck shell\",starts:{end:/[^\\\\]\\n/,subLanguage:\"bash\"}}],illegal:\"\"}]}}},function(e,t){e.exports=function(e){return{aliases:[\"md\",\"mkdown\",\"mkd\"],contains:[{className:\"section\",variants:[{begin:\"^#{1,6}\",end:\"$\"},{begin:\"^.+?\\\\n[=-]{2,}$\"}]},{begin:\"<\",end:\">\",subLanguage:\"xml\",relevance:0},{className:\"bullet\",begin:\"^([*+-]|(\\\\d+\\\\.))\\\\s+\"},{className:\"strong\",begin:\"[*_]{2}.+?[*_]{2}\"},{className:\"emphasis\",variants:[{begin:\"\\\\*.+?\\\\*\"},{begin:\"_.+?_\",relevance:0}]},{className:\"quote\",begin:\"^>\\\\s+\",end:\"$\"},{className:\"code\",variants:[{begin:\"^```w*s*$\",end:\"^```s*$\"},{begin:\"`.+?`\"},{begin:\"^( {4}|\\t)\",end:\"$\",relevance:0}]},{begin:\"^[-\\\\*]{3,}\",end:\"$\"},{begin:\"\\\\[.+?\\\\][\\\\(\\\\[].*?[\\\\)\\\\]]\",returnBegin:!0,contains:[{className:\"string\",begin:\"\\\\[\",end:\"\\\\]\",excludeBegin:!0,returnEnd:!0,relevance:0},{className:\"link\",begin:\"\\\\]\\\\(\",end:\"\\\\)\",excludeBegin:!0,excludeEnd:!0},{className:\"symbol\",begin:\"\\\\]\\\\[\",end:\"\\\\]\",excludeBegin:!0,excludeEnd:!0}],relevance:10},{begin:/^\\[[^\\n]+\\]:/,returnBegin:!0,contains:[{className:\"symbol\",begin:/\\[/,end:/\\]/,excludeBegin:!0,excludeEnd:!0},{className:\"link\",begin:/:\\s*/,end:/$/,excludeBegin:!0}]}]}}},function(e,t){e.exports=function(e){var t=\"((0|[1-9][\\\\d_]*)|0[bB][01_]+|0[xX]([\\\\da-fA-F][\\\\da-fA-F_]*|_[\\\\da-fA-F][\\\\da-fA-F_]*))\",n=\"\\\\\\\\(['\\\"\\\\?\\\\\\\\abfnrtv]|u[\\\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\\\dA-Fa-f]{2}|U[\\\\dA-Fa-f]{8})|&[a-zA-Z\\\\d]{2,};\",r={className:\"number\",begin:\"\\\\b\"+t+\"(L|u|U|Lu|LU|uL|UL)?\",relevance:0},i={className:\"number\",begin:\"\\\\b(((0[xX](([\\\\da-fA-F][\\\\da-fA-F_]*|_[\\\\da-fA-F][\\\\da-fA-F_]*)\\\\.([\\\\da-fA-F][\\\\da-fA-F_]*|_[\\\\da-fA-F][\\\\da-fA-F_]*)|\\\\.?([\\\\da-fA-F][\\\\da-fA-F_]*|_[\\\\da-fA-F][\\\\da-fA-F_]*))[pP][+-]?(0|[1-9][\\\\d_]*|\\\\d[\\\\d_]*|[\\\\d_]+?\\\\d))|((0|[1-9][\\\\d_]*|\\\\d[\\\\d_]*|[\\\\d_]+?\\\\d)(\\\\.\\\\d*|([eE][+-]?(0|[1-9][\\\\d_]*|\\\\d[\\\\d_]*|[\\\\d_]+?\\\\d)))|\\\\d+\\\\.(0|[1-9][\\\\d_]*|\\\\d[\\\\d_]*|[\\\\d_]+?\\\\d)(0|[1-9][\\\\d_]*|\\\\d[\\\\d_]*|[\\\\d_]+?\\\\d)|\\\\.(0|[1-9][\\\\d_]*)([eE][+-]?(0|[1-9][\\\\d_]*|\\\\d[\\\\d_]*|[\\\\d_]+?\\\\d))?))([fF]|L|i|[fF]i|Li)?|\"+t+\"(i|[fF]i|Li))\",relevance:0},a={className:\"string\",begin:\"'(\"+n+\"|.)\",end:\"'\",illegal:\".\"},o={className:\"string\",begin:'\"',contains:[{begin:n,relevance:0}],end:'\"[cwd]?'},s=e.COMMENT(\"\\\\/\\\\+\",\"\\\\+\\\\/\",{contains:[\"self\"],relevance:10});return{lexemes:e.UNDERSCORE_IDENT_RE,keywords:{keyword:\"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__\",built_in:\"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring\",literal:\"false null true\"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,{className:\"string\",begin:'x\"[\\\\da-fA-F\\\\s\\\\n\\\\r]*\"[cwd]?',relevance:10},o,{className:\"string\",begin:'[rq]\"',end:'\"[cwd]?',relevance:5},{className:\"string\",begin:\"`\",end:\"`[cwd]?\"},{className:\"string\",begin:'q\"\\\\{',end:'\\\\}\"'},i,r,a,{className:\"meta\",begin:\"^#!\",end:\"$\",relevance:5},{className:\"meta\",begin:\"#(line)\",end:\"$\",relevance:5},{className:\"keyword\",begin:\"@[a-zA-Z_][a-zA-Z_\\\\d]*\"}]}}},function(e,t){e.exports=function(e){var t={begin:/[A-Z\\_\\.\\-]+\\s*:/,returnBegin:!0,end:\";\",endsWithParent:!0,contains:[{className:\"attribute\",begin:/\\S/,end:\":\",excludeEnd:!0,starts:{endsWithParent:!0,excludeEnd:!0,contains:[{begin:/[\\w-]+\\(/,returnBegin:!0,contains:[{className:\"built_in\",begin:/[\\w-]+/},{begin:/\\(/,end:/\\)/,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]}]},e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE,{className:\"number\",begin:\"#[0-9A-Fa-f]+\"},{className:\"meta\",begin:\"!important\"}]}}]};return{case_insensitive:!0,illegal:/[=\\/|'\\$]/,contains:[e.C_BLOCK_COMMENT_MODE,{className:\"selector-id\",begin:/#[A-Za-z0-9_-]+/},{className:\"selector-class\",begin:/\\.[A-Za-z0-9_-]+/},{className:\"selector-attr\",begin:/\\[/,end:/\\]/,illegal:\"$\"},{className:\"selector-pseudo\",begin:/:(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\"'.]+/},{begin:\"@(font-face|page)\",lexemes:\"[a-z-]+\",keywords:\"font-face page\"},{begin:\"@\",end:\"[{;]\",illegal:/:/,contains:[{className:\"keyword\",begin:/\\w+/},{begin:/\\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE]}]},{className:\"selector-tag\",begin:\"[a-zA-Z-][a-zA-Z0-9_-]*\",relevance:0},{begin:\"{\",end:\"}\",illegal:/\\S/,contains:[e.C_BLOCK_COMMENT_MODE,t]}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!1,lexemes:\"[a-zA-Z][a-zA-Z0-9_-]*\",keywords:{keyword:\"base-uri child-src connect-src default-src font-src form-action frame-ancestors frame-src img-src media-src object-src plugin-types report-uri sandbox script-src style-src\"},contains:[{className:\"string\",begin:\"'\",end:\"'\"},{className:\"attribute\",begin:\"^Content\",end:\":\",excludeEnd:!0}]}}},function(e,t){e.exports=function(e){var t={keyword:\"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield\",literal:\"null false true\"},n={className:\"string\",begin:'@\"',end:'\"',contains:[{begin:'\"\"'}]},r=e.inherit(n,{illegal:/\\n/}),i={className:\"subst\",begin:\"{\",end:\"}\",keywords:t},a=e.inherit(i,{illegal:/\\n/}),o={className:\"string\",begin:/\\$\"/,end:'\"',illegal:/\\n/,contains:[{begin:\"{{\"},{begin:\"}}\"},e.BACKSLASH_ESCAPE,a]},s={className:\"string\",begin:/\\$@\"/,end:'\"',contains:[{begin:\"{{\"},{begin:\"}}\"},{begin:'\"\"'},i]},l=e.inherit(s,{illegal:/\\n/,contains:[{begin:\"{{\"},{begin:\"}}\"},{begin:'\"\"'},a]});i.contains=[s,o,n,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE],a.contains=[l,o,r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.inherit(e.C_BLOCK_COMMENT_MODE,{illegal:/\\n/})];var c={variants:[s,o,n,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},u=e.IDENT_RE+\"(<\"+e.IDENT_RE+\"(\\\\s*,\\\\s*\"+e.IDENT_RE+\")*>)?(\\\\[\\\\])?\";return{aliases:[\"csharp\"],keywords:t,illegal:/::/,contains:[e.COMMENT(\"///\",\"$\",{returnBegin:!0,contains:[{className:\"doctag\",variants:[{begin:\"///\",relevance:0},{begin:\"\\x3c!--|--\\x3e\"},{begin:\"\"}]}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:\"meta\",begin:\"#\",end:\"$\",keywords:{\"meta-keyword\":\"if else elif endif define undef warning error line region endregion pragma checksum\"}},c,e.C_NUMBER_MODE,{beginKeywords:\"class interface\",end:/[{;=]/,illegal:/[^\\s:]/,contains:[e.TITLE_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:\"namespace\",end:/[{;=]/,illegal:/[^\\s:]/,contains:[e.inherit(e.TITLE_MODE,{begin:\"[a-zA-Z](\\\\.?\\\\w)*\"}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:\"meta\",begin:\"^\\\\s*\\\\[\",excludeBegin:!0,end:\"\\\\]\",excludeEnd:!0,contains:[{className:\"meta-string\",begin:/\"/,end:/\"/}]},{beginKeywords:\"new return throw await else\",relevance:0},{className:\"function\",begin:\"(\"+u+\"\\\\s+)+\"+e.IDENT_RE+\"\\\\s*\\\\(\",returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:t,contains:[{begin:e.IDENT_RE+\"\\\\s*\\\\(\",returnBegin:!0,contains:[e.TITLE_MODE],relevance:0},{className:\"params\",begin:/\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,relevance:0,contains:[c,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}]}}},function(e,t){e.exports=function(e){var t=\"(_[uif](8|16|32|64))?\",n=\"[a-zA-Z_]\\\\w*[!?=]?|[-+~]\\\\@|<<|>>|=~|===?|<=>|[<>]=?|\\\\*\\\\*|[-/+%^&*~`|]|\\\\[\\\\][=?]?\",r={keyword:\"abstract alias as as? asm begin break case class def do else elsif end ensure enum extend for fun if include instance_sizeof is_a? lib macro module next nil? of out pointerof private protected rescue responds_to? return require select self sizeof struct super then type typeof union uninitialized unless until when while with yield __DIR__ __END_LINE__ __FILE__ __LINE__\",literal:\"false nil true\"},i={className:\"subst\",begin:\"#{\",end:\"}\",keywords:r},a={className:\"template-variable\",variants:[{begin:\"\\\\{\\\\{\",end:\"\\\\}\\\\}\"},{begin:\"\\\\{%\",end:\"%\\\\}\"}],keywords:r};function o(e,t){var n=[{begin:e,end:t}];return n[0].contains=n,n}var s={className:\"string\",contains:[e.BACKSLASH_ESCAPE,i],variants:[{begin:/'/,end:/'/},{begin:/\"/,end:/\"/},{begin:/`/,end:/`/},{begin:\"%w?\\\\(\",end:\"\\\\)\",contains:o(\"\\\\(\",\"\\\\)\")},{begin:\"%w?\\\\[\",end:\"\\\\]\",contains:o(\"\\\\[\",\"\\\\]\")},{begin:\"%w?{\",end:\"}\",contains:o(\"{\",\"}\")},{begin:\"%w?<\",end:\">\",contains:o(\"<\",\">\")},{begin:\"%w?/\",end:\"/\"},{begin:\"%w?%\",end:\"%\"},{begin:\"%w?-\",end:\"-\"},{begin:\"%w?\\\\|\",end:\"\\\\|\"},{begin:/<<-\\w+$/,end:/^\\s*\\w+$/}],relevance:0},l=[a,s,{className:\"string\",variants:[{begin:\"%q\\\\(\",end:\"\\\\)\",contains:o(\"\\\\(\",\"\\\\)\")},{begin:\"%q\\\\[\",end:\"\\\\]\",contains:o(\"\\\\[\",\"\\\\]\")},{begin:\"%q{\",end:\"}\",contains:o(\"{\",\"}\")},{begin:\"%q<\",end:\">\",contains:o(\"<\",\">\")},{begin:\"%q/\",end:\"/\"},{begin:\"%q%\",end:\"%\"},{begin:\"%q-\",end:\"-\"},{begin:\"%q\\\\|\",end:\"\\\\|\"},{begin:/<<-'\\w+'$/,end:/^\\s*\\w+$/}],relevance:0},{begin:\"(!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~)\\\\s*\",contains:[{className:\"regexp\",contains:[e.BACKSLASH_ESCAPE,i],variants:[{begin:\"//[a-z]*\",relevance:0},{begin:\"/\",end:\"/[a-z]*\"},{begin:\"%r\\\\(\",end:\"\\\\)\",contains:o(\"\\\\(\",\"\\\\)\")},{begin:\"%r\\\\[\",end:\"\\\\]\",contains:o(\"\\\\[\",\"\\\\]\")},{begin:\"%r{\",end:\"}\",contains:o(\"{\",\"}\")},{begin:\"%r<\",end:\">\",contains:o(\"<\",\">\")},{begin:\"%r/\",end:\"/\"},{begin:\"%r%\",end:\"%\"},{begin:\"%r-\",end:\"-\"},{begin:\"%r\\\\|\",end:\"\\\\|\"}]}],relevance:0},{className:\"regexp\",contains:[e.BACKSLASH_ESCAPE,i],variants:[{begin:\"%r\\\\(\",end:\"\\\\)\",contains:o(\"\\\\(\",\"\\\\)\")},{begin:\"%r\\\\[\",end:\"\\\\]\",contains:o(\"\\\\[\",\"\\\\]\")},{begin:\"%r{\",end:\"}\",contains:o(\"{\",\"}\")},{begin:\"%r<\",end:\">\",contains:o(\"<\",\">\")},{begin:\"%r/\",end:\"/\"},{begin:\"%r%\",end:\"%\"},{begin:\"%r-\",end:\"-\"},{begin:\"%r\\\\|\",end:\"\\\\|\"}],relevance:0},{className:\"meta\",begin:\"@\\\\[\",end:\"\\\\]\",contains:[e.inherit(e.QUOTE_STRING_MODE,{className:\"meta-string\"})]},e.HASH_COMMENT_MODE,{className:\"class\",beginKeywords:\"class module struct\",end:\"$|;\",illegal:/=/,contains:[e.HASH_COMMENT_MODE,e.inherit(e.TITLE_MODE,{begin:\"[A-Za-z_]\\\\w*(::\\\\w+)*(\\\\?|\\\\!)?\"}),{begin:\"<\"}]},{className:\"class\",beginKeywords:\"lib enum union\",end:\"$|;\",illegal:/=/,contains:[e.HASH_COMMENT_MODE,e.inherit(e.TITLE_MODE,{begin:\"[A-Za-z_]\\\\w*(::\\\\w+)*(\\\\?|\\\\!)?\"})],relevance:10},{className:\"function\",beginKeywords:\"def\",end:/\\B\\b/,contains:[e.inherit(e.TITLE_MODE,{begin:n,endsParent:!0})]},{className:\"function\",beginKeywords:\"fun macro\",end:/\\B\\b/,contains:[e.inherit(e.TITLE_MODE,{begin:n,endsParent:!0})],relevance:5},{className:\"symbol\",begin:e.UNDERSCORE_IDENT_RE+\"(\\\\!|\\\\?)?:\",relevance:0},{className:\"symbol\",begin:\":\",contains:[s,{begin:n}],relevance:0},{className:\"number\",variants:[{begin:\"\\\\b0b([01_]*[01])\"+t},{begin:\"\\\\b0o([0-7_]*[0-7])\"+t},{begin:\"\\\\b0x([A-Fa-f0-9_]*[A-Fa-f0-9])\"+t},{begin:\"\\\\b(([0-9][0-9_]*[0-9]|[0-9])(\\\\.[0-9_]*[0-9])?([eE][+-]?[0-9_]*[0-9])?)\"+t}],relevance:0}];return i.contains=l,a.contains=l.slice(1),{aliases:[\"cr\"],lexemes:\"[a-zA-Z_]\\\\w*[!?=]?\",keywords:r,contains:l}}},function(e,t){e.exports=function(e){var t=\"group clone ms master location colocation order fencing_topology rsc_ticket acl_target acl_group user role tag xml\";return{aliases:[\"crm\",\"pcmk\"],case_insensitive:!0,keywords:{keyword:\"params meta operations op rule attributes utilization read write deny defined not_defined in_range date spec in ref reference attribute type xpath version and or lt gt tag lte gte eq ne \\\\ number string\",literal:\"Master Started Slave Stopped start promote demote stop monitor true false\"},contains:[e.HASH_COMMENT_MODE,{beginKeywords:\"node\",starts:{end:\"\\\\s*([\\\\w_-]+:)?\",starts:{className:\"title\",end:\"\\\\s*[\\\\$\\\\w_][\\\\w_-]*\"}}},{beginKeywords:\"primitive rsc_template\",starts:{className:\"title\",end:\"\\\\s*[\\\\$\\\\w_][\\\\w_-]*\",starts:{end:\"\\\\s*@?[\\\\w_][\\\\w_\\\\.:-]*\"}}},{begin:\"\\\\b(\"+t.split(\" \").join(\"|\")+\")\\\\s+\",keywords:t,starts:{className:\"title\",end:\"[\\\\$\\\\w_][\\\\w_-]*\"}},{beginKeywords:\"property rsc_defaults op_defaults\",starts:{className:\"title\",end:\"\\\\s*([\\\\w_-]+:)?\"}},e.QUOTE_STRING_MODE,{className:\"meta\",begin:\"(ocf|systemd|service|lsb):[\\\\w_:-]+\",relevance:0},{className:\"number\",begin:\"\\\\b\\\\d+(\\\\.\\\\d+)?(ms|s|h|m)?\",relevance:0},{className:\"literal\",begin:\"[-]?(infinity|inf)\",relevance:0},{className:\"attr\",begin:/([A-Za-z\\$_\\#][\\w_-]+)=/,relevance:0},{className:\"tag\",begin:\"\",relevance:0}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,aliases:[\"cos\",\"cls\"],keywords:\"property parameter class classmethod clientmethod extends as break catch close continue do d|0 else elseif for goto halt hang h|0 if job j|0 kill k|0 lock l|0 merge new open quit q|0 read r|0 return set s|0 tcommit throw trollback try tstart use view while write w|0 xecute x|0 zkill znspace zn ztrap zwrite zw zzdump zzwrite print zbreak zinsert zload zprint zremove zsave zzprint mv mvcall mvcrt mvdim mvprint zquit zsync ascii\",contains:[{className:\"number\",begin:\"\\\\b(\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)\",relevance:0},{className:\"string\",variants:[{begin:'\"',end:'\"',contains:[{begin:'\"\"',relevance:0}]}]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:\"comment\",begin:/;/,end:\"$\",relevance:0},{className:\"built_in\",begin:/(?:\\$\\$?|\\.\\.)\\^?[a-zA-Z]+/},{className:\"built_in\",begin:/\\$\\$\\$[a-zA-Z]+/},{className:\"built_in\",begin:/%[a-z]+(?:\\.[a-z]+)*/},{className:\"symbol\",begin:/\\^%?[a-zA-Z][\\w]*/},{className:\"keyword\",begin:/##class|##super|#define|#dim/},{begin:/&sql\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0,subLanguage:\"sql\"},{begin:/&(js|jscript|javascript)/,excludeBegin:!0,excludeEnd:!0,subLanguage:\"javascript\"},{begin:/&html<\\s*\\s*>/,subLanguage:\"xml\"}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:\"_ as at cofix else end exists exists2 fix for forall fun if IF in let match mod Prop return Set then Type using where with Abort About Add Admit Admitted All Arguments Assumptions Axiom Back BackTo Backtrack Bind Blacklist Canonical Cd Check Class Classes Close Coercion Coercions CoFixpoint CoInductive Collection Combined Compute Conjecture Conjectures Constant constr Constraint Constructors Context Corollary CreateHintDb Cut Declare Defined Definition Delimit Dependencies DependentDerive Drop eauto End Equality Eval Example Existential Existentials Existing Export exporting Extern Extract Extraction Fact Field Fields File Fixpoint Focus for From Function Functional Generalizable Global Goal Grab Grammar Graph Guarded Heap Hint HintDb Hints Hypotheses Hypothesis ident Identity If Immediate Implicit Import Include Inductive Infix Info Initial Inline Inspect Instance Instances Intro Intros Inversion Inversion_clear Language Left Lemma Let Libraries Library Load LoadPath Local Locate Ltac ML Mode Module Modules Monomorphic Morphism Next NoInline Notation Obligation Obligations Opaque Open Optimize Options Parameter Parameters Parametric Path Paths pattern Polymorphic Preterm Print Printing Program Projections Proof Proposition Pwd Qed Quit Rec Record Recursive Redirect Relation Remark Remove Require Reserved Reset Resolve Restart Rewrite Right Ring Rings Save Scheme Scope Scopes Script Search SearchAbout SearchHead SearchPattern SearchRewrite Section Separate Set Setoid Show Solve Sorted Step Strategies Strategy Structure SubClass Table Tables Tactic Term Test Theorem Time Timeout Transparent Type Typeclasses Types Undelimit Undo Unfocus Unfocused Unfold Universe Universes Unset Unshelve using Variable Variables Variant Verbose Visibility where with\",built_in:\"abstract absurd admit after apply as assert assumption at auto autorewrite autounfold before bottom btauto by case case_eq cbn cbv change classical_left classical_right clear clearbody cofix compare compute congruence constr_eq constructor contradict contradiction cut cutrewrite cycle decide decompose dependent destruct destruction dintuition discriminate discrR do double dtauto eapply eassumption eauto ecase econstructor edestruct ediscriminate eelim eexact eexists einduction einjection eleft elim elimtype enough equality erewrite eright esimplify_eq esplit evar exact exactly_once exfalso exists f_equal fail field field_simplify field_simplify_eq first firstorder fix fold fourier functional generalize generalizing gfail give_up has_evar hnf idtac in induction injection instantiate intro intro_pattern intros intuition inversion inversion_clear is_evar is_var lapply lazy left lia lra move native_compute nia nsatz omega once pattern pose progress proof psatz quote record red refine reflexivity remember rename repeat replace revert revgoals rewrite rewrite_strat right ring ring_simplify rtauto set setoid_reflexivity setoid_replace setoid_rewrite setoid_symmetry setoid_transitivity shelve shelve_unifiable simpl simple simplify_eq solve specialize split split_Rabs split_Rmult stepl stepr subst sum swap symmetry tactic tauto time timeout top transitivity trivial try tryif unfold unify until using vm_compute with\"},contains:[e.QUOTE_STRING_MODE,e.COMMENT(\"\\\\(\\\\*\",\"\\\\*\\\\)\"),e.C_NUMBER_MODE,{className:\"type\",excludeBegin:!0,begin:\"\\\\|\\\\s*\",end:\"\\\\w+\"},{begin:/[-=]>/}]}}},function(e,t){e.exports=function(e){var t={keyword:\"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not\",literal:\"true false null undefined yes no on off\",built_in:\"npm require console print module global window document\"},n=\"[A-Za-z$_][0-9A-Za-z$_]*\",r={className:\"subst\",begin:/#\\{/,end:/}/,keywords:t},i=[e.BINARY_NUMBER_MODE,e.inherit(e.C_NUMBER_MODE,{starts:{end:\"(\\\\s*/)?\",relevance:0}}),{className:\"string\",variants:[{begin:/'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE]},{begin:/'/,end:/'/,contains:[e.BACKSLASH_ESCAPE]},{begin:/\"\"\"/,end:/\"\"\"/,contains:[e.BACKSLASH_ESCAPE,r]},{begin:/\"/,end:/\"/,contains:[e.BACKSLASH_ESCAPE,r]}]},{className:\"regexp\",variants:[{begin:\"///\",end:\"///\",contains:[r,e.HASH_COMMENT_MODE]},{begin:\"//[gim]*\",relevance:0},{begin:/\\/(?![ *])(\\\\\\/|.)*?\\/[gim]*(?=\\W|$)/}]},{begin:\"@\"+n},{subLanguage:\"javascript\",excludeBegin:!0,excludeEnd:!0,variants:[{begin:\"```\",end:\"```\"},{begin:\"`\",end:\"`\"}]}];r.contains=i;var a=e.inherit(e.TITLE_MODE,{begin:n}),o={className:\"params\",begin:\"\\\\([^\\\\(]\",returnBegin:!0,contains:[{begin:/\\(/,end:/\\)/,keywords:t,contains:[\"self\"].concat(i)}]};return{aliases:[\"coffee\",\"cson\",\"iced\"],keywords:t,illegal:/\\/\\*/,contains:i.concat([e.COMMENT(\"###\",\"###\"),e.HASH_COMMENT_MODE,{className:\"function\",begin:\"^\\\\s*\"+n+\"\\\\s*=\\\\s*(\\\\(.*\\\\))?\\\\s*\\\\B[-=]>\",end:\"[-=]>\",returnBegin:!0,contains:[a,o]},{begin:/[:\\(,=]\\s*/,relevance:0,contains:[{className:\"function\",begin:\"(\\\\(.*\\\\))?\\\\s*\\\\B[-=]>\",end:\"[-=]>\",returnBegin:!0,contains:[o]}]},{className:\"class\",beginKeywords:\"class\",end:\"$\",illegal:/[:=\"\\[\\]]/,contains:[{beginKeywords:\"extends\",endsWithParent:!0,illegal:/[:=\"\\[\\]]/,contains:[a]},a]},{begin:n+\":\",end:\":\",returnBegin:!0,returnEnd:!0,relevance:0}])}}},function(e,t){e.exports=function(e){return{aliases:[\"cmake.in\"],case_insensitive:!0,keywords:{keyword:\"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file qt5_use_modules qt5_use_package qt5_wrap_cpp on off true false and or equal less greater strless strgreater strequal matches\"},contains:[{className:\"variable\",begin:\"\\\\${\",end:\"}\"},e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{contains:[{className:\"meta\",begin:/^([\\w.-]+|\\s*#_)=>/,starts:{end:/$/,subLanguage:\"clojure\"}}]}}},function(e,t){e.exports=function(e){var t=\"[a-zA-Z_\\\\-!.?+*=<>&#'][a-zA-Z_\\\\-!.?+*=<>&#'0-9/;:]*\",n={begin:t,relevance:0},r={className:\"number\",begin:\"[-+]?\\\\d+(\\\\.\\\\d+)?\",relevance:0},i=e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),a=e.COMMENT(\";\",\"$\",{relevance:0}),o={className:\"literal\",begin:/\\b(true|false|nil)\\b/},s={begin:\"[\\\\[\\\\{]\",end:\"[\\\\]\\\\}]\"},l={className:\"comment\",begin:\"\\\\^\"+t},c=e.COMMENT(\"\\\\^\\\\{\",\"\\\\}\"),u={className:\"symbol\",begin:\"[:]{1,2}\"+t},d={begin:\"\\\\(\",end:\"\\\\)\"},f={endsWithParent:!0,relevance:0},p={keywords:{\"builtin-name\":\"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize\"},lexemes:t,className:\"name\",begin:t,starts:f},m=[d,i,l,c,a,u,s,r,o,n];return d.contains=[e.COMMENT(\"comment\",\"\"),p,f],f.contains=m,s.contains=m,c.contains=[s],{aliases:[\"clj\"],illegal:/\\S/,contains:[d,i,l,c,a,u,s,r,o]}}},function(e,t){e.exports=function(e){return{aliases:[\"clean\",\"icl\",\"dcl\"],keywords:{keyword:\"if let in with where case of class instance otherwise implementation definition system module from import qualified as special code inline foreign export ccall stdcall generic derive infix infixl infixr\",literal:\"True False\"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,{begin:\"->|<-[|:]?|::|#!?|>>=|\\\\{\\\\||\\\\|\\\\}|:==|=:|\\\\.\\\\.|<>|`\"}]}}},function(e,t){e.exports=function(e){var t=\"assembly module package import alias class interface object given value assign void function new of extends satisfies abstracts in out return break continue throw assert dynamic if else switch case for while try catch finally then let this outer super is exists nonempty\",n={className:\"subst\",excludeBegin:!0,excludeEnd:!0,begin:/``/,end:/``/,keywords:t,relevance:10},r=[{className:\"string\",begin:'\"\"\"',end:'\"\"\"',relevance:10},{className:\"string\",begin:'\"',end:'\"',contains:[n]},{className:\"string\",begin:\"'\",end:\"'\"},{className:\"number\",begin:\"#[0-9a-fA-F_]+|\\\\$[01_]+|[0-9_]+(?:\\\\.[0-9_](?:[eE][+-]?\\\\d+)?)?[kMGTPmunpf]?\",relevance:0}];return n.contains=r,{keywords:{keyword:t+\" shared abstract formal default actual variable late native deprecatedfinal sealed annotation suppressWarnings small\",meta:\"doc by license see throws tagged\"},illegal:\"\\\\$[^01]|#[^0-9a-fA-F]\",contains:[e.C_LINE_COMMENT_MODE,e.COMMENT(\"/\\\\*\",\"\\\\*/\",{contains:[\"self\"]}),{className:\"meta\",begin:'@[a-z]\\\\w*(?:\\\\:\"[^\"]*\")?'}].concat(r)}}},function(e,t){e.exports=function(e){return{aliases:[\"capnp\"],keywords:{keyword:\"struct enum interface union group import using const annotation extends in of on as with from fixed\",built_in:\"Void Bool Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Float32 Float64 Text Data AnyPointer AnyStruct Capability List\",literal:\"true false\"},contains:[e.QUOTE_STRING_MODE,e.NUMBER_MODE,e.HASH_COMMENT_MODE,{className:\"meta\",begin:/@0x[\\w\\d]{16};/,illegal:/\\n/},{className:\"symbol\",begin:/@\\d+\\b/},{className:\"class\",beginKeywords:\"struct enum\",end:/\\{/,illegal:/\\n/,contains:[e.inherit(e.TITLE_MODE,{starts:{endsWithParent:!0,excludeEnd:!0}})]},{className:\"class\",beginKeywords:\"interface\",end:/\\{/,illegal:/\\n/,contains:[e.inherit(e.TITLE_MODE,{starts:{endsWithParent:!0,excludeEnd:!0}})]}]}}},function(e,t){e.exports=function(e){var t=\"div mod in and or not xor asserterror begin case do downto else end exit for if of repeat then to until while with var\",n=[e.C_LINE_COMMENT_MODE,e.COMMENT(/\\{/,/\\}/,{relevance:0}),e.COMMENT(/\\(\\*/,/\\*\\)/,{relevance:10})],r={className:\"string\",begin:/'/,end:/'/,contains:[{begin:/''/}]},i={className:\"string\",begin:/(#\\d+)+/},a={className:\"function\",beginKeywords:\"procedure\",end:/[:;]/,keywords:\"procedure|10\",contains:[e.TITLE_MODE,{className:\"params\",begin:/\\(/,end:/\\)/,keywords:t,contains:[r,i]}].concat(n)},o={className:\"class\",begin:\"OBJECT (Table|Form|Report|Dataport|Codeunit|XMLport|MenuSuite|Page|Query) (\\\\d+) ([^\\\\r\\\\n]+)\",returnBegin:!0,contains:[e.TITLE_MODE,a]};return{case_insensitive:!0,keywords:{keyword:t,literal:\"false true\"},illegal:/\\/\\*/,contains:[r,i,{className:\"number\",begin:\"\\\\b\\\\d+(\\\\.\\\\d+)?(DT|D|T)\",relevance:0},{className:\"string\",begin:'\"',end:'\"'},e.NUMBER_MODE,o,a]}}},function(e,t){e.exports=function(e){var t={className:\"literal\",begin:\"[\\\\+\\\\-]\",relevance:0};return{aliases:[\"bf\"],contains:[e.COMMENT(\"[^\\\\[\\\\]\\\\.,\\\\+\\\\-<> \\r\\n]\",\"[\\\\[\\\\]\\\\.,\\\\+\\\\-<> \\r\\n]\",{returnEnd:!0,relevance:0}),{className:\"title\",begin:\"[\\\\[\\\\]]\",relevance:0},{className:\"string\",begin:\"[\\\\.,]\",relevance:0},{begin:/\\+\\+|\\-\\-/,returnBegin:!0,contains:[t]},t]}}},function(e,t){e.exports=function(e){return{contains:[{className:\"attribute\",begin://},{begin:/::=/,starts:{end:/$/,contains:[{begin://},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]}}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,illegal:\"^.\",lexemes:\"[a-zA-Z][a-zA-Z0-9_$%!#]*\",keywords:{keyword:\"ABS ASC AND ATN AUTO|0 BEEP BLOAD|10 BSAVE|10 CALL CALLS CDBL CHAIN CHDIR CHR$|10 CINT CIRCLE CLEAR CLOSE CLS COLOR COM COMMON CONT COS CSNG CSRLIN CVD CVI CVS DATA DATE$ DEFDBL DEFINT DEFSNG DEFSTR DEF|0 SEG USR DELETE DIM DRAW EDIT END ENVIRON ENVIRON$ EOF EQV ERASE ERDEV ERDEV$ ERL ERR ERROR EXP FIELD FILES FIX FOR|0 FRE GET GOSUB|10 GOTO HEX$ IF|0 THEN ELSE|0 INKEY$ INP INPUT INPUT# INPUT$ INSTR IMP INT IOCTL IOCTL$ KEY ON OFF LIST KILL LEFT$ LEN LET LINE LLIST LOAD LOC LOCATE LOF LOG LPRINT USING LSET MERGE MID$ MKDIR MKD$ MKI$ MKS$ MOD NAME NEW NEXT NOISE NOT OCT$ ON OR PEN PLAY STRIG OPEN OPTION BASE OUT PAINT PALETTE PCOPY PEEK PMAP POINT POKE POS PRINT PRINT] PSET PRESET PUT RANDOMIZE READ REM RENUM RESET|0 RESTORE RESUME RETURN|0 RIGHT$ RMDIR RND RSET RUN SAVE SCREEN SGN SHELL SIN SOUND SPACE$ SPC SQR STEP STICK STOP STR$ STRING$ SWAP SYSTEM TAB TAN TIME$ TIMER TROFF TRON TO USR VAL VARPTR VARPTR$ VIEW WAIT WHILE WEND WIDTH WINDOW WRITE XOR\"},contains:[e.QUOTE_STRING_MODE,e.COMMENT(\"REM\",\"$\",{relevance:10}),e.COMMENT(\"'\",\"$\",{relevance:0}),{className:\"symbol\",begin:\"^[0-9]+ \",relevance:10},{className:\"number\",begin:\"\\\\b([0-9]+[0-9edED.]*[#!]?)\",relevance:0},{className:\"number\",begin:\"(&[hH][0-9a-fA-F]{1,4})\"},{className:\"number\",begin:\"(&[oO][0-7]{1,6})\"}]}}},function(e,t){e.exports=function(e){var t={className:\"variable\",variants:[{begin:/\\$[\\w\\d#@][\\w\\d_]*/},{begin:/\\$\\{(.*?)}/}]},n={className:\"string\",begin:/\"/,end:/\"/,contains:[e.BACKSLASH_ESCAPE,t,{className:\"variable\",begin:/\\$\\(/,end:/\\)/,contains:[e.BACKSLASH_ESCAPE]}]};return{aliases:[\"sh\",\"zsh\"],lexemes:/\\b-?[a-z\\._]+\\b/,keywords:{keyword:\"if then else elif fi for while in do done case esac function\",literal:\"true false\",built_in:\"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp\",_:\"-ne -eq -lt -gt -f -d -e -s -l -a\"},contains:[{className:\"meta\",begin:/^#![^\\n]+sh\\s*$/,relevance:10},{className:\"function\",begin:/\\w[\\w\\d_]*\\s*\\(\\s*\\)\\s*\\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\\w[\\w\\d_]*/})],relevance:0},e.HASH_COMMENT_MODE,n,{className:\"string\",begin:/'/,end:/'/},t]}}},function(e,t){e.exports=function(e){return{keywords:\"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod\",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,{className:\"meta\",begin:\"#\",end:\"$\"},{className:\"class\",beginKeywords:\"class interface\",end:\"{\",excludeEnd:!0,illegal:\":\",contains:[{beginKeywords:\"extends implements\"},e.UNDERSCORE_TITLE_MODE]}]}}},function(e,t){e.exports=function(e){return{keywords:{keyword:\"BEGIN END if else while do for in break continue delete next nextfile function func exit|10\"},contains:[{className:\"variable\",variants:[{begin:/\\$[\\w\\d#@][\\w\\d_]*/},{begin:/\\$\\{(.*?)}/}]},{className:\"string\",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/(u|b)?r?'''/,end:/'''/,relevance:10},{begin:/(u|b)?r?\"\"\"/,end:/\"\"\"/,relevance:10},{begin:/(u|r|ur)'/,end:/'/,relevance:10},{begin:/(u|r|ur)\"/,end:/\"/,relevance:10},{begin:/(b|br)'/,end:/'/},{begin:/(b|br)\"/,end:/\"/},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},e.REGEXP_MODE,e.HASH_COMMENT_MODE,e.NUMBER_MODE]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,lexemes:\"\\\\.?\"+e.IDENT_RE,keywords:{keyword:\"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr\",built_in:\"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf\",meta:\".byte .cseg .db .def .device .dseg .dw .endmacro .equ .eseg .exit .include .list .listmac .macro .nolist .org .set\"},contains:[e.C_BLOCK_COMMENT_MODE,e.COMMENT(\";\",\"$\",{relevance:0}),e.C_NUMBER_MODE,e.BINARY_NUMBER_MODE,{className:\"number\",begin:\"\\\\b(\\\\$[a-zA-Z0-9]+|0o[0-7]+)\"},e.QUOTE_STRING_MODE,{className:\"string\",begin:\"'\",end:\"[^\\\\\\\\]'\",illegal:\"[^\\\\\\\\][^']\"},{className:\"symbol\",begin:\"^[A-Za-z0-9_.$]+:\"},{className:\"meta\",begin:\"#\",end:\"$\"},{className:\"subst\",begin:\"@[0-9]+\"}]}}},function(e,t){e.exports=function(e){var t={variants:[e.COMMENT(\";\",\"$\",{relevance:0}),e.COMMENT(\"#cs\",\"#ce\"),e.COMMENT(\"#comments-start\",\"#comments-end\")]},n={begin:\"\\\\$[A-z0-9_]+\"},r={className:\"string\",variants:[{begin:/\"/,end:/\"/,contains:[{begin:/\"\"/,relevance:0}]},{begin:/'/,end:/'/,contains:[{begin:/''/,relevance:0}]}]},i={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]};return{case_insensitive:!0,illegal:/\\/\\*/,keywords:{keyword:\"ByRef Case Const ContinueCase ContinueLoop Default Dim Do Else ElseIf EndFunc EndIf EndSelect EndSwitch EndWith Enum Exit ExitLoop For Func Global If In Local Next ReDim Return Select Static Step Switch Then To Until Volatile WEnd While With\",built_in:\"Abs ACos AdlibRegister AdlibUnRegister Asc AscW ASin Assign ATan AutoItSetOption AutoItWinGetTitle AutoItWinSetTitle Beep Binary BinaryLen BinaryMid BinaryToString BitAND BitNOT BitOR BitRotate BitShift BitXOR BlockInput Break Call CDTray Ceiling Chr ChrW ClipGet ClipPut ConsoleRead ConsoleWrite ConsoleWriteError ControlClick ControlCommand ControlDisable ControlEnable ControlFocus ControlGetFocus ControlGetHandle ControlGetPos ControlGetText ControlHide ControlListView ControlMove ControlSend ControlSetText ControlShow ControlTreeView Cos Dec DirCopy DirCreate DirGetSize DirMove DirRemove DllCall DllCallAddress DllCallbackFree DllCallbackGetPtr DllCallbackRegister DllClose DllOpen DllStructCreate DllStructGetData DllStructGetPtr DllStructGetSize DllStructSetData DriveGetDrive DriveGetFileSystem DriveGetLabel DriveGetSerial DriveGetType DriveMapAdd DriveMapDel DriveMapGet DriveSetLabel DriveSpaceFree DriveSpaceTotal DriveStatus EnvGet EnvSet EnvUpdate Eval Execute Exp FileChangeDir FileClose FileCopy FileCreateNTFSLink FileCreateShortcut FileDelete FileExists FileFindFirstFile FileFindNextFile FileFlush FileGetAttrib FileGetEncoding FileGetLongName FileGetPos FileGetShortcut FileGetShortName FileGetSize FileGetTime FileGetVersion FileInstall FileMove FileOpen FileOpenDialog FileRead FileReadLine FileReadToArray FileRecycle FileRecycleEmpty FileSaveDialog FileSelectFolder FileSetAttrib FileSetEnd FileSetPos FileSetTime FileWrite FileWriteLine Floor FtpSetProxy FuncName GUICreate GUICtrlCreateAvi GUICtrlCreateButton GUICtrlCreateCheckbox GUICtrlCreateCombo GUICtrlCreateContextMenu GUICtrlCreateDate GUICtrlCreateDummy GUICtrlCreateEdit GUICtrlCreateGraphic GUICtrlCreateGroup GUICtrlCreateIcon GUICtrlCreateInput GUICtrlCreateLabel GUICtrlCreateList GUICtrlCreateListView GUICtrlCreateListViewItem GUICtrlCreateMenu GUICtrlCreateMenuItem GUICtrlCreateMonthCal GUICtrlCreateObj GUICtrlCreatePic GUICtrlCreateProgress GUICtrlCreateRadio GUICtrlCreateSlider GUICtrlCreateTab GUICtrlCreateTabItem GUICtrlCreateTreeView GUICtrlCreateTreeViewItem GUICtrlCreateUpdown GUICtrlDelete GUICtrlGetHandle GUICtrlGetState GUICtrlRead GUICtrlRecvMsg GUICtrlRegisterListViewSort GUICtrlSendMsg GUICtrlSendToDummy GUICtrlSetBkColor GUICtrlSetColor GUICtrlSetCursor GUICtrlSetData GUICtrlSetDefBkColor GUICtrlSetDefColor GUICtrlSetFont GUICtrlSetGraphic GUICtrlSetImage GUICtrlSetLimit GUICtrlSetOnEvent GUICtrlSetPos GUICtrlSetResizing GUICtrlSetState GUICtrlSetStyle GUICtrlSetTip GUIDelete GUIGetCursorInfo GUIGetMsg GUIGetStyle GUIRegisterMsg GUISetAccelerators GUISetBkColor GUISetCoord GUISetCursor GUISetFont GUISetHelp GUISetIcon GUISetOnEvent GUISetState GUISetStyle GUIStartGroup GUISwitch Hex HotKeySet HttpSetProxy HttpSetUserAgent HWnd InetClose InetGet InetGetInfo InetGetSize InetRead IniDelete IniRead IniReadSection IniReadSectionNames IniRenameSection IniWrite IniWriteSection InputBox Int IsAdmin IsArray IsBinary IsBool IsDeclared IsDllStruct IsFloat IsFunc IsHWnd IsInt IsKeyword IsNumber IsObj IsPtr IsString Log MemGetStats Mod MouseClick MouseClickDrag MouseDown MouseGetCursor MouseGetPos MouseMove MouseUp MouseWheel MsgBox Number ObjCreate ObjCreateInterface ObjEvent ObjGet ObjName OnAutoItExitRegister OnAutoItExitUnRegister Ping PixelChecksum PixelGetColor PixelSearch ProcessClose ProcessExists ProcessGetStats ProcessList ProcessSetPriority ProcessWait ProcessWaitClose ProgressOff ProgressOn ProgressSet Ptr Random RegDelete RegEnumKey RegEnumVal RegRead RegWrite Round Run RunAs RunAsWait RunWait Send SendKeepActive SetError SetExtended ShellExecute ShellExecuteWait Shutdown Sin Sleep SoundPlay SoundSetWaveVolume SplashImageOn SplashOff SplashTextOn Sqrt SRandom StatusbarGetText StderrRead StdinWrite StdioClose StdoutRead String StringAddCR StringCompare StringFormat StringFromASCIIArray StringInStr StringIsAlNum StringIsAlpha StringIsASCII StringIsDigit StringIsFloat StringIsInt StringIsLower StringIsSpace StringIsUpper StringIsXDigit StringLeft StringLen StringLower StringMid StringRegExp StringRegExpReplace StringReplace StringReverse StringRight StringSplit StringStripCR StringStripWS StringToASCIIArray StringToBinary StringTrimLeft StringTrimRight StringUpper Tan TCPAccept TCPCloseSocket TCPConnect TCPListen TCPNameToIP TCPRecv TCPSend TCPShutdown, UDPShutdown TCPStartup, UDPStartup TimerDiff TimerInit ToolTip TrayCreateItem TrayCreateMenu TrayGetMsg TrayItemDelete TrayItemGetHandle TrayItemGetState TrayItemGetText TrayItemSetOnEvent TrayItemSetState TrayItemSetText TraySetClick TraySetIcon TraySetOnEvent TraySetPauseIcon TraySetState TraySetToolTip TrayTip UBound UDPBind UDPCloseSocket UDPOpen UDPRecv UDPSend VarGetType WinActivate WinActive WinClose WinExists WinFlash WinGetCaretPos WinGetClassList WinGetClientSize WinGetHandle WinGetPos WinGetProcess WinGetState WinGetText WinGetTitle WinKill WinList WinMenuSelectItem WinMinimizeAll WinMinimizeAllUndo WinMove WinSetOnTop WinSetState WinSetTitle WinSetTrans WinWait\",literal:\"True False And Null Not Or\"},contains:[t,n,r,i,{className:\"meta\",begin:\"#\",end:\"$\",keywords:{\"meta-keyword\":\"comments include include-once NoTrayIcon OnAutoItStartRegister pragma compile RequireAdmin\"},contains:[{begin:/\\\\\\n/,relevance:0},{beginKeywords:\"include\",keywords:{\"meta-keyword\":\"include\"},end:\"$\",contains:[r,{className:\"meta-string\",variants:[{begin:\"<\",end:\">\"},{begin:/\"/,end:/\"/,contains:[{begin:/\"\"/,relevance:0}]},{begin:/'/,end:/'/,contains:[{begin:/''/,relevance:0}]}]}]},r,t]},{className:\"symbol\",begin:\"@[A-z0-9_]+\"},{className:\"function\",beginKeywords:\"Func\",end:\"$\",illegal:\"\\\\$|\\\\[|%\",contains:[e.UNDERSCORE_TITLE_MODE,{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\",contains:[n,r,i]}]}]}}},function(e,t){e.exports=function(e){var t={begin:\"`[\\\\s\\\\S]\"};return{case_insensitive:!0,aliases:[\"ahk\"],keywords:{keyword:\"Break Continue Critical Exit ExitApp Gosub Goto New OnExit Pause return SetBatchLines SetTimer Suspend Thread Throw Until ahk_id ahk_class ahk_pid ahk_exe ahk_group\",literal:\"A|0 true false NOT AND OR\",built_in:\"ComSpec Clipboard ClipboardAll ErrorLevel\"},contains:[{className:\"built_in\",begin:\"A_[a-zA-Z0-9]+\"},t,e.inherit(e.QUOTE_STRING_MODE,{contains:[t]}),e.COMMENT(\";\",\"$\",{relevance:0}),e.C_BLOCK_COMMENT_MODE,{className:\"number\",begin:e.NUMBER_RE,relevance:0},{className:\"subst\",begin:\"%(?=[a-zA-Z0-9#_$@])\",end:\"%\",illegal:\"[^a-zA-Z0-9#_$@]\"},{className:\"built_in\",begin:\"^\\\\s*\\\\w+\\\\s*,\"},{className:\"meta\",begin:\"^\\\\s*#w+\",end:\"$\",relevance:0},{className:\"symbol\",contains:[t],variants:[{begin:'^[^\\\\n\";]+::(?!=)'},{begin:'^[^\\\\n\";]+:(?!=)',relevance:0}]},{begin:\",\\\\s*,\"}]}}},function(e,t){e.exports=function(e){var t=\"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance\";return{keywords:t,illegal:/<\\/|#/,contains:[e.COMMENT(\"/\\\\*\\\\*\",\"\\\\*/\",{relevance:0,contains:[{begin:/\\w+@/,relevance:0},{className:\"doctag\",begin:\"@[A-Za-z]+\"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:\"class\",beginKeywords:\"aspect\",end:/[{;=]/,excludeEnd:!0,illegal:/[:;\"\\[\\]]/,contains:[{beginKeywords:\"extends implements pertypewithin perthis pertarget percflowbelow percflow issingleton\"},e.UNDERSCORE_TITLE_MODE,{begin:/\\([^\\)]*/,end:/[)]+/,keywords:t+\" get set args call\",excludeEnd:!1}]},{className:\"class\",beginKeywords:\"class interface\",end:/[{;=]/,excludeEnd:!0,relevance:0,keywords:\"class interface\",illegal:/[:\"\\[\\]]/,contains:[{beginKeywords:\"extends implements\"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:\"pointcut after before around throwing returning\",end:/[)]/,excludeEnd:!1,illegal:/[\"\\[\\]]/,contains:[{begin:e.UNDERSCORE_IDENT_RE+\"\\\\s*\\\\(\",returnBegin:!0,contains:[e.UNDERSCORE_TITLE_MODE]}]},{begin:/[:]/,returnBegin:!0,end:/[{;]/,relevance:0,excludeEnd:!1,keywords:t,illegal:/[\"\\[\\]]/,contains:[{begin:e.UNDERSCORE_IDENT_RE+\"\\\\s*\\\\(\",keywords:t+\" get set args call\",relevance:0},e.QUOTE_STRING_MODE]},{beginKeywords:\"new throw\",relevance:0},{className:\"function\",begin:/\\w+ +\\w+(\\.)?\\w+\\s*\\([^\\)]*\\)\\s*((throws)[\\w\\s,]+)?[\\{;]/,returnBegin:!0,end:/[{;=]/,keywords:t,excludeEnd:!0,contains:[{begin:e.UNDERSCORE_IDENT_RE+\"\\\\s*\\\\(\",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:\"params\",begin:/\\(/,end:/\\)/,relevance:0,keywords:t,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_NUMBER_MODE,{className:\"meta\",begin:\"@[A-Za-z]+\"}]}}},function(e,t){e.exports=function(e){return{aliases:[\"adoc\"],contains:[e.COMMENT(\"^/{4,}\\\\n\",\"\\\\n/{4,}$\",{relevance:10}),e.COMMENT(\"^//\",\"$\",{relevance:0}),{className:\"title\",begin:\"^\\\\.\\\\w.*$\"},{begin:\"^[=\\\\*]{4,}\\\\n\",end:\"\\\\n^[=\\\\*]{4,}$\",relevance:10},{className:\"section\",relevance:10,variants:[{begin:\"^(={1,5}) .+?( \\\\1)?$\"},{begin:\"^[^\\\\[\\\\]\\\\n]+?\\\\n[=\\\\-~\\\\^\\\\+]{2,}$\"}]},{className:\"meta\",begin:\"^:.+?:\",end:\"\\\\s\",excludeEnd:!0,relevance:10},{className:\"meta\",begin:\"^\\\\[.+?\\\\]$\",relevance:0},{className:\"quote\",begin:\"^_{4,}\\\\n\",end:\"\\\\n_{4,}$\",relevance:10},{className:\"code\",begin:\"^[\\\\-\\\\.]{4,}\\\\n\",end:\"\\\\n[\\\\-\\\\.]{4,}$\",relevance:10},{begin:\"^\\\\+{4,}\\\\n\",end:\"\\\\n\\\\+{4,}$\",contains:[{begin:\"<\",end:\">\",subLanguage:\"xml\",relevance:0}],relevance:10},{className:\"bullet\",begin:\"^(\\\\*+|\\\\-+|\\\\.+|[^\\\\n]+?::)\\\\s+\"},{className:\"symbol\",begin:\"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\\\s+\",relevance:10},{className:\"strong\",begin:\"\\\\B\\\\*(?![\\\\*\\\\s])\",end:\"(\\\\n{2}|\\\\*)\",contains:[{begin:\"\\\\\\\\*\\\\w\",relevance:0}]},{className:\"emphasis\",begin:\"\\\\B'(?!['\\\\s])\",end:\"(\\\\n{2}|')\",contains:[{begin:\"\\\\\\\\'\\\\w\",relevance:0}],relevance:0},{className:\"emphasis\",begin:\"_(?![_\\\\s])\",end:\"(\\\\n{2}|_)\",relevance:0},{className:\"string\",variants:[{begin:\"``.+?''\"},{begin:\"`.+?'\"}]},{className:\"code\",begin:\"(`.+?`|\\\\+.+?\\\\+)\",relevance:0},{className:\"code\",begin:\"^[ \\\\t]\",end:\"$\",relevance:0},{begin:\"^'{3,}[ \\\\t]*$\",relevance:10},{begin:\"(link:)?(http|https|ftp|file|irc|image:?):\\\\S+\\\\[.*?\\\\]\",returnBegin:!0,contains:[{begin:\"(link|image:?):\",relevance:0},{className:\"link\",begin:\"\\\\w\",end:\"[^\\\\[]+\",relevance:0},{className:\"string\",begin:\"\\\\[\",end:\"\\\\]\",excludeBegin:!0,excludeEnd:!0,relevance:0}],relevance:10}]}}},function(e,t){e.exports=function(e){var t={endsWithParent:!0,illegal:/`]+/}]}]}]};return{aliases:[\"html\",\"xhtml\",\"rss\",\"atom\",\"xjb\",\"xsd\",\"xsl\",\"plist\"],case_insensitive:!0,contains:[{className:\"meta\",begin:\"\",relevance:10,contains:[{begin:\"\\\\[\",end:\"\\\\]\"}]},e.COMMENT(\"\\x3c!--\",\"--\\x3e\",{relevance:10}),{begin:\"<\\\\!\\\\[CDATA\\\\[\",end:\"\\\\]\\\\]>\",relevance:10},{begin:/<\\?(php)?/,end:/\\?>/,subLanguage:\"php\",contains:[{begin:\"/\\\\*\",end:\"\\\\*/\",skip:!0}]},{className:\"tag\",begin:\"|$)\",end:\">\",keywords:{name:\"style\"},contains:[t],starts:{end:\"\",returnEnd:!0,subLanguage:[\"css\",\"xml\"]}},{className:\"tag\",begin:\"|$)\",end:\">\",keywords:{name:\"script\"},contains:[t],starts:{end:\"<\\/script>\",returnEnd:!0,subLanguage:[\"actionscript\",\"javascript\",\"handlebars\",\"xml\"]}},{className:\"meta\",variants:[{begin:/<\\?xml/,end:/\\?>/,relevance:10},{begin:/<\\?\\w+/,end:/\\?>/}]},{className:\"tag\",begin:\"\",contains:[{className:\"name\",begin:/[^\\/><\\s]+/,relevance:0},t]}]}}},function(e,t){e.exports=function(e){return{case_insensitive:!0,aliases:[\"arm\"],lexemes:\"\\\\.?\"+e.IDENT_RE,keywords:{meta:\".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND \",built_in:\"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 pc lr sp ip sl sb fp a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 {PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @\"},contains:[{className:\"keyword\",begin:\"\\\\b(adc|(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|wfe|wfi|yield)(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?[sptrx]?\",end:\"\\\\s\"},e.COMMENT(\"[;@]\",\"$\",{relevance:0}),e.C_BLOCK_COMMENT_MODE,e.QUOTE_STRING_MODE,{className:\"string\",begin:\"'\",end:\"[^\\\\\\\\]'\",relevance:0},{className:\"title\",begin:\"\\\\|\",end:\"\\\\|\",illegal:\"\\\\n\",relevance:0},{className:\"number\",variants:[{begin:\"[#$=]?0x[0-9a-f]+\"},{begin:\"[#$=]?0b[01]+\"},{begin:\"[#$=]\\\\d+\"},{begin:\"\\\\b\\\\d+\"}],relevance:0},{className:\"symbol\",variants:[{begin:\"^[a-z_\\\\.\\\\$][a-z0-9_\\\\.\\\\$]+\"},{begin:\"^\\\\s*[a-z_\\\\.\\\\$][a-z0-9_\\\\.\\\\$]+:\"},{begin:\"[=#]\\\\w+\"}],relevance:0}]}}},function(e,t){e.exports=function(e){var t=e.getLanguage(\"cpp\").exports;return{keywords:{keyword:\"boolean byte word string String array \"+t.keywords.keyword,built_in:\"setup loop while catch for if do goto try switch case else default break continue return KeyboardController MouseController SoftwareSerial EthernetServer EthernetClient LiquidCrystal RobotControl GSMVoiceCall EthernetUDP EsploraTFT HttpClient RobotMotor WiFiClient GSMScanner FileSystem Scheduler GSMServer YunClient YunServer IPAddress GSMClient GSMModem Keyboard Ethernet Console GSMBand Esplora Stepper Process WiFiUDP GSM_SMS Mailbox USBHost Firmata PImage Client Server GSMPIN FileIO Bridge Serial EEPROM Stream Mouse Audio Servo File Task GPRS WiFi Wire TFT GSM SPI SD runShellCommandAsynchronously analogWriteResolution retrieveCallingNumber printFirmwareVersion analogReadResolution sendDigitalPortPair noListenOnLocalhost readJoystickButton setFirmwareVersion readJoystickSwitch scrollDisplayRight getVoiceCallStatus scrollDisplayLeft writeMicroseconds delayMicroseconds beginTransmission getSignalStrength runAsynchronously getAsynchronously listenOnLocalhost getCurrentCarrier readAccelerometer messageAvailable sendDigitalPorts lineFollowConfig countryNameWrite runShellCommand readStringUntil rewindDirectory readTemperature setClockDivider readLightSensor endTransmission analogReference detachInterrupt countryNameRead attachInterrupt encryptionType readBytesUntil robotNameWrite readMicrophone robotNameRead cityNameWrite userNameWrite readJoystickY readJoystickX mouseReleased openNextFile scanNetworks noInterrupts digitalWrite beginSpeaker mousePressed isActionDone mouseDragged displayLogos noAutoscroll addParameter remoteNumber getModifiers keyboardRead userNameRead waitContinue processInput parseCommand printVersion readNetworks writeMessage blinkVersion cityNameRead readMessage setDataMode parsePacket isListening setBitOrder beginPacket isDirectory motorsWrite drawCompass digitalRead clearScreen serialEvent rightToLeft setTextSize leftToRight requestFrom keyReleased compassRead analogWrite interrupts WiFiServer disconnect playMelody parseFloat autoscroll getPINUsed setPINUsed setTimeout sendAnalog readSlider analogRead beginWrite createChar motorsStop keyPressed tempoWrite readButton subnetMask debugPrint macAddress writeGreen randomSeed attachGPRS readString sendString remotePort releaseAll mouseMoved background getXChange getYChange answerCall getResult voiceCall endPacket constrain getSocket writeJSON getButton available connected findUntil readBytes exitValue readGreen writeBlue startLoop IPAddress isPressed sendSysex pauseMode gatewayIP setCursor getOemKey tuneWrite noDisplay loadImage switchPIN onRequest onReceive changePIN playFile noBuffer parseInt overflow checkPIN knobRead beginTFT bitClear updateIR bitWrite position writeRGB highByte writeRed setSpeed readBlue noStroke remoteIP transfer shutdown hangCall beginSMS endWrite attached maintain noCursor checkReg checkPUK shiftOut isValid shiftIn pulseIn connect println localIP pinMode getIMEI display noBlink process getBand running beginSD drawBMP lowByte setBand release bitRead prepare pointTo readRed setMode noFill remove listen stroke detach attach noTone exists buffer height bitSet circle config cursor random IRread setDNS endSMS getKey micros millis begin print write ready flush width isPIN blink clear press mkdir rmdir close point yield image BSSID click delay read text move peek beep rect line open seek fill size turn stop home find step tone sqrt RSSI SSID end bit tan cos sin pow map abs max min get run put\",literal:\"DIGITAL_MESSAGE FIRMATA_STRING ANALOG_MESSAGE REPORT_DIGITAL REPORT_ANALOG INPUT_PULLUP SET_PIN_MODE INTERNAL2V56 SYSTEM_RESET LED_BUILTIN INTERNAL1V1 SYSEX_START INTERNAL EXTERNAL DEFAULT OUTPUT INPUT HIGH LOW\"},contains:[t.preprocessor,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t={className:\"keyword\",begin:\"\\\\b[a-z\\\\d_]*_t\\\\b\"},n={className:\"string\",variants:[{begin:'(u8?|U)?L?\"',end:'\"',illegal:\"\\\\n\",contains:[e.BACKSLASH_ESCAPE]},{begin:'(u8?|U)?R\"',end:'\"',contains:[e.BACKSLASH_ESCAPE]},{begin:\"'\\\\\\\\?.\",end:\"'\",illegal:\".\"}]},r={className:\"number\",variants:[{begin:\"\\\\b(0b[01']+)\"},{begin:\"(-?)\\\\b([\\\\d']+(\\\\.[\\\\d']*)?|\\\\.[\\\\d']+)(u|U|l|L|ul|UL|f|F|b|B)\"},{begin:\"(-?)(\\\\b0[xX][a-fA-F0-9']+|(\\\\b[\\\\d']+(\\\\.[\\\\d']*)?|\\\\.[\\\\d']+)([eE][-+]?[\\\\d']+)?)\"}],relevance:0},i={className:\"meta\",begin:/#\\s*[a-z]+\\b/,end:/$/,keywords:{\"meta-keyword\":\"if else elif endif define undef warning error line pragma ifdef ifndef include\"},contains:[{begin:/\\\\\\n/,relevance:0},e.inherit(n,{className:\"meta-string\"}),{className:\"meta-string\",begin:/<[^\\n>]*>/,end:/$/,illegal:\"\\\\n\"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},a=e.IDENT_RE+\"\\\\s*\\\\(\",o={keyword:\"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not\",built_in:\"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr\",literal:\"true false nullptr NULL\"},s=[t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,r,n];return{aliases:[\"c\",\"cc\",\"h\",\"c++\",\"h++\",\"hpp\"],keywords:o,illegal:\"\",keywords:o,contains:[\"self\",t]},{begin:e.IDENT_RE+\"::\",keywords:o},{variants:[{begin:/=/,end:/;/},{begin:/\\(/,end:/\\)/},{beginKeywords:\"new throw return else\",end:/;/}],keywords:o,contains:s.concat([{begin:/\\(/,end:/\\)/,keywords:o,contains:s.concat([\"self\"]),relevance:0}]),relevance:0},{className:\"function\",begin:\"(\"+e.IDENT_RE+\"[\\\\*&\\\\s]+)+\"+a,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:o,illegal:/[^\\w\\s\\*&]/,contains:[{begin:a,returnBegin:!0,contains:[e.TITLE_MODE],relevance:0},{className:\"params\",begin:/\\(/,end:/\\)/,keywords:o,relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,r,t]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,i]},{className:\"class\",beginKeywords:\"class struct\",end:/[{;:]/,contains:[{begin://,contains:[\"self\"]},e.TITLE_MODE]}]),exports:{preprocessor:i,strings:n,keywords:o}}}},function(e,t){e.exports=function(e){var t=e.inherit(e.QUOTE_STRING_MODE,{illegal:\"\"}),n={className:\"params\",begin:\"\\\\(\",end:\"\\\\)\",contains:[\"self\",e.C_NUMBER_MODE,t]},r=e.COMMENT(\"--\",\"$\"),i=[r,e.COMMENT(\"\\\\(\\\\*\",\"\\\\*\\\\)\",{contains:[\"self\",r]}),e.HASH_COMMENT_MODE];return{aliases:[\"osascript\"],keywords:{keyword:\"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the|0 then third through thru timeout times to transaction try until where while whose with without\",literal:\"AppleScript false linefeed return pi quote result space tab true\",built_in:\"alias application boolean class constant date file integer list number real record string text activate beep count delay launch log offset read round run say summarize write character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year\"},contains:[t,e.C_NUMBER_MODE,{className:\"built_in\",begin:\"\\\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\\\b|^\\\\s*return\\\\b\"},{className:\"literal\",begin:\"\\\\b(text item delimiters|current application|missing value)\\\\b\"},{className:\"keyword\",begin:\"\\\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference)|POSIX file|POSIX path|(date|time) string|quoted form)\\\\b\"},{beginKeywords:\"on\",illegal:\"[${=;\\\\n]\",contains:[e.UNDERSCORE_TITLE_MODE,n]}].concat(i),illegal:\"//|->|=>|\\\\[\\\\[\"}}},function(e,t){e.exports=function(e){var t={className:\"number\",begin:\"[\\\\$%]\\\\d+\"};return{aliases:[\"apacheconf\"],case_insensitive:!0,contains:[e.HASH_COMMENT_MODE,{className:\"section\",begin:\"\"},{className:\"attribute\",begin:/\\w+/,relevance:0,keywords:{nomarkup:\"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername\"},starts:{end:/$/,relevance:0,keywords:{literal:\"on off all\"},contains:[{className:\"meta\",begin:\"\\\\s\\\\[\",end:\"\\\\]$\"},{className:\"variable\",begin:\"[\\\\$%]\\\\{\",end:\"\\\\}\",contains:[\"self\",t]},t,e.QUOTE_STRING_MODE]}}],illegal:/\\S/}}},function(e,t){e.exports=function(e){var t=\"[A-Za-z](_?[A-Za-z0-9.])*\",n=e.COMMENT(\"--\",\"$\"),r={begin:\"\\\\s+:\\\\s+\",end:\"\\\\s*(:=|;|\\\\)|=>|$)\",illegal:\"[]{}%#'\\\"\",contains:[{beginKeywords:\"loop for declare others\",endsParent:!0},{className:\"keyword\",beginKeywords:\"not null constant access function procedure in out aliased exception\"},{className:\"type\",begin:t,endsParent:!0,relevance:0}]};return{case_insensitive:!0,keywords:{keyword:\"abort else new return abs elsif not reverse abstract end accept entry select access exception of separate aliased exit or some all others subtype and for out synchronized array function overriding at tagged generic package task begin goto pragma terminate body private then if procedure type case in protected constant interface is raise use declare range delay limited record when delta loop rem while digits renames with do mod requeue xor\",literal:\"True False\"},contains:[n,{className:\"string\",begin:/\"/,end:/\"/,contains:[{begin:/\"\"/,relevance:0}]},{className:\"string\",begin:/'.'/},{className:\"number\",begin:\"\\\\b(\\\\d(_|\\\\d)*#\\\\w+(\\\\.\\\\w+)?#([eE][-+]?\\\\d(_|\\\\d)*)?|\\\\d(_|\\\\d)*(\\\\.\\\\d(_|\\\\d)*)?([eE][-+]?\\\\d(_|\\\\d)*)?)\",relevance:0},{className:\"symbol\",begin:\"'\"+t},{className:\"title\",begin:\"(\\\\bwith\\\\s+)?(\\\\bprivate\\\\s+)?\\\\bpackage\\\\s+(\\\\bbody\\\\s+)?\",end:\"(is|$)\",keywords:\"package body\",excludeBegin:!0,excludeEnd:!0,illegal:\"[]{}%#'\\\"\"},{begin:\"(\\\\b(with|overriding)\\\\s+)?\\\\b(function|procedure)\\\\s+\",end:\"(\\\\bis|\\\\bwith|\\\\brenames|\\\\)\\\\s*;)\",keywords:\"overriding function procedure with is renames return\",returnBegin:!0,contains:[n,{className:\"title\",begin:\"(\\\\bwith\\\\s+)?\\\\b(function|procedure)\\\\s+\",end:\"(\\\\(|\\\\s+|$)\",excludeBegin:!0,excludeEnd:!0,illegal:\"[]{}%#'\\\"\"},r,{className:\"type\",begin:\"\\\\breturn\\\\s+\",end:\"(\\\\s+|;|$)\",keywords:\"return\",excludeBegin:!0,excludeEnd:!0,endsParent:!0,illegal:\"[]{}%#'\\\"\"}]},{className:\"type\",begin:\"\\\\b(sub)?type\\\\s+\",end:\"\\\\s+\",keywords:\"type\",excludeBegin:!0,illegal:\"[]{}%#'\\\"\"},r]}}},function(e,t){e.exports=function(e){var t={className:\"rest_arg\",begin:\"[.]{3}\",end:\"[a-zA-Z_$][a-zA-Z0-9_$]*\",relevance:10};return{aliases:[\"as\"],keywords:{keyword:\"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with\",literal:\"true false null undefined\"},contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.C_NUMBER_MODE,{className:\"class\",beginKeywords:\"package\",end:\"{\",contains:[e.TITLE_MODE]},{className:\"class\",beginKeywords:\"class interface\",end:\"{\",excludeEnd:!0,contains:[{beginKeywords:\"extends implements\"},e.TITLE_MODE]},{className:\"meta\",beginKeywords:\"import include\",end:\";\",keywords:{\"meta-keyword\":\"import include\"}},{className:\"function\",beginKeywords:\"function\",end:\"[{;]\",excludeEnd:!0,illegal:\"\\\\S\",contains:[e.TITLE_MODE,{className:\"params\",begin:\"\\\\(\",end:\"\\\\)\",contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,t]},{begin:\":\\\\s*([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)\"}]},e.METHOD_GUARD],illegal:/#/}}},function(e,t){e.exports=function(e){return{contains:[{className:\"number\",begin:\"\\\\b\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}(:\\\\d{1,5})?\\\\b\"},{className:\"number\",begin:\"\\\\b\\\\d+\\\\b\",relevance:0},{className:\"string\",begin:'\"(GET|POST|HEAD|PUT|DELETE|CONNECT|OPTIONS|PATCH|TRACE)',end:'\"',keywords:\"GET POST HEAD PUT DELETE CONNECT OPTIONS PATCH TRACE\",illegal:\"\\\\n\",relevance:10},{className:\"string\",begin:/\\[/,end:/\\]/,illegal:\"\\\\n\"},{className:\"string\",begin:'\"',end:'\"',illegal:\"\\\\n\"}]}}},function(e,t){e.exports=function(e){var t=\"^[a-zA-Z][a-zA-Z0-9-]*\",n=\"[!@#$^&',?+~`|:]\",r=e.COMMENT(\";\",\"$\"),i={begin:t+\"\\\\s*=\",returnBegin:!0,end:/=/,relevance:0,contains:[{className:\"attribute\",begin:t}]};return{illegal:n,keywords:[\"ALPHA\",\"BIT\",\"CHAR\",\"CR\",\"CRLF\",\"CTL\",\"DIGIT\",\"DQUOTE\",\"HEXDIG\",\"HTAB\",\"LF\",\"LWSP\",\"OCTET\",\"SP\",\"VCHAR\",\"WSP\"].join(\" \"),contains:[i,r,{className:\"symbol\",begin:/%b[0-1]+(-[0-1]+|(\\.[0-1]+)+){0,1}/},{className:\"symbol\",begin:/%d[0-9]+(-[0-9]+|(\\.[0-9]+)+){0,1}/},{className:\"symbol\",begin:/%x[0-9A-F]+(-[0-9A-F]+|(\\.[0-9A-F]+)+){0,1}/},{className:\"symbol\",begin:/%[si]/},e.QUOTE_STRING_MODE,e.NUMBER_MODE]}}},function(e,t){e.exports=function(e){var t=\"[A-Za-zА-Яа-яёЁ_][A-Za-zА-Яа-яёЁ_0-9]+\",n=\"далее возврат вызватьисключение выполнить для если и из или иначе иначеесли исключение каждого конецесли конецпопытки конеццикла не новый перейти перем по пока попытка прервать продолжить тогда цикл экспорт \",r=\"null истина ложь неопределено\",i=e.inherit(e.NUMBER_MODE),a={className:\"string\",begin:'\"|\\\\|',end:'\"|$',contains:[{begin:'\"\"'}]},o={begin:\"'\",end:\"'\",excludeBegin:!0,excludeEnd:!0,contains:[{className:\"number\",begin:\"\\\\d{4}([\\\\.\\\\\\\\/:-]?\\\\d{2}){0,5}\"}]},s=e.inherit(e.C_LINE_COMMENT_MODE);return{case_insensitive:!0,lexemes:t,keywords:{keyword:n,built_in:\"разделительстраниц разделительстрок символтабуляции ansitooem oemtoansi ввестивидсубконто ввестиперечисление ввестипериод ввестиплансчетов выбранныйплансчетов датагод датамесяц датачисло заголовоксистемы значениевстроку значениеизстроки каталогиб каталогпользователя кодсимв конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лог лог10 максимальноеколичествосубконто названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найтиссылки началопериодаби началостандартногоинтервала начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода обработкаожидания основнойжурналрасчетов основнойплансчетов основнойязык очиститьокносообщений периодстр получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта префиксавтонумерации пропись пустоезначение разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо симв создатьобъект статусвозврата стрколичествострок сформироватьпозициюдокумента счетпокоду текущеевремя типзначения типзначениястр установитьтана установитьтапо фиксшаблон шаблон acos asin atan base64значение base64строка cos exp log log10 pow sin sqrt tan xmlзначение xmlстрока xmlтип xmlтипзнч активноеокно безопасныйрежим безопасныйрежимразделенияданных булево ввестидату ввестизначение ввестистроку ввестичисло возможностьчтенияxml вопрос восстановитьзначение врег выгрузитьжурналрегистрации выполнитьобработкуоповещения выполнитьпроверкуправдоступа вычислить год данныеформывзначение дата день деньгода деньнедели добавитьмесяц заблокироватьданныедляредактирования заблокироватьработупользователя завершитьработусистемы загрузитьвнешнююкомпоненту закрытьсправку записатьjson записатьxml записатьдатуjson записьжурналарегистрации заполнитьзначениясвойств запроситьразрешениепользователя запуститьприложение запуститьсистему зафиксироватьтранзакцию значениевданныеформы значениевстрокувнутр значениевфайл значениезаполнено значениеизстрокивнутр значениеизфайла изxmlтипа импортмоделиxdto имякомпьютера имяпользователя инициализироватьпредопределенныеданные информацияобошибке каталогбиблиотекимобильногоустройства каталогвременныхфайлов каталогдокументов каталогпрограммы кодироватьстроку кодлокализацииинформационнойбазы кодсимвола командасистемы конецгода конецдня конецквартала конецмесяца конецминуты конецнедели конецчаса конфигурациябазыданныхизмененадинамически конфигурацияизменена копироватьданныеформы копироватьфайл краткоепредставлениеошибки лев макс местноевремя месяц мин минута монопольныйрежим найти найтинедопустимыесимволыxml найтиокнопонавигационнойссылке найтипомеченныенаудаление найтипоссылкам найтифайлы началогода началодня началоквартала началомесяца началоминуты началонедели началочаса начатьзапросразрешенияпользователя начатьзапускприложения начатькопированиефайла начатьперемещениефайла начатьподключениевнешнейкомпоненты начатьподключениерасширенияработыскриптографией начатьподключениерасширенияработысфайлами начатьпоискфайлов начатьполучениекаталогавременныхфайлов начатьполучениекаталогадокументов начатьполучениерабочегокаталогаданныхпользователя начатьполучениефайлов начатьпомещениефайла начатьпомещениефайлов начатьсозданиедвоичныхданныхизфайла начатьсозданиекаталога начатьтранзакцию начатьудалениефайлов начатьустановкувнешнейкомпоненты начатьустановкурасширенияработыскриптографией начатьустановкурасширенияработысфайлами неделягода необходимостьзавершениясоединения номерсеансаинформационнойбазы номерсоединенияинформационнойбазы нрег нстр обновитьинтерфейс обновитьнумерациюобъектов обновитьповторноиспользуемыезначения обработкапрерыванияпользователя объединитьфайлы окр описаниеошибки оповестить оповеститьобизменении отключитьобработчикзапросанастроекклиенталицензирования отключитьобработчикожидания отключитьобработчикоповещения открытьзначение открытьиндекссправки открытьсодержаниесправки открытьсправку открытьформу открытьформумодально отменитьтранзакцию очиститьжурналрегистрации очиститьнастройкипользователя очиститьсообщения параметрыдоступа перейтипонавигационнойссылке переместитьфайл подключитьвнешнююкомпоненту подключитьобработчикзапросанастроекклиенталицензирования подключитьобработчикожидания подключитьобработчикоповещения подключитьрасширениеработыскриптографией подключитьрасширениеработысфайлами подробноепредставлениеошибки показатьвводдаты показатьвводзначения показатьвводстроки показатьвводчисла показатьвопрос показатьзначение показатьинформациюобошибке показатьнакарте показатьоповещениепользователя показатьпредупреждение полноеимяпользователя получитьcomобъект получитьxmlтип получитьадреспоместоположению получитьблокировкусеансов получитьвремязавершенияспящегосеанса получитьвремязасыпанияпассивногосеанса получитьвремяожиданияблокировкиданных получитьданныевыбора получитьдополнительныйпараметрклиенталицензирования получитьдопустимыекодылокализации получитьдопустимыечасовыепояса получитьзаголовокклиентскогоприложения получитьзаголовоксистемы получитьзначенияотборажурналарегистрации получитьидентификаторконфигурации получитьизвременногохранилища получитьимявременногофайла получитьимяклиенталицензирования получитьинформациюэкрановклиента получитьиспользованиежурналарегистрации получитьиспользованиесобытияжурналарегистрации получитькраткийзаголовокприложения получитьмакетоформления получитьмаскувсефайлы получитьмаскувсефайлыклиента получитьмаскувсефайлысервера получитьместоположениепоадресу получитьминимальнуюдлинупаролейпользователей получитьнавигационнуюссылку получитьнавигационнуюссылкуинформационнойбазы получитьобновлениеконфигурациибазыданных получитьобновлениепредопределенныхданныхинформационнойбазы получитьобщиймакет получитьобщуюформу получитьокна получитьоперативнуюотметкувремени получитьотключениебезопасногорежима получитьпараметрыфункциональныхопцийинтерфейса получитьполноеимяпредопределенногозначения получитьпредставлениянавигационныхссылок получитьпроверкусложностипаролейпользователей получитьразделительпути получитьразделительпутиклиента получитьразделительпутисервера получитьсеансыинформационнойбазы получитьскоростьклиентскогосоединения получитьсоединенияинформационнойбазы получитьсообщенияпользователю получитьсоответствиеобъектаиформы получитьсоставстандартногоинтерфейсаodata получитьструктурухранениябазыданных получитьтекущийсеансинформационнойбазы получитьфайл получитьфайлы получитьформу получитьфункциональнуюопцию получитьфункциональнуюопциюинтерфейса получитьчасовойпоясинформационнойбазы пользователиос поместитьвовременноехранилище поместитьфайл поместитьфайлы прав праводоступа предопределенноезначение представлениекодалокализации представлениепериода представлениеправа представлениеприложения представлениесобытияжурналарегистрации представлениечасовогопояса предупреждение прекратитьработусистемы привилегированныйрежим продолжитьвызов прочитатьjson прочитатьxml прочитатьдатуjson пустаястрока рабочийкаталогданныхпользователя разблокироватьданныедляредактирования разделитьфайл разорватьсоединениесвнешнимисточникомданных раскодироватьстроку рольдоступна секунда сигнал символ скопироватьжурналрегистрации смещениелетнеговремени смещениестандартноговремени соединитьбуферыдвоичныхданных создатькаталог создатьфабрикуxdto сокрл сокрлп сокрп сообщить состояние сохранитьзначение сохранитьнастройкипользователя сред стрдлина стрзаканчиваетсяна стрзаменить стрнайти стрначинаетсяс строка строкасоединенияинформационнойбазы стрполучитьстроку стрразделить стрсоединить стрсравнить стрчисловхождений стрчислострок стршаблон текущаядата текущаядатасеанса текущаяуниверсальнаядата текущаяуниверсальнаядатавмиллисекундах текущийвариантинтерфейсаклиентскогоприложения текущийвариантосновногошрифтаклиентскогоприложения текущийкодлокализации текущийрежимзапуска текущийязык текущийязыксистемы тип типзнч транзакцияактивна трег удалитьданныеинформационнойбазы удалитьизвременногохранилища удалитьобъекты удалитьфайлы универсальноевремя установитьбезопасныйрежим установитьбезопасныйрежимразделенияданных установитьблокировкусеансов установитьвнешнююкомпоненту установитьвремязавершенияспящегосеанса установитьвремязасыпанияпассивногосеанса установитьвремяожиданияблокировкиданных установитьзаголовокклиентскогоприложения установитьзаголовоксистемы установитьиспользованиежурналарегистрации установитьиспользованиесобытияжурналарегистрации установитькраткийзаголовокприложения установитьминимальнуюдлинупаролейпользователей установитьмонопольныйрежим установитьнастройкиклиенталицензирования установитьобновлениепредопределенныхданныхинформационнойбазы установитьотключениебезопасногорежима установитьпараметрыфункциональныхопцийинтерфейса установитьпривилегированныйрежим установитьпроверкусложностипаролейпользователей установитьрасширениеработыскриптографией установитьрасширениеработысфайлами установитьсоединениесвнешнимисточникомданных установитьсоответствиеобъектаиформы установитьсоставстандартногоинтерфейсаodata установитьчасовойпоясинформационнойбазы установитьчасовойпояссеанса формат цел час часовойпояс часовойпояссеанса число числопрописью этоадресвременногохранилища wsссылки библиотекакартинок библиотекамакетовоформлениякомпоновкиданных библиотекастилей бизнеспроцессы внешниеисточникиданных внешниеобработки внешниеотчеты встроенныепокупки главныйинтерфейс главныйстиль документы доставляемыеуведомления журналыдокументов задачи информацияобинтернетсоединении использованиерабочейдаты историяработыпользователя константы критерииотбора метаданные обработки отображениерекламы отправкадоставляемыхуведомлений отчеты панельзадачос параметрзапуска параметрысеанса перечисления планывидоврасчета планывидовхарактеристик планыобмена планысчетов полнотекстовыйпоиск пользователиинформационнойбазы последовательности проверкавстроенныхпокупок рабочаядата расширенияконфигурации регистрыбухгалтерии регистрынакопления регистрырасчета регистрысведений регламентныезадания сериализаторxdto справочники средствагеопозиционирования средствакриптографии средствамультимедиа средстваотображениярекламы средствапочты средствателефонии фабрикаxdto файловыепотоки фоновыезадания хранилищанастроек хранилищевариантовотчетов хранилищенастроекданныхформ хранилищеобщихнастроек хранилищепользовательскихнастроекдинамическихсписков хранилищепользовательскихнастроекотчетов хранилищесистемныхнастроек \",class:\"webцвета windowsцвета windowsшрифты библиотекакартинок рамкистиля символы цветастиля шрифтыстиля автоматическоесохранениеданныхформывнастройках автонумерациявформе автораздвижениесерий анимациядиаграммы вариантвыравниванияэлементовизаголовков вариантуправлениявысотойтаблицы вертикальнаяпрокруткаформы вертикальноеположение вертикальноеположениеэлемента видгруппыформы виддекорацииформы виддополненияэлементаформы видизмененияданных видкнопкиформы видпереключателя видподписейкдиаграмме видполяформы видфлажка влияниеразмеранапузырекдиаграммы горизонтальноеположение горизонтальноеположениеэлемента группировкаколонок группировкаподчиненныхэлементовформы группыиэлементы действиеперетаскивания дополнительныйрежимотображения допустимыедействияперетаскивания интервалмеждуэлементамиформы использованиевывода использованиеполосыпрокрутки используемоезначениеточкибиржевойдиаграммы историявыборапривводе источникзначенийоситочекдиаграммы источникзначенияразмерапузырькадиаграммы категориягруппыкоманд максимумсерий начальноеотображениедерева начальноеотображениесписка обновлениетекстаредактирования ориентациядендрограммы ориентациядиаграммы ориентацияметокдиаграммы ориентацияметоксводнойдиаграммы ориентацияэлементаформы отображениевдиаграмме отображениевлегендедиаграммы отображениегруппыкнопок отображениезаголовкашкалыдиаграммы отображениезначенийсводнойдиаграммы отображениезначенияизмерительнойдиаграммы отображениеинтерваладиаграммыганта отображениекнопки отображениекнопкивыбора отображениеобсужденийформы отображениеобычнойгруппы отображениеотрицательныхзначенийпузырьковойдиаграммы отображениепанелипоиска отображениеподсказки отображениепредупрежденияприредактировании отображениеразметкиполосырегулирования отображениестраницформы отображениетаблицы отображениетекстазначениядиаграммыганта отображениеуправленияобычнойгруппы отображениефигурыкнопки палитрацветовдиаграммы поведениеобычнойгруппы поддержкамасштабадендрограммы поддержкамасштабадиаграммыганта поддержкамасштабасводнойдиаграммы поисквтаблицепривводе положениезаголовкаэлементаформы положениекартинкикнопкиформы положениекартинкиэлементаграфическойсхемы положениекоманднойпанелиформы положениекоманднойпанелиэлементаформы положениеопорнойточкиотрисовки положениеподписейкдиаграмме положениеподписейшкалызначенийизмерительнойдиаграммы положениесостоянияпросмотра положениестрокипоиска положениетекстасоединительнойлинии положениеуправленияпоиском положениешкалывремени порядокотображенияточекгоризонтальнойгистограммы порядоксерийвлегендедиаграммы размеркартинки расположениезаголовкашкалыдиаграммы растягиваниеповертикалидиаграммыганта режимавтоотображениясостояния режимвводастроктаблицы режимвыборанезаполненного режимвыделениядаты режимвыделениястрокитаблицы режимвыделениятаблицы режимизмененияразмера режимизменениясвязанногозначения режимиспользованиядиалогапечати режимиспользованияпараметракоманды режиммасштабированияпросмотра режимосновногоокнаклиентскогоприложения режимоткрытияокнаформы режимотображениявыделения режимотображениягеографическойсхемы режимотображениязначенийсерии режимотрисовкисеткиграфическойсхемы режимполупрозрачностидиаграммы режимпробеловдиаграммы режимразмещениянастранице режимредактированияколонки режимсглаживаниядиаграммы режимсглаживанияиндикатора режимсписказадач сквозноевыравнивание сохранениеданныхформывнастройках способзаполнениятекстазаголовкашкалыдиаграммы способопределенияограничивающегозначениядиаграммы стандартнаягруппакоманд стандартноеоформление статусоповещенияпользователя стильстрелки типаппроксимациилиниитрендадиаграммы типдиаграммы типединицышкалывремени типимпортасерийслоягеографическойсхемы типлиниигеографическойсхемы типлиниидиаграммы типмаркерагеографическойсхемы типмаркерадиаграммы типобластиоформления типорганизацииисточникаданныхгеографическойсхемы типотображениясериислоягеографическойсхемы типотображенияточечногообъектагеографическойсхемы типотображенияшкалыэлементалегендыгеографическойсхемы типпоискаобъектовгеографическойсхемы типпроекциигеографическойсхемы типразмещенияизмерений типразмещенияреквизитовизмерений типрамкиэлементауправления типсводнойдиаграммы типсвязидиаграммыганта типсоединениязначенийпосериямдиаграммы типсоединенияточекдиаграммы типсоединительнойлинии типстороныэлементаграфическойсхемы типформыотчета типшкалырадарнойдиаграммы факторлиниитрендадиаграммы фигуракнопки фигурыграфическойсхемы фиксациявтаблице форматдняшкалывремени форматкартинки ширинаподчиненныхэлементовформы виддвижениябухгалтерии виддвижениянакопления видпериодарегистрарасчета видсчета видточкимаршрутабизнеспроцесса использованиеагрегатарегистранакопления использованиегруппиэлементов использованиережимапроведения использованиесреза периодичностьагрегатарегистранакопления режимавтовремя режимзаписидокумента режимпроведениядокумента авторегистрацияизменений допустимыйномерсообщения отправкаэлементаданных получениеэлементаданных использованиерасшифровкитабличногодокумента ориентациястраницы положениеитоговколоноксводнойтаблицы положениеитоговстроксводнойтаблицы положениетекстаотносительнокартинки расположениезаголовкагруппировкитабличногодокумента способчтениязначенийтабличногодокумента типдвустороннейпечати типзаполненияобластитабличногодокумента типкурсоровтабличногодокумента типлиниирисункатабличногодокумента типлинииячейкитабличногодокумента типнаправленияпереходатабличногодокумента типотображениявыделениятабличногодокумента типотображениялинийсводнойтаблицы типразмещениятекстатабличногодокумента типрисункатабличногодокумента типсмещениятабличногодокумента типузоратабличногодокумента типфайлатабличногодокумента точностьпечати чередованиерасположениястраниц отображениевремениэлементовпланировщика типфайлаформатированногодокумента обходрезультатазапроса типзаписизапроса видзаполнениярасшифровкипостроителяотчета типдобавленияпредставлений типизмеренияпостроителяотчета типразмещенияитогов доступкфайлу режимдиалогавыборафайла режимоткрытияфайла типизмеренияпостроителязапроса видданныханализа методкластеризации типединицыинтервалавременианализаданных типзаполнениятаблицырезультатаанализаданных типиспользованиячисловыхзначенийанализаданных типисточникаданныхпоискаассоциаций типколонкианализаданныхдереворешений типколонкианализаданныхкластеризация типколонкианализаданныхобщаястатистика типколонкианализаданныхпоискассоциаций типколонкианализаданныхпоискпоследовательностей типколонкимоделипрогноза типмерырасстоянияанализаданных типотсеченияправилассоциации типполяанализаданных типстандартизациианализаданных типупорядочиванияправилассоциациианализаданных типупорядочиванияшаблоновпоследовательностейанализаданных типупрощениядереварешений wsнаправлениепараметра вариантxpathxs вариантзаписидатыjson вариантпростоготипаxs видгруппымоделиxs видфасетаxdto действиепостроителяdom завершенностьпростоготипаxs завершенностьсоставноготипаxs завершенностьсхемыxs запрещенныеподстановкиxs исключениягруппподстановкиxs категорияиспользованияатрибутаxs категорияограниченияидентичностиxs категорияограниченияпространствименxs методнаследованияxs модельсодержимогоxs назначениетипаxml недопустимыеподстановкиxs обработкапробельныхсимволовxs обработкасодержимогоxs ограничениезначенияxs параметрыотбораузловdom переносстрокjson позициявдокументеdom пробельныесимволыxml типатрибутаxml типзначенияjson типканоническогоxml типкомпонентыxs типпроверкиxml типрезультатаdomxpath типузлаdom типузлаxml формаxml формапредставленияxs форматдатыjson экранированиесимволовjson видсравнениякомпоновкиданных действиеобработкирасшифровкикомпоновкиданных направлениесортировкикомпоновкиданных расположениевложенныхэлементоврезультатакомпоновкиданных расположениеитоговкомпоновкиданных расположениегруппировкикомпоновкиданных расположениеполейгруппировкикомпоновкиданных расположениеполякомпоновкиданных расположениереквизитовкомпоновкиданных расположениересурсовкомпоновкиданных типбухгалтерскогоостаткакомпоновкиданных типвыводатекстакомпоновкиданных типгруппировкикомпоновкиданных типгруппыэлементовотборакомпоновкиданных типдополненияпериодакомпоновкиданных типзаголовкаполейкомпоновкиданных типмакетагруппировкикомпоновкиданных типмакетаобластикомпоновкиданных типостаткакомпоновкиданных типпериодакомпоновкиданных типразмещениятекстакомпоновкиданных типсвязинаборовданныхкомпоновкиданных типэлементарезультатакомпоновкиданных расположениелегендыдиаграммыкомпоновкиданных типпримененияотборакомпоновкиданных режимотображенияэлементанастройкикомпоновкиданных режимотображениянастроеккомпоновкиданных состояниеэлементанастройкикомпоновкиданных способвосстановлениянастроеккомпоновкиданных режимкомпоновкирезультата использованиепараметракомпоновкиданных автопозицияресурсовкомпоновкиданных вариантиспользованиягруппировкикомпоновкиданных расположениересурсоввдиаграммекомпоновкиданных фиксациякомпоновкиданных использованиеусловногооформлениякомпоновкиданных важностьинтернетпочтовогосообщения обработкатекстаинтернетпочтовогосообщения способкодированияинтернетпочтовоговложения способкодированиянеasciiсимволовинтернетпочтовогосообщения типтекстапочтовогосообщения протоколинтернетпочты статусразборапочтовогосообщения режимтранзакциизаписижурналарегистрации статустранзакциизаписижурналарегистрации уровеньжурналарегистрации расположениехранилищасертификатовкриптографии режимвключениясертификатовкриптографии режимпроверкисертификатакриптографии типхранилищасертификатовкриптографии кодировкаименфайловвzipфайле методсжатияzip методшифрованияzip режимвосстановленияпутейфайловzip режимобработкиподкаталоговzip режимсохраненияпутейzip уровеньсжатияzip звуковоеоповещение направлениепереходакстроке позициявпотоке порядокбайтов режимблокировкиданных режимуправленияблокировкойданных сервисвстроенныхпокупок состояниефоновогозадания типподписчикадоставляемыхуведомлений уровеньиспользованиязащищенногосоединенияftp направлениепорядкасхемызапроса типдополненияпериодамисхемызапроса типконтрольнойточкисхемызапроса типобъединениясхемызапроса типпараметрадоступнойтаблицысхемызапроса типсоединениясхемызапроса httpметод автоиспользованиеобщегореквизита автопрефиксномеразадачи вариантвстроенногоязыка видиерархии видрегистранакопления видтаблицывнешнегоисточникаданных записьдвиженийприпроведении заполнениепоследовательностей индексирование использованиебазыпланавидоврасчета использованиебыстроговыбора использованиеобщегореквизита использованиеподчинения использованиеполнотекстовогопоиска использованиеразделяемыхданныхобщегореквизита использованиереквизита назначениеиспользованияприложения назначениерасширенияконфигурации направлениепередачи обновлениепредопределенныхданных оперативноепроведение основноепредставлениевидарасчета основноепредставлениевидахарактеристики основноепредставлениезадачи основноепредставлениепланаобмена основноепредставлениесправочника основноепредставлениесчета перемещениеграницыприпроведении периодичностьномерабизнеспроцесса периодичностьномерадокумента периодичностьрегистрарасчета периодичностьрегистрасведений повторноеиспользованиевозвращаемыхзначений полнотекстовыйпоискпривводепостроке принадлежностьобъекта проведение разделениеаутентификацииобщегореквизита разделениеданныхобщегореквизита разделениерасширенийконфигурацииобщегореквизита режимавтонумерацииобъектов режимзаписирегистра режимиспользованиямодальности режимиспользованиясинхронныхвызововрасширенийплатформыивнешнихкомпонент режимповторногоиспользованиясеансов режимполученияданныхвыборапривводепостроке режимсовместимости режимсовместимостиинтерфейса режимуправленияблокировкойданныхпоумолчанию сериикодовпланавидовхарактеристик сериикодовпланасчетов сериикодовсправочника созданиепривводе способвыбора способпоискастрокипривводепостроке способредактирования типданныхтаблицывнешнегоисточникаданных типкодапланавидоврасчета типкодасправочника типмакета типномерабизнеспроцесса типномерадокумента типномеразадачи типформы удалениедвижений важностьпроблемыприменениярасширенияконфигурации вариантинтерфейсаклиентскогоприложения вариантмасштабаформклиентскогоприложения вариантосновногошрифтаклиентскогоприложения вариантстандартногопериода вариантстандартнойдатыначала видграницы видкартинки видотображенияполнотекстовогопоиска видрамки видсравнения видцвета видчисловогозначения видшрифта допустимаядлина допустимыйзнак использованиеbyteordermark использованиеметаданныхполнотекстовогопоиска источникрасширенийконфигурации клавиша кодвозвратадиалога кодировкаxbase кодировкатекста направлениепоиска направлениесортировки обновлениепредопределенныхданных обновлениеприизмененииданных отображениепанелиразделов проверказаполнения режимдиалогавопрос режимзапускаклиентскогоприложения режимокругления режимоткрытияформприложения режимполнотекстовогопоиска скоростьклиентскогосоединения состояниевнешнегоисточникаданных состояниеобновленияконфигурациибазыданных способвыборасертификатаwindows способкодированиястроки статуссообщения типвнешнейкомпоненты типплатформы типповеденияклавишиenter типэлементаинформацииовыполненииобновленияконфигурациибазыданных уровеньизоляциитранзакций хешфункция частидаты\",type:\"comобъект ftpсоединение httpзапрос httpсервисответ httpсоединение wsопределения wsпрокси xbase анализданных аннотацияxs блокировкаданных буфердвоичныхданных включениеxs выражениекомпоновкиданных генераторслучайныхчисел географическаясхема географическиекоординаты графическаясхема группамоделиxs данныерасшифровкикомпоновкиданных двоичныеданные дендрограмма диаграмма диаграммаганта диалогвыборафайла диалогвыборацвета диалогвыборашрифта диалограсписаниярегламентногозадания диалогредактированиястандартногопериода диапазон документdom документhtml документацияxs доставляемоеуведомление записьdom записьfastinfoset записьhtml записьjson записьxml записьzipфайла записьданных записьтекста записьузловdom запрос защищенноесоединениеopenssl значенияполейрасшифровкикомпоновкиданных извлечениетекста импортxs интернетпочта интернетпочтовоесообщение интернетпочтовыйпрофиль интернетпрокси интернетсоединение информациядляприложенияxs использованиеатрибутаxs использованиесобытияжурналарегистрации источникдоступныхнастроеккомпоновкиданных итераторузловdom картинка квалификаторыдаты квалификаторыдвоичныхданных квалификаторыстроки квалификаторычисла компоновщикмакетакомпоновкиданных компоновщикнастроеккомпоновкиданных конструктормакетаоформлениякомпоновкиданных конструкторнастроеккомпоновкиданных конструкторформатнойстроки линия макеткомпоновкиданных макетобластикомпоновкиданных макетоформлениякомпоновкиданных маскаxs менеджеркриптографии наборсхемxml настройкикомпоновкиданных настройкисериализацииjson обработкакартинок обработкарасшифровкикомпоновкиданных обходдереваdom объявлениеатрибутаxs объявлениенотацииxs объявлениеэлементаxs описаниеиспользованиясобытиядоступжурналарегистрации описаниеиспользованиясобытияотказвдоступежурналарегистрации описаниеобработкирасшифровкикомпоновкиданных описаниепередаваемогофайла описаниетипов определениегруппыатрибутовxs определениегруппымоделиxs определениеограниченияидентичностиxs определениепростоготипаxs определениесоставноготипаxs определениетипадокументаdom определенияxpathxs отборкомпоновкиданных пакетотображаемыхдокументов параметрвыбора параметркомпоновкиданных параметрызаписиjson параметрызаписиxml параметрычтенияxml переопределениеxs планировщик полеанализаданных полекомпоновкиданных построительdom построительзапроса построительотчета построительотчетаанализаданных построительсхемxml поток потоквпамяти почта почтовоесообщение преобразованиеxsl преобразованиекканоническомуxml процессорвыводарезультатакомпоновкиданныхвколлекциюзначений процессорвыводарезультатакомпоновкиданныхвтабличныйдокумент процессоркомпоновкиданных разыменовательпространствименdom рамка расписаниерегламентногозадания расширенноеимяxml результатчтенияданных своднаядиаграмма связьпараметравыбора связьпотипу связьпотипукомпоновкиданных сериализаторxdto сертификатклиентаwindows сертификатклиентафайл сертификаткриптографии сертификатыудостоверяющихцентровwindows сертификатыудостоверяющихцентровфайл сжатиеданных системнаяинформация сообщениепользователю сочетаниеклавиш сравнениезначений стандартнаядатаначала стандартныйпериод схемаxml схемакомпоновкиданных табличныйдокумент текстовыйдокумент тестируемоеприложение типданныхxml уникальныйидентификатор фабрикаxdto файл файловыйпоток фасетдлиныxs фасетколичестваразрядовдробнойчастиxs фасетмаксимальноговключающегозначенияxs фасетмаксимальногоисключающегозначенияxs фасетмаксимальнойдлиныxs фасетминимальноговключающегозначенияxs фасетминимальногоисключающегозначенияxs фасетминимальнойдлиныxs фасетобразцаxs фасетобщегоколичестваразрядовxs фасетперечисленияxs фасетпробельныхсимволовxs фильтрузловdom форматированнаястрока форматированныйдокумент фрагментxs хешированиеданных хранилищезначения цвет чтениеfastinfoset чтениеhtml чтениеjson чтениеxml чтениеzipфайла чтениеданных чтениетекста чтениеузловdom шрифт элементрезультатакомпоновкиданных comsafearray деревозначений массив соответствие списокзначений структура таблицазначений фиксированнаяструктура фиксированноесоответствие фиксированныймассив \",literal:r},contains:[{className:\"meta\",lexemes:t,begin:\"#|&\",end:\"$\",keywords:{\"meta-keyword\":n+\"загрузитьизфайла вебклиент вместо внешнеесоединение клиент конецобласти мобильноеприложениеклиент мобильноеприложениесервер наклиенте наклиентенасервере наклиентенасерверебезконтекста насервере насерверебезконтекста область перед после сервер толстыйклиентобычноеприложение толстыйклиентуправляемоеприложение тонкийклиент \"},contains:[s]},{className:\"function\",lexemes:t,variants:[{begin:\"процедура|функция\",end:\"\\\\)\",keywords:\"процедура функция\"},{begin:\"конецпроцедуры|конецфункции\",keywords:\"конецпроцедуры конецфункции\"}],contains:[{begin:\"\\\\(\",end:\"\\\\)\",endsParent:!0,contains:[{className:\"params\",lexemes:t,begin:t,end:\",\",excludeEnd:!0,endsWithParent:!0,keywords:{keyword:\"знач\",literal:r},contains:[i,a,o]},s]},e.inherit(e.TITLE_MODE,{begin:t})]},s,{className:\"symbol\",begin:\"~\",end:\";|:\",excludeEnd:!0},i,a,o]}}},function(e,t,n){!function(e){\"object\"==typeof window&&window||\"object\"==typeof self&&self;(function(e){var t=[],n=Object.keys,r={},i={},a=/^(no-?highlight|plain|text)$/i,o=/\\blang(?:uage)?-([\\w-]+)\\b/i,s=/((^(<[^>]+>|\\t|)+|(?:\\n)))/gm,l=\"
\",c={classPrefix:\"hljs-\",tabReplace:null,useBR:!1,languages:void 0};function u(e){return e.replace(/&/g,\"&\").replace(//g,\">\")}function d(e){return e.nodeName.toLowerCase()}function f(e,t){var n=e&&e.exec(t);return n&&0===n.index}function p(e){return a.test(e)}function m(e){var t,n={},r=Array.prototype.slice.call(arguments,1);for(t in e)n[t]=e[t];return r.forEach(function(e){for(t in e)n[t]=e[t]}),n}function g(e){var t=[];return function e(n,r){for(var i=n.firstChild;i;i=i.nextSibling)3===i.nodeType?r+=i.nodeValue.length:1===i.nodeType&&(t.push({event:\"start\",offset:r,node:i}),r=e(i,r),d(i).match(/br|hr|img|input/)||t.push({event:\"stop\",offset:r,node:i}));return r}(e,0),t}function h(e){function t(e){return e&&e.source||e}function r(n,r){return new RegExp(t(n),\"m\"+(e.case_insensitive?\"i\":\"\")+(r?\"g\":\"\"))}!function i(a,o){if(a.compiled)return;a.compiled=!0;a.keywords=a.keywords||a.beginKeywords;if(a.keywords){var s={},l=function(t,n){e.case_insensitive&&(n=n.toLowerCase()),n.split(\" \").forEach(function(e){var n=e.split(\"|\");s[n[0]]=[t,n[1]?Number(n[1]):1]})};\"string\"==typeof a.keywords?l(\"keyword\",a.keywords):n(a.keywords).forEach(function(e){l(e,a.keywords[e])}),a.keywords=s}a.lexemesRe=r(a.lexemes||/\\w+/,!0);o&&(a.beginKeywords&&(a.begin=\"\\\\b(\"+a.beginKeywords.split(\" \").join(\"|\")+\")\\\\b\"),a.begin||(a.begin=/\\B|\\b/),a.beginRe=r(a.begin),a.end||a.endsWithParent||(a.end=/\\B|\\b/),a.end&&(a.endRe=r(a.end)),a.terminator_end=t(a.end)||\"\",a.endsWithParent&&o.terminator_end&&(a.terminator_end+=(a.end?\"|\":\"\")+o.terminator_end));a.illegal&&(a.illegalRe=r(a.illegal));null==a.relevance&&(a.relevance=1);a.contains||(a.contains=[]);a.contains=Array.prototype.concat.apply([],a.contains.map(function(e){return function(e){e.variants&&!e.cached_variants&&(e.cached_variants=e.variants.map(function(t){return m(e,{variants:null},t)}));return e.cached_variants||e.endsWithParent&&[m(e)]||[e]}(\"self\"===e?a:e)}));a.contains.forEach(function(e){i(e,a)});a.starts&&i(a.starts,o);var c=a.contains.map(function(e){return e.beginKeywords?\"\\\\.?(\"+e.begin+\")\\\\.?\":e.begin}).concat([a.terminator_end,a.illegal]).map(t).filter(Boolean);a.terminators=c.length?r(c.join(\"|\"),!0):{exec:function(){return null}}}(e)}function b(e,t,n,i){function a(e,t){var n=m.case_insensitive?t[0].toLowerCase():t[0];return e.keywords.hasOwnProperty(n)&&e.keywords[n]}function o(e,t,n,r){var i=r?\"\":c.classPrefix,a='')+t+o}function s(){x+=null!=_.subLanguage?function(){var e=\"string\"==typeof _.subLanguage;if(e&&!r[_.subLanguage])return u(S);var t=e?b(_.subLanguage,S,!0,y[_.subLanguage]):v(S,_.subLanguage.length?_.subLanguage:void 0);_.relevance>0&&(w+=t.relevance);e&&(y[_.subLanguage]=t.top);return o(t.language,t.value,!1,!0)}():function(){var e,t,n,r;if(!_.keywords)return u(S);r=\"\",t=0,_.lexemesRe.lastIndex=0,n=_.lexemesRe.exec(S);for(;n;)r+=u(S.substring(t,n.index)),(e=a(_,n))?(w+=e[1],r+=o(e[0],u(n[0]))):r+=u(n[0]),t=_.lexemesRe.lastIndex,n=_.lexemesRe.exec(S);return r+u(S.substr(t))}(),S=\"\"}function d(e){x+=e.className?o(e.className,\"\",!0):\"\",_=Object.create(e,{parent:{value:_}})}function p(e,t){if(S+=e,null==t)return s(),0;var r=function(e,t){var n,r;for(n=0,r=t.contains.length;n\")+'\"');return S+=t,t.length||1}var m=E(e);if(!m)throw new Error('Unknown language: \"'+e+'\"');h(m);var g,_=i||m,y={},x=\"\";for(g=_;g!==m;g=g.parent)g.className&&(x=o(g.className,\"\",!0)+x);var S=\"\",w=0;try{for(var C,O,M=0;_.terminators.lastIndex=M,C=_.terminators.exec(t);)O=p(t.substring(M,C.index),C[0]),M=C.index+O;for(p(t.substr(M)),g=_;g.parent;g=g.parent)g.className&&(x+=l);return{relevance:w,value:x,language:e,top:_}}catch(e){if(e.message&&-1!==e.message.indexOf(\"Illegal\"))return{relevance:0,value:u(t)};throw e}}function v(e,t){t=t||c.languages||n(r);var i={relevance:0,value:u(e)},a=i;return t.filter(E).forEach(function(t){var n=b(t,e,!1);n.language=t,n.relevance>a.relevance&&(a=n),n.relevance>i.relevance&&(a=i,i=n)}),a.language&&(i.second_best=a),i}function _(e){return c.tabReplace||c.useBR?e.replace(s,function(e,t){return c.useBR&&\"\\n\"===e?\"
\":c.tabReplace?t.replace(/\\t/g,c.tabReplace):\"\"}):e}function y(e){var n,r,a,s,l,f=function(e){var t,n,r,i,a=e.className+\" \";if(a+=e.parentNode?e.parentNode.className:\"\",n=o.exec(a))return E(n[1])?n[1]:\"no-highlight\";for(a=a.split(/\\s+/),t=0,r=a.length;t/g,\"\\n\"):n=e,l=n.textContent,a=f?b(f,l,!0):v(l),(r=g(n)).length&&((s=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\")).innerHTML=a.value,a.value=function(e,n,r){var i=0,a=\"\",o=[];function s(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset\"}function c(e){a+=\"\"}function f(e){(\"start\"===e.event?l:c)(e.node)}for(;e.length||n.length;){var p=s();if(a+=u(r.substring(i,p[0].offset)),i=p[0].offset,p===e){o.reverse().forEach(c);do{f(p.splice(0,1)[0]),p=s()}while(p===e&&p.length&&p[0].offset===i);o.reverse().forEach(l)}else\"start\"===p[0].event?o.push(p[0].node):o.pop(),f(p.splice(0,1)[0])}return a+u(r.substr(i))}(r,g(s),l)),a.value=_(a.value),e.innerHTML=a.value,e.className=function(e,t,n){var r=t?i[t]:n,a=[e.trim()];e.match(/\\bhljs\\b/)||a.push(\"hljs\");-1===e.indexOf(r)&&a.push(r);return a.join(\" \").trim()}(e.className,f,a.language),e.result={language:a.language,re:a.relevance},a.second_best&&(e.second_best={language:a.second_best.language,re:a.second_best.relevance}))}function x(){if(!x.called){x.called=!0;var e=document.querySelectorAll(\"pre code\");t.forEach.call(e,y)}}function E(e){return e=(e||\"\").toLowerCase(),r[e]||r[i[e]]}e.highlight=b,e.highlightAuto=v,e.fixMarkup=_,e.highlightBlock=y,e.configure=function(e){c=m(c,e)},e.initHighlighting=x,e.initHighlightingOnLoad=function(){addEventListener(\"DOMContentLoaded\",x,!1),addEventListener(\"load\",x,!1)},e.registerLanguage=function(t,n){var a=r[t]=n(e);a.aliases&&a.aliases.forEach(function(e){i[e]=t})},e.listLanguages=function(){return n(r)},e.getLanguage=E,e.inherit=m,e.IDENT_RE=\"[a-zA-Z]\\\\w*\",e.UNDERSCORE_IDENT_RE=\"[a-zA-Z_]\\\\w*\",e.NUMBER_RE=\"\\\\b\\\\d+(\\\\.\\\\d+)?\",e.C_NUMBER_RE=\"(-?)(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)\",e.BINARY_NUMBER_RE=\"\\\\b(0b[01]+)\",e.RE_STARTERS_RE=\"!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~\",e.BACKSLASH_ESCAPE={begin:\"\\\\\\\\[\\\\s\\\\S]\",relevance:0},e.APOS_STRING_MODE={className:\"string\",begin:\"'\",end:\"'\",illegal:\"\\\\n\",contains:[e.BACKSLASH_ESCAPE]},e.QUOTE_STRING_MODE={className:\"string\",begin:'\"',end:'\"',illegal:\"\\\\n\",contains:[e.BACKSLASH_ESCAPE]},e.PHRASAL_WORDS_MODE={begin:/\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b/},e.COMMENT=function(t,n,r){var i=e.inherit({className:\"comment\",begin:t,end:n,contains:[]},r||{});return i.contains.push(e.PHRASAL_WORDS_MODE),i.contains.push({className:\"doctag\",begin:\"(?:TODO|FIXME|NOTE|BUG|XXX):\",relevance:0}),i},e.C_LINE_COMMENT_MODE=e.COMMENT(\"//\",\"$\"),e.C_BLOCK_COMMENT_MODE=e.COMMENT(\"/\\\\*\",\"\\\\*/\"),e.HASH_COMMENT_MODE=e.COMMENT(\"#\",\"$\"),e.NUMBER_MODE={className:\"number\",begin:e.NUMBER_RE,relevance:0},e.C_NUMBER_MODE={className:\"number\",begin:e.C_NUMBER_RE,relevance:0},e.BINARY_NUMBER_MODE={className:\"number\",begin:e.BINARY_NUMBER_RE,relevance:0},e.CSS_NUMBER_MODE={className:\"number\",begin:e.NUMBER_RE+\"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?\",relevance:0},e.REGEXP_MODE={className:\"regexp\",begin:/\\//,end:/\\/[gimuy]*/,illegal:/\\n/,contains:[e.BACKSLASH_ESCAPE,{begin:/\\[/,end:/\\]/,relevance:0,contains:[e.BACKSLASH_ESCAPE]}]},e.TITLE_MODE={className:\"title\",begin:e.IDENT_RE,relevance:0},e.UNDERSCORE_TITLE_MODE={className:\"title\",begin:e.UNDERSCORE_IDENT_RE,relevance:0},e.METHOD_GUARD={begin:\"\\\\.\\\\s*\"+e.UNDERSCORE_IDENT_RE,relevance:0}})(t)}()}]);"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sourceRoot":""} \ No newline at end of file diff --git a/build/site/static/index.d.ts b/build/site/static/index.d.ts new file mode 100644 index 0000000000..4d90aa9176 --- /dev/null +++ b/build/site/static/index.d.ts @@ -0,0 +1,3 @@ +import * as vega from 'vega'; +import { TopLevelSpec } from '../../src'; +export declare function embedExample($target: any, spec: TopLevelSpec, actions?: boolean, tooltip?: boolean): vega.View; diff --git a/build/site/static/index.js b/build/site/static/index.js new file mode 100644 index 0000000000..bbaf5bb032 --- /dev/null +++ b/build/site/static/index.js @@ -0,0 +1,180 @@ +import { text } from 'd3-fetch'; +import { event, select, selectAll } from 'd3-selection'; +import * as hljs from 'highlight.js'; +import * as vega from 'vega'; +import { post } from 'vega-embed/build/post'; +import { Handler } from 'vega-tooltip'; +import { compile } from '../../src'; +import { runStreamingExample } from './streaming'; +window['runStreamingExample'] = runStreamingExample; +window['embedExample'] = embedExample; +var loader = vega.loader({ + baseURL: BASEURL +}); +var editorURL = 'https://vega.github.io/editor/'; +function trim(str) { + return str.replace(/^\s+|\s+$/g, ''); +} +/* Anchors */ +selectAll('h2, h3, h4, h5, h6').each(function () { + var sel = select(this); + var name = sel.attr('id'); + var title = sel.text(); + sel.html('' + trim(title)); +}); +/* Documentation */ +function renderExample($target, specText) { + $target.classed('example', true); + $target.text(''); + var vis = $target.append('div').attr('class', 'example-vis'); + // Decrease visual noise by removing $schema and description from code examples. + var textClean = specText.replace(/(\s)+\"(\$schema|description)\": \".*?\",/g, ''); + var code = $target.append('pre').attr('class', 'example-code') + .append('code').attr('class', 'json').text(textClean); + hljs.highlightBlock(code.node()); + var spec = JSON.parse(specText); + embedExample(vis.node(), spec, true, !$target.classed('no-tooltip')); +} +export function embedExample($target, spec, actions, tooltip) { + if (actions === void 0) { actions = true; } + if (tooltip === void 0) { tooltip = true; } + var vgSpec = compile(spec).spec; + var view = new vega.View(vega.parse(vgSpec), { loader: loader }) + .renderer('svg') + .initialize($target); + if (tooltip) { + var handler = new Handler().call; + view.tooltip(handler); + } + view.run(); + if (actions) { + select($target) + .append('div') + .attr('class', 'vega-actions') + .append('a') + .text('Open in Vega Editor') + .attr('href', '#') + .on('click', function () { + post(window, editorURL, { + mode: 'vega-lite', + spec: JSON.stringify(spec, null, 2), + config: vgSpec.config, + renderer: 'svg' + }); + event.preventDefault(); + }); + } + return view; +} +function getSpec(el) { + var sel = select(el); + var name = sel.attr('data-name'); + if (name) { + var dir = sel.attr('data-dir'); + var fullUrl = BASEURL + '/examples/specs/' + (dir ? (dir + '/') : '') + name + '.vl.json'; + text(fullUrl).then(function (spec) { + renderExample(sel, spec); + }).catch(console.error); + } + else { + console.error('No "data-name" specified to import examples from'); + } +} +window['changeSpec'] = function (elId, newSpec) { + var el = document.getElementById(elId); + select(el).attr('data-name', newSpec); + getSpec(el); +}; +window['buildSpecOpts'] = function (id, baseName) { + var oldName = select('#' + id).attr('data-name'); + var prefixSel = select('select[name=' + id + ']'); + var inputsSel = selectAll('input[name=' + id + ']:checked'); + var prefix = prefixSel.empty() ? id : prefixSel.property('value'); + var values = inputsSel.nodes().map(function (n) { return n.value; }).sort().join('_'); + var newName = baseName + prefix + (values ? '_' + values : ''); + if (oldName !== newName) { + window['changeSpec'](id, newName); + } +}; +selectAll('.vl-example').each(function () { + getSpec(this); +}); +// caroussel for the front page +// adapted from https://codepen.io/LANparty/pen/wePYXb +var carousel = document.getElementById('carousel'); +function carouselHide(slides, indicators, links, active) { + indicators[active].setAttribute('data-state', ''); + links[active].setAttribute('data-state', ''); + slides[active].setAttribute('data-state', ''); + slides[active].style.display = 'none'; + var video = slides[active].querySelector('video'); + if (video) { + video.pause(); + } +} +function carouselShow(slides, indicators, links, active) { + indicators[active].checked = true; + indicators[active].setAttribute('data-state', 'active'); + links[active].setAttribute('data-state', 'active'); + slides[active].setAttribute('data-state', 'active'); + var video = slides[active].querySelector('video'); + if (video) { + video.currentTime = 0; + slides[active].style.display = 'block'; + video.play(); + } + else { + slides[active].style.display = 'block'; + } +} +function setSlide(slides, indicators, links, active) { + return function () { + // Reset all slides + for (var i = 0; i < indicators.length; i++) { + indicators[i].setAttribute('data-state', ''); + slides[i].setAttribute('data-state', ''); + carouselHide(slides, indicators, links, i); + } + // Set defined slide as active + indicators[active].setAttribute('data-state', 'active'); + slides[active].setAttribute('data-state', 'active'); + carouselShow(slides, indicators, links, active); + // Switch button text + var numSlides = carousel.querySelectorAll('.indicator').length; + if (numSlides === active + 1) { + carousel.querySelector('.next-slide').textContent = 'Start over'; + } + else { + carousel.querySelector('.next-slide').textContent = 'Next step'; + } + }; +} +if (carousel) { + var slides_1 = carousel.querySelectorAll('.slide'); + var indicators_1 = carousel.querySelectorAll('.indicator'); + var links_1 = carousel.querySelectorAll('.slide-nav'); + // tslint:disable-next-line:prefer-for-of + for (var i = 0; i < indicators_1.length; i++) { + indicators_1[i].addEventListener('click', setSlide(slides_1, indicators_1, links_1, +indicators_1[i].getAttribute('data-slide'))); + } + // tslint:disable-next-line:prefer-for-of + for (var i = 0; i < links_1.length; i++) { + links_1[i].addEventListener('click', setSlide(slides_1, indicators_1, links_1, +links_1[i].getAttribute('data-slide'))); + } + carousel.querySelector('.next-slide').addEventListener('click', function () { + var slide = +carousel.querySelector('.indicator[data-state=active]').getAttribute('data-slide'); + var numSlides = carousel.querySelectorAll('.indicator').length; + setSlide(slides_1, indicators_1, links_1, (slide + 1) % numSlides)(); + }); + [].forEach.call(slides_1, function (slide) { + var video = slide.querySelector('video'); + if (video) { + video.addEventListener('mouseover', function () { + slide.querySelector('.example-vis').style.visibility = 'visible'; + video.style.display = 'none'; + video.pause(); + }); + } + }); +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/site/static/index.js.map b/build/site/static/index.js.map new file mode 100644 index 0000000000..3a4867d0f0 --- /dev/null +++ b/build/site/static/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../site/static/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,UAAU,CAAC;AAC9B,OAAO,EAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAY,MAAM,cAAc,CAAC;AACjE,OAAO,KAAK,IAAI,MAAM,cAAc,CAAC;AACrC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAC,IAAI,EAAC,MAAM,uBAAuB,CAAC;AAC3C,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AACrC,OAAO,EAAC,OAAO,EAAe,MAAM,WAAW,CAAC;AAChD,OAAO,EAAC,mBAAmB,EAAC,MAAM,aAAa,CAAC;AAGhD,MAAM,CAAC,qBAAqB,CAAC,GAAG,mBAAmB,CAAC;AACpD,MAAM,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC;AAItC,IAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,IAAM,SAAS,GAAG,gCAAgC,CAAC;AAEnD,cAAc,GAAW;IACvB,OAAO,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,aAAa;AACb,SAAS,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC;IACnC,IAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACzB,IAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACzB,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,iEAAiE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAClH,CAAC,CAAC,CAAC;AAEH,mBAAmB;AACnB,uBAAuB,OAAsC,EAAE,QAAgB;IAC7E,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEjB,IAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAE/D,gFAAgF;IAChF,IAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,4CAA4C,EAAE,EAAE,CAAC,CAAC;IACrF,IAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC;SAC/D,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAS,CAAC,CAAC;IAExC,IAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAElC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,uBAAuB,OAAY,EAAE,IAAkB,EAAE,OAAY,EAAE,OAAY;IAA1B,wBAAA,EAAA,cAAY;IAAE,wBAAA,EAAA,cAAY;IACvF,IAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;IAElC,IAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAC,MAAM,EAAE,MAAM,EAAC,CAAC;SAC7D,QAAQ,CAAC,KAAK,CAAC;SACf,UAAU,CAAC,OAAO,CAAC,CAAC;IAEvB,IAAI,OAAO,EAAE;QACX,IAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC,IAAI,CAAC;QACnC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;KACvB;IAED,IAAI,CAAC,GAAG,EAAE,CAAC;IAEX,IAAI,OAAO,EAAE;QACX,MAAM,CAAC,OAAO,CAAC;aACZ,MAAM,CAAC,KAAK,CAAC;aACb,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC;aAC7B,MAAM,CAAC,GAAG,CAAC;aACX,IAAI,CAAC,qBAAqB,CAAC;aAC3B,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;aACjB,EAAE,CAAC,OAAO,EAAE;YACX,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE;gBACtB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnC,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,QAAQ,EAAE,KAAK;aAChB,CAAC,CAAC;YACH,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,CAAC,CAAC,CAAC;KACN;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iBAAiB,EAAe;IAC9B,IAAM,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IACvB,IAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACnC,IAAI,IAAI,EAAE;QACR,IAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjC,IAAM,OAAO,GAAG,OAAO,GAAG,kBAAkB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,GAAG,UAAU,CAAC;QAE5F,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAA,IAAI;YACrB,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;KACzB;SAAM;QACL,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;KACnE;AACH,CAAC;AAED,MAAM,CAAC,YAAY,CAAC,GAAG,UAAS,IAAY,EAAE,OAAe;IAC3D,IAAM,EAAE,GAAG,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,CAAC,eAAe,CAAC,GAAG,UAAS,EAAU,EAAE,QAAgB;IAC7D,IAAM,OAAO,GAAG,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACnD,IAAM,SAAS,GAAG,MAAM,CAAC,cAAc,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC;IACpD,IAAM,SAAS,GAAG,SAAS,CAAC,aAAa,GAAG,EAAE,GAAG,WAAW,CAAC,CAAC;IAC9D,IAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACpE,IAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,UAAC,CAAM,IAAK,OAAA,CAAC,CAAC,KAAK,EAAP,CAAO,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3E,IAAM,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACjE,IAAI,OAAO,KAAK,OAAO,EAAE;QACvB,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;KACnC;AACH,CAAC,CAAC;AAEF,SAAS,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC;IAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,+BAA+B;AAC/B,sDAAsD;AAEtD,IAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;AAErD,sBAAsB,MAAuB,EAAE,UAA2B,EAAE,KAAsB,EAAE,MAAc;IAChH,UAAU,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAClD,KAAK,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;IAEtC,IAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACpD,IAAI,KAAK,EAAE;QACT,KAAK,CAAC,KAAK,EAAE,CAAC;KACf;AACH,CAAC;AAED,sBAAsB,MAAuB,EAAE,UAA2B,EAAE,KAAsB,EAAE,MAAc;IAChH,UAAU,CAAC,MAAM,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;IAClC,UAAU,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACxD,KAAK,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACnD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAEpD,IAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACpD,IAAI,KAAK,EAAE;QACT,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;QACtB,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;QACvC,KAAK,CAAC,IAAI,EAAE,CAAC;KACd;SAAM;QACL,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;KACxC;AACH,CAAC;AAED,kBAAkB,MAA2B,EAAE,UAA+B,EAAE,KAAsB,EAAE,MAAc;IACpH,OAAO;QACL,mBAAmB;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAC1C,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAC7C,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YACzC,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;SAC5C;QAED,8BAA8B;QAC9B,UAAU,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QACpD,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAEhD,qBAAqB;QACrB,IAAM,SAAS,GAAG,QAAQ,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;QACjE,IAAI,SAAS,KAAK,MAAM,GAAG,CAAC,EAAE;YAC5B,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,WAAW,GAAG,YAAY,CAAC;SAClE;aAAM;YACL,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,WAAW,GAAG,WAAW,CAAC;SACjE;IACH,CAAC,CAAC;AACJ,CAAC;AAED,IAAI,QAAQ,EAAE;IACZ,IAAM,QAAM,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnD,IAAM,YAAU,GAAG,QAAQ,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC3D,IAAM,OAAK,GAAG,QAAQ,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAEtD,yCAAyC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAC1C,YAAU,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,QAAM,EAAE,YAAU,EAAE,OAAK,EAAE,CAAC,YAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;KACzH;IAED,yCAAyC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACrC,OAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,QAAM,EAAE,YAAU,EAAE,OAAK,EAAE,CAAC,OAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;KAC/G;IAED,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE;QAC9D,IAAM,KAAK,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,+BAA+B,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAClG,IAAM,SAAS,GAAG,QAAQ,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;QACjE,QAAQ,CAAC,QAAM,EAAE,YAAU,EAAE,OAAK,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAM,EAAE,UAAC,KAAc;QACrC,IAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,KAAK,EAAE;YACT,KAAK,CAAC,gBAAgB,CAAC,WAAW,EAAE;gBACjC,KAAK,CAAC,aAAa,CAAC,cAAc,CAAS,CAAC,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC;gBAC1E,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;gBAC7B,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,CAAC,CAAC,CAAC;SACJ;IACH,CAAC,CAAC,CAAC;CACJ","sourcesContent":["import {text} from 'd3-fetch';\nimport {event, select, selectAll, Selection} from 'd3-selection';\nimport * as hljs from 'highlight.js';\nimport * as vega from 'vega';\nimport {post} from 'vega-embed/build/post';\nimport {Handler} from 'vega-tooltip';\nimport {compile, TopLevelSpec} from '../../src';\nimport {runStreamingExample} from './streaming';\n\n\nwindow['runStreamingExample'] = runStreamingExample;\nwindow['embedExample'] = embedExample;\n\ndeclare const BASEURL: string;\n\nconst loader = vega.loader({\n baseURL: BASEURL\n});\n\nconst editorURL = 'https://vega.github.io/editor/';\n\nfunction trim(str: string) {\n return str.replace(/^\\s+|\\s+$/g, '');\n}\n\n/* Anchors */\nselectAll('h2, h3, h4, h5, h6').each(function(this: d3.BaseType) {\n const sel = select(this);\n const name = sel.attr('id');\n const title = sel.text();\n sel.html('' + trim(title));\n});\n\n/* Documentation */\nfunction renderExample($target: Selection, specText: string) {\n $target.classed('example', true);\n $target.text('');\n\n const vis = $target.append('div').attr('class', 'example-vis');\n\n // Decrease visual noise by removing $schema and description from code examples.\n const textClean = specText.replace(/(\\s)+\\\"(\\$schema|description)\\\": \\\".*?\\\",/g, '');\n const code = $target.append('pre').attr('class', 'example-code')\n .append('code').attr('class', 'json').text(textClean);\n hljs.highlightBlock(code.node() as any);\n\n const spec = JSON.parse(specText);\n\n embedExample(vis.node(), spec, true, !$target.classed('no-tooltip'));\n}\n\nexport function embedExample($target: any, spec: TopLevelSpec, actions=true, tooltip=true) {\n const vgSpec = compile(spec).spec;\n\n const view = new vega.View(vega.parse(vgSpec), {loader: loader})\n .renderer('svg')\n .initialize($target);\n\n if (tooltip) {\n const handler = new Handler().call;\n view.tooltip(handler);\n }\n\n view.run();\n\n if (actions) {\n select($target)\n .append('div')\n .attr('class', 'vega-actions')\n .append('a')\n .text('Open in Vega Editor')\n .attr('href', '#')\n .on('click', function () {\n post(window, editorURL, {\n mode: 'vega-lite',\n spec: JSON.stringify(spec, null, 2),\n config: vgSpec.config,\n renderer: 'svg'\n });\n event.preventDefault();\n });\n }\n\n return view;\n}\n\nfunction getSpec(el: d3.BaseType) {\n const sel = select(el);\n const name = sel.attr('data-name');\n if (name) {\n const dir = sel.attr('data-dir');\n const fullUrl = BASEURL + '/examples/specs/' + (dir ? (dir + '/') : '') + name + '.vl.json';\n\n text(fullUrl).then(spec => {\n renderExample(sel, spec);\n }).catch(console.error);\n } else {\n console.error('No \"data-name\" specified to import examples from');\n }\n}\n\nwindow['changeSpec'] = function(elId: string, newSpec: string) {\n const el = document.getElementById(elId);\n select(el).attr('data-name', newSpec);\n getSpec(el);\n};\n\nwindow['buildSpecOpts'] = function(id: string, baseName: string) {\n const oldName = select('#' + id).attr('data-name');\n const prefixSel = select('select[name=' + id + ']');\n const inputsSel = selectAll('input[name=' + id + ']:checked');\n const prefix = prefixSel.empty() ? id : prefixSel.property('value');\n const values = inputsSel.nodes().map((n: any) => n.value).sort().join('_');\n const newName = baseName + prefix + (values ? '_' + values : '');\n if (oldName !== newName) {\n window['changeSpec'](id, newName);\n }\n};\n\nselectAll('.vl-example').each(function(this: d3.BaseType) {\n getSpec(this);\n});\n\n// caroussel for the front page\n// adapted from https://codepen.io/LANparty/pen/wePYXb\n\nconst carousel = document.getElementById('carousel');\n\nfunction carouselHide(slides: NodeListOf, indicators: NodeListOf, links: NodeListOf, active: number) {\n indicators[active].setAttribute('data-state', '');\n links[active].setAttribute('data-state', '');\n slides[active].setAttribute('data-state', '');\n slides[active].style.display = 'none';\n\n const video = slides[active].querySelector('video');\n if (video) {\n video.pause();\n }\n}\n\nfunction carouselShow(slides: NodeListOf, indicators: NodeListOf, links: NodeListOf, active: number) {\n indicators[active].checked = true;\n indicators[active].setAttribute('data-state', 'active');\n links[active].setAttribute('data-state', 'active');\n slides[active].setAttribute('data-state', 'active');\n\n const video = slides[active].querySelector('video');\n if (video) {\n video.currentTime = 0;\n slides[active].style.display = 'block';\n video.play();\n } else {\n slides[active].style.display = 'block';\n }\n}\n\nfunction setSlide(slides: NodeListOf, indicators: NodeListOf, links: NodeListOf, active: number) {\n return function() {\n // Reset all slides\n for (let i = 0; i < indicators.length; i++) {\n indicators[i].setAttribute('data-state', '');\n slides[i].setAttribute('data-state', '');\n carouselHide(slides, indicators, links, i);\n }\n\n // Set defined slide as active\n indicators[active].setAttribute('data-state', 'active');\n slides[active].setAttribute('data-state', 'active');\n carouselShow(slides, indicators, links, active);\n\n // Switch button text\n const numSlides = carousel.querySelectorAll('.indicator').length;\n if (numSlides === active + 1) {\n carousel.querySelector('.next-slide').textContent = 'Start over';\n } else {\n carousel.querySelector('.next-slide').textContent = 'Next step';\n }\n };\n}\n\nif (carousel) {\n const slides = carousel.querySelectorAll('.slide');\n const indicators = carousel.querySelectorAll('.indicator');\n const links = carousel.querySelectorAll('.slide-nav');\n\n // tslint:disable-next-line:prefer-for-of\n for (let i = 0; i < indicators.length; i++) {\n indicators[i].addEventListener('click', setSlide(slides, indicators, links, +indicators[i].getAttribute('data-slide')));\n }\n\n // tslint:disable-next-line:prefer-for-of\n for (let i = 0; i < links.length; i++) {\n links[i].addEventListener('click', setSlide(slides, indicators, links, +links[i].getAttribute('data-slide')));\n }\n\n carousel.querySelector('.next-slide').addEventListener('click', () => {\n const slide = +carousel.querySelector('.indicator[data-state=active]').getAttribute('data-slide');\n const numSlides = carousel.querySelectorAll('.indicator').length;\n setSlide(slides, indicators, links, (slide + 1) % numSlides)();\n });\n\n [].forEach.call(slides, (slide: Element) => {\n const video = slide.querySelector('video');\n if (video) {\n video.addEventListener('mouseover', () => {\n (slide.querySelector('.example-vis') as any).style.visibility = 'visible';\n video.style.display = 'none';\n video.pause();\n });\n }\n });\n}\n"]} \ No newline at end of file diff --git a/build/site/static/streaming.d.ts b/build/site/static/streaming.d.ts new file mode 100644 index 0000000000..c74f2301f5 --- /dev/null +++ b/build/site/static/streaming.d.ts @@ -0,0 +1 @@ +export declare function runStreamingExample(eleId: string): void; diff --git a/build/site/static/streaming.js b/build/site/static/streaming.js new file mode 100644 index 0000000000..5e870f19fb --- /dev/null +++ b/build/site/static/streaming.js @@ -0,0 +1,45 @@ +import { embedExample } from '.'; +export function runStreamingExample(eleId) { + var vlSpec = { + $schema: 'https://vega.github.io/schema/vega-lite/v2.json', + data: { name: 'table' }, + autosize: { + resize: true + }, + width: 400, + mark: 'line', + encoding: { + x: { field: 'x', type: 'quantitative', scale: { zero: false } }, + y: { field: 'y', type: 'quantitative' }, + color: { field: 'category', type: 'nominal' } + } + }; + var view = embedExample(eleId, vlSpec, false, false); + /** + * Generates a new tuple with random walk. + */ + function newGenerator() { + var counter = -1; + var previousY = [5, 5, 5, 5]; + return function () { + counter++; + var newVals = previousY.map(function (v, category) { return ({ + x: counter, + y: v + Math.round(Math.random() * 10 - category * 3), + category: category + }); }); + previousY = newVals.map(function (v) { return v.y; }); + return newVals; + }; + } + var valueGenerator = newGenerator(); + var minimumX = -100; + window.setInterval(function () { + minimumX++; + var changeSet = view.changeset() + .insert(valueGenerator()) + .remove(function (t) { return t.x < minimumX; }); + view.change('table', changeSet).run(); + }, 1000); +} +//# sourceMappingURL=streaming.js.map \ No newline at end of file diff --git a/build/site/static/streaming.js.map b/build/site/static/streaming.js.map new file mode 100644 index 0000000000..e3d3a2568a --- /dev/null +++ b/build/site/static/streaming.js.map @@ -0,0 +1 @@ +{"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../../site/static/streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,GAAG,CAAC;AAG/B,MAAM,8BAA8B,KAAa;IAC/C,IAAM,MAAM,GAAiB;QAC3B,OAAO,EAAE,iDAAiD;QAC1D,IAAI,EAAE,EAAC,IAAI,EAAE,OAAO,EAAC;QACrB,QAAQ,EAAE;YACR,MAAM,EAAE,IAAI;SACb;QACD,KAAK,EAAE,GAAG;QACV,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE;YACR,CAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,EAAC,IAAI,EAAE,KAAK,EAAC,EAAC;YAC3D,CAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC;YACrC,KAAK,EAAE,EAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAC;SAC5C;KACF,CAAC;IAEF,IAAM,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAEvD;;OAEG;IACH;QACE,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;QACjB,IAAI,SAAS,GAAG,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,CAAC;QAC1B,OAAO;YACL,OAAO,EAAE,CAAC;YACV,IAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,UAAC,CAAC,EAAE,QAAQ,IAAK,OAAA,CAAC;gBAC9C,CAAC,EAAE,OAAO;gBACV,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,QAAQ,GAAG,CAAC,CAAC;gBACpD,QAAQ,UAAA;aACT,CAAC,EAJ6C,CAI7C,CAAC,CAAC;YACJ,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,UAAC,CAAC,IAAI,OAAA,CAAC,CAAC,CAAC,EAAH,CAAG,CAAC,CAAC;YACnC,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC;IACJ,CAAC;IAED,IAAM,cAAc,GAAG,YAAY,EAAE,CAAC;IAEtC,IAAI,QAAQ,GAAG,CAAC,GAAG,CAAC;IACpB,MAAM,CAAC,WAAW,CAAC;QACjB,QAAQ,EAAE,CAAC;QACX,IAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;aAC/B,MAAM,CAAC,cAAc,EAAE,CAAC;aACxB,MAAM,CAAC,UAAC,CAAc,IAAK,OAAA,CAAC,CAAC,CAAC,GAAG,QAAQ,EAAd,CAAc,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;IACxC,CAAC,EAAE,IAAI,CAAC,CAAC;AACX,CAAC","sourcesContent":["import {embedExample} from '.';\nimport {TopLevelSpec} from '../../src';\n\nexport function runStreamingExample(eleId: string) {\n const vlSpec: TopLevelSpec = {\n $schema: 'https://vega.github.io/schema/vega-lite/v2.json',\n data: {name: 'table'},\n autosize: {\n resize: true\n },\n width: 400,\n mark: 'line',\n encoding: {\n x: {field: 'x', type: 'quantitative', scale: {zero: false}},\n y: {field: 'y', type: 'quantitative'},\n color: {field: 'category', type: 'nominal'}\n }\n };\n\n const view = embedExample(eleId, vlSpec, false, false);\n\n /**\n * Generates a new tuple with random walk.\n */\n function newGenerator() {\n let counter = -1;\n let previousY = [5,5,5,5];\n return () => {\n counter++;\n const newVals = previousY.map((v, category) => ({\n x: counter,\n y: v + Math.round(Math.random() * 10 - category * 3),\n category\n }));\n previousY = newVals.map((v)=> v.y);\n return newVals;\n };\n }\n\n const valueGenerator = newGenerator();\n\n let minimumX = -100;\n window.setInterval(() => {\n minimumX++;\n const changeSet = view.changeset()\n .insert(valueGenerator())\n .remove((t: {x: number}) => t.x < minimumX);\n view.change('table', changeSet).run();\n }, 1000);\n}\n"]} \ No newline at end of file diff --git a/build/src/aggregate.d.ts b/build/src/aggregate.d.ts new file mode 100644 index 0000000000..38680434bd --- /dev/null +++ b/build/src/aggregate.d.ts @@ -0,0 +1,14 @@ +import { AggregateOp } from 'vega'; +export declare const AGGREGATE_OPS: AggregateOp[]; +export declare function isAggregateOp(a: string): a is AggregateOp; +export declare const COUNTING_OPS: AggregateOp[]; +export declare function isCountingAggregateOp(aggregate: string): boolean; +/** Additive-based aggregation operations. These can be applied to stack. */ +export declare const SUM_OPS: AggregateOp[]; +/** + * Aggregation operators that always produce values within the range [domainMin, domainMax]. + */ +export declare const SHARED_DOMAIN_OPS: AggregateOp[]; +export declare const SHARED_DOMAIN_OP_INDEX: { + [T: string]: true; +}; diff --git a/build/src/aggregate.js b/build/src/aggregate.js new file mode 100644 index 0000000000..08ab69ee61 --- /dev/null +++ b/build/src/aggregate.js @@ -0,0 +1,56 @@ +import { toSet } from 'vega-util'; +import { contains, flagKeys } from './util'; +var AGGREGATE_OP_INDEX = { + argmax: 1, + argmin: 1, + average: 1, + count: 1, + distinct: 1, + max: 1, + mean: 1, + median: 1, + min: 1, + missing: 1, + q1: 1, + q3: 1, + ci0: 1, + ci1: 1, + stderr: 1, + stdev: 1, + stdevp: 1, + sum: 1, + valid: 1, + values: 1, + variance: 1, + variancep: 1, +}; +export var AGGREGATE_OPS = flagKeys(AGGREGATE_OP_INDEX); +export function isAggregateOp(a) { + return !!AGGREGATE_OP_INDEX[a]; +} +export var COUNTING_OPS = ['count', 'valid', 'missing', 'distinct']; +export function isCountingAggregateOp(aggregate) { + return aggregate && contains(COUNTING_OPS, aggregate); +} +/** Additive-based aggregation operations. These can be applied to stack. */ +export var SUM_OPS = [ + 'count', + 'sum', + 'distinct', + 'valid', + 'missing' +]; +/** + * Aggregation operators that always produce values within the range [domainMin, domainMax]. + */ +export var SHARED_DOMAIN_OPS = [ + 'mean', + 'average', + 'median', + 'q1', + 'q3', + 'min', + 'max', +]; +export var SHARED_DOMAIN_OP_INDEX = toSet(SHARED_DOMAIN_OPS); +//# sourceMappingURL=aggregate.js.map \ No newline at end of file diff --git a/build/src/aggregate.js.map b/build/src/aggregate.js.map new file mode 100644 index 0000000000..bea7236890 --- /dev/null +++ b/build/src/aggregate.js.map @@ -0,0 +1 @@ +{"version":3,"file":"aggregate.js","sourceRoot":"","sources":["../../src/aggregate.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,KAAK,EAAC,MAAM,WAAW,CAAC;AAChC,OAAO,EAAC,QAAQ,EAAQ,QAAQ,EAAC,MAAM,QAAQ,CAAC;AAEhD,IAAM,kBAAkB,GAAsB;IAC5C,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;IACX,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;IACN,OAAO,EAAE,CAAC;IACV,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;IACN,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,CAAC;IACX,SAAS,EAAE,CAAC;CACb,CAAC;AAEF,MAAM,CAAC,IAAM,aAAa,GAAG,QAAQ,CAAC,kBAAkB,CAAC,CAAC;AAE1D,MAAM,wBAAwB,CAAS;IACrC,OAAO,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,IAAM,YAAY,GAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAErF,MAAM,gCAAgC,SAAiB;IACrD,OAAO,SAAS,IAAI,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;AACxD,CAAC;AAED,6EAA6E;AAC7E,MAAM,CAAC,IAAM,OAAO,GAAkB;IAClC,OAAO;IACP,KAAK;IACL,UAAU;IACV,OAAO;IACP,SAAS;CACZ,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,IAAM,iBAAiB,GAAkB;IAC5C,MAAM;IACN,SAAS;IACT,QAAQ;IACR,IAAI;IACJ,IAAI;IACJ,KAAK;IACL,KAAK;CACR,CAAC;AAEF,MAAM,CAAC,IAAM,sBAAsB,GAAG,KAAK,CAAC,iBAAiB,CAAC,CAAC","sourcesContent":["import {AggregateOp} from 'vega';\nimport {toSet} from 'vega-util';\nimport {contains, Flag, flagKeys} from './util';\n\nconst AGGREGATE_OP_INDEX: Flag = {\n argmax: 1,\n argmin: 1,\n average: 1,\n count: 1,\n distinct: 1,\n max: 1,\n mean: 1,\n median: 1,\n min: 1,\n missing: 1,\n q1: 1,\n q3: 1,\n ci0: 1,\n ci1: 1,\n stderr: 1,\n stdev: 1,\n stdevp: 1,\n sum: 1,\n valid: 1,\n values: 1,\n variance: 1,\n variancep: 1,\n};\n\nexport const AGGREGATE_OPS = flagKeys(AGGREGATE_OP_INDEX);\n\nexport function isAggregateOp(a: string): a is AggregateOp {\n return !!AGGREGATE_OP_INDEX[a];\n}\n\nexport const COUNTING_OPS: AggregateOp[] = ['count', 'valid', 'missing', 'distinct'];\n\nexport function isCountingAggregateOp(aggregate: string): boolean {\n return aggregate && contains(COUNTING_OPS, aggregate);\n}\n\n/** Additive-based aggregation operations. These can be applied to stack. */\nexport const SUM_OPS: AggregateOp[] = [\n 'count',\n 'sum',\n 'distinct',\n 'valid',\n 'missing'\n];\n\n/**\n * Aggregation operators that always produce values within the range [domainMin, domainMax].\n */\nexport const SHARED_DOMAIN_OPS: AggregateOp[] = [\n 'mean',\n 'average',\n 'median',\n 'q1',\n 'q3',\n 'min',\n 'max',\n];\n\nexport const SHARED_DOMAIN_OP_INDEX = toSet(SHARED_DOMAIN_OPS);\n"]} \ No newline at end of file diff --git a/build/src/axis.d.ts b/build/src/axis.d.ts new file mode 100644 index 0000000000..21c34985ab --- /dev/null +++ b/build/src/axis.d.ts @@ -0,0 +1,134 @@ +import { DateTime } from './datetime'; +import { Guide, GuideEncodingEntry, VlOnlyGuideConfig } from './guide'; +import { AxisOrient, VgAxis, VgAxisBase, VgAxisConfig } from './vega.schema'; +export interface AxisConfig extends VgAxisConfig, VlOnlyGuideConfig { +} +export interface Axis extends VgAxisBase, Guide { + /** + * The orientation of the axis. One of `"top"`, `"bottom"`, `"left"` or `"right"`. The orientation can be used to further specialize the axis type (e.g., a y axis oriented for the right edge of the chart). + * + * __Default value:__ `"bottom"` for x-axes and `"left"` for y-axes. + */ + orient?: AxisOrient; + /** + * The offset, in pixels, by which to displace the axis from the edge of the enclosing group or data rectangle. + * + * __Default value:__ derived from the [axis config](https://vega.github.io/vega-lite/docs/config.html#facet-scale-config)'s `offset` (`0` by default) + */ + offset?: number; + /** + * The anchor position of the axis in pixels. For x-axis with top or bottom orientation, this sets the axis group x coordinate. For y-axis with left or right orientation, this sets the axis group y coordinate. + * + * __Default value__: `0` + */ + position?: number; + /** + * The rotation angle of the axis labels. + * + * __Default value:__ `-90` for nominal and ordinal fields; `0` otherwise. + * + * @minimum -360 + * @maximum 360 + */ + labelAngle?: number; + /** + * A desired number of ticks, for axes visualizing quantitative scales. The resulting number may be different so that values are "nice" (multiples of 2, 5, 10) and lie within the underlying scale's range. + * @minimum 0 + * + * __Default value__: Determine using a formula `ceil(width/40)` for x and `ceil(height/40)` for y. + */ + tickCount?: number; + /** + * Explicitly set the visible axis tick values. + */ + values?: number[] | string[] | boolean[] | DateTime[]; + /** + * A non-positive integer indicating z-index of the axis. + * If zindex is 0, axes should be drawn behind all chart elements. + * To put them in front, use `"zindex = 1"`. + * + * __Default value:__ `1` (in front of the marks) for actual axis and `0` (behind the marks) for grids. + * + * @TJS-type integer + * @minimum 0 + */ + zindex?: number; + /** + * Mark definitions for custom axis encoding. + * + * @hide + */ + encoding?: AxisEncoding; +} +export declare type AxisPart = keyof AxisEncoding; +export declare const AXIS_PARTS: AxisPart[]; +/** + * A dictionary listing whether a certain axis property is applicable for only main axes or only grid axes. + * (Properties not listed are applicable for both) + */ +export declare const AXIS_PROPERTY_TYPE: { + [k in keyof VgAxis]: 'main' | 'grid' | 'both'; +}; +export interface AxisEncoding { + /** + * Custom encoding for the axis container. + */ + axis?: GuideEncodingEntry; + /** + * Custom encoding for the axis domain rule mark. + */ + domain?: GuideEncodingEntry; + /** + * Custom encoding for axis gridline rule marks. + */ + grid?: GuideEncodingEntry; + /** + * Custom encoding for axis label text marks. + */ + labels?: GuideEncodingEntry; + /** + * Custom encoding for axis tick rule marks. + */ + ticks?: GuideEncodingEntry; + /** + * Custom encoding for the axis title text mark. + */ + title?: GuideEncodingEntry; +} +export declare function isAxisProperty(prop: string): prop is keyof Axis; +export declare const VG_AXIS_PROPERTIES: ("title" | "orient" | "scale" | "zindex" | "ticks" | "labels" | "labelBound" | "labelFlush" | "labelPadding" | "labelOverlap" | "domain" | "grid" | "gridScale" | "tickSize" | "tickCount" | "format" | "values" | "offset" | "position" | "titlePadding" | "minExtent" | "maxExtent" | "encode")[]; +export declare const AXIS_PROPERTIES: ("title" | "orient" | "zindex" | "ticks" | "labels" | "labelBound" | "labelFlush" | "labelPadding" | "labelOverlap" | "domain" | "grid" | "tickSize" | "tickCount" | "format" | "values" | "offset" | "position" | "titlePadding" | "minExtent" | "maxExtent" | "labelAngle" | "encoding" | "titleMaxLength")[]; +export interface AxisConfigMixins { + /** + * Axis configuration, which determines default properties for all `x` and `y` [axes](https://vega.github.io/vega-lite/docs/axis.html). For a full list of axis configuration options, please see the [corresponding section of the axis documentation](https://vega.github.io/vega-lite/docs/axis.html#config). + */ + axis?: AxisConfig; + /** + * X-axis specific config. + */ + axisX?: VgAxisConfig; + /** + * Y-axis specific config. + */ + axisY?: VgAxisConfig; + /** + * Specific axis config for y-axis along the left edge of the chart. + */ + axisLeft?: VgAxisConfig; + /** + * Specific axis config for y-axis along the right edge of the chart. + */ + axisRight?: VgAxisConfig; + /** + * Specific axis config for x-axis along the top edge of the chart. + */ + axisTop?: VgAxisConfig; + /** + * Specific axis config for x-axis along the bottom edge of the chart. + */ + axisBottom?: VgAxisConfig; + /** + * Specific axis config for axes with "band" scales. + */ + axisBand?: VgAxisConfig; +} diff --git a/build/src/axis.js b/build/src/axis.js new file mode 100644 index 0000000000..fca38fb63f --- /dev/null +++ b/build/src/axis.js @@ -0,0 +1,54 @@ +import * as tslib_1 from "tslib"; +import { flagKeys } from './util'; +export var AXIS_PARTS = ['domain', 'grid', 'labels', 'ticks', 'title']; +/** + * A dictionary listing whether a certain axis property is applicable for only main axes or only grid axes. + * (Properties not listed are applicable for both) + */ +export var AXIS_PROPERTY_TYPE = { + grid: 'grid', + gridScale: 'grid', + domain: 'main', + labels: 'main', + labelFlush: 'main', + labelOverlap: 'main', + minExtent: 'main', + maxExtent: 'main', + offset: 'main', + ticks: 'main', + title: 'main', + values: 'both', + scale: 'both', + zindex: 'both' // this is actually set afterward, so it doesn't matter +}; +var COMMON_AXIS_PROPERTIES_INDEX = { + orient: 1, + domain: 1, + format: 1, + grid: 1, + labelBound: 1, + labelFlush: 1, + labelPadding: 1, + labels: 1, + labelOverlap: 1, + maxExtent: 1, + minExtent: 1, + offset: 1, + position: 1, + tickCount: 1, + ticks: 1, + tickSize: 1, + title: 1, + titlePadding: 1, + values: 1, + zindex: 1, +}; +var AXIS_PROPERTIES_INDEX = tslib_1.__assign({}, COMMON_AXIS_PROPERTIES_INDEX, { encoding: 1, labelAngle: 1, titleMaxLength: 1 }); +var VG_AXIS_PROPERTIES_INDEX = tslib_1.__assign({ scale: 1 }, COMMON_AXIS_PROPERTIES_INDEX, { gridScale: 1, encode: 1 }); +export function isAxisProperty(prop) { + return !!AXIS_PROPERTIES_INDEX[prop]; +} +export var VG_AXIS_PROPERTIES = flagKeys(VG_AXIS_PROPERTIES_INDEX); +// Export for dependent projects +export var AXIS_PROPERTIES = flagKeys(AXIS_PROPERTIES_INDEX); +//# sourceMappingURL=axis.js.map \ No newline at end of file diff --git a/build/src/axis.js.map b/build/src/axis.js.map new file mode 100644 index 0000000000..0331e04f7b --- /dev/null +++ b/build/src/axis.js.map @@ -0,0 +1 @@ +{"version":3,"file":"axis.js","sourceRoot":"","sources":["../../src/axis.ts"],"names":[],"mappings":";AAEA,OAAO,EAAO,QAAQ,EAAC,MAAM,QAAQ,CAAC;AA2EtC,MAAM,CAAC,IAAM,UAAU,GAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAIrF;;;GAGG;AACH,MAAM,CAAC,IAAM,kBAAkB,GAG3B;IACF,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,MAAM;IAEjB,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,MAAM;IACd,UAAU,EAAE,MAAM;IAClB,YAAY,EAAE,MAAM;IACpB,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;IACjB,MAAM,EAAE,MAAM;IACd,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,MAAM;IAEd,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,MAAM,CAAC,uDAAuD;CACvE,CAAC;AAkCF,IAAM,4BAA4B,GAAgC;IAChE,MAAM,EAAE,CAAC;IAET,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,CAAC;IACb,YAAY,EAAE,CAAC;IACf,MAAM,EAAE,CAAC;IACT,YAAY,EAAE,CAAC;IACf,SAAS,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC;IACZ,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,CAAC;IACX,SAAS,EAAE,CAAC;IACZ,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;IACR,YAAY,EAAE,CAAC;IACf,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;CACV,CAAC;AAEF,IAAM,qBAAqB,wBACtB,4BAA4B,IAC/B,QAAQ,EAAE,CAAC,EACX,UAAU,EAAE,CAAC,EACb,cAAc,EAAE,CAAC,GAClB,CAAC;AAEF,IAAM,wBAAwB,sBAC5B,KAAK,EAAE,CAAC,IACL,4BAA4B,IAC/B,SAAS,EAAE,CAAC,EACZ,MAAM,EAAE,CAAC,GACV,CAAC;AAEF,MAAM,yBAAyB,IAAY;IACzC,OAAO,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,IAAM,kBAAkB,GAAG,QAAQ,CAAC,wBAAwB,CAAC,CAAC;AAErE,gCAAgC;AAChC,MAAM,CAAC,IAAM,eAAe,GAAG,QAAQ,CAAC,qBAAqB,CAAC,CAAC","sourcesContent":["import {DateTime} from './datetime';\nimport {Guide, GuideEncodingEntry, VlOnlyGuideConfig} from './guide';\nimport {Flag, flagKeys} from './util';\nimport {AxisOrient, VgAxis, VgAxisBase, VgAxisConfig} from './vega.schema';\n\n\n\nexport interface AxisConfig extends VgAxisConfig, VlOnlyGuideConfig {}\n\nexport interface Axis extends VgAxisBase, Guide {\n /**\n * The orientation of the axis. One of `\"top\"`, `\"bottom\"`, `\"left\"` or `\"right\"`. The orientation can be used to further specialize the axis type (e.g., a y axis oriented for the right edge of the chart).\n *\n * __Default value:__ `\"bottom\"` for x-axes and `\"left\"` for y-axes.\n */\n orient?: AxisOrient;\n\n /**\n * The offset, in pixels, by which to displace the axis from the edge of the enclosing group or data rectangle.\n *\n * __Default value:__ derived from the [axis config](https://vega.github.io/vega-lite/docs/config.html#facet-scale-config)'s `offset` (`0` by default)\n */\n offset?: number;\n\n /**\n * The anchor position of the axis in pixels. For x-axis with top or bottom orientation, this sets the axis group x coordinate. For y-axis with left or right orientation, this sets the axis group y coordinate.\n *\n * __Default value__: `0`\n */\n position?: number;\n\n\n /**\n * The rotation angle of the axis labels.\n *\n * __Default value:__ `-90` for nominal and ordinal fields; `0` otherwise.\n *\n * @minimum -360\n * @maximum 360\n */\n labelAngle?: number;\n\n /**\n * A desired number of ticks, for axes visualizing quantitative scales. The resulting number may be different so that values are \"nice\" (multiples of 2, 5, 10) and lie within the underlying scale's range.\n * @minimum 0\n *\n * __Default value__: Determine using a formula `ceil(width/40)` for x and `ceil(height/40)` for y.\n */\n tickCount?: number;\n\n /**\n * Explicitly set the visible axis tick values.\n */\n values?: number[] | string[] | boolean[] | DateTime[];\n\n /**\n * A non-positive integer indicating z-index of the axis.\n * If zindex is 0, axes should be drawn behind all chart elements.\n * To put them in front, use `\"zindex = 1\"`.\n *\n * __Default value:__ `1` (in front of the marks) for actual axis and `0` (behind the marks) for grids.\n *\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n\n /**\n * Mark definitions for custom axis encoding.\n *\n * @hide\n */\n encoding?: AxisEncoding;\n}\n\n\nexport type AxisPart = keyof AxisEncoding;\nexport const AXIS_PARTS: AxisPart[] = ['domain', 'grid', 'labels', 'ticks', 'title'];\n\n\n\n/**\n * A dictionary listing whether a certain axis property is applicable for only main axes or only grid axes.\n * (Properties not listed are applicable for both)\n */\nexport const AXIS_PROPERTY_TYPE: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in keyof VgAxis]: 'main' | 'grid' | 'both'\n} = {\n grid: 'grid',\n gridScale: 'grid',\n\n domain: 'main',\n labels: 'main',\n labelFlush: 'main',\n labelOverlap: 'main',\n minExtent: 'main',\n maxExtent: 'main',\n offset: 'main',\n ticks: 'main',\n title: 'main',\n values: 'both',\n\n scale: 'both',\n zindex: 'both' // this is actually set afterward, so it doesn't matter\n};\n\nexport interface AxisEncoding {\n /**\n * Custom encoding for the axis container.\n */\n axis?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the axis domain rule mark.\n */\n domain?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis gridline rule marks.\n */\n grid?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis label text marks.\n */\n labels?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis tick rule marks.\n */\n ticks?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the axis title text mark.\n */\n title?: GuideEncodingEntry;\n}\n\nconst COMMON_AXIS_PROPERTIES_INDEX: Flag = {\n orient: 1, // other things can depend on orient\n\n domain: 1,\n format: 1,\n grid: 1,\n labelBound: 1,\n labelFlush: 1,\n labelPadding: 1,\n labels: 1,\n labelOverlap: 1,\n maxExtent: 1,\n minExtent: 1,\n offset: 1,\n position: 1,\n tickCount: 1,\n ticks: 1,\n tickSize: 1,\n title: 1,\n titlePadding: 1,\n values: 1,\n zindex: 1,\n};\n\nconst AXIS_PROPERTIES_INDEX: Flag = {\n ...COMMON_AXIS_PROPERTIES_INDEX,\n encoding: 1,\n labelAngle: 1,\n titleMaxLength: 1\n};\n\nconst VG_AXIS_PROPERTIES_INDEX: Flag = {\n scale: 1,\n ...COMMON_AXIS_PROPERTIES_INDEX,\n gridScale: 1,\n encode: 1\n};\n\nexport function isAxisProperty(prop: string): prop is keyof Axis {\n return !!AXIS_PROPERTIES_INDEX[prop];\n}\n\nexport const VG_AXIS_PROPERTIES = flagKeys(VG_AXIS_PROPERTIES_INDEX);\n\n// Export for dependent projects\nexport const AXIS_PROPERTIES = flagKeys(AXIS_PROPERTIES_INDEX);\n\nexport interface AxisConfigMixins {\n /**\n * Axis configuration, which determines default properties for all `x` and `y` [axes](https://vega.github.io/vega-lite/docs/axis.html). For a full list of axis configuration options, please see the [corresponding section of the axis documentation](https://vega.github.io/vega-lite/docs/axis.html#config).\n */\n axis?: AxisConfig;\n\n /**\n * X-axis specific config.\n */\n axisX?: VgAxisConfig;\n\n /**\n * Y-axis specific config.\n */\n axisY?: VgAxisConfig;\n\n /**\n * Specific axis config for y-axis along the left edge of the chart.\n */\n axisLeft?: VgAxisConfig;\n\n /**\n * Specific axis config for y-axis along the right edge of the chart.\n */\n axisRight?: VgAxisConfig;\n\n /**\n * Specific axis config for x-axis along the top edge of the chart.\n */\n axisTop?: VgAxisConfig;\n\n /**\n * Specific axis config for x-axis along the bottom edge of the chart.\n */\n axisBottom?: VgAxisConfig;\n\n /**\n * Specific axis config for axes with \"band\" scales.\n */\n axisBand?: VgAxisConfig;\n}\n"]} \ No newline at end of file diff --git a/build/src/bin.d.ts b/build/src/bin.d.ts new file mode 100644 index 0000000000..690b5f3d3e --- /dev/null +++ b/build/src/bin.d.ts @@ -0,0 +1,65 @@ +import { Channel } from './channel'; +export interface BaseBin { + /** + * The number base to use for automatic bin determination (default is base 10). + * + * __Default value:__ `10` + * + */ + base?: number; + /** + * An exact step size to use between bins. + * + * __Note:__ If provided, options such as maxbins will be ignored. + */ + step?: number; + /** + * An array of allowable step sizes to choose from. + * @minItems 1 + */ + steps?: number[]; + /** + * A minimum allowable step size (particularly useful for integer values). + */ + minstep?: number; + /** + * Scale factors indicating allowable subdivisions. The default value is [5, 2], which indicates that for base 10 numbers (the default base), the method may consider dividing bin sizes by 5 and/or 2. For example, for an initial step size of 10, the method can check if bin sizes of 2 (= 10/5), 5 (= 10/2), or 1 (= 10/(5*2)) might also satisfy the given constraints. + * + * __Default value:__ `[5, 2]` + * + * @minItems 1 + */ + divide?: number[]; + /** + * Maximum number of bins. + * + * __Default value:__ `6` for `row`, `column` and `shape` channels; `10` for other channels + * + * @minimum 2 + */ + maxbins?: number; + /** + * A value in the binned domain at which to anchor the bins, shifting the bin boundaries if necessary to ensure that a boundary aligns with the anchor value. + * + * __Default Value:__ the minimum bin extent value + */ + anchor?: number; + /** + * If true (the default), attempts to make the bin boundaries use human-friendly boundaries, such as multiples of ten. + */ + nice?: boolean; +} +/** + * Binning properties or boolean flag for determining whether to bin data or not. + */ +export interface BinParams extends BaseBin { + /** + * A two-element (`[min, max]`) array indicating the range of desired bin values. + * @minItems 2 + * @maxItems 2 + */ + extent?: number[]; +} +export declare function binToString(bin: BinParams | boolean): string; +export declare function isBinParams(bin: BinParams | boolean): bin is BinParams; +export declare function autoMaxBins(channel: Channel): number; diff --git a/build/src/bin.js b/build/src/bin.js new file mode 100644 index 0000000000..28bf6fe82a --- /dev/null +++ b/build/src/bin.js @@ -0,0 +1,30 @@ +import { isBoolean } from 'vega-util'; +import { COLOR, COLUMN, FILL, OPACITY, ROW, SHAPE, SIZE, STROKE } from './channel'; +import { keys, varName } from './util'; +export function binToString(bin) { + if (isBoolean(bin)) { + return 'bin'; + } + return 'bin' + keys(bin).map(function (p) { return varName("_" + p + "_" + bin[p]); }).join(''); +} +export function isBinParams(bin) { + return bin && !isBoolean(bin); +} +export function autoMaxBins(channel) { + switch (channel) { + case ROW: + case COLUMN: + case SIZE: + case COLOR: + case FILL: + case STROKE: + case OPACITY: + // Facets and Size shouldn't have too many bins + // We choose 6 like shape to simplify the rule + case SHAPE: + return 6; // Vega's "shape" has 6 distinct values + default: + return 10; + } +} +//# sourceMappingURL=bin.js.map \ No newline at end of file diff --git a/build/src/bin.js.map b/build/src/bin.js.map new file mode 100644 index 0000000000..51feb4bbb7 --- /dev/null +++ b/build/src/bin.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/bin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAAU,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAC,MAAM,WAAW,CAAC;AAC1F,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,MAAM,QAAQ,CAAC;AAmErC,MAAM,sBAAsB,GAAwB;IAClD,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;QAClB,OAAO,KAAK,CAAC;KACd;IACD,OAAO,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,OAAO,CAAC,MAAI,CAAC,SAAI,GAAG,CAAC,CAAC,CAAG,CAAC,EAA1B,CAA0B,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,sBAAsB,GAAwB;IAClD,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,sBAAsB,OAAgB;IAC1C,QAAQ,OAAO,EAAE;QACf,KAAK,GAAG,CAAC;QACT,KAAK,MAAM,CAAC;QACZ,KAAK,IAAI,CAAC;QACV,KAAK,KAAK,CAAC;QACX,KAAK,IAAI,CAAC;QACV,KAAK,MAAM,CAAC;QACZ,KAAK,OAAO,CAAC;QACX,+CAA+C;QAC/C,8CAA8C;QAChD,KAAK,KAAK;YACR,OAAO,CAAC,CAAC,CAAC,uCAAuC;QACnD;YACE,OAAO,EAAE,CAAC;KACb;AACH,CAAC","sourcesContent":["import {isBoolean} from 'vega-util';\nimport {Channel, COLOR, COLUMN, FILL, OPACITY, ROW, SHAPE, SIZE, STROKE} from './channel';\nimport {keys, varName} from './util';\n\n\nexport interface BaseBin {\n /**\n * The number base to use for automatic bin determination (default is base 10).\n *\n * __Default value:__ `10`\n *\n */\n base?: number;\n /**\n * An exact step size to use between bins.\n *\n * __Note:__ If provided, options such as maxbins will be ignored.\n */\n step?: number;\n /**\n * An array of allowable step sizes to choose from.\n * @minItems 1\n */\n steps?: number[];\n /**\n * A minimum allowable step size (particularly useful for integer values).\n */\n minstep?: number;\n /**\n * Scale factors indicating allowable subdivisions. The default value is [5, 2], which indicates that for base 10 numbers (the default base), the method may consider dividing bin sizes by 5 and/or 2. For example, for an initial step size of 10, the method can check if bin sizes of 2 (= 10/5), 5 (= 10/2), or 1 (= 10/(5*2)) might also satisfy the given constraints.\n *\n * __Default value:__ `[5, 2]`\n *\n * @minItems 1\n */\n divide?: number[];\n /**\n * Maximum number of bins.\n *\n * __Default value:__ `6` for `row`, `column` and `shape` channels; `10` for other channels\n *\n * @minimum 2\n */\n maxbins?: number;\n /**\n * A value in the binned domain at which to anchor the bins, shifting the bin boundaries if necessary to ensure that a boundary aligns with the anchor value.\n *\n * __Default Value:__ the minimum bin extent value\n */\n anchor?: number;\n /**\n * If true (the default), attempts to make the bin boundaries use human-friendly boundaries, such as multiples of ten.\n */\n nice?: boolean;\n}\n\n\n/**\n * Binning properties or boolean flag for determining whether to bin data or not.\n */\nexport interface BinParams extends BaseBin {\n /**\n * A two-element (`[min, max]`) array indicating the range of desired bin values.\n * @minItems 2\n * @maxItems 2\n */\n extent?: number[]; // VgBinTransform uses a different extent so we need to pull this out.\n}\n\nexport function binToString(bin: BinParams | boolean) {\n if (isBoolean(bin)) {\n return 'bin';\n }\n return 'bin' + keys(bin).map(p => varName(`_${p}_${bin[p]}`)).join('');\n}\n\nexport function isBinParams(bin: BinParams | boolean): bin is BinParams {\n return bin && !isBoolean(bin);\n}\n\nexport function autoMaxBins(channel: Channel): number {\n switch (channel) {\n case ROW:\n case COLUMN:\n case SIZE:\n case COLOR:\n case FILL:\n case STROKE:\n case OPACITY:\n // Facets and Size shouldn't have too many bins\n // We choose 6 like shape to simplify the rule\n case SHAPE:\n return 6; // Vega's \"shape\" has 6 distinct values\n default:\n return 10;\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/channel.d.ts b/build/src/channel.d.ts new file mode 100644 index 0000000000..8074501ba1 --- /dev/null +++ b/build/src/channel.d.ts @@ -0,0 +1,97 @@ +import { RangeType } from './compile/scale/type'; +import { Encoding } from './encoding'; +import { FacetMapping } from './facet'; +import { Mark } from './mark'; +import { Flag } from './util'; +export declare namespace Channel { + const ROW: 'row'; + const COLUMN: 'column'; + const X: 'x'; + const Y: 'y'; + const X2: 'x2'; + const Y2: 'y2'; + const LATITUDE: 'latitude'; + const LONGITUDE: 'longitude'; + const LATITUDE2: 'latitude2'; + const LONGITUDE2: 'longitude2'; + const COLOR: 'color'; + const FILL: 'fill'; + const STROKE: 'stroke'; + const SHAPE: 'shape'; + const SIZE: 'size'; + const OPACITY: 'opacity'; + const TEXT: 'text'; + const ORDER: 'order'; + const DETAIL: 'detail'; + const KEY: 'key'; + const TOOLTIP: 'tooltip'; + const HREF: 'href'; +} +export declare type Channel = keyof Encoding | keyof FacetMapping; +export declare const X: "x"; +export declare const Y: "y"; +export declare const X2: "x2"; +export declare const Y2: "y2"; +export declare const LATITUDE: "latitude"; +export declare const LATITUDE2: "latitude2"; +export declare const LONGITUDE: "longitude"; +export declare const LONGITUDE2: "longitude2"; +export declare const ROW: "row"; +export declare const COLUMN: "column"; +export declare const SHAPE: "shape"; +export declare const SIZE: "size"; +export declare const COLOR: "color"; +export declare const FILL: "fill"; +export declare const STROKE: "stroke"; +export declare const TEXT: "text"; +export declare const DETAIL: "detail"; +export declare const KEY: "key"; +export declare const ORDER: "order"; +export declare const OPACITY: "opacity"; +export declare const TOOLTIP: "tooltip"; +export declare const HREF: "href"; +export declare type GeoPositionChannel = 'longitude' | 'latitude' | 'longitude2' | 'latitude2'; +export declare const GEOPOSITION_CHANNEL_INDEX: Flag; +export declare const GEOPOSITION_CHANNELS: GeoPositionChannel[]; +export declare type ColorChannel = 'color' | 'fill' | 'stroke'; +export declare function isColorChannel(channel: Channel): channel is ColorChannel; +export declare const CHANNELS: Channel[]; +/** + * Channels that cannot have an array of channelDef. + * model.fieldDef, getFieldDef only work for these channels. + * + * (The only two channels that can have an array of channelDefs are "detail" and "order". + * Since there can be multiple fieldDefs for detail and order, getFieldDef/model.fieldDef + * are not applicable for them. Similarly, selection projection won't work with "detail" and "order".) + */ +export declare const SINGLE_DEF_CHANNELS: SingleDefChannel[]; +export declare type SingleDefChannel = 'x' | 'y' | 'x2' | 'y2' | 'longitude' | 'latitude' | 'longitude2' | 'latitude2' | 'row' | 'column' | 'color' | 'fill' | 'stroke' | 'size' | 'shape' | 'opacity' | 'text' | 'tooltip' | 'href' | 'key'; +export declare function isChannel(str: string): str is Channel; +export declare const UNIT_CHANNELS: ("text" | "shape" | "x" | "y" | "x2" | "y2" | "longitude" | "latitude" | "longitude2" | "latitude2" | "color" | "fill" | "stroke" | "opacity" | "size" | "detail" | "key" | "tooltip" | "href" | "order")[]; +export declare const NONPOSITION_CHANNELS: ("text" | "shape" | "color" | "fill" | "stroke" | "opacity" | "size" | "detail" | "key" | "tooltip" | "href" | "order")[]; +export declare type NonPositionChannel = typeof NONPOSITION_CHANNELS[0]; +export declare const POSITION_SCALE_CHANNELS: ("x" | "y")[]; +export declare type PositionScaleChannel = typeof POSITION_SCALE_CHANNELS[0]; +export declare const NONPOSITION_SCALE_CHANNELS: ("shape" | "color" | "fill" | "stroke" | "opacity" | "size")[]; +export declare type NonPositionScaleChannel = typeof NONPOSITION_SCALE_CHANNELS[0]; +/** List of channels with scales */ +export declare const SCALE_CHANNELS: ("shape" | "x" | "y" | "color" | "fill" | "stroke" | "opacity" | "size")[]; +export declare type ScaleChannel = typeof SCALE_CHANNELS[0]; +export declare function isScaleChannel(channel: Channel): channel is ScaleChannel; +export declare type SupportedMark = { + [mark in Mark]?: boolean; +}; +/** + * Return whether a channel supports a particular mark type. + * @param channel channel name + * @param mark the mark type + * @return whether the mark supports the channel + */ +export declare function supportMark(channel: Channel, mark: Mark): boolean; +/** + * Return a dictionary showing whether a channel supports mark type. + * @param channel + * @return A dictionary mapping mark types to boolean values. + */ +export declare function getSupportedMark(channel: Channel): SupportedMark; +export declare function rangeType(channel: Channel): RangeType; diff --git a/build/src/channel.js b/build/src/channel.js new file mode 100644 index 0000000000..11c100c783 --- /dev/null +++ b/build/src/channel.js @@ -0,0 +1,218 @@ +/* + * Constants and utilities for encoding channels (Visual variables) + * such as 'x', 'y', 'color'. + */ +import * as tslib_1 from "tslib"; +import { flagKeys } from './util'; +export var Channel; +(function (Channel) { + // Facet + Channel.ROW = 'row'; + Channel.COLUMN = 'column'; + // Position + Channel.X = 'x'; + Channel.Y = 'y'; + Channel.X2 = 'x2'; + Channel.Y2 = 'y2'; + // Geo Position + Channel.LATITUDE = 'latitude'; + Channel.LONGITUDE = 'longitude'; + Channel.LATITUDE2 = 'latitude2'; + Channel.LONGITUDE2 = 'longitude2'; + // Mark property with scale + Channel.COLOR = 'color'; + Channel.FILL = 'fill'; + Channel.STROKE = 'stroke'; + Channel.SHAPE = 'shape'; + Channel.SIZE = 'size'; + Channel.OPACITY = 'opacity'; + // Non-scale channel + Channel.TEXT = 'text'; + Channel.ORDER = 'order'; + Channel.DETAIL = 'detail'; + Channel.KEY = 'key'; + Channel.TOOLTIP = 'tooltip'; + Channel.HREF = 'href'; +})(Channel || (Channel = {})); +export var X = Channel.X; +export var Y = Channel.Y; +export var X2 = Channel.X2; +export var Y2 = Channel.Y2; +export var LATITUDE = Channel.LATITUDE; +export var LATITUDE2 = Channel.LATITUDE2; +export var LONGITUDE = Channel.LONGITUDE; +export var LONGITUDE2 = Channel.LONGITUDE2; +export var ROW = Channel.ROW; +export var COLUMN = Channel.COLUMN; +export var SHAPE = Channel.SHAPE; +export var SIZE = Channel.SIZE; +export var COLOR = Channel.COLOR; +export var FILL = Channel.FILL; +export var STROKE = Channel.STROKE; +export var TEXT = Channel.TEXT; +export var DETAIL = Channel.DETAIL; +export var KEY = Channel.KEY; +export var ORDER = Channel.ORDER; +export var OPACITY = Channel.OPACITY; +export var TOOLTIP = Channel.TOOLTIP; +export var HREF = Channel.HREF; +export var GEOPOSITION_CHANNEL_INDEX = { + longitude: 1, + longitude2: 1, + latitude: 1, + latitude2: 1, +}; +export var GEOPOSITION_CHANNELS = flagKeys(GEOPOSITION_CHANNEL_INDEX); +var UNIT_CHANNEL_INDEX = tslib_1.__assign({ + // position + x: 1, y: 1, x2: 1, y2: 1 }, GEOPOSITION_CHANNEL_INDEX, { + // color + color: 1, fill: 1, stroke: 1, + // other non-position with scale + opacity: 1, size: 1, shape: 1, + // channels without scales + order: 1, text: 1, detail: 1, key: 1, tooltip: 1, href: 1 }); +export function isColorChannel(channel) { + return channel === 'color' || channel === 'fill' || channel === 'stroke'; +} +var FACET_CHANNEL_INDEX = { + row: 1, + column: 1 +}; +var CHANNEL_INDEX = tslib_1.__assign({}, UNIT_CHANNEL_INDEX, FACET_CHANNEL_INDEX); +export var CHANNELS = flagKeys(CHANNEL_INDEX); +var _o = CHANNEL_INDEX.order, _d = CHANNEL_INDEX.detail, SINGLE_DEF_CHANNEL_INDEX = tslib_1.__rest(CHANNEL_INDEX, ["order", "detail"]); +/** + * Channels that cannot have an array of channelDef. + * model.fieldDef, getFieldDef only work for these channels. + * + * (The only two channels that can have an array of channelDefs are "detail" and "order". + * Since there can be multiple fieldDefs for detail and order, getFieldDef/model.fieldDef + * are not applicable for them. Similarly, selection projection won't work with "detail" and "order".) + */ +export var SINGLE_DEF_CHANNELS = flagKeys(SINGLE_DEF_CHANNEL_INDEX); +export function isChannel(str) { + return !!CHANNEL_INDEX[str]; +} +// CHANNELS without COLUMN, ROW +export var UNIT_CHANNELS = flagKeys(UNIT_CHANNEL_INDEX); +// NONPOSITION_CHANNELS = UNIT_CHANNELS without X, Y, X2, Y2; +var _x = UNIT_CHANNEL_INDEX.x, _y = UNIT_CHANNEL_INDEX.y, +// x2 and y2 share the same scale as x and y +_x2 = UNIT_CHANNEL_INDEX.x2, _y2 = UNIT_CHANNEL_INDEX.y2, _latitude = UNIT_CHANNEL_INDEX.latitude, _longitude = UNIT_CHANNEL_INDEX.longitude, _latitude2 = UNIT_CHANNEL_INDEX.latitude2, _longitude2 = UNIT_CHANNEL_INDEX.longitude2, +// The rest of unit channels then have scale +NONPOSITION_CHANNEL_INDEX = tslib_1.__rest(UNIT_CHANNEL_INDEX, ["x", "y", "x2", "y2", "latitude", "longitude", "latitude2", "longitude2"]); +export var NONPOSITION_CHANNELS = flagKeys(NONPOSITION_CHANNEL_INDEX); +// POSITION_SCALE_CHANNELS = X and Y; +var POSITION_SCALE_CHANNEL_INDEX = { x: 1, y: 1 }; +export var POSITION_SCALE_CHANNELS = flagKeys(POSITION_SCALE_CHANNEL_INDEX); +// NON_POSITION_SCALE_CHANNEL = SCALE_CHANNELS without X, Y +var +// x2 and y2 share the same scale as x and y +// text and tooltip have format instead of scale, +// href has neither format, nor scale +_t = NONPOSITION_CHANNEL_INDEX.text, _tt = NONPOSITION_CHANNEL_INDEX.tooltip, _hr = NONPOSITION_CHANNEL_INDEX.href, +// detail and order have no scale +_dd = NONPOSITION_CHANNEL_INDEX.detail, _k = NONPOSITION_CHANNEL_INDEX.key, _oo = NONPOSITION_CHANNEL_INDEX.order, NONPOSITION_SCALE_CHANNEL_INDEX = tslib_1.__rest(NONPOSITION_CHANNEL_INDEX, ["text", "tooltip", "href", "detail", "key", "order"]); +export var NONPOSITION_SCALE_CHANNELS = flagKeys(NONPOSITION_SCALE_CHANNEL_INDEX); +// Declare SCALE_CHANNEL_INDEX +var SCALE_CHANNEL_INDEX = tslib_1.__assign({}, POSITION_SCALE_CHANNEL_INDEX, NONPOSITION_SCALE_CHANNEL_INDEX); +/** List of channels with scales */ +export var SCALE_CHANNELS = flagKeys(SCALE_CHANNEL_INDEX); +export function isScaleChannel(channel) { + return !!SCALE_CHANNEL_INDEX[channel]; +} +/** + * Return whether a channel supports a particular mark type. + * @param channel channel name + * @param mark the mark type + * @return whether the mark supports the channel + */ +export function supportMark(channel, mark) { + return mark in getSupportedMark(channel); +} +/** + * Return a dictionary showing whether a channel supports mark type. + * @param channel + * @return A dictionary mapping mark types to boolean values. + */ +export function getSupportedMark(channel) { + switch (channel) { + case COLOR: + case FILL: + case STROKE: + case DETAIL: + case KEY: + case TOOLTIP: + case HREF: + case ORDER: // TODO: revise (order might not support rect, which is not stackable?) + case OPACITY: + case ROW: + case COLUMN: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, rect: true, line: true, trail: true, area: true, text: true, geoshape: true + }; + case X: + case Y: + case LATITUDE: + case LONGITUDE: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, rect: true, line: true, trail: true, area: true, text: true + }; + case X2: + case Y2: + case LATITUDE2: + case LONGITUDE2: + return { + rule: true, bar: true, rect: true, area: true + }; + case SIZE: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, text: true, line: true, trail: true + }; + case SHAPE: + return { point: true, geoshape: true }; + case TEXT: + return { text: true }; + } +} +export function rangeType(channel) { + switch (channel) { + case X: + case Y: + case SIZE: + case OPACITY: + // X2 and Y2 use X and Y scales, so they similarly have continuous range. + case X2: + case Y2: + return 'continuous'; + case ROW: + case COLUMN: + case SHAPE: + // TEXT, TOOLTIP, and HREF have no scale but have discrete output + case TEXT: + case TOOLTIP: + case HREF: + return 'discrete'; + // Color can be either continuous or discrete, depending on scale type. + case COLOR: + case FILL: + case STROKE: + return 'flexible'; + // No scale, no range type. + case LATITUDE: + case LONGITUDE: + case LATITUDE2: + case LONGITUDE2: + case DETAIL: + case KEY: + case ORDER: + return undefined; + } + /* istanbul ignore next: should never reach here. */ + throw new Error('rangeType not implemented for ' + channel); +} +//# sourceMappingURL=channel.js.map \ No newline at end of file diff --git a/build/src/channel.js.map b/build/src/channel.js.map new file mode 100644 index 0000000000..2281b2d9a3 --- /dev/null +++ b/build/src/channel.js.map @@ -0,0 +1 @@ +{"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/channel.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Constants and utilities for encoding channels (Visual variables)\n * such as 'x', 'y', 'color'.\n */\n\nimport {RangeType} from './compile/scale/type';\nimport {Encoding} from './encoding';\nimport {FacetMapping} from './facet';\nimport {Mark} from './mark';\nimport {Flag, flagKeys} from './util';\n\nexport namespace Channel {\n // Facet\n export const ROW: 'row' = 'row';\n export const COLUMN: 'column' = 'column';\n\n // Position\n export const X: 'x' = 'x';\n export const Y: 'y' = 'y';\n export const X2: 'x2' = 'x2';\n export const Y2: 'y2' = 'y2';\n\n // Geo Position\n export const LATITUDE: 'latitude' = 'latitude';\n export const LONGITUDE: 'longitude' = 'longitude';\n export const LATITUDE2: 'latitude2' = 'latitude2';\n export const LONGITUDE2: 'longitude2' = 'longitude2';\n\n // Mark property with scale\n export const COLOR: 'color' = 'color';\n\n export const FILL: 'fill' = 'fill';\n\n export const STROKE: 'stroke' = 'stroke';\n\n export const SHAPE: 'shape' = 'shape';\n export const SIZE: 'size' = 'size';\n export const OPACITY: 'opacity' = 'opacity';\n\n // Non-scale channel\n export const TEXT: 'text' = 'text';\n export const ORDER: 'order' = 'order';\n export const DETAIL: 'detail' = 'detail';\n export const KEY: 'key' = 'key';\n\n export const TOOLTIP: 'tooltip' = 'tooltip';\n export const HREF: 'href' = 'href';\n}\n\nexport type Channel = keyof Encoding | keyof FacetMapping;\n\nexport const X = Channel.X;\nexport const Y = Channel.Y;\nexport const X2 = Channel.X2;\nexport const Y2 = Channel.Y2;\n\nexport const LATITUDE = Channel.LATITUDE;\nexport const LATITUDE2 = Channel.LATITUDE2;\nexport const LONGITUDE = Channel.LONGITUDE;\nexport const LONGITUDE2 = Channel.LONGITUDE2;\n\nexport const ROW = Channel.ROW;\nexport const COLUMN = Channel.COLUMN;\nexport const SHAPE = Channel.SHAPE;\nexport const SIZE = Channel.SIZE;\nexport const COLOR = Channel.COLOR;\n\nexport const FILL = Channel.FILL;\nexport const STROKE = Channel.STROKE;\nexport const TEXT = Channel.TEXT;\nexport const DETAIL = Channel.DETAIL;\nexport const KEY = Channel.KEY;\nexport const ORDER = Channel.ORDER;\nexport const OPACITY = Channel.OPACITY;\nexport const TOOLTIP = Channel.TOOLTIP;\nexport const HREF = Channel.HREF;\n\nexport type GeoPositionChannel = 'longitude' | 'latitude' | 'longitude2' | 'latitude2';\n\nexport const GEOPOSITION_CHANNEL_INDEX: Flag = {\n longitude: 1,\n longitude2: 1,\n latitude: 1,\n latitude2: 1,\n};\n\nexport const GEOPOSITION_CHANNELS = flagKeys(GEOPOSITION_CHANNEL_INDEX);\n\nconst UNIT_CHANNEL_INDEX: Flag> = {\n // position\n x: 1,\n y: 1,\n x2: 1,\n y2: 1,\n\n ...GEOPOSITION_CHANNEL_INDEX,\n\n // color\n color: 1,\n fill: 1,\n stroke: 1,\n\n // other non-position with scale\n opacity: 1,\n size: 1,\n shape: 1,\n\n // channels without scales\n order: 1,\n text: 1,\n detail: 1,\n key: 1,\n tooltip: 1,\n href: 1,\n};\n\nexport type ColorChannel = 'color' | 'fill' | 'stroke';\n\nexport function isColorChannel(channel: Channel): channel is ColorChannel {\n return channel === 'color' || channel === 'fill' || channel === 'stroke';\n}\n\nconst FACET_CHANNEL_INDEX: Flag> = {\n row: 1,\n column: 1\n};\n\nconst CHANNEL_INDEX = {\n ...UNIT_CHANNEL_INDEX,\n ...FACET_CHANNEL_INDEX\n};\n\nexport const CHANNELS = flagKeys(CHANNEL_INDEX);\n\nconst {order: _o, detail: _d, ...SINGLE_DEF_CHANNEL_INDEX} = CHANNEL_INDEX;\n/**\n * Channels that cannot have an array of channelDef.\n * model.fieldDef, getFieldDef only work for these channels.\n *\n * (The only two channels that can have an array of channelDefs are \"detail\" and \"order\".\n * Since there can be multiple fieldDefs for detail and order, getFieldDef/model.fieldDef\n * are not applicable for them. Similarly, selection projection won't work with \"detail\" and \"order\".)\n */\n\nexport const SINGLE_DEF_CHANNELS: SingleDefChannel[] = flagKeys(SINGLE_DEF_CHANNEL_INDEX);\n\n// Using the following line leads to TypeError: Cannot read property 'elementTypes' of undefined\n// when running the schema generator\n// export type SingleDefChannel = typeof SINGLE_DEF_CHANNELS[0];\nexport type SingleDefChannel = 'x' | 'y' | 'x2' | 'y2' |\n 'longitude' | 'latitude' | 'longitude2' | 'latitude2' |\n 'row' | 'column' |\n 'color' | 'fill' | 'stroke' |\n 'size' | 'shape' | 'opacity' |\n 'text' | 'tooltip' | 'href' | 'key';\n\nexport function isChannel(str: string): str is Channel {\n return !!CHANNEL_INDEX[str];\n}\n\n// CHANNELS without COLUMN, ROW\nexport const UNIT_CHANNELS = flagKeys(UNIT_CHANNEL_INDEX);\n\n\n// NONPOSITION_CHANNELS = UNIT_CHANNELS without X, Y, X2, Y2;\nconst {\n x: _x, y: _y,\n // x2 and y2 share the same scale as x and y\n x2: _x2, y2: _y2,\n latitude: _latitude, longitude: _longitude,\n latitude2: _latitude2, longitude2: _longitude2,\n // The rest of unit channels then have scale\n ...NONPOSITION_CHANNEL_INDEX\n} = UNIT_CHANNEL_INDEX;\n\nexport const NONPOSITION_CHANNELS = flagKeys(NONPOSITION_CHANNEL_INDEX);\nexport type NonPositionChannel = typeof NONPOSITION_CHANNELS[0];\n\n// POSITION_SCALE_CHANNELS = X and Y;\nconst POSITION_SCALE_CHANNEL_INDEX: {x:1, y:1} = {x:1, y:1};\nexport const POSITION_SCALE_CHANNELS = flagKeys(POSITION_SCALE_CHANNEL_INDEX);\nexport type PositionScaleChannel = typeof POSITION_SCALE_CHANNELS[0];\n\n// NON_POSITION_SCALE_CHANNEL = SCALE_CHANNELS without X, Y\nconst {\n // x2 and y2 share the same scale as x and y\n // text and tooltip have format instead of scale,\n // href has neither format, nor scale\n text: _t, tooltip: _tt, href: _hr,\n // detail and order have no scale\n detail: _dd, key: _k, order: _oo,\n ...NONPOSITION_SCALE_CHANNEL_INDEX\n} = NONPOSITION_CHANNEL_INDEX;\nexport const NONPOSITION_SCALE_CHANNELS = flagKeys(NONPOSITION_SCALE_CHANNEL_INDEX);\nexport type NonPositionScaleChannel = typeof NONPOSITION_SCALE_CHANNELS[0];\n\n// Declare SCALE_CHANNEL_INDEX\nconst SCALE_CHANNEL_INDEX = {\n ...POSITION_SCALE_CHANNEL_INDEX,\n ...NONPOSITION_SCALE_CHANNEL_INDEX\n};\n\n/** List of channels with scales */\nexport const SCALE_CHANNELS = flagKeys(SCALE_CHANNEL_INDEX);\nexport type ScaleChannel = typeof SCALE_CHANNELS[0];\n\nexport function isScaleChannel(channel: Channel): channel is ScaleChannel {\n return !!SCALE_CHANNEL_INDEX[channel];\n}\n\nexport type SupportedMark = {\n [mark in Mark]?: boolean\n};\n\n/**\n * Return whether a channel supports a particular mark type.\n * @param channel channel name\n * @param mark the mark type\n * @return whether the mark supports the channel\n */\nexport function supportMark(channel: Channel, mark: Mark) {\n return mark in getSupportedMark(channel);\n}\n\n/**\n * Return a dictionary showing whether a channel supports mark type.\n * @param channel\n * @return A dictionary mapping mark types to boolean values.\n */\nexport function getSupportedMark(channel: Channel): SupportedMark {\n switch (channel) {\n case COLOR:\n case FILL:\n case STROKE:\n\n case DETAIL:\n case KEY:\n case TOOLTIP:\n case HREF:\n case ORDER: // TODO: revise (order might not support rect, which is not stackable?)\n case OPACITY:\n case ROW:\n case COLUMN:\n return { // all marks\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, rect: true, line: true, trail: true, area: true, text: true, geoshape: true\n };\n case X:\n case Y:\n case LATITUDE:\n case LONGITUDE:\n return { // all marks except geoshape. geoshape does not use X, Y -- it uses a projection\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, rect: true, line: true, trail: true, area: true, text: true\n };\n case X2:\n case Y2:\n case LATITUDE2:\n case LONGITUDE2:\n return {\n rule: true, bar: true, rect: true, area: true\n };\n case SIZE:\n return {\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, text: true, line: true, trail: true\n };\n case SHAPE:\n return {point: true, geoshape: true};\n case TEXT:\n return {text: true};\n }\n}\n\nexport function rangeType(channel: Channel): RangeType {\n switch (channel) {\n case X:\n case Y:\n case SIZE:\n case OPACITY:\n // X2 and Y2 use X and Y scales, so they similarly have continuous range.\n case X2:\n case Y2:\n return 'continuous';\n\n case ROW:\n case COLUMN:\n case SHAPE:\n // TEXT, TOOLTIP, and HREF have no scale but have discrete output\n case TEXT:\n case TOOLTIP:\n case HREF:\n return 'discrete';\n\n // Color can be either continuous or discrete, depending on scale type.\n case COLOR:\n case FILL:\n case STROKE:\n return 'flexible';\n\n // No scale, no range type.\n\n case LATITUDE:\n case LONGITUDE:\n case LATITUDE2:\n case LONGITUDE2:\n case DETAIL:\n case KEY:\n case ORDER:\n return undefined;\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('rangeType not implemented for ' + channel);\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/axis/assemble.d.ts b/build/src/compile/axis/assemble.d.ts new file mode 100644 index 0000000000..b3c16c644a --- /dev/null +++ b/build/src/compile/axis/assemble.d.ts @@ -0,0 +1,7 @@ +import { Config } from '../../config'; +import { VgAxis } from '../../vega.schema'; +import { AxisComponent, AxisComponentIndex } from './component'; +export declare function assembleAxis(axisCmpt: AxisComponent, kind: 'main' | 'grid', config: Config, opt?: { + header: boolean; +}): VgAxis; +export declare function assembleAxes(axisComponents: AxisComponentIndex, config: Config): VgAxis[]; diff --git a/build/src/compile/axis/assemble.js b/build/src/compile/axis/assemble.js new file mode 100644 index 0000000000..742978e677 --- /dev/null +++ b/build/src/compile/axis/assemble.js @@ -0,0 +1,69 @@ +import * as tslib_1 from "tslib"; +import { isArray } from 'vega-util'; +import { AXIS_PARTS, AXIS_PROPERTY_TYPE } from '../../axis'; +import { title as fieldDefTitle } from '../../fielddef'; +import { keys } from '../../util'; +function assembleTitle(title, config) { + if (isArray(title)) { + return title.map(function (fieldDef) { return fieldDefTitle(fieldDef, config); }).join(', '); + } + return title; +} +export function assembleAxis(axisCmpt, kind, config, opt) { + if (opt === void 0) { opt = { header: false }; } + var _a = axisCmpt.combine(), orient = _a.orient, scale = _a.scale, title = _a.title, zindex = _a.zindex, axis = tslib_1.__rest(_a, ["orient", "scale", "title", "zindex"]); + // Remove properties that are not valid for this kind of axis + keys(axis).forEach(function (key) { + var propType = AXIS_PROPERTY_TYPE[key]; + if (propType && propType !== kind && propType !== 'both') { + delete axis[key]; + } + }); + if (kind === 'grid') { + if (!axis.grid) { + return undefined; + } + // Remove unnecessary encode block + if (axis.encode) { + // Only need to keep encode block for grid + var grid = axis.encode.grid; + axis.encode = tslib_1.__assign({}, (grid ? { grid: grid } : {})); + if (keys(axis.encode).length === 0) { + delete axis.encode; + } + } + return tslib_1.__assign({ scale: scale, + orient: orient }, axis, { domain: false, labels: false, + // Always set min/maxExtent to 0 to ensure that `config.axis*.minExtent` and `config.axis*.maxExtent` + // would not affect gridAxis + maxExtent: 0, minExtent: 0, ticks: false, zindex: zindex !== undefined ? zindex : 0 // put grid behind marks by default + }); + } + else { // kind === 'main' + if (!opt.header && axisCmpt.mainExtracted) { + // if mainExtracted has been extracted to a separate facet + return undefined; + } + // Remove unnecessary encode block + if (axis.encode) { + for (var _i = 0, AXIS_PARTS_1 = AXIS_PARTS; _i < AXIS_PARTS_1.length; _i++) { + var part = AXIS_PARTS_1[_i]; + if (!axisCmpt.hasAxisPart(part)) { + delete axis.encode[part]; + } + } + if (keys(axis.encode).length === 0) { + delete axis.encode; + } + } + var titleString = assembleTitle(title, config); + return tslib_1.__assign({ scale: scale, + orient: orient, grid: false }, (titleString ? { title: titleString } : {}), axis, { zindex: zindex !== undefined ? zindex : 1 // put axis line above marks by default + }); + } +} +export function assembleAxes(axisComponents, config) { + var _a = axisComponents.x, x = _a === void 0 ? [] : _a, _b = axisComponents.y, y = _b === void 0 ? [] : _b; + return x.map(function (a) { return assembleAxis(a, 'main', config); }).concat(x.map(function (a) { return assembleAxis(a, 'grid', config); }), y.map(function (a) { return assembleAxis(a, 'main', config); }), y.map(function (a) { return assembleAxis(a, 'grid', config); })).filter(function (a) { return a; }); // filter undefined +} +//# sourceMappingURL=assemble.js.map \ No newline at end of file diff --git a/build/src/compile/axis/assemble.js.map b/build/src/compile/axis/assemble.js.map new file mode 100644 index 0000000000..f77c8bd3f2 --- /dev/null +++ b/build/src/compile/axis/assemble.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../../../src/compile/axis/assemble.ts"],"names":[],"mappings":"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","sourcesContent":["import {isArray} from 'vega-util';\n\nimport {AXIS_PARTS, AXIS_PROPERTY_TYPE} from '../../axis';\nimport {Config} from '../../config';\nimport {FieldDefBase, title as fieldDefTitle} from '../../fielddef';\nimport {keys} from '../../util';\nimport {VgAxis} from '../../vega.schema';\nimport {AxisComponent, AxisComponentIndex} from './component';\n\nfunction assembleTitle(title: string | FieldDefBase[], config: Config) {\n if (isArray(title)) {\n return title.map(fieldDef => fieldDefTitle(fieldDef, config)).join(', ');\n }\n return title;\n}\n\nexport function assembleAxis(\n axisCmpt: AxisComponent,\n kind: 'main' | 'grid',\n config: Config,\n opt: {\n header: boolean // whether this is called via a header\n } = {header: false}\n): VgAxis {\n const {orient, scale, title, zindex, ...axis} = axisCmpt.combine();\n\n // Remove properties that are not valid for this kind of axis\n keys(axis).forEach((key) => {\n const propType = AXIS_PROPERTY_TYPE[key];\n if (propType && propType !== kind && propType !== 'both') {\n delete axis[key];\n }\n });\n\n if (kind === 'grid') {\n if (!axis.grid) {\n return undefined;\n }\n\n // Remove unnecessary encode block\n if (axis.encode) {\n // Only need to keep encode block for grid\n const {grid} = axis.encode;\n axis.encode = {\n ...(grid ? {grid} : {})\n };\n\n if (keys(axis.encode).length === 0) {\n delete axis.encode;\n }\n }\n\n return {\n scale,\n orient,\n ...axis,\n domain: false,\n labels: false,\n\n // Always set min/maxExtent to 0 to ensure that `config.axis*.minExtent` and `config.axis*.maxExtent`\n // would not affect gridAxis\n maxExtent: 0,\n minExtent: 0,\n ticks: false,\n zindex: zindex !== undefined ? zindex : 0 // put grid behind marks by default\n };\n } else { // kind === 'main'\n\n if (!opt.header && axisCmpt.mainExtracted) {\n // if mainExtracted has been extracted to a separate facet\n return undefined;\n }\n\n // Remove unnecessary encode block\n if (axis.encode) {\n for (const part of AXIS_PARTS) {\n if (\n !axisCmpt.hasAxisPart(part)\n ) {\n delete axis.encode[part];\n }\n }\n if (keys(axis.encode).length === 0) {\n delete axis.encode;\n }\n }\n\n const titleString = assembleTitle(title, config);\n\n return {\n scale,\n orient,\n grid: false,\n ...(titleString ? {title: titleString} : {}),\n ...axis,\n zindex: zindex !== undefined ? zindex : 1 // put axis line above marks by default\n };\n }\n}\n\nexport function assembleAxes(axisComponents: AxisComponentIndex, config: Config): VgAxis[] {\n const {x=[], y=[]} = axisComponents;\n return [\n ...x.map(a => assembleAxis(a, 'main', config)),\n ...x.map(a => assembleAxis(a, 'grid', config)),\n ...y.map(a => assembleAxis(a, 'main', config)),\n ...y.map(a => assembleAxis(a, 'grid', config))\n ].filter(a => a); // filter undefined\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/axis/component.d.ts b/build/src/compile/axis/component.d.ts new file mode 100644 index 0000000000..8ab24a1d7b --- /dev/null +++ b/build/src/compile/axis/component.d.ts @@ -0,0 +1,24 @@ +import { Axis, AxisPart } from '../../axis'; +import { FieldDefBase } from '../../fielddef'; +import { Omit } from '../../util'; +import { VgAxis } from '../../vega.schema'; +import { Split } from '../split'; +export declare type AxisComponentProps = Omit & { + title: string | FieldDefBase[]; +}; +export declare class AxisComponent extends Split { + readonly explicit: Partial; + readonly implicit: Partial; + mainExtracted: boolean; + constructor(explicit?: Partial, implicit?: Partial, mainExtracted?: boolean); + clone(): AxisComponent; + hasAxisPart(part: AxisPart): boolean; +} +export interface AxisComponentIndex { + x?: AxisComponent[]; + y?: AxisComponent[]; +} +export interface AxisIndex { + x?: Axis; + y?: Axis; +} diff --git a/build/src/compile/axis/component.js b/build/src/compile/axis/component.js new file mode 100644 index 0000000000..f664e9c5e3 --- /dev/null +++ b/build/src/compile/axis/component.js @@ -0,0 +1,36 @@ +import * as tslib_1 from "tslib"; +import { duplicate } from '../../util'; +import { Split } from '../split'; +function isFalseOrNull(v) { + return v === false || v === null; +} +var AxisComponent = /** @class */ (function (_super) { + tslib_1.__extends(AxisComponent, _super); + function AxisComponent(explicit, implicit, mainExtracted) { + if (explicit === void 0) { explicit = {}; } + if (implicit === void 0) { implicit = {}; } + if (mainExtracted === void 0) { mainExtracted = false; } + var _this = _super.call(this) || this; + _this.explicit = explicit; + _this.implicit = implicit; + _this.mainExtracted = mainExtracted; + return _this; + } + AxisComponent.prototype.clone = function () { + return new AxisComponent(duplicate(this.explicit), duplicate(this.implicit), this.mainExtracted); + }; + AxisComponent.prototype.hasAxisPart = function (part) { + // FIXME(https://github.com/vega/vega-lite/issues/2552) this method can be wrong if users use a Vega theme. + if (part === 'axis') { // always has the axis container part + return true; + } + if (part === 'grid' || part === 'title') { + return !!this.get(part); + } + // Other parts are enabled by default, so they should not be false or null. + return !isFalseOrNull(this.get(part)); + }; + return AxisComponent; +}(Split)); +export { AxisComponent }; +//# sourceMappingURL=component.js.map \ No newline at end of file diff --git a/build/src/compile/axis/component.js.map b/build/src/compile/axis/component.js.map new file mode 100644 index 0000000000..8afc5c7509 --- /dev/null +++ b/build/src/compile/axis/component.js.map @@ -0,0 +1 @@ +{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../src/compile/axis/component.ts"],"names":[],"mappings":";AAEA,OAAO,EAAC,SAAS,EAAO,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAC,KAAK,EAAC,MAAM,UAAU,CAAC;AAG/B,uBAAuB,CAAiB;IACtC,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC;AACnC,CAAC;AAOD;IAAmC,yCAAyB;IAC1D,uBACkB,QAA0C,EAC1C,QAA0C,EACnD,aAAqB;QAFZ,yBAAA,EAAA,aAA0C;QAC1C,yBAAA,EAAA,aAA0C;QACnD,8BAAA,EAAA,qBAAqB;QAH9B,YAKE,iBAAO,SACR;QALiB,cAAQ,GAAR,QAAQ,CAAkC;QAC1C,cAAQ,GAAR,QAAQ,CAAkC;QACnD,mBAAa,GAAb,aAAa,CAAQ;;IAG9B,CAAC;IAEM,6BAAK,GAAZ;QACE,OAAO,IAAI,aAAa,CACtB,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EACxB,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,aAAa,CAC7C,CAAC;IACJ,CAAC;IAEM,mCAAW,GAAlB,UAAmB,IAAc;QAC/B,2GAA2G;QAE3G,IAAI,IAAI,KAAK,MAAM,EAAE,EAAE,qCAAqC;YAC1D,OAAO,IAAI,CAAC;SACb;QAED,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,EAAE;YACvC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;SACzB;QACD,2EAA2E;QAC3E,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC;IACH,oBAAC;AAAD,CAAC,AA7BD,CAAmC,KAAK,GA6BvC","sourcesContent":["import {Axis, AxisPart} from '../../axis';\nimport {FieldDefBase} from '../../fielddef';\nimport {duplicate, Omit} from '../../util';\nimport {VgAxis} from '../../vega.schema';\nimport {Split} from '../split';\n\n\nfunction isFalseOrNull(v: boolean | null) {\n return v === false || v === null;\n}\n\nexport type AxisComponentProps = Omit & {\n\n title: string | FieldDefBase[];\n};\n\nexport class AxisComponent extends Split {\n constructor(\n public readonly explicit: Partial = {},\n public readonly implicit: Partial = {},\n public mainExtracted = false\n ) {\n super();\n }\n\n public clone() {\n return new AxisComponent(\n duplicate(this.explicit),\n duplicate(this.implicit), this.mainExtracted\n );\n }\n\n public hasAxisPart(part: AxisPart) {\n // FIXME(https://github.com/vega/vega-lite/issues/2552) this method can be wrong if users use a Vega theme.\n\n if (part === 'axis') { // always has the axis container part\n return true;\n }\n\n if (part === 'grid' || part === 'title') {\n return !!this.get(part);\n }\n // Other parts are enabled by default, so they should not be false or null.\n return !isFalseOrNull(this.get(part));\n }\n}\n\nexport interface AxisComponentIndex {\n x?: AxisComponent[];\n y?: AxisComponent[];\n}\n\nexport interface AxisIndex {\n x?: Axis;\n y?: Axis;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/axis/config.d.ts b/build/src/compile/axis/config.d.ts new file mode 100644 index 0000000000..3713bf518c --- /dev/null +++ b/build/src/compile/axis/config.d.ts @@ -0,0 +1,4 @@ +import { PositionScaleChannel } from '../../channel'; +import { Config } from '../../config'; +import { ScaleType } from '../../scale'; +export declare function getAxisConfig(property: string, config: Config, channel: PositionScaleChannel, orient: string, scaleType: ScaleType): any; diff --git a/build/src/compile/axis/config.js b/build/src/compile/axis/config.js new file mode 100644 index 0000000000..af426146c3 --- /dev/null +++ b/build/src/compile/axis/config.js @@ -0,0 +1,17 @@ +export function getAxisConfig(property, config, channel, orient, scaleType) { + if (orient === void 0) { orient = ''; } + // configTypes to loop, starting from higher precedence + var configTypes = (scaleType === 'band' ? ['axisBand'] : []).concat([ + channel === 'x' ? 'axisX' : 'axisY', + 'axis' + orient.substr(0, 1).toUpperCase() + orient.substr(1), + 'axis' + ]); + for (var _i = 0, configTypes_1 = configTypes; _i < configTypes_1.length; _i++) { + var configType = configTypes_1[_i]; + if (config[configType] && config[configType][property] !== undefined) { + return config[configType][property]; + } + } + return undefined; +} +//# sourceMappingURL=config.js.map \ No newline at end of file diff --git a/build/src/compile/axis/config.js.map b/build/src/compile/axis/config.js.map new file mode 100644 index 0000000000..af1e4e6dc1 --- /dev/null +++ b/build/src/compile/axis/config.js.map @@ -0,0 +1 @@ +{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/compile/axis/config.ts"],"names":[],"mappings":"AAIA,MAAM,wBAAwB,QAAgB,EAAE,MAAc,EAAE,OAA6B,EAAE,MAAmB,EAAE,SAAoB;IAAzC,uBAAA,EAAA,WAAmB;IAChH,uDAAuD;IACvD,IAAM,WAAW,GAAG,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;QACpE,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO;QACnC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5D,MAAM;KACP,CAAC,CAAC;IACH,KAAyB,UAAW,EAAX,2BAAW,EAAX,yBAAW,EAAX,IAAW,EAAE;QAAjC,IAAM,UAAU,oBAAA;QACnB,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE;YACpE,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC;SACrC;KACF;IAED,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import {PositionScaleChannel} from '../../channel';\nimport {Config} from '../../config';\nimport {ScaleType} from '../../scale';\n\nexport function getAxisConfig(property: string, config: Config, channel: PositionScaleChannel, orient: string = '', scaleType: ScaleType) {\n // configTypes to loop, starting from higher precedence\n const configTypes = (scaleType === 'band' ? ['axisBand'] : []).concat([\n channel === 'x' ? 'axisX' : 'axisY',\n 'axis' + orient.substr(0,1).toUpperCase() + orient.substr(1), // axisTop, axisBottom, ...\n 'axis'\n ]);\n for (const configType of configTypes) {\n if (config[configType] && config[configType][property] !== undefined) {\n return config[configType][property];\n }\n }\n\n return undefined;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/axis/encode.d.ts b/build/src/compile/axis/encode.d.ts new file mode 100644 index 0000000000..dbf2e55739 --- /dev/null +++ b/build/src/compile/axis/encode.d.ts @@ -0,0 +1,11 @@ +import { Axis } from '../../axis'; +import { Channel, PositionScaleChannel } from '../../channel'; +import { FieldDef } from '../../fielddef'; +import { AxisOrient, HorizontalAlign } from '../../vega.schema'; +import { UnitModel } from '../unit'; +export declare function labels(model: UnitModel, channel: PositionScaleChannel, specifiedLabelsSpec: any, orient: AxisOrient): any; +export declare function labelBaseline(angle: number, orient: AxisOrient): { + value: string; +}; +export declare function labelAngle(axis: Axis, channel: Channel, fieldDef: FieldDef): number; +export declare function labelAlign(angle: number, orient: AxisOrient): HorizontalAlign; diff --git a/build/src/compile/axis/encode.js b/build/src/compile/axis/encode.js new file mode 100644 index 0000000000..97a42aa4f5 --- /dev/null +++ b/build/src/compile/axis/encode.js @@ -0,0 +1,104 @@ +import * as tslib_1 from "tslib"; +import { X } from '../../channel'; +import { isTimeFieldDef } from '../../fielddef'; +import { ScaleType } from '../../scale'; +import { NOMINAL, ORDINAL } from '../../type'; +import { contains, keys } from '../../util'; +import { timeFormatExpression } from '../common'; +import { getAxisConfig } from './config'; +export function labels(model, channel, specifiedLabelsSpec, orient) { + var fieldDef = model.fieldDef(channel) || + (channel === 'x' ? model.fieldDef('x2') : + channel === 'y' ? model.fieldDef('y2') : + undefined); + var axis = model.axis(channel); + var config = model.config; + var labelsSpec = {}; + // Text + if (isTimeFieldDef(fieldDef)) { + var isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC; + var expr = timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat, isUTCScale); + if (expr) { + labelsSpec.text = { signal: expr }; + } + } + // Label Angle + var angle = getAxisConfig('labelAngle', model.config, channel, orient, model.getScaleComponent(channel).get('type')); + if (angle === undefined) { + angle = labelAngle(axis, channel, fieldDef); + if (angle) { + labelsSpec.angle = { value: angle }; + } + } + if (angle !== undefined) { + var align = labelAlign(angle, orient); + if (align) { + labelsSpec.align = { value: align }; + } + labelsSpec.baseline = labelBaseline(angle, orient); + } + labelsSpec = tslib_1.__assign({}, labelsSpec, specifiedLabelsSpec); + return keys(labelsSpec).length === 0 ? undefined : labelsSpec; +} +export function labelBaseline(angle, orient) { + if (orient === 'top' || orient === 'bottom') { + if (angle <= 45 || 315 <= angle) { + return { value: orient === 'top' ? 'bottom' : 'top' }; + } + else if (135 <= angle && angle <= 225) { + return { value: orient === 'top' ? 'top' : 'bottom' }; + } + else { + return { value: 'middle' }; + } + } + else { + if ((angle <= 45 || 315 <= angle) || (135 <= angle && angle <= 225)) { + return { value: 'middle' }; + } + else if (45 <= angle && angle <= 135) { + return { value: orient === 'left' ? 'top' : 'bottom' }; + } + else { + return { value: orient === 'left' ? 'bottom' : 'top' }; + } + } +} +export function labelAngle(axis, channel, fieldDef) { + if (axis.labelAngle !== undefined) { + // Make angle within [0,360) + return ((axis.labelAngle % 360) + 360) % 360; + } + else { + if (channel === X && contains([NOMINAL, ORDINAL], fieldDef.type)) { + return 270; + } + } + return undefined; +} +export function labelAlign(angle, orient) { + angle = ((angle % 360) + 360) % 360; + if (orient === 'top' || orient === 'bottom') { + if (angle % 180 === 0) { + return 'center'; + } + else if (0 < angle && angle < 180) { + return orient === 'top' ? 'right' : 'left'; + } + else { + return orient === 'top' ? 'left' : 'right'; + } + } + else { + if ((angle + 90) % 180 === 0) { + return 'center'; + } + else if (90 <= angle && angle < 270) { + return orient === 'left' ? 'left' : 'right'; + } + else { + return orient === 'left' ? 'right' : 'left'; + } + } +} +//# sourceMappingURL=encode.js.map \ No newline at end of file diff --git a/build/src/compile/axis/encode.js.map b/build/src/compile/axis/encode.js.map new file mode 100644 index 0000000000..07fbaaa5bd --- /dev/null +++ b/build/src/compile/axis/encode.js.map @@ -0,0 +1 @@ +{"version":3,"file":"encode.js","sourceRoot":"","sources":["../../../../src/compile/axis/encode.ts"],"names":[],"mappings":"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","sourcesContent":["import {Axis} from '../../axis';\nimport {Channel, PositionScaleChannel, X} from '../../channel';\nimport {FieldDef, isTimeFieldDef} from '../../fielddef';\nimport {ScaleType} from '../../scale';\nimport {NOMINAL, ORDINAL} from '../../type';\nimport {contains, keys} from '../../util';\nimport {AxisOrient, HorizontalAlign} from '../../vega.schema';\nimport {timeFormatExpression} from '../common';\nimport {UnitModel} from '../unit';\nimport {getAxisConfig} from './config';\n\nexport function labels(model: UnitModel, channel: PositionScaleChannel, specifiedLabelsSpec: any, orient: AxisOrient) {\n const fieldDef = model.fieldDef(channel) ||\n (\n channel === 'x' ? model.fieldDef('x2') :\n channel === 'y' ? model.fieldDef('y2') :\n undefined\n );\n const axis = model.axis(channel);\n const config = model.config;\n\n let labelsSpec: any = {};\n\n // Text\n if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC;\n\n const expr = timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat, isUTCScale);\n\n if (expr) {\n labelsSpec.text = {signal: expr};\n }\n }\n\n // Label Angle\n let angle = getAxisConfig('labelAngle', model.config, channel, orient, model.getScaleComponent(channel).get('type'));\n if (angle === undefined) {\n angle = labelAngle(axis, channel, fieldDef);\n if (angle) {\n labelsSpec.angle = {value: angle};\n }\n }\n\n if (angle !== undefined) {\n const align = labelAlign(angle, orient);\n if (align) {\n labelsSpec.align = {value: align};\n }\n\n labelsSpec.baseline = labelBaseline(angle, orient);\n }\n\n labelsSpec = {\n ...labelsSpec,\n ...specifiedLabelsSpec\n };\n\n return keys(labelsSpec).length === 0 ? undefined : labelsSpec;\n}\n\nexport function labelBaseline(angle: number, orient: AxisOrient) {\n if (orient === 'top' || orient === 'bottom') {\n if (angle <= 45 || 315 <= angle) {\n return {value: orient === 'top' ? 'bottom' : 'top'};\n } else if (135 <= angle && angle <= 225) {\n return {value: orient === 'top' ? 'top': 'bottom'};\n } else {\n return {value: 'middle'};\n }\n } else {\n if ((angle <= 45 || 315 <= angle) || (135 <= angle && angle <= 225)) {\n return {value: 'middle'};\n } else if (45 <= angle && angle <= 135) {\n return {value: orient === 'left' ? 'top' : 'bottom'};\n } else {\n return {value: orient === 'left' ? 'bottom' : 'top'};\n }\n }\n}\n\nexport function labelAngle(axis: Axis, channel: Channel, fieldDef: FieldDef) {\n if (axis.labelAngle !== undefined) {\n // Make angle within [0,360)\n return ((axis.labelAngle % 360) + 360) % 360;\n } else {\n if (channel === X && contains([NOMINAL, ORDINAL], fieldDef.type)) {\n return 270;\n }\n }\n return undefined;\n}\n\nexport function labelAlign(angle: number, orient: AxisOrient): HorizontalAlign {\n angle = ((angle % 360) + 360) % 360;\n if (orient === 'top' || orient === 'bottom') {\n if (angle % 180 === 0) {\n return 'center';\n } else if (0 < angle && angle < 180) {\n return orient === 'top' ? 'right' : 'left';\n } else {\n return orient === 'top' ? 'left' : 'right';\n }\n } else {\n if ((angle + 90) % 180 === 0) {\n return 'center';\n } else if (90 <= angle && angle < 270) {\n return orient === 'left' ? 'left' : 'right';\n } else {\n return orient === 'left' ? 'right' : 'left';\n }\n }\n}\n\n"]} \ No newline at end of file diff --git a/build/src/compile/axis/parse.d.ts b/build/src/compile/axis/parse.d.ts new file mode 100644 index 0000000000..93f43ddbcb --- /dev/null +++ b/build/src/compile/axis/parse.d.ts @@ -0,0 +1,5 @@ +import { LayerModel } from '../layer'; +import { UnitModel } from '../unit'; +import { AxisComponentIndex } from './component'; +export declare function parseUnitAxis(model: UnitModel): AxisComponentIndex; +export declare function parseLayerAxis(model: LayerModel): void; diff --git a/build/src/compile/axis/parse.js b/build/src/compile/axis/parse.js new file mode 100644 index 0000000000..e123f62750 --- /dev/null +++ b/build/src/compile/axis/parse.js @@ -0,0 +1,256 @@ +import { AXIS_PARTS, isAxisProperty, VG_AXIS_PROPERTIES } from '../../axis'; +import { POSITION_SCALE_CHANNELS, X, Y } from '../../channel'; +import { toFieldDefBase } from '../../fielddef'; +import { keys } from '../../util'; +import { getSpecifiedOrDefaultValue, guideEncodeEntry, mergeTitle, mergeTitleComponent, mergeTitleFieldDefs, numberFormat } from '../common'; +import { parseGuideResolve } from '../resolve'; +import { defaultTieBreaker, mergeValuesWithExplicit } from '../split'; +import { AxisComponent } from './component'; +import { getAxisConfig } from './config'; +import * as encode from './encode'; +import * as properties from './properties'; +export function parseUnitAxis(model) { + return POSITION_SCALE_CHANNELS.reduce(function (axis, channel) { + if (model.component.scales[channel] && model.axis(channel)) { + axis[channel] = [parseAxis(channel, model)]; + } + return axis; + }, {}); +} +var OPPOSITE_ORIENT = { + bottom: 'top', + top: 'bottom', + left: 'right', + right: 'left' +}; +export function parseLayerAxis(model) { + var _a = model.component, axes = _a.axes, resolve = _a.resolve; + var axisCount = { top: 0, bottom: 0, right: 0, left: 0 }; + for (var _i = 0, _b = model.children; _i < _b.length; _i++) { + var child = _b[_i]; + child.parseAxisAndHeader(); + for (var _c = 0, _d = keys(child.component.axes); _c < _d.length; _c++) { + var channel = _d[_c]; + resolve.axis[channel] = parseGuideResolve(model.component.resolve, channel); + if (resolve.axis[channel] === 'shared') { + // If the resolve says shared (and has not been overridden) + // We will try to merge and see if there is a conflict + axes[channel] = mergeAxisComponents(axes[channel], child.component.axes[channel]); + if (!axes[channel]) { + // If merge returns nothing, there is a conflict so we cannot make the axis shared. + // Thus, mark axis as independent and remove the axis component. + resolve.axis[channel] = 'independent'; + delete axes[channel]; + } + } + } + } + // Move axes to layer's axis component and merge shared axes + for (var _e = 0, _f = [X, Y]; _e < _f.length; _e++) { + var channel = _f[_e]; + for (var _g = 0, _h = model.children; _g < _h.length; _g++) { + var child = _h[_g]; + if (!child.component.axes[channel]) { + // skip if the child does not have a particular axis + continue; + } + if (resolve.axis[channel] === 'independent') { + // If axes are independent, concat the axisComponent array. + axes[channel] = (axes[channel] || []).concat(child.component.axes[channel]); + // Automatically adjust orient + for (var _j = 0, _k = child.component.axes[channel]; _j < _k.length; _j++) { + var axisComponent = _k[_j]; + var _l = axisComponent.getWithExplicit('orient'), orient = _l.value, explicit = _l.explicit; + if (axisCount[orient] > 0 && !explicit) { + // Change axis orient if the number do not match + var oppositeOrient = OPPOSITE_ORIENT[orient]; + if (axisCount[orient] > axisCount[oppositeOrient]) { + axisComponent.set('orient', oppositeOrient, false); + } + } + axisCount[orient]++; + // TODO(https://github.com/vega/vega-lite/issues/2634): automaticaly add extra offset? + } + } + // After merging, make sure to remove axes from child + delete child.component.axes[channel]; + } + } +} +function mergeAxisComponents(mergedAxisCmpts, childAxisCmpts) { + if (mergedAxisCmpts) { + // FIXME: this is a bit wrong once we support multiple axes + if (mergedAxisCmpts.length !== childAxisCmpts.length) { + return undefined; // Cannot merge axis component with different number of axes. + } + var length_1 = mergedAxisCmpts.length; + for (var i = 0; i < length_1; i++) { + var merged = mergedAxisCmpts[i]; + var child = childAxisCmpts[i]; + if ((!!merged) !== (!!child)) { + return undefined; + } + else if (merged && child) { + var mergedOrient = merged.getWithExplicit('orient'); + var childOrient = child.getWithExplicit('orient'); + if (mergedOrient.explicit && childOrient.explicit && mergedOrient.value !== childOrient.value) { + // TODO: throw warning if resolve is explicit (We don't have info about explicit/implicit resolve yet.) + // Cannot merge due to inconsistent orient + return undefined; + } + else { + mergedAxisCmpts[i] = mergeAxisComponent(merged, child); + } + } + } + } + else { + // For first one, return a copy of the child + return childAxisCmpts.map(function (axisComponent) { return axisComponent.clone(); }); + } + return mergedAxisCmpts; +} +function mergeAxisComponent(merged, child) { + var _loop_1 = function (prop) { + var mergedValueWithExplicit = mergeValuesWithExplicit(merged.getWithExplicit(prop), child.getWithExplicit(prop), prop, 'axis', + // Tie breaker function + function (v1, v2) { + switch (prop) { + case 'title': + return mergeTitleComponent(v1, v2); + case 'gridScale': + return { + explicit: v1.explicit, + value: v1.value || v2.value + }; + } + return defaultTieBreaker(v1, v2, prop, 'axis'); + }); + merged.setWithExplicit(prop, mergedValueWithExplicit); + }; + for (var _i = 0, VG_AXIS_PROPERTIES_1 = VG_AXIS_PROPERTIES; _i < VG_AXIS_PROPERTIES_1.length; _i++) { + var prop = VG_AXIS_PROPERTIES_1[_i]; + _loop_1(prop); + } + return merged; +} +function getFieldDefTitle(model, channel) { + var channel2 = channel === 'x' ? 'x2' : 'y2'; + var fieldDef = model.fieldDef(channel); + var fieldDef2 = model.fieldDef(channel2); + var title1 = fieldDef ? fieldDef.title : undefined; + var title2 = fieldDef2 ? fieldDef2.title : undefined; + if (title1 && title2) { + return mergeTitle(title1, title2); + } + else if (title1) { + return title1; + } + else if (title2) { + return title2; + } + else if (title1 !== undefined) { // falsy value to disable config + return title1; + } + else if (title2 !== undefined) { // falsy value to disable config + return title2; + } + return undefined; +} +function parseAxis(channel, model) { + var axis = model.axis(channel); + var axisComponent = new AxisComponent(); + // 1.2. Add properties + VG_AXIS_PROPERTIES.forEach(function (property) { + var value = getProperty(property, axis, channel, model); + if (value !== undefined) { + var explicit = + // specified axis.values is already respected, but may get transformed. + property === 'values' ? !!axis.values : + // both VL axis.encoding and axis.labelAngle affect VG axis.encode + property === 'encode' ? !!axis.encoding || !!axis.labelAngle : + // title can be explicit if fieldDef.title is set + property === 'title' && value === getFieldDefTitle(model, channel) ? true : + // Otherwise, things are explicit if the returned value matches the specified property + value === axis[property]; + var configValue = getAxisConfig(property, model.config, channel, axisComponent.get('orient'), model.getScaleComponent(channel).get('type')); + // only set property if it is explicitly set or has no config value (otherwise we will accidentally override config) + if (explicit || configValue === undefined) { + // Do not apply implicit rule if there is a config value + axisComponent.set(property, value, explicit); + } + else if (property === 'grid' && configValue) { + // Grid is an exception because we need to set grid = true to generate another grid axis + axisComponent.set(property, configValue, false); + } + } + }); + // 2) Add guide encode definition groups + var axisEncoding = axis.encoding || {}; + var axisEncode = AXIS_PARTS.reduce(function (e, part) { + if (!axisComponent.hasAxisPart(part)) { + // No need to create encode for a disabled part. + return e; + } + var axisEncodingPart = guideEncodeEntry(axisEncoding[part] || {}, model); + var value = part === 'labels' ? + encode.labels(model, channel, axisEncodingPart, axisComponent.get('orient')) : + axisEncodingPart; + if (value !== undefined && keys(value).length > 0) { + e[part] = { update: value }; + } + return e; + }, {}); + // FIXME: By having encode as one property, we won't have fine grained encode merging. + if (keys(axisEncode).length > 0) { + axisComponent.set('encode', axisEncode, !!axis.encoding || axis.labelAngle !== undefined); + } + return axisComponent; +} +function getProperty(property, specifiedAxis, channel, model) { + var fieldDef = model.fieldDef(channel); + switch (property) { + case 'scale': + return model.scaleName(channel); + case 'gridScale': + return properties.gridScale(model, channel); + case 'format': + // We don't include temporal field here as we apply format in encode block + return numberFormat(fieldDef, specifiedAxis.format, model.config); + case 'grid': { + var scaleType = model.getScaleComponent(channel).get('type'); + return getSpecifiedOrDefaultValue(specifiedAxis.grid, properties.grid(scaleType, fieldDef)); + } + case 'labelFlush': + return properties.labelFlush(fieldDef, channel, specifiedAxis); + case 'labelOverlap': { + var scaleType = model.getScaleComponent(channel).get('type'); + return properties.labelOverlap(fieldDef, specifiedAxis, channel, scaleType); + } + case 'orient': + return getSpecifiedOrDefaultValue(specifiedAxis.orient, properties.orient(channel)); + case 'tickCount': { + var scaleType = model.getScaleComponent(channel).get('type'); + var sizeType = channel === 'x' ? 'width' : channel === 'y' ? 'height' : undefined; + var size = sizeType ? model.getSizeSignalRef(sizeType) + : undefined; + return getSpecifiedOrDefaultValue(specifiedAxis.tickCount, properties.tickCount(channel, fieldDef, scaleType, size)); + } + case 'title': + var channel2 = channel === 'x' ? 'x2' : 'y2'; + var fieldDef2 = model.fieldDef(channel2); + // Keep undefined so we use default if title is unspecified. + // For other falsy value, keep them so we will hide the title. + var fieldDefTitle = getFieldDefTitle(model, channel); + var specifiedTitle = fieldDefTitle !== undefined ? fieldDefTitle : + specifiedAxis.title === undefined ? undefined : specifiedAxis.title; + return getSpecifiedOrDefaultValue(specifiedTitle, + // If title not specified, store base parts of fieldDef (and fieldDef2 if exists) + mergeTitleFieldDefs([toFieldDefBase(fieldDef)], fieldDef2 ? [toFieldDefBase(fieldDef2)] : [])); + case 'values': + return properties.values(specifiedAxis, model, fieldDef, channel); + } + // Otherwise, return specified property. + return isAxisProperty(property) ? specifiedAxis[property] : undefined; +} +//# sourceMappingURL=parse.js.map \ No newline at end of file diff --git a/build/src/compile/axis/parse.js.map b/build/src/compile/axis/parse.js.map new file mode 100644 index 0000000000..5a36966001 --- /dev/null +++ b/build/src/compile/axis/parse.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../src/compile/axis/parse.ts"],"names":[],"mappings":"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","sourcesContent":["import {Axis, AXIS_PARTS, AxisEncoding, isAxisProperty, VG_AXIS_PROPERTIES} from '../../axis';\nimport {POSITION_SCALE_CHANNELS, PositionScaleChannel, X, Y} from '../../channel';\nimport {FieldDefBase, toFieldDefBase} from '../../fielddef';\nimport {keys} from '../../util';\nimport {AxisOrient, VgAxis, VgAxisEncode} from '../../vega.schema';\nimport {getSpecifiedOrDefaultValue, guideEncodeEntry, mergeTitle, mergeTitleComponent, mergeTitleFieldDefs, numberFormat} from '../common';\nimport {LayerModel} from '../layer';\nimport {parseGuideResolve} from '../resolve';\nimport {defaultTieBreaker, Explicit, mergeValuesWithExplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {AxisComponent, AxisComponentIndex, AxisComponentProps} from './component';\nimport {getAxisConfig} from './config';\nimport * as encode from './encode';\nimport * as properties from './properties';\n\n\nexport function parseUnitAxis(model: UnitModel): AxisComponentIndex {\n return POSITION_SCALE_CHANNELS.reduce(function(axis, channel) {\n if (model.component.scales[channel] && model.axis(channel)) {\n axis[channel] = [parseAxis(channel, model)];\n }\n return axis;\n }, {} as AxisComponentIndex);\n}\n\nconst OPPOSITE_ORIENT: {[K in AxisOrient]: AxisOrient} = {\n bottom: 'top',\n top: 'bottom',\n left: 'right',\n right: 'left'\n};\n\nexport function parseLayerAxis(model: LayerModel) {\n const {axes, resolve} = model.component;\n const axisCount: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in AxisOrient]: number\n } = {top: 0, bottom: 0, right: 0, left: 0};\n\n for (const child of model.children) {\n child.parseAxisAndHeader();\n\n for (const channel of keys(child.component.axes)) {\n resolve.axis[channel] = parseGuideResolve(model.component.resolve, channel);\n if (resolve.axis[channel] === 'shared') {\n // If the resolve says shared (and has not been overridden)\n // We will try to merge and see if there is a conflict\n\n axes[channel] = mergeAxisComponents(axes[channel], child.component.axes[channel]);\n\n if (!axes[channel]) {\n // If merge returns nothing, there is a conflict so we cannot make the axis shared.\n // Thus, mark axis as independent and remove the axis component.\n resolve.axis[channel] = 'independent';\n delete axes[channel];\n }\n }\n }\n }\n\n // Move axes to layer's axis component and merge shared axes\n for (const channel of [X, Y]) {\n for (const child of model.children) {\n if (!child.component.axes[channel]) {\n // skip if the child does not have a particular axis\n continue;\n }\n\n if (resolve.axis[channel] === 'independent') {\n // If axes are independent, concat the axisComponent array.\n axes[channel] = (axes[channel] || []).concat(child.component.axes[channel]);\n\n // Automatically adjust orient\n for (const axisComponent of child.component.axes[channel]) {\n const {value: orient, explicit} = axisComponent.getWithExplicit('orient');\n if (axisCount[orient] > 0 && !explicit) {\n // Change axis orient if the number do not match\n const oppositeOrient = OPPOSITE_ORIENT[orient];\n if (axisCount[orient] > axisCount[oppositeOrient]) {\n axisComponent.set('orient', oppositeOrient, false);\n }\n }\n axisCount[orient]++;\n\n // TODO(https://github.com/vega/vega-lite/issues/2634): automaticaly add extra offset?\n }\n }\n\n // After merging, make sure to remove axes from child\n delete child.component.axes[channel];\n }\n }\n}\n\nfunction mergeAxisComponents(mergedAxisCmpts: AxisComponent[], childAxisCmpts: AxisComponent[]): AxisComponent[] {\n if (mergedAxisCmpts) {\n // FIXME: this is a bit wrong once we support multiple axes\n if (mergedAxisCmpts.length !== childAxisCmpts.length) {\n return undefined; // Cannot merge axis component with different number of axes.\n }\n const length = mergedAxisCmpts.length;\n for (let i = 0; i < length ; i++) {\n const merged = mergedAxisCmpts[i];\n const child = childAxisCmpts[i];\n\n if ((!!merged) !== (!!child)) {\n return undefined;\n } else if (merged && child) {\n const mergedOrient = merged.getWithExplicit('orient');\n const childOrient = child.getWithExplicit('orient');\n\n if (mergedOrient.explicit && childOrient.explicit && mergedOrient.value !== childOrient.value) {\n // TODO: throw warning if resolve is explicit (We don't have info about explicit/implicit resolve yet.)\n\n // Cannot merge due to inconsistent orient\n return undefined;\n } else {\n mergedAxisCmpts[i] = mergeAxisComponent(merged, child);\n }\n }\n }\n } else {\n // For first one, return a copy of the child\n return childAxisCmpts.map(axisComponent => axisComponent.clone());\n }\n return mergedAxisCmpts;\n}\n\nfunction mergeAxisComponent(merged: AxisComponent, child: AxisComponent): AxisComponent {\n for (const prop of VG_AXIS_PROPERTIES) {\n const mergedValueWithExplicit = mergeValuesWithExplicit(\n merged.getWithExplicit(prop),\n child.getWithExplicit(prop),\n prop, 'axis',\n\n // Tie breaker function\n (v1: Explicit, v2: Explicit) => {\n switch (prop) {\n case 'title':\n return mergeTitleComponent(v1, v2);\n case 'gridScale':\n return {\n explicit: v1.explicit, // keep the old explicit\n value: v1.value || v2.value\n };\n }\n return defaultTieBreaker(v1, v2, prop, 'axis');\n }\n );\n merged.setWithExplicit(prop, mergedValueWithExplicit);\n }\n return merged;\n}\n\nfunction getFieldDefTitle(model: UnitModel, channel: 'x' | 'y') {\n const channel2 = channel === 'x' ? 'x2' : 'y2';\n const fieldDef = model.fieldDef(channel);\n const fieldDef2 = model.fieldDef(channel2);\n\n const title1 = fieldDef ? fieldDef.title : undefined;\n const title2 = fieldDef2 ? fieldDef2.title : undefined;\n\n if (title1 && title2) {\n return mergeTitle(title1, title2);\n } else if (title1) {\n return title1;\n } else if (title2) {\n return title2;\n } else if (title1 !== undefined) { // falsy value to disable config\n return title1;\n } else if (title2 !== undefined) { // falsy value to disable config\n return title2;\n }\n\n return undefined;\n}\n\nfunction parseAxis(channel: PositionScaleChannel, model: UnitModel): AxisComponent {\n const axis = model.axis(channel);\n\n const axisComponent = new AxisComponent();\n\n // 1.2. Add properties\n VG_AXIS_PROPERTIES.forEach(function(property) {\n const value = getProperty(property, axis, channel, model);\n if (value !== undefined) {\n const explicit =\n // specified axis.values is already respected, but may get transformed.\n property === 'values' ? !!axis.values :\n // both VL axis.encoding and axis.labelAngle affect VG axis.encode\n property === 'encode' ? !!axis.encoding || !!axis.labelAngle :\n // title can be explicit if fieldDef.title is set\n property === 'title' && value === getFieldDefTitle(model, channel) ? true :\n // Otherwise, things are explicit if the returned value matches the specified property\n value === axis[property];\n\n const configValue = getAxisConfig(property, model.config, channel, axisComponent.get('orient'), model.getScaleComponent(channel).get('type'));\n\n // only set property if it is explicitly set or has no config value (otherwise we will accidentally override config)\n if (explicit || configValue === undefined) {\n // Do not apply implicit rule if there is a config value\n axisComponent.set(property, value, explicit);\n } else if (property === 'grid' && configValue) {\n // Grid is an exception because we need to set grid = true to generate another grid axis\n axisComponent.set(property, configValue, false);\n }\n }\n });\n\n // 2) Add guide encode definition groups\n const axisEncoding = axis.encoding || {};\n const axisEncode = AXIS_PARTS.reduce((e: VgAxisEncode, part) => {\n if (!axisComponent.hasAxisPart(part)) {\n // No need to create encode for a disabled part.\n return e;\n }\n\n const axisEncodingPart = guideEncodeEntry(axisEncoding[part] || {}, model);\n\n const value = part === 'labels' ?\n encode.labels(model, channel, axisEncodingPart, axisComponent.get('orient')) :\n axisEncodingPart;\n\n if (value !== undefined && keys(value).length > 0) {\n e[part] = {update: value};\n }\n return e;\n }, {} as VgAxisEncode);\n\n // FIXME: By having encode as one property, we won't have fine grained encode merging.\n if (keys(axisEncode).length > 0) {\n axisComponent.set('encode', axisEncode, !!axis.encoding || axis.labelAngle !== undefined);\n }\n\n return axisComponent;\n}\n\nfunction getProperty(property: K, specifiedAxis: Axis, channel: PositionScaleChannel, model: UnitModel): AxisComponentProps[K] {\n const fieldDef = model.fieldDef(channel);\n switch (property) {\n case 'scale':\n return model.scaleName(channel);\n case 'gridScale':\n return properties.gridScale(model, channel);\n case 'format':\n // We don't include temporal field here as we apply format in encode block\n return numberFormat(fieldDef, specifiedAxis.format, model.config);\n case 'grid': {\n const scaleType = model.getScaleComponent(channel).get('type');\n return getSpecifiedOrDefaultValue(specifiedAxis.grid, properties.grid(scaleType, fieldDef));\n }\n case 'labelFlush':\n return properties.labelFlush(fieldDef, channel, specifiedAxis);\n case 'labelOverlap': {\n const scaleType = model.getScaleComponent(channel).get('type');\n return properties.labelOverlap(fieldDef, specifiedAxis, channel, scaleType);\n }\n case 'orient':\n return getSpecifiedOrDefaultValue(specifiedAxis.orient, properties.orient(channel));\n case 'tickCount': {\n const scaleType = model.getScaleComponent(channel).get('type');\n const sizeType = channel === 'x' ? 'width' : channel === 'y' ? 'height' : undefined;\n const size = sizeType ? model.getSizeSignalRef(sizeType)\n : undefined;\n return getSpecifiedOrDefaultValue(specifiedAxis.tickCount, properties.tickCount(channel, fieldDef, scaleType, size));\n }\n case 'title':\n const channel2 = channel === 'x' ? 'x2' : 'y2';\n const fieldDef2 = model.fieldDef(channel2);\n // Keep undefined so we use default if title is unspecified.\n // For other falsy value, keep them so we will hide the title.\n const fieldDefTitle = getFieldDefTitle(model, channel);\n const specifiedTitle = fieldDefTitle !== undefined ? fieldDefTitle :\n specifiedAxis.title === undefined ? undefined : specifiedAxis.title;\n\n return getSpecifiedOrDefaultValue[]>(\n specifiedTitle,\n // If title not specified, store base parts of fieldDef (and fieldDef2 if exists)\n mergeTitleFieldDefs(\n [toFieldDefBase(fieldDef)],\n fieldDef2 ? [toFieldDefBase(fieldDef2)] : []\n )\n );\n case 'values':\n return properties.values(specifiedAxis, model, fieldDef, channel);\n }\n // Otherwise, return specified property.\n return isAxisProperty(property) ? specifiedAxis[property] : undefined;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/axis/properties.d.ts b/build/src/compile/axis/properties.d.ts new file mode 100644 index 0000000000..b25c8ae454 --- /dev/null +++ b/build/src/compile/axis/properties.d.ts @@ -0,0 +1,25 @@ +import { Axis } from '../../axis'; +import { PositionScaleChannel } from '../../channel'; +import { Config } from '../../config'; +import { FieldDef } from '../../fielddef'; +import { ScaleType } from '../../scale'; +import { VgSignalRef } from '../../vega.schema'; +import { UnitModel } from '../unit'; +/** + * Default rules for whether to show a grid should be shown for a channel. + * If `grid` is unspecified, the default value is `true` for ordinal scales that are not binned + */ +export declare function grid(scaleType: ScaleType, fieldDef: FieldDef): boolean; +export declare function gridScale(model: UnitModel, channel: PositionScaleChannel): string; +export declare function labelFlush(fieldDef: FieldDef, channel: PositionScaleChannel, specifiedAxis: Axis): number | boolean; +export declare function labelOverlap(fieldDef: FieldDef, specifiedAxis: Axis, channel: PositionScaleChannel, scaleType: ScaleType): boolean | "parity" | "greedy"; +export declare function orient(channel: PositionScaleChannel): "left" | "bottom"; +export declare function tickCount(channel: PositionScaleChannel, fieldDef: FieldDef, scaleType: ScaleType, size: VgSignalRef): { + signal: string; +}; +export declare function title(maxLength: number, fieldDef: FieldDef, config: Config): string; +export declare function values(specifiedAxis: Axis, model: UnitModel, fieldDef: FieldDef, channel: PositionScaleChannel): (string | number | boolean | import("../../../../../../../../../../Users/kanitw/Documents/_code/_idl/_visrec/vega-lite/src/datetime").DateTime | { + signal: string; +})[] | { + signal: string; +}; diff --git a/build/src/compile/axis/properties.js b/build/src/compile/axis/properties.js new file mode 100644 index 0000000000..cae772c744 --- /dev/null +++ b/build/src/compile/axis/properties.js @@ -0,0 +1,86 @@ +import { truncate } from 'vega-util'; +import { binToString } from '../../bin'; +import { X, Y } from '../../channel'; +import { title as fieldDefTitle, valueArray } from '../../fielddef'; +import * as log from '../../log'; +import { hasDiscreteDomain, isSelectionDomain } from '../../scale'; +import { QUANTITATIVE } from '../../type'; +import { contains } from '../../util'; +// TODO: we need to refactor this method after we take care of config refactoring +/** + * Default rules for whether to show a grid should be shown for a channel. + * If `grid` is unspecified, the default value is `true` for ordinal scales that are not binned + */ +export function grid(scaleType, fieldDef) { + return !hasDiscreteDomain(scaleType) && !fieldDef.bin; +} +export function gridScale(model, channel) { + var gridChannel = channel === 'x' ? 'y' : 'x'; + if (model.getScaleComponent(gridChannel)) { + return model.scaleName(gridChannel); + } + return undefined; +} +export function labelFlush(fieldDef, channel, specifiedAxis) { + if (specifiedAxis.labelFlush !== undefined) { + return specifiedAxis.labelFlush; + } + if (channel === 'x' && contains(['quantitative', 'temporal'], fieldDef.type)) { + return true; + } + return undefined; +} +export function labelOverlap(fieldDef, specifiedAxis, channel, scaleType) { + if (specifiedAxis.labelOverlap !== undefined) { + return specifiedAxis.labelOverlap; + } + // do not prevent overlap for nominal data because there is no way to infer what the missing labels are + if (fieldDef.type !== 'nominal') { + if (scaleType === 'log') { + return 'greedy'; + } + return true; + } + return undefined; +} +export function orient(channel) { + switch (channel) { + case X: + return 'bottom'; + case Y: + return 'left'; + } + /* istanbul ignore next: This should never happen. */ + throw new Error(log.message.INVALID_CHANNEL_FOR_AXIS); +} +export function tickCount(channel, fieldDef, scaleType, size) { + if (!hasDiscreteDomain(scaleType) && scaleType !== 'log' && !contains(['month', 'hours', 'day', 'quarter'], fieldDef.timeUnit)) { + if (fieldDef.bin) { + // for binned data, we don't want more ticks than maxbins + return { signal: "ceil(" + size.signal + "/20)" }; + } + return { signal: "ceil(" + size.signal + "/40)" }; + } + return undefined; +} +export function title(maxLength, fieldDef, config) { + // if not defined, automatically determine axis title from field def + var fieldTitle = fieldDefTitle(fieldDef, config); + return maxLength ? truncate(fieldTitle, maxLength) : fieldTitle; +} +export function values(specifiedAxis, model, fieldDef, channel) { + var vals = specifiedAxis.values; + if (vals) { + return valueArray(fieldDef, vals); + } + if (fieldDef.bin && fieldDef.type === QUANTITATIVE) { + var domain = model.scaleDomain(channel); + if (domain && domain !== 'unaggregated' && !isSelectionDomain(domain)) { // explicit value + return undefined; + } + var signal = model.getName(binToString(fieldDef.bin) + "_" + fieldDef.field + "_bins"); + return { signal: "sequence(" + signal + ".start, " + signal + ".stop + " + signal + ".step, " + signal + ".step)" }; + } + return undefined; +} +//# sourceMappingURL=properties.js.map \ No newline at end of file diff --git a/build/src/compile/axis/properties.js.map b/build/src/compile/axis/properties.js.map new file mode 100644 index 0000000000..5c1b2d97e2 --- /dev/null +++ b/build/src/compile/axis/properties.js.map @@ -0,0 +1 @@ +{"version":3,"file":"properties.js","sourceRoot":"","sources":["../../../../src/compile/axis/properties.ts"],"names":[],"mappings":"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","sourcesContent":["import {truncate} from 'vega-util';\nimport {Axis} from '../../axis';\nimport {binToString} from '../../bin';\nimport {PositionScaleChannel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {FieldDef, title as fieldDefTitle, valueArray} from '../../fielddef';\nimport * as log from '../../log';\nimport {hasDiscreteDomain, isSelectionDomain, ScaleType} from '../../scale';\nimport {QUANTITATIVE} from '../../type';\nimport {contains} from '../../util';\nimport {VgSignalRef} from '../../vega.schema';\nimport {UnitModel} from '../unit';\n\n\n// TODO: we need to refactor this method after we take care of config refactoring\n/**\n * Default rules for whether to show a grid should be shown for a channel.\n * If `grid` is unspecified, the default value is `true` for ordinal scales that are not binned\n */\nexport function grid(scaleType: ScaleType, fieldDef: FieldDef) {\n return !hasDiscreteDomain(scaleType) && !fieldDef.bin;\n}\n\nexport function gridScale(model: UnitModel, channel: PositionScaleChannel) {\n const gridChannel: PositionScaleChannel = channel === 'x' ? 'y' : 'x';\n if (model.getScaleComponent(gridChannel)) {\n return model.scaleName(gridChannel);\n }\n return undefined;\n}\n\nexport function labelFlush(fieldDef: FieldDef, channel: PositionScaleChannel, specifiedAxis: Axis) {\n if (specifiedAxis.labelFlush !== undefined) {\n return specifiedAxis.labelFlush;\n }\n if (channel === 'x' && contains(['quantitative', 'temporal'], fieldDef.type)) {\n return true;\n }\n return undefined;\n}\n\nexport function labelOverlap(fieldDef: FieldDef, specifiedAxis: Axis, channel: PositionScaleChannel, scaleType: ScaleType) {\n if (specifiedAxis.labelOverlap !== undefined) {\n return specifiedAxis.labelOverlap;\n }\n\n // do not prevent overlap for nominal data because there is no way to infer what the missing labels are\n if (fieldDef.type !== 'nominal') {\n if (scaleType === 'log') {\n return 'greedy';\n }\n return true;\n }\n\n return undefined;\n}\n\nexport function orient(channel: PositionScaleChannel) {\n switch (channel) {\n case X:\n return 'bottom';\n case Y:\n return 'left';\n }\n /* istanbul ignore next: This should never happen. */\n throw new Error(log.message.INVALID_CHANNEL_FOR_AXIS);\n}\n\nexport function tickCount(channel: PositionScaleChannel, fieldDef: FieldDef, scaleType: ScaleType, size: VgSignalRef) {\n if (!hasDiscreteDomain(scaleType) && scaleType !== 'log' && !contains(['month', 'hours', 'day', 'quarter'], fieldDef.timeUnit)) {\n\n if (fieldDef.bin) {\n // for binned data, we don't want more ticks than maxbins\n return {signal: `ceil(${size.signal}/20)`};\n }\n return {signal: `ceil(${size.signal}/40)`};\n }\n\n return undefined;\n}\n\nexport function title(maxLength: number, fieldDef: FieldDef, config: Config) {\n // if not defined, automatically determine axis title from field def\n const fieldTitle = fieldDefTitle(fieldDef, config);\n return maxLength ? truncate(fieldTitle, maxLength) : fieldTitle;\n}\n\nexport function values(specifiedAxis: Axis, model: UnitModel, fieldDef: FieldDef, channel: PositionScaleChannel) {\n const vals = specifiedAxis.values;\n\n if (vals) {\n return valueArray(fieldDef, vals);\n }\n\n if (fieldDef.bin && fieldDef.type === QUANTITATIVE) {\n const domain = model.scaleDomain(channel);\n if (domain && domain !== 'unaggregated' && !isSelectionDomain(domain)) { // explicit value\n return undefined;\n }\n\n const signal = model.getName(`${binToString(fieldDef.bin)}_${fieldDef.field}_bins`);\n return {signal: `sequence(${signal}.start, ${signal}.stop + ${signal}.step, ${signal}.step)`};\n }\n\n return undefined;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/baseconcat.d.ts b/build/src/compile/baseconcat.d.ts new file mode 100644 index 0000000000..e36ef8e669 --- /dev/null +++ b/build/src/compile/baseconcat.d.ts @@ -0,0 +1,18 @@ +import { Config } from '../config'; +import { Resolve } from '../resolve'; +import { BaseSpec } from '../spec'; +import { VgData, VgSignal } from '../vega.schema'; +import { Model } from './model'; +import { RepeaterValue } from './repeater'; +export declare abstract class BaseConcatModel extends Model { + constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, repeater: RepeaterValue, resolve: Resolve); + parseData(): void; + parseSelection(): void; + parseMarkGroup(): void; + parseAxisAndHeader(): void; + assembleSelectionTopLevelSignals(signals: any[]): VgSignal[]; + assembleSelectionSignals(): VgSignal[]; + assembleLayoutSignals(): VgSignal[]; + assembleSelectionData(data: VgData[]): VgData[]; + assembleMarks(): any[]; +} diff --git a/build/src/compile/baseconcat.js b/build/src/compile/baseconcat.js new file mode 100644 index 0000000000..403c14f642 --- /dev/null +++ b/build/src/compile/baseconcat.js @@ -0,0 +1,78 @@ +import * as tslib_1 from "tslib"; +import { keys } from '../util'; +import { parseData } from './data/parse'; +import { assembleLayoutSignals } from './layoutsize/assemble'; +import { Model } from './model'; +var BaseConcatModel = /** @class */ (function (_super) { + tslib_1.__extends(BaseConcatModel, _super); + function BaseConcatModel(spec, parent, parentGivenName, config, repeater, resolve) { + return _super.call(this, spec, parent, parentGivenName, config, repeater, resolve) || this; + } + BaseConcatModel.prototype.parseData = function () { + this.component.data = parseData(this); + this.children.forEach(function (child) { + child.parseData(); + }); + }; + BaseConcatModel.prototype.parseSelection = function () { + var _this = this; + // Merge selections up the hierarchy so that they may be referenced + // across unit specs. Persist their definitions within each child + // to assemble signals which remain within output Vega unit groups. + this.component.selection = {}; + var _loop_1 = function (child) { + child.parseSelection(); + keys(child.component.selection).forEach(function (key) { + _this.component.selection[key] = child.component.selection[key]; + }); + }; + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + _loop_1(child); + } + }; + BaseConcatModel.prototype.parseMarkGroup = function () { + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseMarkGroup(); + } + }; + BaseConcatModel.prototype.parseAxisAndHeader = function () { + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseAxisAndHeader(); + } + // TODO(#2415): support shared axes + }; + BaseConcatModel.prototype.assembleSelectionTopLevelSignals = function (signals) { + return this.children.reduce(function (sg, child) { return child.assembleSelectionTopLevelSignals(sg); }, signals); + }; + BaseConcatModel.prototype.assembleSelectionSignals = function () { + this.children.forEach(function (child) { return child.assembleSelectionSignals(); }); + return []; + }; + BaseConcatModel.prototype.assembleLayoutSignals = function () { + return this.children.reduce(function (signals, child) { + return signals.concat(child.assembleLayoutSignals()); + }, assembleLayoutSignals(this)); + }; + BaseConcatModel.prototype.assembleSelectionData = function (data) { + return this.children.reduce(function (db, child) { return child.assembleSelectionData(db); }, data); + }; + BaseConcatModel.prototype.assembleMarks = function () { + // only children have marks + return this.children.map(function (child) { + var title = child.assembleTitle(); + var style = child.assembleGroupStyle(); + var layoutSizeEncodeEntry = child.assembleLayoutSize(); + return tslib_1.__assign({ type: 'group', name: child.getName('group') }, (title ? { title: title } : {}), (style ? { style: style } : {}), (layoutSizeEncodeEntry ? { + encode: { + update: layoutSizeEncodeEntry + } + } : {}), child.assembleGroup()); + }); + }; + return BaseConcatModel; +}(Model)); +export { BaseConcatModel }; +//# sourceMappingURL=baseconcat.js.map \ No newline at end of file diff --git a/build/src/compile/baseconcat.js.map b/build/src/compile/baseconcat.js.map new file mode 100644 index 0000000000..ca41e8ff6f --- /dev/null +++ b/build/src/compile/baseconcat.js.map @@ -0,0 +1 @@ +{"version":3,"file":"baseconcat.js","sourceRoot":"","sources":["../../../src/compile/baseconcat.ts"],"names":[],"mappings":"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","sourcesContent":["import {Config} from '../config';\nimport {Resolve} from '../resolve';\nimport {BaseSpec} from '../spec';\nimport {keys} from '../util';\nimport {VgData, VgSignal} from '../vega.schema';\nimport {parseData} from './data/parse';\nimport {assembleLayoutSignals} from './layoutsize/assemble';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\n\nexport abstract class BaseConcatModel extends Model {\n constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, repeater: RepeaterValue, resolve: Resolve) {\n super(spec, parent, parentGivenName, config, repeater, resolve);\n }\n\n public parseData() {\n this.component.data = parseData(this);\n this.children.forEach((child) => {\n child.parseData();\n });\n }\n public parseSelection() {\n // Merge selections up the hierarchy so that they may be referenced\n // across unit specs. Persist their definitions within each child\n // to assemble signals which remain within output Vega unit groups.\n this.component.selection = {};\n for (const child of this.children) {\n child.parseSelection();\n keys(child.component.selection).forEach((key) => {\n this.component.selection[key] = child.component.selection[key];\n });\n }\n }\n\n public parseMarkGroup() {\n for (const child of this.children) {\n child.parseMarkGroup();\n }\n }\n\n public parseAxisAndHeader() {\n for (const child of this.children) {\n child.parseAxisAndHeader();\n }\n\n // TODO(#2415): support shared axes\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return this.children.reduce((sg, child) => child.assembleSelectionTopLevelSignals(sg), signals);\n }\n\n public assembleSelectionSignals(): VgSignal[] {\n this.children.forEach((child) => child.assembleSelectionSignals());\n return [];\n }\n\n public assembleLayoutSignals(): VgSignal[] {\n return this.children.reduce((signals, child) => {\n return signals.concat(child.assembleLayoutSignals());\n }, assembleLayoutSignals(this));\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return this.children.reduce((db, child) => child.assembleSelectionData(db), data);\n }\n\n public assembleMarks(): any[] {\n // only children have marks\n return this.children.map(child => {\n const title = child.assembleTitle();\n const style = child.assembleGroupStyle();\n const layoutSizeEncodeEntry = child.assembleLayoutSize();\n return {\n type: 'group',\n name: child.getName('group'),\n ...(title ? {title} : {}),\n ...(style ? {style} : {}),\n ...(layoutSizeEncodeEntry ? {\n encode: {\n update: layoutSizeEncodeEntry\n }\n } : {}),\n ...child.assembleGroup()\n };\n });\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/buildmodel.d.ts b/build/src/compile/buildmodel.d.ts new file mode 100644 index 0000000000..3ee1a1ffd4 --- /dev/null +++ b/build/src/compile/buildmodel.d.ts @@ -0,0 +1,5 @@ +import { Config } from '../config'; +import { LayoutSizeMixins, NormalizedSpec } from '../spec'; +import { Model } from './model'; +import { RepeaterValue } from './repeater'; +export declare function buildModel(spec: NormalizedSpec, parent: Model, parentGivenName: string, unitSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean): Model; diff --git a/build/src/compile/buildmodel.js b/build/src/compile/buildmodel.js new file mode 100644 index 0000000000..6c4d75ddff --- /dev/null +++ b/build/src/compile/buildmodel.js @@ -0,0 +1,26 @@ +import * as log from '../log'; +import { isConcatSpec, isFacetSpec, isLayerSpec, isRepeatSpec, isUnitSpec } from '../spec'; +import { ConcatModel } from './concat'; +import { FacetModel } from './facet'; +import { LayerModel } from './layer'; +import { RepeatModel } from './repeat'; +import { UnitModel } from './unit'; +export function buildModel(spec, parent, parentGivenName, unitSize, repeater, config, fit) { + if (isFacetSpec(spec)) { + return new FacetModel(spec, parent, parentGivenName, repeater, config); + } + if (isLayerSpec(spec)) { + return new LayerModel(spec, parent, parentGivenName, unitSize, repeater, config, fit); + } + if (isUnitSpec(spec)) { + return new UnitModel(spec, parent, parentGivenName, unitSize, repeater, config, fit); + } + if (isRepeatSpec(spec)) { + return new RepeatModel(spec, parent, parentGivenName, repeater, config); + } + if (isConcatSpec(spec)) { + return new ConcatModel(spec, parent, parentGivenName, repeater, config); + } + throw new Error(log.message.INVALID_SPEC); +} +//# sourceMappingURL=buildmodel.js.map \ No newline at end of file diff --git a/build/src/compile/buildmodel.js.map b/build/src/compile/buildmodel.js.map new file mode 100644 index 0000000000..35245e47b5 --- /dev/null +++ b/build/src/compile/buildmodel.js.map @@ -0,0 +1 @@ +{"version":3,"file":"buildmodel.js","sourceRoot":"","sources":["../../../src/compile/buildmodel.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAmC,MAAM,SAAS,CAAC;AAC3H,OAAO,EAAC,WAAW,EAAC,MAAM,UAAU,CAAC;AACrC,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AACnC,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AAEnC,OAAO,EAAC,WAAW,EAAC,MAAM,UAAU,CAAC;AAErC,OAAO,EAAC,SAAS,EAAC,MAAM,QAAQ,CAAC;AAEjC,MAAM,qBAAqB,IAAoB,EAAE,MAAa,EAAE,eAAuB,EACrF,QAA0B,EAAE,QAAuB,EAAE,MAAc,EAAE,GAAY;IACjF,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE;QACrB,OAAO,IAAI,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;KACxE;IAED,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE;QACrB,OAAO,IAAI,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;KACvF;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE;QACpB,OAAO,IAAI,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;KACtF;IAED,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE;QACtB,OAAO,IAAI,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;KACzE;IAED,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE;QACtB,OAAO,IAAI,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;KACzE;IAED,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;AAC5C,CAAC","sourcesContent":["import {Config} from '../config';\nimport * as log from '../log';\nimport {isConcatSpec, isFacetSpec, isLayerSpec, isRepeatSpec, isUnitSpec, LayoutSizeMixins, NormalizedSpec} from '../spec';\nimport {ConcatModel} from './concat';\nimport {FacetModel} from './facet';\nimport {LayerModel} from './layer';\nimport {Model} from './model';\nimport {RepeatModel} from './repeat';\nimport {RepeaterValue} from './repeater';\nimport {UnitModel} from './unit';\n\nexport function buildModel(spec: NormalizedSpec, parent: Model, parentGivenName: string,\n unitSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean): Model {\n if (isFacetSpec(spec)) {\n return new FacetModel(spec, parent, parentGivenName, repeater, config);\n }\n\n if (isLayerSpec(spec)) {\n return new LayerModel(spec, parent, parentGivenName, unitSize, repeater, config, fit);\n }\n\n if (isUnitSpec(spec)) {\n return new UnitModel(spec, parent, parentGivenName, unitSize, repeater, config, fit);\n }\n\n if (isRepeatSpec(spec)) {\n return new RepeatModel(spec, parent, parentGivenName, repeater, config);\n }\n\n if (isConcatSpec(spec)) {\n return new ConcatModel(spec, parent, parentGivenName, repeater, config);\n }\n\n throw new Error(log.message.INVALID_SPEC);\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/common.d.ts b/build/src/compile/common.d.ts new file mode 100644 index 0000000000..f98be9ef87 --- /dev/null +++ b/build/src/compile/common.d.ts @@ -0,0 +1,58 @@ +import { Channel } from '../channel'; +import { Config, ViewConfig } from '../config'; +import { FieldDef, FieldDefBase, FieldRefOption, OrderFieldDef } from '../fielddef'; +import { GuideEncodingEntry } from '../guide'; +import { MarkConfig, MarkDef, TextConfig } from '../mark'; +import { TimeUnit } from '../timeunit'; +import { VgEncodeEntry, VgSort } from '../vega.schema'; +import { AxisComponentProps } from './axis/component'; +import { Explicit } from './split'; +import { UnitModel } from './unit'; +export declare function applyConfig(e: VgEncodeEntry, config: ViewConfig | MarkConfig | TextConfig, // TODO(#1842): consolidate MarkConfig | TextConfig? +propsList: string[]): VgEncodeEntry; +export declare function applyMarkConfig(e: VgEncodeEntry, model: UnitModel, propsList: (keyof MarkConfig)[]): VgEncodeEntry; +export declare function getStyles(mark: MarkDef): string[]; +/** + * Return property value from style or mark specific config property if exists. + * Otherwise, return general mark specific config. + */ +export declare function getMarkConfig

(prop: P, mark: MarkDef, config: Config): MarkConfig[P]; +export declare function formatSignalRef(fieldDef: FieldDef, specifiedFormat: string, expr: 'datum' | 'parent', config: Config): { + signal: string; +}; +export declare function getSpecifiedOrDefaultValue(specifiedValue: T, defaultValue: T | { + signal: string; +}): T | { + signal: string; +}; +/** + * Returns number format for a fieldDef + * + * @param format explicitly specified format + */ +export declare function numberFormat(fieldDef: FieldDef, specifiedFormat: string, config: Config): string; +export declare function numberFormatExpr(field: string, specifiedFormat: string, config: Config): string; +export declare function binFormatExpression(startField: string, endField: string, format: string, config: Config): string; +/** + * Returns the time expression used for axis/legend labels or text mark for a temporal field + */ +export declare function timeFormatExpression(field: string, timeUnit: TimeUnit, format: string, shortTimeLabels: boolean, timeFormatConfig: string, isUTCScale: boolean, alwaysReturn?: boolean): string; +/** + * Return Vega sort parameters (tuple of field and order). + */ +export declare function sortParams(orderDef: OrderFieldDef | OrderFieldDef[], fieldRefOption?: FieldRefOption): VgSort; +export declare type AxisTitleComponent = AxisComponentProps['title']; +export declare function mergeTitleFieldDefs(f1: FieldDefBase[], f2: FieldDefBase[]): FieldDefBase[]; +export declare function mergeTitle(title1: string, title2: string): string; +export declare function mergeTitleComponent(v1: Explicit, v2: Explicit): { + explicit: boolean; + value: FieldDefBase[]; +} | { + explicit: boolean; + value: string; +}; +/** + * Checks whether a fieldDef for a particular channel requires a computed bin range. + */ +export declare function binRequiresRange(fieldDef: FieldDef, channel: Channel): boolean; +export declare function guideEncodeEntry(encoding: GuideEncodingEntry, model: UnitModel): {}; diff --git a/build/src/compile/common.js b/build/src/compile/common.js new file mode 100644 index 0000000000..7685369313 --- /dev/null +++ b/build/src/compile/common.js @@ -0,0 +1,200 @@ +import * as tslib_1 from "tslib"; +import { isArray } from 'vega-util'; +import { isScaleChannel } from '../channel'; +import { isScaleFieldDef, isTimeFieldDef, vgField } from '../fielddef'; +import { ScaleType } from '../scale'; +import { formatExpression } from '../timeunit'; +import { QUANTITATIVE } from '../type'; +import { contains, keys, stringify } from '../util'; +import { wrapCondition } from './mark/mixins'; +export function applyConfig(e, config, // TODO(#1842): consolidate MarkConfig | TextConfig? +propsList) { + for (var _i = 0, propsList_1 = propsList; _i < propsList_1.length; _i++) { + var property = propsList_1[_i]; + var value = config[property]; + if (value !== undefined) { + e[property] = { value: value }; + } + } + return e; +} +export function applyMarkConfig(e, model, propsList) { + for (var _i = 0, propsList_2 = propsList; _i < propsList_2.length; _i++) { + var property = propsList_2[_i]; + var value = getMarkConfig(property, model.markDef, model.config); + if (value !== undefined) { + e[property] = { value: value }; + } + } + return e; +} +export function getStyles(mark) { + return [].concat(mark.type, mark.style || []); +} +/** + * Return property value from style or mark specific config property if exists. + * Otherwise, return general mark specific config. + */ +export function getMarkConfig(prop, mark, config) { + // By default, read from mark config first! + var value = config.mark[prop]; + // Then read mark specific config, which has higher precedence + var markSpecificConfig = config[mark.type]; + if (markSpecificConfig[prop] !== undefined) { + value = markSpecificConfig[prop]; + } + // Then read style config, which has even higher precedence. + var styles = getStyles(mark); + for (var _i = 0, styles_1 = styles; _i < styles_1.length; _i++) { + var style = styles_1[_i]; + var styleConfig = config.style[style]; + // MarkConfig extends VgMarkConfig so a prop may not be a valid property for style + // However here we also check if it is defined, so it is okay to cast here + var p = prop; + if (styleConfig && styleConfig[p] !== undefined) { + value = styleConfig[p]; + } + } + return value; +} +export function formatSignalRef(fieldDef, specifiedFormat, expr, config) { + var format = numberFormat(fieldDef, specifiedFormat, config); + if (fieldDef.bin) { + var startField = vgField(fieldDef, { expr: expr }); + var endField = vgField(fieldDef, { expr: expr, binSuffix: 'end' }); + return { + signal: binFormatExpression(startField, endField, format, config) + }; + } + else if (fieldDef.type === 'quantitative') { + return { + signal: "" + formatExpr(vgField(fieldDef, { expr: expr, binSuffix: 'range' }), format) + }; + } + else if (isTimeFieldDef(fieldDef)) { + var isUTCScale = isScaleFieldDef(fieldDef) && fieldDef['scale'] && fieldDef['scale'].type === ScaleType.UTC; + return { + signal: timeFormatExpression(vgField(fieldDef, { expr: expr }), fieldDef.timeUnit, specifiedFormat, config.text.shortTimeLabels, config.timeFormat, isUTCScale, true) + }; + } + else { + return { + signal: "''+" + vgField(fieldDef, { expr: expr }) + }; + } +} +export function getSpecifiedOrDefaultValue(specifiedValue, defaultValue) { + if (specifiedValue !== undefined) { + return specifiedValue; + } + return defaultValue; +} +/** + * Returns number format for a fieldDef + * + * @param format explicitly specified format + */ +export function numberFormat(fieldDef, specifiedFormat, config) { + if (fieldDef.type === QUANTITATIVE) { + // add number format for quantitative type only + // Specified format in axis/legend has higher precedence than fieldDef.format + if (specifiedFormat) { + return specifiedFormat; + } + // TODO: need to make this work correctly for numeric ordinal / nominal type + return config.numberFormat; + } + return undefined; +} +function formatExpr(field, format) { + return "format(" + field + ", \"" + (format || '') + "\")"; +} +export function numberFormatExpr(field, specifiedFormat, config) { + return formatExpr(field, specifiedFormat || config.numberFormat); +} +export function binFormatExpression(startField, endField, format, config) { + return startField + " === null || isNaN(" + startField + ") ? \"null\" : " + numberFormatExpr(startField, format, config) + " + \" - \" + " + numberFormatExpr(endField, format, config); +} +/** + * Returns the time expression used for axis/legend labels or text mark for a temporal field + */ +export function timeFormatExpression(field, timeUnit, format, shortTimeLabels, timeFormatConfig, isUTCScale, alwaysReturn) { + if (alwaysReturn === void 0) { alwaysReturn = false; } + if (!timeUnit || format) { + // If there is not time unit, or if user explicitly specify format for axis/legend/text. + format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit. + if (format || alwaysReturn) { + return (isUTCScale ? 'utc' : 'time') + "Format(" + field + ", '" + format + "')"; + } + else { + return undefined; + } + } + else { + return formatExpression(timeUnit, field, shortTimeLabels, isUTCScale); + } +} +/** + * Return Vega sort parameters (tuple of field and order). + */ +export function sortParams(orderDef, fieldRefOption) { + return (isArray(orderDef) ? orderDef : [orderDef]).reduce(function (s, orderChannelDef) { + s.field.push(vgField(orderChannelDef, fieldRefOption)); + s.order.push(orderChannelDef.sort || 'ascending'); + return s; + }, { field: [], order: [] }); +} +export function mergeTitleFieldDefs(f1, f2) { + var merged = f1.slice(); + f2.forEach(function (fdToMerge) { + for (var _i = 0, merged_1 = merged; _i < merged_1.length; _i++) { + var fieldDef1 = merged_1[_i]; + // If already exists, no need to append to merged array + if (stringify(fieldDef1) === stringify(fdToMerge)) { + return; + } + } + merged.push(fdToMerge); + }); + return merged; +} +export function mergeTitle(title1, title2) { + return title1 === title2 ? + title1 : // if title is the same just use one of them + title1 + ', ' + title2; // join title with comma if different +} +export function mergeTitleComponent(v1, v2) { + if (isArray(v1.value) && isArray(v2.value)) { + return { + explicit: v1.explicit, + value: mergeTitleFieldDefs(v1.value, v2.value) + }; + } + else if (!isArray(v1.value) && !isArray(v2.value)) { + return { + explicit: v1.explicit, + value: mergeTitle(v1.value, v2.value) + }; + } + /* istanbul ignore next: Condition should not happen -- only for warning in development. */ + throw new Error('It should never reach here'); +} +/** + * Checks whether a fieldDef for a particular channel requires a computed bin range. + */ +export function binRequiresRange(fieldDef, channel) { + if (!fieldDef.bin) { + console.warn('Only use this method with binned field defs'); + return false; + } + // We need the range only when the user explicitly forces a binned field to be use discrete scale. In this case, bin range is used in axis and legend labels. + // We could check whether the axis or legend exists (not disabled) but that seems overkill. + return isScaleChannel(channel) && contains(['ordinal', 'nominal'], fieldDef.type); +} +export function guideEncodeEntry(encoding, model) { + return keys(encoding).reduce(function (encode, channel) { + var valueDef = encoding[channel]; + return tslib_1.__assign({}, encode, wrapCondition(model, valueDef, channel, function (x) { return ({ value: x.value }); })); + }, {}); +} +//# sourceMappingURL=common.js.map \ No newline at end of file diff --git a/build/src/compile/common.js.map b/build/src/compile/common.js.map new file mode 100644 index 0000000000..f921e9b96d --- /dev/null +++ b/build/src/compile/common.js.map @@ -0,0 +1 @@ +{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/compile/common.ts"],"names":[],"mappings":"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","sourcesContent":["import {isArray} from 'vega-util';\nimport {Channel, isScaleChannel} from '../channel';\nimport {Config, ViewConfig} from '../config';\nimport {FieldDef, FieldDefBase, FieldRefOption, isScaleFieldDef, isTimeFieldDef, OrderFieldDef, ValueDef, vgField} from '../fielddef';\nimport {GuideEncodingEntry} from '../guide';\nimport {MarkConfig, MarkDef, TextConfig} from '../mark';\nimport {ScaleType} from '../scale';\nimport {formatExpression, TimeUnit} from '../timeunit';\nimport {QUANTITATIVE} from '../type';\nimport {contains, keys, stringify} from '../util';\nimport {VgEncodeChannel, VgEncodeEntry, VgMarkConfig, VgSort} from '../vega.schema';\nimport {AxisComponentProps} from './axis/component';\nimport {wrapCondition} from './mark/mixins';\nimport {Explicit} from './split';\nimport {UnitModel} from './unit';\n\n\nexport function applyConfig(e: VgEncodeEntry,\n config: ViewConfig | MarkConfig | TextConfig, // TODO(#1842): consolidate MarkConfig | TextConfig?\n propsList: string[]) {\n for (const property of propsList) {\n const value = config[property];\n if (value !== undefined) {\n e[property] = {value: value};\n }\n }\n return e;\n}\n\nexport function applyMarkConfig(e: VgEncodeEntry, model: UnitModel, propsList: (keyof MarkConfig)[]) {\n for (const property of propsList) {\n const value = getMarkConfig(property, model.markDef, model.config);\n if (value !== undefined) {\n e[property] = {value: value};\n }\n }\n return e;\n}\n\nexport function getStyles(mark: MarkDef): string[] {\n return [].concat(mark.type, mark.style || []);\n}\n\n/**\n * Return property value from style or mark specific config property if exists.\n * Otherwise, return general mark specific config.\n */\nexport function getMarkConfig

(prop: P, mark: MarkDef, config: Config): MarkConfig[P] {\n // By default, read from mark config first!\n let value = config.mark[prop];\n\n // Then read mark specific config, which has higher precedence\n const markSpecificConfig = config[mark.type];\n if (markSpecificConfig[prop] !== undefined) {\n value = markSpecificConfig[prop];\n }\n\n // Then read style config, which has even higher precedence.\n const styles = getStyles(mark);\n for (const style of styles) {\n const styleConfig = config.style[style];\n\n // MarkConfig extends VgMarkConfig so a prop may not be a valid property for style\n // However here we also check if it is defined, so it is okay to cast here\n const p = prop as keyof VgMarkConfig;\n if (styleConfig && styleConfig[p] !== undefined) {\n value = styleConfig[p];\n }\n }\n\n return value;\n}\n\nexport function formatSignalRef(fieldDef: FieldDef, specifiedFormat: string, expr: 'datum' | 'parent', config: Config) {\n const format = numberFormat(fieldDef, specifiedFormat, config);\n if (fieldDef.bin) {\n const startField = vgField(fieldDef, {expr});\n const endField = vgField(fieldDef, {expr, binSuffix: 'end'});\n return {\n signal: binFormatExpression(startField, endField, format, config)\n };\n } else if (fieldDef.type === 'quantitative') {\n return {\n signal: `${formatExpr(vgField(fieldDef, {expr, binSuffix: 'range'}), format)}`\n };\n } else if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = isScaleFieldDef(fieldDef) && fieldDef['scale'] && fieldDef['scale'].type === ScaleType.UTC;\n return {\n signal: timeFormatExpression(vgField(fieldDef, {expr}), fieldDef.timeUnit, specifiedFormat, config.text.shortTimeLabels, config.timeFormat, isUTCScale, true)\n };\n } else {\n return {\n signal: `''+${vgField(fieldDef, {expr})}`\n };\n }\n}\n\nexport function getSpecifiedOrDefaultValue(specifiedValue: T, defaultValue: T | {signal: string}) {\n if (specifiedValue !== undefined) {\n return specifiedValue;\n }\n return defaultValue;\n}\n\n/**\n * Returns number format for a fieldDef\n *\n * @param format explicitly specified format\n */\nexport function numberFormat(fieldDef: FieldDef, specifiedFormat: string, config: Config) {\n if (fieldDef.type === QUANTITATIVE) {\n // add number format for quantitative type only\n\n // Specified format in axis/legend has higher precedence than fieldDef.format\n if (specifiedFormat) {\n return specifiedFormat;\n }\n\n // TODO: need to make this work correctly for numeric ordinal / nominal type\n return config.numberFormat;\n }\n return undefined;\n}\n\nfunction formatExpr(field: string, format: string) {\n return `format(${field}, \"${format || ''}\")`;\n}\n\nexport function numberFormatExpr(field: string, specifiedFormat: string, config: Config) {\n return formatExpr(field, specifiedFormat || config.numberFormat);\n}\n\n\nexport function binFormatExpression(startField: string, endField: string, format: string, config: Config) {\n return `${startField} === null || isNaN(${startField}) ? \"null\" : ${numberFormatExpr(startField, format, config)} + \" - \" + ${numberFormatExpr(endField, format, config)}`;\n}\n\n\n/**\n * Returns the time expression used for axis/legend labels or text mark for a temporal field\n */\nexport function timeFormatExpression(field: string, timeUnit: TimeUnit, format: string, shortTimeLabels: boolean, timeFormatConfig: string, isUTCScale: boolean, alwaysReturn: boolean = false): string {\n if (!timeUnit || format) {\n // If there is not time unit, or if user explicitly specify format for axis/legend/text.\n format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit.\n\n if (format || alwaysReturn) {\n return `${isUTCScale ? 'utc' : 'time'}Format(${field}, '${format}')`;\n } else {\n return undefined;\n }\n } else {\n return formatExpression(timeUnit, field, shortTimeLabels, isUTCScale);\n }\n}\n\n/**\n * Return Vega sort parameters (tuple of field and order).\n */\nexport function sortParams(orderDef: OrderFieldDef | OrderFieldDef[], fieldRefOption?: FieldRefOption): VgSort {\n return (isArray(orderDef) ? orderDef : [orderDef]).reduce((s, orderChannelDef) => {\n s.field.push(vgField(orderChannelDef, fieldRefOption));\n s.order.push(orderChannelDef.sort || 'ascending');\n return s;\n }, {field:[], order: []});\n}\n\nexport type AxisTitleComponent = AxisComponentProps['title'];\n\nexport function mergeTitleFieldDefs(f1: FieldDefBase[], f2: FieldDefBase[]) {\n const merged = [...f1];\n\n f2.forEach((fdToMerge) => {\n for (const fieldDef1 of merged) {\n // If already exists, no need to append to merged array\n if (stringify(fieldDef1) === stringify(fdToMerge)) {\n return;\n }\n }\n merged.push(fdToMerge);\n });\n return merged;\n}\n\nexport function mergeTitle(title1: string, title2: string) {\n return title1 === title2 ?\n title1 : // if title is the same just use one of them\n title1 + ', ' + title2; // join title with comma if different\n}\n\nexport function mergeTitleComponent(\n v1: Explicit, v2: Explicit\n) {\n if (isArray(v1.value) && isArray(v2.value)) {\n return {\n explicit: v1.explicit,\n value: mergeTitleFieldDefs(v1.value, v2.value)\n };\n } else if (!isArray(v1.value) && !isArray(v2.value)) {\n return {\n explicit: v1.explicit, // keep the old explicit\n value: mergeTitle(v1.value, v2.value)\n };\n }\n /* istanbul ignore next: Condition should not happen -- only for warning in development. */\n throw new Error('It should never reach here');\n}\n\n/**\n * Checks whether a fieldDef for a particular channel requires a computed bin range.\n */\nexport function binRequiresRange(fieldDef: FieldDef, channel: Channel) {\n if (!fieldDef.bin) {\n console.warn('Only use this method with binned field defs');\n return false;\n }\n\n // We need the range only when the user explicitly forces a binned field to be use discrete scale. In this case, bin range is used in axis and legend labels.\n // We could check whether the axis or legend exists (not disabled) but that seems overkill.\n return isScaleChannel(channel) && contains(['ordinal', 'nominal'], fieldDef.type);\n}\n\nexport function guideEncodeEntry(encoding: GuideEncodingEntry, model: UnitModel) {\n return keys(encoding).reduce((encode, channel: VgEncodeChannel) => {\n const valueDef = encoding[channel];\n return {\n ...encode,\n ...wrapCondition(model, valueDef, channel, (x: ValueDef) => ({value: x.value}))\n };\n }, {});\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/compile.d.ts b/build/src/compile/compile.d.ts new file mode 100644 index 0000000000..a062704e38 --- /dev/null +++ b/build/src/compile/compile.d.ts @@ -0,0 +1,39 @@ +import { Config } from '../config'; +import * as vlFieldDef from '../fielddef'; +import * as log from '../log'; +import { TopLevelSpec } from '../spec'; +export interface CompileOptions { + config?: Config; + logger?: log.LoggerInterface; + fieldTitle?: vlFieldDef.FieldTitleFormatter; +} +/** + * Vega-Lite's main function, for compiling Vega-lite spec into Vega spec. + * + * At a high-level, we make the following transformations in different phases: + * + * Input spec + * | + * | (Normalization) + * v + * Normalized Spec (Row/Column channels in single-view specs becomes faceted specs, composite marks becomes layered specs.) + * | + * | (Build Model) + * v + * A model tree of the spec + * | + * | (Parse) + * v + * A model tree with parsed components (intermediate structure of visualization primitives in a format that can be easily merged) + * | + * | (Optimize) + * v + * A model tree with parsed components with the data component optimized + * | + * | (Assemble) + * v + * Vega spec + */ +export declare function compile(inputSpec: TopLevelSpec, opt?: CompileOptions): { + spec: any; +}; diff --git a/build/src/compile/compile.js b/build/src/compile/compile.js new file mode 100644 index 0000000000..77d27a51cb --- /dev/null +++ b/build/src/compile/compile.js @@ -0,0 +1,123 @@ +import * as tslib_1 from "tslib"; +import { initConfig, stripAndRedirectConfig } from '../config'; +import * as vlFieldDef from '../fielddef'; +import * as log from '../log'; +import { isLayerSpec, isUnitSpec, normalize } from '../spec'; +import { extractTopLevelProperties, normalizeAutoSize } from '../toplevelprops'; +import { keys, mergeDeep } from '../util'; +import { buildModel } from './buildmodel'; +import { assembleRootData } from './data/assemble'; +import { optimizeDataflow } from './data/optimize'; +/** + * Vega-Lite's main function, for compiling Vega-lite spec into Vega spec. + * + * At a high-level, we make the following transformations in different phases: + * + * Input spec + * | + * | (Normalization) + * v + * Normalized Spec (Row/Column channels in single-view specs becomes faceted specs, composite marks becomes layered specs.) + * | + * | (Build Model) + * v + * A model tree of the spec + * | + * | (Parse) + * v + * A model tree with parsed components (intermediate structure of visualization primitives in a format that can be easily merged) + * | + * | (Optimize) + * v + * A model tree with parsed components with the data component optimized + * | + * | (Assemble) + * v + * Vega spec + */ +export function compile(inputSpec, opt) { + if (opt === void 0) { opt = {}; } + // 0. Augment opt with default opts + if (opt.logger) { + // set the singleton logger to the provided logger + log.set(opt.logger); + } + if (opt.fieldTitle) { + // set the singleton field title formatter + vlFieldDef.setTitleFormatter(opt.fieldTitle); + } + try { + // 1. Initialize config by deep merging default config with the config provided via option and the input spec. + var config = initConfig(mergeDeep({}, opt.config, inputSpec.config)); + // 2. Normalize: Convert input spec -> normalized spec + // - Decompose all extended unit specs into composition of unit spec. For example, a box plot get expanded into multiple layers of bars, ticks, and rules. The shorthand row/column channel is also expanded to a facet spec. + var spec = normalize(inputSpec, config); + // - Normalize autosize to be a autosize properties object. + var autosize = normalizeAutoSize(inputSpec.autosize, config.autosize, isLayerSpec(spec) || isUnitSpec(spec)); + // 3. Build Model: normalized spec -> Model (a tree structure) + // This phases instantiates the models with default config by doing a top-down traversal. This allows us to pass properties that child models derive from their parents via their constructors. + // See the abstract `Model` class and its children (UnitModel, LayerModel, FacetModel, RepeatModel, ConcatModel) for different types of models. + var model = buildModel(spec, null, '', undefined, undefined, config, autosize.type === 'fit'); + // 4 Parse: Model --> Model with components + // Note that components = intermediate representations that are equivalent to Vega specs. + // We need these intermediate representation because we need to merge many visualizaiton "components" like projections, scales, axes, and legends. + // We will later convert these components into actual Vega specs in the assemble phase. + // In this phase, we do a bottom-up traversal over the whole tree to + // parse for each type of components once (e.g., data, layout, mark, scale). + // By doing bottom-up traversal, we start parsing components of unit specs and + // then merge child components of parent composite specs. + // + // Please see inside model.parse() for order of different components parsed. + model.parse(); + // 5. Optimize the dataflow. This will modify the data component of the model. + optimizeDataflow(model.component.data); + // 6. Assemble: convert model components --> Vega Spec. + return assembleTopLevelModel(model, getTopLevelProperties(inputSpec, config, autosize)); + } + finally { + // Reset the singleton logger if a logger is provided + if (opt.logger) { + log.reset(); + } + // Reset the singleton field title formatter if provided + if (opt.fieldTitle) { + vlFieldDef.resetTitleFormatter(); + } + } +} +function getTopLevelProperties(topLevelSpec, config, autosize) { + return tslib_1.__assign({ autosize: keys(autosize).length === 1 && autosize.type ? autosize.type : autosize }, extractTopLevelProperties(config), extractTopLevelProperties(topLevelSpec)); +} +/* + * Assemble the top-level model. + * + * Note: this couldn't be `model.assemble()` since the top-level model + * needs some special treatment to generate top-level properties. + */ +function assembleTopLevelModel(model, topLevelProperties) { + // TODO: change type to become VgSpec + // Config with Vega-Lite only config removed. + var vgConfig = model.config ? stripAndRedirectConfig(model.config) : undefined; + var data = [].concat(model.assembleSelectionData([]), + // only assemble data in the root + assembleRootData(model.component.data, topLevelProperties.datasets || {})); + delete topLevelProperties.datasets; + var projections = model.assembleProjections(); + var title = model.assembleTitle(); + var style = model.assembleGroupStyle(); + var layoutSignals = model.assembleLayoutSignals(); + // move width and height signals with values to top level + layoutSignals = layoutSignals.filter(function (signal) { + if ((signal.name === 'width' || signal.name === 'height') && signal.value !== undefined) { + topLevelProperties[signal.name] = +signal.value; + return false; + } + return true; + }); + var output = tslib_1.__assign({ $schema: 'https://vega.github.io/schema/vega/v3.json' }, (model.description ? { description: model.description } : {}), topLevelProperties, (title ? { title: title } : {}), (style ? { style: style } : {}), { data: data }, (projections.length > 0 ? { projections: projections } : {}), model.assembleGroup(layoutSignals.concat(model.assembleSelectionTopLevelSignals([]))), (vgConfig ? { config: vgConfig } : {})); + return { + spec: output + // TODO: add warning / errors here + }; +} +//# sourceMappingURL=compile.js.map \ No newline at end of file diff --git a/build/src/compile/compile.js.map b/build/src/compile/compile.js.map new file mode 100644 index 0000000000..97035e546c --- /dev/null +++ b/build/src/compile/compile.js.map @@ -0,0 +1 @@ +{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../../src/compile/compile.ts"],"names":[],"mappings":"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","sourcesContent":["import {Config, initConfig, stripAndRedirectConfig} from '../config';\nimport * as vlFieldDef from '../fielddef';\nimport * as log from '../log';\nimport {isLayerSpec, isUnitSpec, LayoutSizeMixins, normalize, TopLevel, TopLevelSpec} from '../spec';\nimport {AutoSizeParams, extractTopLevelProperties, normalizeAutoSize, TopLevelProperties} from '../toplevelprops';\nimport {keys, mergeDeep} from '../util';\nimport {buildModel} from './buildmodel';\nimport {assembleRootData} from './data/assemble';\nimport {optimizeDataflow} from './data/optimize';\nimport {Model} from './model';\n\nexport interface CompileOptions {\n config?: Config;\n logger?: log.LoggerInterface;\n\n fieldTitle?: vlFieldDef.FieldTitleFormatter;\n}\n\n/**\n * Vega-Lite's main function, for compiling Vega-lite spec into Vega spec.\n *\n * At a high-level, we make the following transformations in different phases:\n *\n * Input spec\n * |\n * | (Normalization)\n * v\n * Normalized Spec (Row/Column channels in single-view specs becomes faceted specs, composite marks becomes layered specs.)\n * |\n * | (Build Model)\n * v\n * A model tree of the spec\n * |\n * | (Parse)\n * v\n * A model tree with parsed components (intermediate structure of visualization primitives in a format that can be easily merged)\n * |\n * | (Optimize)\n * v\n * A model tree with parsed components with the data component optimized\n * |\n * | (Assemble)\n * v\n * Vega spec\n */\nexport function compile(inputSpec: TopLevelSpec, opt: CompileOptions = {}) {\n // 0. Augment opt with default opts\n if (opt.logger) {\n // set the singleton logger to the provided logger\n log.set(opt.logger);\n }\n\n if (opt.fieldTitle) {\n // set the singleton field title formatter\n vlFieldDef.setTitleFormatter(opt.fieldTitle);\n }\n\n try {\n // 1. Initialize config by deep merging default config with the config provided via option and the input spec.\n const config = initConfig(mergeDeep({}, opt.config, inputSpec.config));\n\n // 2. Normalize: Convert input spec -> normalized spec\n\n // - Decompose all extended unit specs into composition of unit spec. For example, a box plot get expanded into multiple layers of bars, ticks, and rules. The shorthand row/column channel is also expanded to a facet spec.\n const spec = normalize(inputSpec, config);\n // - Normalize autosize to be a autosize properties object.\n const autosize = normalizeAutoSize(inputSpec.autosize, config.autosize, isLayerSpec(spec) || isUnitSpec(spec));\n\n // 3. Build Model: normalized spec -> Model (a tree structure)\n\n // This phases instantiates the models with default config by doing a top-down traversal. This allows us to pass properties that child models derive from their parents via their constructors.\n // See the abstract `Model` class and its children (UnitModel, LayerModel, FacetModel, RepeatModel, ConcatModel) for different types of models.\n const model: Model = buildModel(spec, null, '', undefined, undefined, config, autosize.type === 'fit');\n\n // 4 Parse: Model --> Model with components\n\n // Note that components = intermediate representations that are equivalent to Vega specs.\n // We need these intermediate representation because we need to merge many visualizaiton \"components\" like projections, scales, axes, and legends.\n // We will later convert these components into actual Vega specs in the assemble phase.\n\n // In this phase, we do a bottom-up traversal over the whole tree to\n // parse for each type of components once (e.g., data, layout, mark, scale).\n // By doing bottom-up traversal, we start parsing components of unit specs and\n // then merge child components of parent composite specs.\n //\n // Please see inside model.parse() for order of different components parsed.\n model.parse();\n\n // 5. Optimize the dataflow. This will modify the data component of the model.\n optimizeDataflow(model.component.data);\n\n // 6. Assemble: convert model components --> Vega Spec.\n return assembleTopLevelModel(model, getTopLevelProperties(inputSpec, config, autosize));\n } finally {\n // Reset the singleton logger if a logger is provided\n if (opt.logger) {\n log.reset();\n }\n // Reset the singleton field title formatter if provided\n if (opt.fieldTitle) {\n vlFieldDef.resetTitleFormatter();\n }\n }\n}\n\n\nfunction getTopLevelProperties(topLevelSpec: TopLevel, config: Config, autosize: AutoSizeParams) {\n return {\n autosize: keys(autosize).length === 1 && autosize.type ? autosize.type : autosize,\n ...extractTopLevelProperties(config),\n ...extractTopLevelProperties(topLevelSpec)\n };\n}\n\n/*\n * Assemble the top-level model.\n *\n * Note: this couldn't be `model.assemble()` since the top-level model\n * needs some special treatment to generate top-level properties.\n */\nfunction assembleTopLevelModel(model: Model, topLevelProperties: TopLevelProperties & LayoutSizeMixins) {\n // TODO: change type to become VgSpec\n\n // Config with Vega-Lite only config removed.\n const vgConfig = model.config ? stripAndRedirectConfig(model.config) : undefined;\n\n const data = [].concat(\n model.assembleSelectionData([]),\n // only assemble data in the root\n assembleRootData(model.component.data, topLevelProperties.datasets || {})\n );\n\n delete topLevelProperties.datasets;\n\n const projections = model.assembleProjections();\n const title = model.assembleTitle();\n const style = model.assembleGroupStyle();\n\n let layoutSignals = model.assembleLayoutSignals();\n\n // move width and height signals with values to top level\n layoutSignals = layoutSignals.filter(signal => {\n if ((signal.name === 'width' || signal.name === 'height') && signal.value !== undefined) {\n topLevelProperties[signal.name] = +signal.value;\n return false;\n }\n return true;\n });\n\n const output = {\n $schema: 'https://vega.github.io/schema/vega/v3.json',\n ...(model.description ? {description: model.description} : {}),\n ...topLevelProperties,\n ...(title? {title} : {}),\n ...(style? {style} : {}),\n data: data,\n ...(projections.length > 0 ? {projections: projections} : {}),\n ...model.assembleGroup([\n ...layoutSignals,\n ...model.assembleSelectionTopLevelSignals([])\n ]),\n ...(vgConfig ? {config: vgConfig} : {})\n };\n\n return {\n spec: output\n // TODO: add warning / errors here\n };\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/concat.d.ts b/build/src/compile/concat.d.ts new file mode 100644 index 0000000000..149af72ec8 --- /dev/null +++ b/build/src/compile/concat.d.ts @@ -0,0 +1,15 @@ +import { Config } from '../config'; +import { NormalizedConcatSpec } from '../spec'; +import { VgLayout } from '../vega.schema'; +import { BaseConcatModel } from './baseconcat'; +import { Model } from './model'; +import { RepeaterValue } from './repeater'; +export declare class ConcatModel extends BaseConcatModel { + readonly type: 'concat'; + readonly children: Model[]; + readonly isVConcat: boolean; + constructor(spec: NormalizedConcatSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config); + parseLayoutSize(): void; + parseAxisGroup(): void; + protected assembleDefaultLayout(): VgLayout; +} diff --git a/build/src/compile/concat.js b/build/src/compile/concat.js new file mode 100644 index 0000000000..0129591110 --- /dev/null +++ b/build/src/compile/concat.js @@ -0,0 +1,35 @@ +import * as tslib_1 from "tslib"; +import * as log from '../log'; +import { isVConcatSpec } from '../spec'; +import { BaseConcatModel } from './baseconcat'; +import { buildModel } from './buildmodel'; +import { parseConcatLayoutSize } from './layoutsize/parse'; +var ConcatModel = /** @class */ (function (_super) { + tslib_1.__extends(ConcatModel, _super); + function ConcatModel(spec, parent, parentGivenName, repeater, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, repeater, spec.resolve) || this; + _this.type = 'concat'; + if (spec.resolve && spec.resolve.axis && (spec.resolve.axis.x === 'shared' || spec.resolve.axis.y === 'shared')) { + log.warn(log.message.CONCAT_CANNOT_SHARE_AXIS); + } + _this.isVConcat = isVConcatSpec(spec); + _this.children = (isVConcatSpec(spec) ? spec.vconcat : spec.hconcat).map(function (child, i) { + return buildModel(child, _this, _this.getName('concat_' + i), undefined, repeater, config, false); + }); + return _this; + } + ConcatModel.prototype.parseLayoutSize = function () { + parseConcatLayoutSize(this); + }; + ConcatModel.prototype.parseAxisGroup = function () { + return null; + }; + ConcatModel.prototype.assembleDefaultLayout = function () { + return tslib_1.__assign({}, (this.isVConcat ? { columns: 1 } : {}), { bounds: 'full', + // Use align each so it can work with multiple plots with different size + align: 'each' }); + }; + return ConcatModel; +}(BaseConcatModel)); +export { ConcatModel }; +//# sourceMappingURL=concat.js.map \ No newline at end of file diff --git a/build/src/compile/concat.js.map b/build/src/compile/concat.js.map new file mode 100644 index 0000000000..e0929ae78e --- /dev/null +++ b/build/src/compile/concat.js.map @@ -0,0 +1 @@ +{"version":3,"file":"concat.js","sourceRoot":"","sources":["../../../src/compile/concat.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,GAAG,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAC,aAAa,EAAuB,MAAM,SAAS,CAAC;AAE5D,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAIzD;IAAiC,uCAAe;IAO9C,qBAAY,IAA0B,EAAE,MAAa,EAAE,eAAuB,EAAE,QAAuB,EAAE,MAAc;QAAvH,YACE,kBAAM,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,SAWrE;QAlBe,UAAI,GAAa,QAAQ,CAAC;QASxC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,QAAQ,CAAC,EAAE;YAC/G,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;SAChD;QAED,KAAI,CAAC,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAErC,KAAI,CAAC,QAAQ,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,UAAC,KAAK,EAAE,CAAC;YAC/E,OAAO,UAAU,CAAC,KAAK,EAAE,KAAI,EAAE,KAAI,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAClG,CAAC,CAAC,CAAC;;IACL,CAAC;IAEM,qCAAe,GAAtB;QACE,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAGM,oCAAc,GAArB;QACE,OAAO,IAAI,CAAC;IACd,CAAC;IAES,2CAAqB,GAA/B;QACE,4BACK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAC,OAAO,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IACvC,MAAM,EAAE,MAAM;YACd,wEAAwE;YACxE,KAAK,EAAE,MAAM,IACb;IACJ,CAAC;IACH,kBAAC;AAAD,CAAC,AAtCD,CAAiC,eAAe,GAsC/C","sourcesContent":["import {Config} from '../config';\nimport * as log from '../log';\nimport {isVConcatSpec, NormalizedConcatSpec} from '../spec';\nimport {VgLayout} from '../vega.schema';\nimport {BaseConcatModel} from './baseconcat';\nimport {buildModel} from './buildmodel';\nimport {parseConcatLayoutSize} from './layoutsize/parse';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\n\nexport class ConcatModel extends BaseConcatModel {\n public readonly type: 'concat' = 'concat';\n\n public readonly children: Model[];\n\n public readonly isVConcat: boolean;\n\n constructor(spec: NormalizedConcatSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, repeater, spec.resolve);\n\n if (spec.resolve && spec.resolve.axis && (spec.resolve.axis.x === 'shared' || spec.resolve.axis.y === 'shared')) {\n log.warn(log.message.CONCAT_CANNOT_SHARE_AXIS);\n }\n\n this.isVConcat = isVConcatSpec(spec);\n\n this.children = (isVConcatSpec(spec) ? spec.vconcat : spec.hconcat).map((child, i) => {\n return buildModel(child, this, this.getName('concat_' + i), undefined, repeater, config, false);\n });\n }\n\n public parseLayoutSize() {\n parseConcatLayoutSize(this);\n }\n\n\n public parseAxisGroup(): void {\n return null;\n }\n\n protected assembleDefaultLayout(): VgLayout {\n return {\n ...(this.isVConcat ? {columns: 1} : {}),\n bounds: 'full',\n // Use align each so it can work with multiple plots with different size\n align: 'each'\n };\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/aggregate.d.ts b/build/src/compile/data/aggregate.d.ts new file mode 100644 index 0000000000..c8e32dd660 --- /dev/null +++ b/build/src/compile/data/aggregate.d.ts @@ -0,0 +1,25 @@ +import { AggregateOp } from 'vega'; +import { AggregateTransform } from '../../transform'; +import { Dict, StringSet } from '../../util'; +import { VgAggregateTransform } from '../../vega.schema'; +import { UnitModel } from './../unit'; +import { DataFlowNode } from './dataflow'; +export declare class AggregateNode extends DataFlowNode { + private dimensions; + private measures; + clone(): AggregateNode; + /** + * @param dimensions string set for dimensions + * @param measures dictionary mapping field name => dict of aggregation functions and names to use + */ + constructor(parent: DataFlowNode, dimensions: StringSet, measures: Dict<{ + [key in AggregateOp]?: string; + }>); + static makeFromEncoding(parent: DataFlowNode, model: UnitModel): AggregateNode; + static makeFromTransform(parent: DataFlowNode, t: AggregateTransform): AggregateNode; + merge(other: AggregateNode): void; + addDimensions(fields: string[]): void; + dependentFields(): {}; + producedFields(): {}; + assemble(): VgAggregateTransform; +} diff --git a/build/src/compile/data/aggregate.js b/build/src/compile/data/aggregate.js new file mode 100644 index 0000000000..807f93fdef --- /dev/null +++ b/build/src/compile/data/aggregate.js @@ -0,0 +1,174 @@ +import * as tslib_1 from "tslib"; +import { isScaleChannel } from '../../channel'; +import { vgField } from '../../fielddef'; +import * as log from '../../log'; +import { differ, duplicate, keys } from '../../util'; +import { binRequiresRange } from '../common'; +import { DataFlowNode } from './dataflow'; +function addDimension(dims, channel, fieldDef) { + if (fieldDef.bin) { + dims[vgField(fieldDef, {})] = true; + dims[vgField(fieldDef, { binSuffix: 'end' })] = true; + if (binRequiresRange(fieldDef, channel)) { + dims[vgField(fieldDef, { binSuffix: 'range' })] = true; + } + } + else { + dims[vgField(fieldDef)] = true; + } + return dims; +} +function mergeMeasures(parentMeasures, childMeasures) { + for (var f in childMeasures) { + if (childMeasures.hasOwnProperty(f)) { + // when we merge a measure, we either have to add an aggregation operator or even a new field + var ops = childMeasures[f]; + for (var op in ops) { + if (ops.hasOwnProperty(op)) { + if (f in parentMeasures) { + // add operator to existing measure field + parentMeasures[f][op] = ops[op]; + } + else { + parentMeasures[f] = { op: ops[op] }; + } + } + } + } + } +} +var AggregateNode = /** @class */ (function (_super) { + tslib_1.__extends(AggregateNode, _super); + /** + * @param dimensions string set for dimensions + * @param measures dictionary mapping field name => dict of aggregation functions and names to use + */ + function AggregateNode(parent, dimensions, measures) { + var _this = _super.call(this, parent) || this; + _this.dimensions = dimensions; + _this.measures = measures; + return _this; + } + AggregateNode.prototype.clone = function () { + return new AggregateNode(null, tslib_1.__assign({}, this.dimensions), duplicate(this.measures)); + }; + AggregateNode.makeFromEncoding = function (parent, model) { + var isAggregate = false; + model.forEachFieldDef(function (fd) { + if (fd.aggregate) { + isAggregate = true; + } + }); + var meas = {}; + var dims = {}; + if (!isAggregate) { + // no need to create this node if the model has no aggregation + return null; + } + model.forEachFieldDef(function (fieldDef, channel) { + var aggregate = fieldDef.aggregate, field = fieldDef.field; + if (aggregate) { + if (aggregate === 'count') { + meas['*'] = meas['*'] || {}; + meas['*']['count'] = vgField(fieldDef); + } + else { + meas[field] = meas[field] || {}; + meas[field][aggregate] = vgField(fieldDef); + // For scale channel with domain === 'unaggregated', add min/max so we can use their union as unaggregated domain + if (isScaleChannel(channel) && model.scaleDomain(channel) === 'unaggregated') { + meas[field]['min'] = vgField({ field: field, aggregate: 'min' }); + meas[field]['max'] = vgField({ field: field, aggregate: 'max' }); + } + } + } + else { + addDimension(dims, channel, fieldDef); + } + }); + if ((keys(dims).length + keys(meas).length) === 0) { + return null; + } + return new AggregateNode(parent, dims, meas); + }; + AggregateNode.makeFromTransform = function (parent, t) { + var dims = {}; + var meas = {}; + for (var _i = 0, _a = t.aggregate; _i < _a.length; _i++) { + var s = _a[_i]; + var op = s.op, field = s.field, as = s.as; + if (op) { + if (op === 'count') { + meas['*'] = meas['*'] || {}; + meas['*']['count'] = as || vgField(s); + } + else { + meas[field] = meas[field] || {}; + meas[field][op] = as || vgField(s); + } + } + } + for (var _b = 0, _c = t.groupby || []; _b < _c.length; _b++) { + var s = _c[_b]; + dims[s] = true; + } + if ((keys(dims).length + keys(meas).length) === 0) { + return null; + } + return new AggregateNode(parent, dims, meas); + }; + AggregateNode.prototype.merge = function (other) { + if (!differ(this.dimensions, other.dimensions)) { + mergeMeasures(this.measures, other.measures); + other.remove(); + } + else { + log.debug('different dimensions, cannot merge'); + } + }; + AggregateNode.prototype.addDimensions = function (fields) { + var _this = this; + fields.forEach(function (f) { return _this.dimensions[f] = true; }); + }; + AggregateNode.prototype.dependentFields = function () { + var out = {}; + keys(this.dimensions).forEach(function (f) { return out[f] = true; }); + keys(this.measures).forEach(function (m) { return out[m] = true; }); + return out; + }; + AggregateNode.prototype.producedFields = function () { + var _this = this; + var out = {}; + keys(this.measures).forEach(function (field) { + keys(_this.measures[field]).forEach(function (op) { + out[op + "_" + field] = true; + }); + }); + return out; + }; + AggregateNode.prototype.assemble = function () { + var ops = []; + var fields = []; + var as = []; + for (var _i = 0, _a = keys(this.measures); _i < _a.length; _i++) { + var field = _a[_i]; + for (var _b = 0, _c = keys(this.measures[field]); _b < _c.length; _b++) { + var op = _c[_b]; + as.push(this.measures[field][op]); + ops.push(op); + fields.push(field); + } + } + var result = { + type: 'aggregate', + groupby: keys(this.dimensions), + ops: ops, + fields: fields, + as: as + }; + return result; + }; + return AggregateNode; +}(DataFlowNode)); +export { AggregateNode }; +//# sourceMappingURL=aggregate.js.map \ No newline at end of file diff --git a/build/src/compile/data/aggregate.js.map b/build/src/compile/data/aggregate.js.map new file mode 100644 index 0000000000..097032dc3e --- /dev/null +++ b/build/src/compile/data/aggregate.js.map @@ -0,0 +1 @@ +{"version":3,"file":"aggregate.js","sourceRoot":"","sources":["../../../../src/compile/data/aggregate.ts"],"names":[],"mappings":"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","sourcesContent":["import {AggregateOp} from 'vega';\n\nimport {Channel, isScaleChannel} from '../../channel';\nimport {FieldDef, vgField} from '../../fielddef';\nimport * as log from '../../log';\nimport {AggregateTransform} from '../../transform';\nimport {Dict, differ, duplicate, keys, StringSet} from '../../util';\nimport {VgAggregateTransform} from '../../vega.schema';\nimport {binRequiresRange} from '../common';\nimport {UnitModel} from './../unit';\nimport {DataFlowNode} from './dataflow';\n\nfunction addDimension(dims: {[field: string]: boolean}, channel: Channel, fieldDef: FieldDef) {\n if (fieldDef.bin) {\n dims[vgField(fieldDef, {})] = true;\n dims[vgField(fieldDef, {binSuffix: 'end'})] = true;\n\n if (binRequiresRange(fieldDef, channel)) {\n dims[vgField(fieldDef, {binSuffix: 'range'})] = true;\n }\n } else {\n dims[vgField(fieldDef)] = true;\n }\n return dims;\n}\n\nfunction mergeMeasures(parentMeasures: Dict>, childMeasures: Dict>) {\n for (const f in childMeasures) {\n if (childMeasures.hasOwnProperty(f)) {\n // when we merge a measure, we either have to add an aggregation operator or even a new field\n const ops = childMeasures[f];\n for (const op in ops) {\n if (ops.hasOwnProperty(op)) {\n if (f in parentMeasures) {\n // add operator to existing measure field\n parentMeasures[f][op] = ops[op];\n } else {\n parentMeasures[f] = {op: ops[op]};\n }\n }\n }\n }\n }\n}\n\nexport class AggregateNode extends DataFlowNode {\n public clone() {\n return new AggregateNode(null, {...this.dimensions}, duplicate(this.measures));\n }\n\n /**\n * @param dimensions string set for dimensions\n * @param measures dictionary mapping field name => dict of aggregation functions and names to use\n */\n constructor(parent: DataFlowNode, private dimensions: StringSet, private measures: Dict<{[key in AggregateOp]?: string}>) {\n super(parent);\n }\n\n public static makeFromEncoding(parent: DataFlowNode, model: UnitModel): AggregateNode {\n let isAggregate = false;\n model.forEachFieldDef(fd => {\n if (fd.aggregate) {\n isAggregate = true;\n }\n });\n\n const meas = {};\n const dims = {};\n\n if (!isAggregate) {\n // no need to create this node if the model has no aggregation\n return null;\n }\n\n model.forEachFieldDef((fieldDef, channel) => {\n const {aggregate, field} = fieldDef;\n if (aggregate) {\n if (aggregate === 'count') {\n meas['*'] = meas['*'] || {};\n meas['*']['count'] = vgField(fieldDef);\n } else {\n meas[field] = meas[field] || {};\n meas[field][aggregate] = vgField(fieldDef);\n\n // For scale channel with domain === 'unaggregated', add min/max so we can use their union as unaggregated domain\n if (isScaleChannel(channel) && model.scaleDomain(channel) === 'unaggregated') {\n meas[field]['min'] = vgField({field, aggregate: 'min'});\n meas[field]['max'] = vgField({field, aggregate: 'max'});\n }\n }\n } else {\n addDimension(dims, channel, fieldDef);\n }\n });\n\n if ((keys(dims).length + keys(meas).length) === 0) {\n return null;\n }\n\n return new AggregateNode(parent, dims, meas);\n }\n\n public static makeFromTransform(parent: DataFlowNode, t: AggregateTransform): AggregateNode {\n const dims = {};\n const meas = {};\n\n for (const s of t.aggregate) {\n const {op, field, as} = s;\n if (op) {\n if (op === 'count') {\n meas['*'] = meas['*'] || {};\n meas['*']['count'] = as || vgField(s);\n } else {\n meas[field] = meas[field] || {};\n meas[field][op] = as || vgField(s);\n }\n }\n }\n\n for (const s of t.groupby || []) {\n dims[s] = true;\n }\n\n if ((keys(dims).length + keys(meas).length) === 0) {\n return null;\n }\n\n return new AggregateNode(parent, dims, meas);\n }\n\n public merge(other: AggregateNode) {\n if (!differ(this.dimensions, other.dimensions)) {\n mergeMeasures(this.measures, other.measures);\n other.remove();\n } else {\n log.debug('different dimensions, cannot merge');\n }\n }\n\n public addDimensions(fields: string[]) {\n fields.forEach(f => this.dimensions[f] = true);\n }\n\n public dependentFields() {\n const out = {};\n\n keys(this.dimensions).forEach(f => out[f] = true);\n keys(this.measures).forEach(m => out[m] = true);\n\n return out;\n }\n\n public producedFields() {\n const out = {};\n\n keys(this.measures).forEach(field => {\n keys(this.measures[field]).forEach(op => {\n out[`${op}_${field}`] = true;\n });\n });\n\n return out;\n }\n\n public assemble(): VgAggregateTransform {\n const ops: AggregateOp[] = [];\n const fields: string[] = [];\n const as: string[] = [];\n\n for (const field of keys(this.measures)) {\n for (const op of keys(this.measures[field])) {\n as.push(this.measures[field][op]);\n ops.push(op);\n fields.push(field);\n }\n }\n\n const result: VgAggregateTransform = {\n type: 'aggregate',\n groupby: keys(this.dimensions),\n ops,\n fields,\n as\n };\n\n return result;\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/assemble.d.ts b/build/src/compile/data/assemble.d.ts new file mode 100644 index 0000000000..4fd4663897 --- /dev/null +++ b/build/src/compile/data/assemble.d.ts @@ -0,0 +1,17 @@ +import { InlineDataset } from '../../data'; +import { Dict } from '../../util'; +import { VgData } from '../../vega.schema'; +import { DataComponent } from './'; +import { FacetNode } from './facet'; +/** + * Assemble data sources that are derived from faceted data. + */ +export declare function assembleFacetData(root: FacetNode): VgData[]; +/** + * Create Vega Data array from a given compiled model and append all of them to the given array + * + * @param model + * @param data array + * @return modified data array + */ +export declare function assembleRootData(dataComponent: DataComponent, datasets: Dict): VgData[]; diff --git a/build/src/compile/data/assemble.js b/build/src/compile/data/assemble.js new file mode 100644 index 0000000000..c3964b96dc --- /dev/null +++ b/build/src/compile/data/assemble.js @@ -0,0 +1,229 @@ +import * as tslib_1 from "tslib"; +import { isUrlData } from '../../data'; +import { vals } from '../../util'; +import { AggregateNode } from './aggregate'; +import { BinNode } from './bin'; +import { CalculateNode } from './calculate'; +import { OutputNode } from './dataflow'; +import { FacetNode } from './facet'; +import { FilterNode } from './filter'; +import { FilterInvalidNode } from './filterinvalid'; +import { ParseNode } from './formatparse'; +import { GeoJSONNode } from './geojson'; +import { GeoPointNode } from './geopoint'; +import { IdentifierNode } from './identifier'; +import { LookupNode } from './lookup'; +import { SourceNode } from './source'; +import { StackNode } from './stack'; +import { TimeUnitNode } from './timeunit'; +import { WindowTransformNode } from './window'; +/** + * Print debug information for dataflow tree. + */ +// tslint:disable-next-line +function debug(node) { + console.log("" + node.constructor.name + (node.debugName ? " (" + node.debugName + ")" : '') + " -> " + (node.children.map(function (c) { + return "" + c.constructor.name + (c.debugName ? " (" + c.debugName + ")" : ''); + }))); + console.log(node); + node.children.forEach(debug); +} +function makeWalkTree(data) { + // to name datasources + var datasetIndex = 0; + /** + * Recursively walk down the tree. + */ + function walkTree(node, dataSource) { + if (node instanceof SourceNode) { + // If the source is a named data source or a data source with values, we need + // to put it in a different data source. Otherwise, Vega may override the data. + if (!isUrlData(node.data)) { + data.push(dataSource); + var newData = { + name: null, + source: dataSource.name, + transform: [] + }; + dataSource = newData; + } + } + if (node instanceof ParseNode) { + if (node.parent instanceof SourceNode && !dataSource.source) { + // If node's parent is a root source and the data source does not refer to another data source, use normal format parse + dataSource.format = tslib_1.__assign({}, dataSource.format || {}, { parse: node.assembleFormatParse() }); + // add calculates for all nested fields + dataSource.transform = dataSource.transform.concat(node.assembleTransforms(true)); + } + else { + // Otherwise use Vega expression to parse + dataSource.transform = dataSource.transform.concat(node.assembleTransforms()); + } + } + if (node instanceof FacetNode) { + if (!dataSource.name) { + dataSource.name = "data_" + datasetIndex++; + } + if (!dataSource.source || dataSource.transform.length > 0) { + data.push(dataSource); + node.data = dataSource.name; + } + else { + node.data = dataSource.source; + } + node.assemble().forEach(function (d) { return data.push(d); }); + // break here because the rest of the tree has to be taken care of by the facet. + return; + } + if (node instanceof FilterNode || + node instanceof CalculateNode || + node instanceof GeoPointNode || + node instanceof GeoJSONNode || + node instanceof AggregateNode || + node instanceof LookupNode || + node instanceof WindowTransformNode || + node instanceof IdentifierNode) { + dataSource.transform.push(node.assemble()); + } + if (node instanceof FilterInvalidNode || + node instanceof BinNode || + node instanceof TimeUnitNode || + node instanceof StackNode) { + dataSource.transform = dataSource.transform.concat(node.assemble()); + } + if (node instanceof AggregateNode) { + if (!dataSource.name) { + dataSource.name = "data_" + datasetIndex++; + } + } + if (node instanceof OutputNode) { + if (dataSource.source && dataSource.transform.length === 0) { + node.setSource(dataSource.source); + } + else if (node.parent instanceof OutputNode) { + // Note that an output node may be required but we still do not assemble a + // separate data source for it. + node.setSource(dataSource.name); + } + else { + if (!dataSource.name) { + dataSource.name = "data_" + datasetIndex++; + } + // Here we set the name of the datasource we generated. From now on + // other assemblers can use it. + node.setSource(dataSource.name); + // if this node has more than one child, we will add a datasource automatically + if (node.numChildren() === 1) { + data.push(dataSource); + var newData = { + name: null, + source: dataSource.name, + transform: [] + }; + dataSource = newData; + } + } + } + switch (node.numChildren()) { + case 0: + // done + if (node instanceof OutputNode && (!dataSource.source || dataSource.transform.length > 0)) { + // do not push empty datasources that are simply references + data.push(dataSource); + } + break; + case 1: + walkTree(node.children[0], dataSource); + break; + default: + if (!dataSource.name) { + dataSource.name = "data_" + datasetIndex++; + } + var source_1 = dataSource.name; + if (!dataSource.source || dataSource.transform.length > 0) { + data.push(dataSource); + } + else { + source_1 = dataSource.source; + } + node.children.forEach(function (child) { + var newData = { + name: null, + source: source_1, + transform: [] + }; + walkTree(child, newData); + }); + break; + } + } + return walkTree; +} +/** + * Assemble data sources that are derived from faceted data. + */ +export function assembleFacetData(root) { + var data = []; + var walkTree = makeWalkTree(data); + root.children.forEach(function (child) { return walkTree(child, { + source: root.name, + name: null, + transform: [] + }); }); + return data; +} +/** + * Create Vega Data array from a given compiled model and append all of them to the given array + * + * @param model + * @param data array + * @return modified data array + */ +export function assembleRootData(dataComponent, datasets) { + var roots = vals(dataComponent.sources); + var data = []; + // roots.forEach(debug); + var walkTree = makeWalkTree(data); + var sourceIndex = 0; + roots.forEach(function (root) { + // assign a name if the source does not have a name yet + if (!root.hasName()) { + root.dataName = "source_" + sourceIndex++; + } + var newData = root.assemble(); + walkTree(root, newData); + }); + // remove empty transform arrays for cleaner output + data.forEach(function (d) { + if (d.transform.length === 0) { + delete d.transform; + } + }); + // move sources without transforms (the ones that are potentially used in lookups) to the beginning + var whereTo = 0; + for (var i = 0; i < data.length; i++) { + var d = data[i]; + if ((d.transform || []).length === 0 && !d.source) { + data.splice(whereTo++, 0, data.splice(i, 1)[0]); + } + } + // now fix the from references in lookup transforms + for (var _i = 0, data_1 = data; _i < data_1.length; _i++) { + var d = data_1[_i]; + for (var _a = 0, _b = d.transform || []; _a < _b.length; _a++) { + var t = _b[_a]; + if (t.type === 'lookup') { + t.from = dataComponent.outputNodes[t.from].getSource(); + } + } + } + // inline values for datasets that are in the datastore + for (var _c = 0, data_2 = data; _c < data_2.length; _c++) { + var d = data_2[_c]; + if (d.name in datasets) { + d.values = datasets[d.name]; + } + } + return data; +} +//# sourceMappingURL=assemble.js.map \ No newline at end of file diff --git a/build/src/compile/data/assemble.js.map b/build/src/compile/data/assemble.js.map new file mode 100644 index 0000000000..15cde77fa1 --- /dev/null +++ b/build/src/compile/data/assemble.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../../../src/compile/data/assemble.ts"],"names":[],"mappings":"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","sourcesContent":["import {InlineDataset, isUrlData} from '../../data';\nimport {Dict, vals} from '../../util';\nimport {VgData} from '../../vega.schema';\nimport {DataComponent} from './';\nimport {AggregateNode} from './aggregate';\nimport {BinNode} from './bin';\nimport {CalculateNode} from './calculate';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {FilterNode} from './filter';\nimport {FilterInvalidNode} from './filterinvalid';\nimport {ParseNode} from './formatparse';\nimport {GeoJSONNode} from './geojson';\nimport {GeoPointNode} from './geopoint';\nimport {IdentifierNode} from './identifier';\nimport {LookupNode} from './lookup';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\nimport {TimeUnitNode} from './timeunit';\nimport {WindowTransformNode} from './window';\n\n/**\n * Print debug information for dataflow tree.\n */\n// tslint:disable-next-line\nfunction debug(node: DataFlowNode) {\n console.log(`${(node.constructor as any).name}${node.debugName ? ` (${node.debugName})` : ''} -> ${\n (node.children.map(c => {\n return `${(c.constructor as any).name}${c.debugName ? ` (${c.debugName})` : ''}`;\n }))\n }`);\n console.log(node);\n node.children.forEach(debug);\n}\n\nfunction makeWalkTree(data: VgData[]) {\n // to name datasources\n let datasetIndex = 0;\n\n /**\n * Recursively walk down the tree.\n */\n function walkTree(node: DataFlowNode, dataSource: VgData) {\n if (node instanceof SourceNode) {\n // If the source is a named data source or a data source with values, we need\n // to put it in a different data source. Otherwise, Vega may override the data.\n if (!isUrlData(node.data)) {\n data.push(dataSource);\n const newData: VgData = {\n name: null,\n source: dataSource.name,\n transform: []\n };\n dataSource = newData;\n }\n }\n\n if (node instanceof ParseNode) {\n if (node.parent instanceof SourceNode && !dataSource.source) {\n // If node's parent is a root source and the data source does not refer to another data source, use normal format parse\n dataSource.format = {\n ...dataSource.format || {},\n parse: node.assembleFormatParse()\n };\n\n // add calculates for all nested fields\n dataSource.transform = dataSource.transform.concat(node.assembleTransforms(true));\n } else {\n // Otherwise use Vega expression to parse\n dataSource.transform = dataSource.transform.concat(node.assembleTransforms());\n }\n }\n\n if (node instanceof FacetNode) {\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n\n if (!dataSource.source || dataSource.transform.length > 0) {\n data.push(dataSource);\n node.data = dataSource.name;\n } else {\n node.data = dataSource.source;\n }\n\n node.assemble().forEach(d => data.push(d));\n\n // break here because the rest of the tree has to be taken care of by the facet.\n return;\n }\n\n if (node instanceof FilterNode ||\n node instanceof CalculateNode ||\n node instanceof GeoPointNode ||\n node instanceof GeoJSONNode ||\n node instanceof AggregateNode ||\n node instanceof LookupNode ||\n node instanceof WindowTransformNode ||\n node instanceof IdentifierNode) {\n dataSource.transform.push(node.assemble());\n }\n\n if (node instanceof FilterInvalidNode ||\n node instanceof BinNode ||\n node instanceof TimeUnitNode ||\n node instanceof StackNode) {\n dataSource.transform = dataSource.transform.concat(node.assemble());\n }\n\n if (node instanceof AggregateNode) {\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n }\n\n if (node instanceof OutputNode) {\n if (dataSource.source && dataSource.transform.length === 0) {\n node.setSource(dataSource.source);\n } else if (node.parent instanceof OutputNode) {\n // Note that an output node may be required but we still do not assemble a\n // separate data source for it.\n node.setSource(dataSource.name);\n } else {\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n\n // Here we set the name of the datasource we generated. From now on\n // other assemblers can use it.\n node.setSource(dataSource.name);\n\n // if this node has more than one child, we will add a datasource automatically\n if (node.numChildren() === 1) {\n data.push(dataSource);\n const newData: VgData = {\n name: null,\n source: dataSource.name,\n transform: []\n };\n dataSource = newData;\n }\n }\n }\n\n switch (node.numChildren()) {\n case 0:\n // done\n if (node instanceof OutputNode && (!dataSource.source || dataSource.transform.length > 0)) {\n // do not push empty datasources that are simply references\n data.push(dataSource);\n }\n break;\n case 1:\n walkTree(node.children[0], dataSource);\n break;\n default:\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n\n let source = dataSource.name;\n if (!dataSource.source || dataSource.transform.length > 0) {\n data.push(dataSource);\n } else {\n source = dataSource.source;\n }\n\n node.children.forEach(child => {\n const newData: VgData = {\n name: null,\n source: source,\n transform: []\n };\n walkTree(child, newData);\n });\n break;\n }\n }\n\n return walkTree;\n}\n\n/**\n * Assemble data sources that are derived from faceted data.\n */\nexport function assembleFacetData(root: FacetNode): VgData[] {\n const data: VgData[] = [];\n const walkTree = makeWalkTree(data);\n\n root.children.forEach(child => walkTree(child, {\n source: root.name,\n name: null,\n transform: []\n }));\n\n return data;\n}\n\n/**\n * Create Vega Data array from a given compiled model and append all of them to the given array\n *\n * @param model\n * @param data array\n * @return modified data array\n */\nexport function assembleRootData(dataComponent: DataComponent, datasets: Dict): VgData[] {\n const roots: SourceNode[] = vals(dataComponent.sources);\n const data: VgData[] = [];\n\n // roots.forEach(debug);\n\n const walkTree = makeWalkTree(data);\n\n let sourceIndex = 0;\n\n roots.forEach(root => {\n // assign a name if the source does not have a name yet\n if (!root.hasName()) {\n root.dataName = `source_${sourceIndex++}`;\n }\n\n const newData: VgData = root.assemble();\n\n walkTree(root, newData);\n });\n\n // remove empty transform arrays for cleaner output\n data.forEach(d => {\n if (d.transform.length === 0) {\n delete d.transform;\n }\n });\n\n // move sources without transforms (the ones that are potentially used in lookups) to the beginning\n let whereTo = 0;\n for (let i = 0; i < data.length; i++) {\n const d = data[i];\n if ((d.transform || []).length === 0 && !d.source) {\n data.splice(whereTo++, 0, data.splice(i, 1)[0]);\n }\n }\n\n // now fix the from references in lookup transforms\n for (const d of data) {\n for (const t of d.transform || []) {\n if (t.type === 'lookup') {\n t.from = dataComponent.outputNodes[t.from].getSource();\n }\n }\n }\n\n // inline values for datasets that are in the datastore\n for (const d of data) {\n if (d.name in datasets) {\n d.values = datasets[d.name];\n }\n }\n\n return data;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/bin.d.ts b/build/src/compile/data/bin.d.ts new file mode 100644 index 0000000000..8f3bd458f2 --- /dev/null +++ b/build/src/compile/data/bin.d.ts @@ -0,0 +1,30 @@ +import { BinParams } from '../../bin'; +import { BinTransform } from '../../transform'; +import { Dict } from '../../util'; +import { VgTransform } from '../../vega.schema'; +import { Model, ModelWithField } from '../model'; +import { DataFlowNode } from './dataflow'; +export interface BinComponent { + bin: BinParams; + field: string; + extentSignal?: string; + signal?: string; + as: string[]; + formula?: string; + formulaAs?: string; +} +export declare class BinNode extends DataFlowNode { + private bins; + clone(): BinNode; + constructor(parent: DataFlowNode, bins: Dict); + static makeFromEncoding(parent: DataFlowNode, model: ModelWithField): BinNode; + /** + * Creates a bin node from BinTransform. + * The optional parameter should provide + */ + static makeFromTransform(parent: DataFlowNode, t: BinTransform, model: Model): BinNode; + merge(other: BinNode): void; + producedFields(): {}; + dependentFields(): {}; + assemble(): VgTransform[]; +} diff --git a/build/src/compile/data/bin.js b/build/src/compile/data/bin.js new file mode 100644 index 0000000000..22cd21e1fc --- /dev/null +++ b/build/src/compile/data/bin.js @@ -0,0 +1,126 @@ +import * as tslib_1 from "tslib"; +import { isString } from 'vega-util'; +import { binToString } from '../../bin'; +import { normalizeBin, vgField } from '../../fielddef'; +import { duplicate, flatten, keys, vals } from '../../util'; +import { binFormatExpression, binRequiresRange } from '../common'; +import { isUnitModel } from '../model'; +import { DataFlowNode } from './dataflow'; +function rangeFormula(model, fieldDef, channel, config) { + if (binRequiresRange(fieldDef, channel)) { + // read format from axis or legend, if there is no format then use config.numberFormat + var guide = isUnitModel(model) ? (model.axis(channel) || model.legend(channel) || {}) : {}; + var startField = vgField(fieldDef, { expr: 'datum', }); + var endField = vgField(fieldDef, { expr: 'datum', binSuffix: 'end' }); + return { + formulaAs: vgField(fieldDef, { binSuffix: 'range' }), + formula: binFormatExpression(startField, endField, guide.format, config) + }; + } + return {}; +} +function binKey(bin, field) { + return binToString(bin) + "_" + field; +} +function getSignalsFromModel(model, key) { + return { + signal: model.getName(key + "_bins"), + extentSignal: model.getName(key + "_extent") + }; +} +function isBinTransform(t) { + return 'as' in t; +} +function createBinComponent(t, model) { + var as; + if (isBinTransform(t)) { + as = isString(t.as) ? [t.as, t.as + "_end"] : [t.as[0], t.as[1]]; + } + else { + as = [vgField(t, {}), vgField(t, { binSuffix: 'end' })]; + } + var bin = normalizeBin(t.bin, undefined) || {}; + var key = binKey(bin, t.field); + var _a = getSignalsFromModel(model, key), signal = _a.signal, extentSignal = _a.extentSignal; + var binComponent = tslib_1.__assign({ bin: bin, field: t.field, as: as }, signal ? { signal: signal } : {}, extentSignal ? { extentSignal: extentSignal } : {}); + return { key: key, binComponent: binComponent }; +} +var BinNode = /** @class */ (function (_super) { + tslib_1.__extends(BinNode, _super); + function BinNode(parent, bins) { + var _this = _super.call(this, parent) || this; + _this.bins = bins; + return _this; + } + BinNode.prototype.clone = function () { + return new BinNode(null, duplicate(this.bins)); + }; + BinNode.makeFromEncoding = function (parent, model) { + var bins = model.reduceFieldDef(function (binComponentIndex, fieldDef, channel) { + if (fieldDef.bin) { + var _a = createBinComponent(fieldDef, model), key = _a.key, binComponent = _a.binComponent; + binComponentIndex[key] = tslib_1.__assign({}, binComponent, binComponentIndex[key], rangeFormula(model, fieldDef, channel, model.config)); + } + return binComponentIndex; + }, {}); + if (keys(bins).length === 0) { + return null; + } + return new BinNode(parent, bins); + }; + /** + * Creates a bin node from BinTransform. + * The optional parameter should provide + */ + BinNode.makeFromTransform = function (parent, t, model) { + var _a; + var _b = createBinComponent(t, model), key = _b.key, binComponent = _b.binComponent; + return new BinNode(parent, (_a = {}, + _a[key] = binComponent, + _a)); + }; + BinNode.prototype.merge = function (other) { + this.bins = tslib_1.__assign({}, this.bins, other.bins); + other.remove(); + }; + BinNode.prototype.producedFields = function () { + var out = {}; + vals(this.bins).forEach(function (c) { + c.as.forEach(function (f) { return out[f] = true; }); + }); + return out; + }; + BinNode.prototype.dependentFields = function () { + var out = {}; + vals(this.bins).forEach(function (c) { + out[c.field] = true; + }); + return out; + }; + BinNode.prototype.assemble = function () { + return flatten(vals(this.bins).map(function (bin) { + var transform = []; + var binTrans = tslib_1.__assign({ type: 'bin', field: bin.field, as: bin.as, signal: bin.signal }, bin.bin); + if (!bin.bin.extent && bin.extentSignal) { + transform.push({ + type: 'extent', + field: bin.field, + signal: bin.extentSignal + }); + binTrans.extent = { signal: bin.extentSignal }; + } + transform.push(binTrans); + if (bin.formula) { + transform.push({ + type: 'formula', + expr: bin.formula, + as: bin.formulaAs + }); + } + return transform; + })); + }; + return BinNode; +}(DataFlowNode)); +export { BinNode }; +//# sourceMappingURL=bin.js.map \ No newline at end of file diff --git a/build/src/compile/data/bin.js.map b/build/src/compile/data/bin.js.map new file mode 100644 index 0000000000..3b9134bd68 --- /dev/null +++ b/build/src/compile/data/bin.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../../../src/compile/data/bin.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAC;AACnC,OAAO,EAAY,WAAW,EAAC,MAAM,WAAW,CAAC;AAGjD,OAAO,EAAW,YAAY,EAAE,OAAO,EAAC,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAO,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAC,MAAM,YAAY,CAAC;AAEhE,OAAO,EAAC,mBAAmB,EAAE,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChE,OAAO,EAAC,WAAW,EAAwB,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAExC,sBAAsB,KAAqB,EAAE,QAA0B,EAAE,OAAgB,EAAE,MAAc;IACrG,IAAI,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;QACvC,sFAAsF;QAEtF,IAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE7F,IAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAC,IAAI,EAAE,OAAO,GAAE,CAAC,CAAC;QACvD,IAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAC,CAAC,CAAC;QAEtE,OAAO;YACL,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAC,SAAS,EAAE,OAAO,EAAC,CAAC;YAClD,OAAO,EAAE,mBAAmB,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;SACzE,CAAC;KACH;IACD,OAAO,EAAE,CAAC;AACd,CAAC;AAED,gBAAgB,GAAc,EAAE,KAAa;IAC3C,OAAU,WAAW,CAAC,GAAG,CAAC,SAAI,KAAO,CAAC;AACxC,CAAC;AAED,6BAA6B,KAAY,EAAE,GAAW;IACpD,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,OAAO,CAAI,GAAG,UAAO,CAAC;QACpC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAI,GAAG,YAAS,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED,wBAAwB,CAAkC;IACxD,OAAO,IAAI,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,4BAA4B,CAAkC,EAAE,KAAY;IAC1E,IAAI,EAAoB,CAAC;IAEzB,IAAI,cAAc,CAAC,CAAC,CAAC,EAAE;QACrB,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAK,CAAC,CAAC,EAAE,SAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;KACjE;SAAM;QACL,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,EAAC,SAAS,EAAE,KAAK,EAAC,CAAC,CAAC,CAAC;KACvD;IAED,IAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;IACjD,IAAM,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAA,oCAAwD,EAAvD,kBAAM,EAAE,8BAAY,CAAoC;IAE/D,IAAM,YAAY,sBAChB,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,EAAE,EAAE,EAAE,IACH,MAAM,CAAC,CAAC,CAAC,EAAC,MAAM,QAAA,EAAC,CAAC,CAAC,CAAC,EAAE,EACtB,YAAY,CAAC,CAAC,CAAC,EAAC,YAAY,cAAA,EAAC,CAAC,CAAC,CAAC,EAAE,CACtC,CAAC;IAEF,OAAO,EAAC,GAAG,KAAA,EAAE,YAAY,cAAA,EAAC,CAAC;AAC7B,CAAC;AAeD;IAA6B,mCAAY;IAKvC,iBAAY,MAAoB,EAAU,IAAwB;QAAlE,YACE,kBAAM,MAAM,CAAC,SACd;QAFyC,UAAI,GAAJ,IAAI,CAAoB;;IAElE,CAAC;IANM,uBAAK,GAAZ;QACE,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjD,CAAC;IAMa,wBAAgB,GAA9B,UAA+B,MAAoB,EAAE,KAAqB;QACxE,IAAM,IAAI,GAAG,KAAK,CAAC,cAAc,CAAC,UAAC,iBAAqC,EAAE,QAAQ,EAAE,OAAO;YACzF,IAAI,QAAQ,CAAC,GAAG,EAAE;gBACV,IAAA,wCAAyD,EAAxD,YAAG,EAAE,8BAAY,CAAwC;gBAChE,iBAAiB,CAAC,GAAG,CAAC,wBACjB,YAAY,EACZ,iBAAiB,CAAC,GAAG,CAAC,EACtB,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CACxD,CAAC;aACH;YACD,OAAO,iBAAiB,CAAC;QAC3B,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;YAC3B,OAAO,IAAI,CAAC;SACb;QAED,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAED;;;OAGG;IACW,yBAAiB,GAA/B,UAAgC,MAAoB,EAAE,CAAe,EAAE,KAAY;;QAC3E,IAAA,iCAAkD,EAAjD,YAAG,EAAE,8BAAY,CAAiC;QACzD,OAAO,IAAI,OAAO,CAAC,MAAM;YACvB,GAAC,GAAG,IAAG,YAAY;gBACnB,CAAC;IACL,CAAC;IAEM,uBAAK,GAAZ,UAAa,KAAc;QACzB,IAAI,CAAC,IAAI,wBAAO,IAAI,CAAC,IAAI,EAAK,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1C,KAAK,CAAC,MAAM,EAAE,CAAC;IACjB,CAAC;IAEM,gCAAc,GAArB;QACE,IAAM,GAAG,GAAG,EAAE,CAAC;QAEf,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,UAAA,CAAC;YACvB,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,EAAb,CAAa,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,CAAC;IACb,CAAC;IAEM,iCAAe,GAAtB;QACE,IAAM,GAAG,GAAG,EAAE,CAAC;QAEf,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,UAAA,CAAC;YACvB,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,CAAC;IACb,CAAC;IAEM,0BAAQ,GAAf;QACE,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAA,GAAG;YACpC,IAAM,SAAS,GAAkB,EAAE,CAAC;YAEpC,IAAM,QAAQ,sBACV,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,GAAG,CAAC,KAAK,EAChB,EAAE,EAAE,GAAG,CAAC,EAAE,EACV,MAAM,EAAE,GAAG,CAAC,MAAM,IACf,GAAG,CAAC,GAAG,CACb,CAAC;YAEF,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,YAAY,EAAE;gBACvC,SAAS,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,QAAQ;oBACd,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,MAAM,EAAE,GAAG,CAAC,YAAY;iBACzB,CAAC,CAAC;gBACH,QAAQ,CAAC,MAAM,GAAG,EAAC,MAAM,EAAE,GAAG,CAAC,YAAY,EAAC,CAAC;aAC9C;YAED,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAEzB,IAAI,GAAG,CAAC,OAAO,EAAE;gBACf,SAAS,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,GAAG,CAAC,OAAO;oBACjB,EAAE,EAAE,GAAG,CAAC,SAAS;iBAClB,CAAC,CAAC;aACJ;YAED,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC,CAAC,CAAC;IACN,CAAC;IACH,cAAC;AAAD,CAAC,AAnGD,CAA6B,YAAY,GAmGxC","sourcesContent":["import {isString} from 'vega-util';\nimport {BinParams, binToString} from '../../bin';\nimport {Channel} from '../../channel';\nimport {Config} from '../../config';\nimport {FieldDef, normalizeBin, vgField} from '../../fielddef';\nimport {BinTransform} from '../../transform';\nimport {Dict, duplicate, flatten, keys, vals} from '../../util';\nimport {VgBinTransform, VgTransform} from '../../vega.schema';\nimport {binFormatExpression, binRequiresRange} from '../common';\nimport {isUnitModel, Model, ModelWithField} from '../model';\nimport {DataFlowNode} from './dataflow';\n\nfunction rangeFormula(model: ModelWithField, fieldDef: FieldDef, channel: Channel, config: Config) {\n if (binRequiresRange(fieldDef, channel)) {\n // read format from axis or legend, if there is no format then use config.numberFormat\n\n const guide = isUnitModel(model) ? (model.axis(channel) || model.legend(channel) || {}) : {};\n\n const startField = vgField(fieldDef, {expr: 'datum',});\n const endField = vgField(fieldDef, {expr: 'datum', binSuffix: 'end'});\n\n return {\n formulaAs: vgField(fieldDef, {binSuffix: 'range'}),\n formula: binFormatExpression(startField, endField, guide.format, config)\n };\n }\n return {};\n}\n\nfunction binKey(bin: BinParams, field: string) {\n return `${binToString(bin)}_${field}`;\n}\n\nfunction getSignalsFromModel(model: Model, key: string) {\n return {\n signal: model.getName(`${key}_bins`),\n extentSignal: model.getName(`${key}_extent`)\n };\n}\n\nfunction isBinTransform(t: FieldDef | BinTransform): t is BinTransform {\n return 'as' in t;\n}\n\nfunction createBinComponent(t: FieldDef | BinTransform, model: Model) {\n let as: [string, string];\n\n if (isBinTransform(t)) {\n as = isString(t.as) ? [t.as, `${t.as}_end`] : [t.as[0],t.as[1]];\n } else {\n as = [vgField(t, {}), vgField(t, {binSuffix: 'end'})];\n }\n\n const bin = normalizeBin(t.bin, undefined) || {};\n const key = binKey(bin, t.field);\n const {signal, extentSignal} = getSignalsFromModel(model, key);\n\n const binComponent: BinComponent = {\n bin: bin,\n field: t.field,\n as: as,\n ...signal ? {signal} : {},\n ...extentSignal ? {extentSignal} : {}\n };\n\n return {key, binComponent};\n}\n\nexport interface BinComponent {\n bin: BinParams;\n field: string;\n extentSignal?: string;\n signal?: string;\n as: string[];\n\n // Range Formula\n\n formula?: string;\n formulaAs?: string;\n}\n\nexport class BinNode extends DataFlowNode {\n public clone() {\n return new BinNode(null, duplicate(this.bins));\n }\n\n constructor(parent: DataFlowNode, private bins: Dict) {\n super(parent);\n }\n\n public static makeFromEncoding(parent: DataFlowNode, model: ModelWithField) {\n const bins = model.reduceFieldDef((binComponentIndex: Dict, fieldDef, channel) => {\n if (fieldDef.bin) {\n const {key, binComponent} = createBinComponent(fieldDef, model);\n binComponentIndex[key] = {\n ...binComponent,\n ...binComponentIndex[key],\n ...rangeFormula(model, fieldDef, channel, model.config)\n };\n }\n return binComponentIndex;\n }, {});\n\n if (keys(bins).length === 0) {\n return null;\n }\n\n return new BinNode(parent, bins);\n }\n\n /**\n * Creates a bin node from BinTransform.\n * The optional parameter should provide\n */\n public static makeFromTransform(parent: DataFlowNode, t: BinTransform, model: Model) {\n const {key, binComponent} = createBinComponent(t, model);\n return new BinNode(parent, {\n [key]: binComponent\n });\n }\n\n public merge(other: BinNode) {\n this.bins = {...this.bins, ...other.bins};\n other.remove();\n }\n\n public producedFields() {\n const out = {};\n\n vals(this.bins).forEach(c => {\n c.as.forEach(f => out[f] = true);\n });\n\n return out;\n }\n\n public dependentFields() {\n const out = {};\n\n vals(this.bins).forEach(c => {\n out[c.field] = true;\n });\n\n return out;\n }\n\n public assemble(): VgTransform[] {\n return flatten(vals(this.bins).map(bin => {\n const transform: VgTransform[] = [];\n\n const binTrans: VgBinTransform = {\n type: 'bin',\n field: bin.field,\n as: bin.as,\n signal: bin.signal,\n ...bin.bin\n };\n\n if (!bin.bin.extent && bin.extentSignal) {\n transform.push({\n type: 'extent',\n field: bin.field,\n signal: bin.extentSignal\n });\n binTrans.extent = {signal: bin.extentSignal};\n }\n\n transform.push(binTrans);\n\n if (bin.formula) {\n transform.push({\n type: 'formula',\n expr: bin.formula,\n as: bin.formulaAs\n });\n }\n\n return transform;\n }));\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/calculate.d.ts b/build/src/compile/data/calculate.d.ts new file mode 100644 index 0000000000..433468f6e6 --- /dev/null +++ b/build/src/compile/data/calculate.d.ts @@ -0,0 +1,18 @@ +import { FieldDef } from '../../fielddef'; +import { VgFormulaTransform } from '../../vega.schema'; +import { ModelWithField } from '../model'; +import { SingleDefChannel } from './../../channel'; +import { CalculateTransform } from './../../transform'; +import { DataFlowNode } from './dataflow'; +/** + * We don't know what a calculate node depends on so we should never move it beyond anything that produces fields. + */ +export declare class CalculateNode extends DataFlowNode { + private transform; + clone(): CalculateNode; + constructor(parent: DataFlowNode, transform: CalculateTransform); + static parseAllForSortIndex(parent: DataFlowNode, model: ModelWithField): DataFlowNode; + producedFields(): {}; + assemble(): VgFormulaTransform; +} +export declare function sortArrayIndexField(fieldDef: FieldDef, channel: SingleDefChannel, expr?: 'datum'): string; diff --git a/build/src/compile/data/calculate.js b/build/src/compile/data/calculate.js new file mode 100644 index 0000000000..b1a176a157 --- /dev/null +++ b/build/src/compile/data/calculate.js @@ -0,0 +1,59 @@ +import * as tslib_1 from "tslib"; +import { isScaleFieldDef, vgField } from '../../fielddef'; +import { fieldFilterExpression } from '../../predicate'; +import { isSortArray } from '../../sort'; +import { duplicate } from '../../util'; +import { DataFlowNode } from './dataflow'; +/** + * We don't know what a calculate node depends on so we should never move it beyond anything that produces fields. + */ +var CalculateNode = /** @class */ (function (_super) { + tslib_1.__extends(CalculateNode, _super); + function CalculateNode(parent, transform) { + var _this = _super.call(this, parent) || this; + _this.transform = transform; + return _this; + } + CalculateNode.prototype.clone = function () { + return new CalculateNode(null, duplicate(this.transform)); + }; + CalculateNode.parseAllForSortIndex = function (parent, model) { + // get all the encoding with sort fields from model + model.forEachFieldDef(function (fieldDef, channel) { + if (!isScaleFieldDef(fieldDef)) { + return; + } + if (isSortArray(fieldDef.sort)) { + var field_1 = fieldDef.field, timeUnit_1 = fieldDef.timeUnit; + var sort = fieldDef.sort; + // generate `datum["a"] === val0 ? 0 : datum["a"] === val1 ? 1 : ... : n` via FieldEqualPredicate + var calculate = sort.map(function (sortValue, i) { + return fieldFilterExpression({ field: field_1, timeUnit: timeUnit_1, equal: sortValue }) + " ? " + i + " : "; + }).join('') + sort.length; + parent = new CalculateNode(parent, { + calculate: calculate, + as: sortArrayIndexField(fieldDef, channel) + }); + } + }); + return parent; + }; + CalculateNode.prototype.producedFields = function () { + var out = {}; + out[this.transform.as] = true; + return out; + }; + CalculateNode.prototype.assemble = function () { + return { + type: 'formula', + expr: this.transform.calculate, + as: this.transform.as + }; + }; + return CalculateNode; +}(DataFlowNode)); +export { CalculateNode }; +export function sortArrayIndexField(fieldDef, channel, expr) { + return vgField(fieldDef, { prefix: channel, suffix: 'sort_index', expr: expr }); +} +//# sourceMappingURL=calculate.js.map \ No newline at end of file diff --git a/build/src/compile/data/calculate.js.map b/build/src/compile/data/calculate.js.map new file mode 100644 index 0000000000..fe28b73efd --- /dev/null +++ b/build/src/compile/data/calculate.js.map @@ -0,0 +1 @@ +{"version":3,"file":"calculate.js","sourceRoot":"","sources":["../../../../src/compile/data/calculate.ts"],"names":[],"mappings":";AACA,OAAO,EAAW,eAAe,EAAE,OAAO,EAAC,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAC,qBAAqB,EAAC,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAC,WAAW,EAAC,MAAM,YAAY,CAAC;AACvC,OAAO,EAAC,SAAS,EAAC,MAAM,YAAY,CAAC;AAKrC,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAExC;;GAEG;AACH;IAAmC,yCAAY;IAK7C,uBAAY,MAAoB,EAAU,SAA6B;QAAvE,YACE,kBAAM,MAAM,CAAC,SACd;QAFyC,eAAS,GAAT,SAAS,CAAoB;;IAEvE,CAAC;IANM,6BAAK,GAAZ;QACE,OAAO,IAAI,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5D,CAAC;IAMa,kCAAoB,GAAlC,UAAmC,MAAoB,EAAE,KAAqB;QAC5E,mDAAmD;QACnD,KAAK,CAAC,eAAe,CAAC,UAAC,QAA0B,EAAE,OAAyB;YAC1E,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE;gBAC9B,OAAO;aACR;YACD,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;gBACvB,IAAA,wBAAK,EAAE,8BAAQ,CAAa;gBACnC,IAAM,IAAI,GAA6C,QAAQ,CAAC,IAAI,CAAC;gBACrE,iGAAiG;gBACjG,IAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,UAAC,SAAS,EAAE,CAAC;oBACtC,OAAU,qBAAqB,CAAC,EAAC,KAAK,SAAA,EAAE,QAAQ,YAAA,EAAE,KAAK,EAAE,SAAS,EAAC,CAAC,WAAM,CAAC,QAAK,CAAC;gBACnF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;gBAE1B,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE;oBACjC,SAAS,WAAA;oBACT,EAAE,EAAE,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC;iBAC3C,CAAC,CAAC;aACJ;QACH,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAEM,sCAAc,GAArB;QACE,IAAM,GAAG,GAAG,EAAE,CAAC;QACf,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QAC9B,OAAO,GAAG,CAAC;IACb,CAAC;IAEM,gCAAQ,GAAf;QACE,OAAO;YACL,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS;YAC9B,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE;SACtB,CAAC;IACJ,CAAC;IACH,oBAAC;AAAD,CAAC,AA7CD,CAAmC,YAAY,GA6C9C;;AAED,MAAM,8BAA8B,QAA0B,EAAE,OAAyB,EAAE,IAAc;IACvG,OAAO,OAAO,CAAC,QAAQ,EAAE,EAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,MAAA,EAAC,CAAC,CAAC;AAC1E,CAAC","sourcesContent":["import {DateTime} from '../../datetime';\nimport {FieldDef, isScaleFieldDef, vgField} from '../../fielddef';\nimport {fieldFilterExpression} from '../../predicate';\nimport {isSortArray} from '../../sort';\nimport {duplicate} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\nimport {ModelWithField} from '../model';\nimport {SingleDefChannel} from './../../channel';\nimport {CalculateTransform} from './../../transform';\nimport {DataFlowNode} from './dataflow';\n\n/**\n * We don't know what a calculate node depends on so we should never move it beyond anything that produces fields.\n */\nexport class CalculateNode extends DataFlowNode {\n public clone() {\n return new CalculateNode(null, duplicate(this.transform));\n }\n\n constructor(parent: DataFlowNode, private transform: CalculateTransform) {\n super(parent);\n }\n\n public static parseAllForSortIndex(parent: DataFlowNode, model: ModelWithField) {\n // get all the encoding with sort fields from model\n model.forEachFieldDef((fieldDef: FieldDef, channel: SingleDefChannel) => {\n if (!isScaleFieldDef(fieldDef)) {\n return;\n }\n if (isSortArray(fieldDef.sort)) {\n const {field, timeUnit} = fieldDef;\n const sort: (number | string | boolean | DateTime)[] = fieldDef.sort;\n // generate `datum[\"a\"] === val0 ? 0 : datum[\"a\"] === val1 ? 1 : ... : n` via FieldEqualPredicate\n const calculate = sort.map((sortValue, i) => {\n return `${fieldFilterExpression({field, timeUnit, equal: sortValue})} ? ${i} : `;\n }).join('') + sort.length;\n\n parent = new CalculateNode(parent, {\n calculate,\n as: sortArrayIndexField(fieldDef, channel)\n });\n }\n });\n return parent;\n }\n\n public producedFields() {\n const out = {};\n out[this.transform.as] = true;\n return out;\n }\n\n public assemble(): VgFormulaTransform {\n return {\n type: 'formula',\n expr: this.transform.calculate,\n as: this.transform.as\n };\n }\n}\n\nexport function sortArrayIndexField(fieldDef: FieldDef, channel: SingleDefChannel, expr?: 'datum') {\n return vgField(fieldDef, {prefix: channel, suffix: 'sort_index', expr});\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/dataflow.d.ts b/build/src/compile/data/dataflow.d.ts new file mode 100644 index 0000000000..4083f75a71 --- /dev/null +++ b/build/src/compile/data/dataflow.d.ts @@ -0,0 +1,62 @@ +import { DataSourceType } from '../../data'; +import { Dict, StringSet } from '../../util'; +/** + * A node in the dataflow tree. + */ +export declare class DataFlowNode { + readonly debugName?: string; + private _children; + private _parent; + constructor(parent: DataFlowNode, debugName?: string); + /** + * Clone this node with a deep copy but don't clone links to children or parents. + */ + clone(): DataFlowNode; + /** + * Set of fields that are being created by this node. + */ + producedFields(): StringSet; + dependentFields(): StringSet; + /** + * Set the parent of the node and also add this not to the parent's children. + */ + parent: DataFlowNode; + readonly children: DataFlowNode[]; + numChildren(): number; + addChild(child: DataFlowNode): void; + removeChild(oldChild: DataFlowNode): void; + /** + * Remove node from the dataflow. + */ + remove(): void; + /** + * Insert another node as a parent of this node. + */ + insertAsParentOf(other: DataFlowNode): void; + swapWithParent(): void; +} +export declare class OutputNode extends DataFlowNode { + readonly type: DataSourceType; + private readonly refCounts; + private _source; + private _name; + clone(): this; + /** + * @param source The name of the source. Will change in assemble. + * @param type The type of the output node. + * @param refCounts A global ref counter map. + */ + constructor(parent: DataFlowNode, source: string, type: DataSourceType, refCounts: Dict); + /** + * Request the datasource name and increase the ref counter. + * + * During the parsing phase, this will return the simple name such as 'main' or 'raw'. + * It is crucial to request the name from an output node to mark it as a required node. + * If nobody ever requests the name, this datasource will not be instantiated in the assemble phase. + * + * In the assemble phase, this will return the correct name. + */ + getSource(): string; + isRequired(): boolean; + setSource(source: string): void; +} diff --git a/build/src/compile/data/dataflow.js b/build/src/compile/data/dataflow.js new file mode 100644 index 0000000000..a4a9e30a1b --- /dev/null +++ b/build/src/compile/data/dataflow.js @@ -0,0 +1,146 @@ +import * as tslib_1 from "tslib"; +/** + * A node in the dataflow tree. + */ +var DataFlowNode = /** @class */ (function () { + function DataFlowNode(parent, debugName) { + this.debugName = debugName; + this._children = []; + this._parent = null; + if (parent) { + this.parent = parent; + } + } + /** + * Clone this node with a deep copy but don't clone links to children or parents. + */ + DataFlowNode.prototype.clone = function () { + throw new Error('Cannot clone node'); + }; + /** + * Set of fields that are being created by this node. + */ + DataFlowNode.prototype.producedFields = function () { + return {}; + }; + DataFlowNode.prototype.dependentFields = function () { + return {}; + }; + Object.defineProperty(DataFlowNode.prototype, "parent", { + get: function () { + return this._parent; + }, + /** + * Set the parent of the node and also add this not to the parent's children. + */ + set: function (parent) { + this._parent = parent; + parent.addChild(this); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(DataFlowNode.prototype, "children", { + get: function () { + return this._children; + }, + enumerable: true, + configurable: true + }); + DataFlowNode.prototype.numChildren = function () { + return this._children.length; + }; + DataFlowNode.prototype.addChild = function (child) { + this._children.push(child); + }; + DataFlowNode.prototype.removeChild = function (oldChild) { + this._children.splice(this._children.indexOf(oldChild), 1); + }; + /** + * Remove node from the dataflow. + */ + DataFlowNode.prototype.remove = function () { + for (var _i = 0, _a = this._children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parent = this._parent; + } + this._parent.removeChild(this); + }; + /** + * Insert another node as a parent of this node. + */ + DataFlowNode.prototype.insertAsParentOf = function (other) { + var parent = other.parent; + parent.removeChild(this); + this.parent = parent; + other.parent = this; + }; + DataFlowNode.prototype.swapWithParent = function () { + var parent = this._parent; + var newParent = parent.parent; + // reconnect the children + for (var _i = 0, _a = this._children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parent = parent; + } + // remove old links + this._children = []; // equivalent to removing every child link one by one + parent.removeChild(this); + parent.parent.removeChild(parent); + // swap two nodes + this.parent = newParent; + parent.parent = this; + }; + return DataFlowNode; +}()); +export { DataFlowNode }; +var OutputNode = /** @class */ (function (_super) { + tslib_1.__extends(OutputNode, _super); + /** + * @param source The name of the source. Will change in assemble. + * @param type The type of the output node. + * @param refCounts A global ref counter map. + */ + function OutputNode(parent, source, type, refCounts) { + var _this = _super.call(this, parent, source) || this; + _this.type = type; + _this.refCounts = refCounts; + _this._source = _this._name = source; + if (_this.refCounts && !(_this._name in _this.refCounts)) { + _this.refCounts[_this._name] = 0; + } + return _this; + } + OutputNode.prototype.clone = function () { + var cloneObj = new this.constructor; + cloneObj.debugName = 'clone_' + this.debugName; + cloneObj._source = this._source; + cloneObj._name = 'clone_' + this._name; + cloneObj.type = this.type; + cloneObj.refCounts = this.refCounts; + cloneObj.refCounts[cloneObj._name] = 0; + return cloneObj; + }; + /** + * Request the datasource name and increase the ref counter. + * + * During the parsing phase, this will return the simple name such as 'main' or 'raw'. + * It is crucial to request the name from an output node to mark it as a required node. + * If nobody ever requests the name, this datasource will not be instantiated in the assemble phase. + * + * In the assemble phase, this will return the correct name. + */ + OutputNode.prototype.getSource = function () { + this.refCounts[this._name]++; + return this._source; + }; + OutputNode.prototype.isRequired = function () { + return !!this.refCounts[this._name]; + }; + OutputNode.prototype.setSource = function (source) { + this._source = source; + }; + return OutputNode; +}(DataFlowNode)); +export { OutputNode }; +//# sourceMappingURL=dataflow.js.map \ No newline at end of file diff --git a/build/src/compile/data/dataflow.js.map b/build/src/compile/data/dataflow.js.map new file mode 100644 index 0000000000..236d904c27 --- /dev/null +++ b/build/src/compile/data/dataflow.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dataflow.js","sourceRoot":"","sources":["../../../../src/compile/data/dataflow.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport {DataSourceType} from '../../data';\nimport {Dict, StringSet} from '../../util';\n\n\n/**\n * A node in the dataflow tree.\n */\nexport class DataFlowNode {\n private _children: DataFlowNode[] = [];\n\n private _parent: DataFlowNode = null;\n\n constructor(parent: DataFlowNode, public readonly debugName?: string) {\n if (parent) {\n this.parent = parent;\n }\n }\n\n /**\n * Clone this node with a deep copy but don't clone links to children or parents.\n */\n public clone(): DataFlowNode {\n throw new Error('Cannot clone node');\n }\n\n /**\n * Set of fields that are being created by this node.\n */\n public producedFields(): StringSet {\n return {};\n }\n\n public dependentFields(): StringSet {\n return {};\n }\n\n get parent() {\n return this._parent;\n }\n\n /**\n * Set the parent of the node and also add this not to the parent's children.\n */\n set parent(parent: DataFlowNode) {\n this._parent = parent;\n parent.addChild(this);\n }\n\n get children() {\n return this._children;\n }\n\n public numChildren() {\n return this._children.length;\n }\n\n public addChild(child: DataFlowNode) {\n this._children.push(child);\n }\n\n public removeChild(oldChild: DataFlowNode) {\n this._children.splice(this._children.indexOf(oldChild), 1);\n }\n\n /**\n * Remove node from the dataflow.\n */\n public remove() {\n for (const child of this._children) {\n child.parent = this._parent;\n }\n this._parent.removeChild(this);\n }\n\n /**\n * Insert another node as a parent of this node.\n */\n public insertAsParentOf(other: DataFlowNode) {\n const parent = other.parent;\n parent.removeChild(this);\n this.parent = parent;\n other.parent = this;\n }\n\n public swapWithParent() {\n const parent = this._parent;\n const newParent = parent.parent;\n\n // reconnect the children\n for (const child of this._children) {\n child.parent = parent;\n }\n\n // remove old links\n this._children = []; // equivalent to removing every child link one by one\n parent.removeChild(this);\n parent.parent.removeChild(parent);\n\n\n // swap two nodes\n this.parent = newParent;\n parent.parent = this;\n }\n}\n\nexport class OutputNode extends DataFlowNode {\n private _source: string;\n\n private _name: string;\n\n public clone(): this {\n const cloneObj = new (this.constructor);\n cloneObj.debugName = 'clone_' + this.debugName;\n cloneObj._source = this._source;\n cloneObj._name = 'clone_' + this._name;\n cloneObj.type = this.type;\n cloneObj.refCounts = this.refCounts;\n cloneObj.refCounts[cloneObj._name] = 0;\n return cloneObj;\n }\n\n /**\n * @param source The name of the source. Will change in assemble.\n * @param type The type of the output node.\n * @param refCounts A global ref counter map.\n */\n constructor(parent: DataFlowNode, source: string, public readonly type: DataSourceType, private readonly refCounts: Dict) {\n super(parent, source);\n\n this._source = this._name = source;\n\n if (this.refCounts && !(this._name in this.refCounts)) {\n this.refCounts[this._name] = 0;\n }\n }\n\n /**\n * Request the datasource name and increase the ref counter.\n *\n * During the parsing phase, this will return the simple name such as 'main' or 'raw'.\n * It is crucial to request the name from an output node to mark it as a required node.\n * If nobody ever requests the name, this datasource will not be instantiated in the assemble phase.\n *\n * In the assemble phase, this will return the correct name.\n */\n public getSource() {\n this.refCounts[this._name]++;\n return this._source;\n }\n\n public isRequired(): boolean {\n return !!this.refCounts[this._name];\n }\n\n public setSource(source: string) {\n this._source = source;\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/facet.d.ts b/build/src/compile/data/facet.d.ts new file mode 100644 index 0000000000..f3e361729f --- /dev/null +++ b/build/src/compile/data/facet.d.ts @@ -0,0 +1,28 @@ +import { VgData } from '../../vega.schema'; +import { FacetModel } from '../facet'; +import { DataFlowNode } from './dataflow'; +/** + * A node that helps us track what fields we are faceting by. + */ +export declare class FacetNode extends DataFlowNode { + readonly model: FacetModel; + readonly name: string; + data: string; + private readonly column; + private readonly row; + private readonly childModel; + /** + * @param model The facet model. + * @param name The name that this facet source will have. + * @param data The source data for this facet data. + */ + constructor(parent: DataFlowNode, model: FacetModel, name: string, data: string); + readonly fields: string[]; + /** + * The name to reference this source is its name. + */ + getSource(): string; + private getChildIndependentFieldsWithStep; + private assembleRowColumnData; + assemble(): VgData[]; +} diff --git a/build/src/compile/data/facet.js b/build/src/compile/data/facet.js new file mode 100644 index 0000000000..7999764810 --- /dev/null +++ b/build/src/compile/data/facet.js @@ -0,0 +1,148 @@ +import * as tslib_1 from "tslib"; +import { isArray } from 'vega-util'; +import { COLUMN, ROW } from '../../channel'; +import { vgField } from '../../fielddef'; +import * as log from '../../log'; +import { hasDiscreteDomain } from '../../scale'; +import { isSortField } from '../../sort'; +import { isVgRangeStep } from '../../vega.schema'; +import { assembleDomain, getFieldFromDomain } from '../scale/domain'; +import { sortArrayIndexField } from './calculate'; +import { DataFlowNode } from './dataflow'; +/** + * A node that helps us track what fields we are faceting by. + */ +var FacetNode = /** @class */ (function (_super) { + tslib_1.__extends(FacetNode, _super); + /** + * @param model The facet model. + * @param name The name that this facet source will have. + * @param data The source data for this facet data. + */ + function FacetNode(parent, model, name, data) { + var _this = _super.call(this, parent) || this; + _this.model = model; + _this.name = name; + _this.data = data; + for (var _i = 0, _a = [COLUMN, ROW]; _i < _a.length; _i++) { + var channel = _a[_i]; + var fieldDef = model.facet[channel]; + if (fieldDef) { + var bin = fieldDef.bin, sort = fieldDef.sort; + _this[channel] = tslib_1.__assign({ name: model.getName(channel + "_domain"), fields: [ + vgField(fieldDef) + ].concat((bin ? [vgField(fieldDef, { binSuffix: 'end' })] : [])) }, (isSortField(sort) ? { sortField: sort } : + isArray(sort) ? { sortIndexField: sortArrayIndexField(fieldDef, channel) } : + {})); + } + } + _this.childModel = model.child; + return _this; + } + Object.defineProperty(FacetNode.prototype, "fields", { + get: function () { + return ((this.column && this.column.fields) || []).concat((this.row && this.row.fields) || []); + }, + enumerable: true, + configurable: true + }); + /** + * The name to reference this source is its name. + */ + FacetNode.prototype.getSource = function () { + return this.name; + }; + FacetNode.prototype.getChildIndependentFieldsWithStep = function () { + var childIndependentFieldsWithStep = {}; + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var channel = _a[_i]; + var childScaleComponent = this.childModel.component.scales[channel]; + if (childScaleComponent && !childScaleComponent.merged) { + var type = childScaleComponent.get('type'); + var range = childScaleComponent.get('range'); + if (hasDiscreteDomain(type) && isVgRangeStep(range)) { + var domain = assembleDomain(this.childModel, channel); + var field = getFieldFromDomain(domain); + if (field) { + childIndependentFieldsWithStep[channel] = field; + } + else { + log.warn('Unknown field for ${channel}. Cannot calculate view size.'); + } + } + } + } + return childIndependentFieldsWithStep; + }; + FacetNode.prototype.assembleRowColumnData = function (channel, crossedDataName, childIndependentFieldsWithStep) { + var childChannel = channel === 'row' ? 'y' : 'x'; + var fields = []; + var ops = []; + var as = []; + if (childIndependentFieldsWithStep[childChannel]) { + if (crossedDataName) { + // If there is a crossed data, calculate max + fields.push("distinct_" + childIndependentFieldsWithStep[childChannel]); + ops.push('max'); + } + else { + // If there is no crossed data, just calculate distinct + fields.push(childIndependentFieldsWithStep[childChannel]); + ops.push('distinct'); + } + // Although it is technically a max, just name it distinct so it's easier to refer to it + as.push("distinct_" + childIndependentFieldsWithStep[childChannel]); + } + var _a = this[channel], sortField = _a.sortField, sortIndexField = _a.sortIndexField; + if (sortField) { + var op = sortField.op, field = sortField.field; + fields.push(field); + ops.push(op); + as.push(vgField(sortField)); + } + else if (sortIndexField) { + fields.push(sortIndexField); + ops.push('max'); + as.push(sortIndexField); + } + return { + name: this[channel].name, + // Use data from the crossed one if it exist + source: crossedDataName || this.data, + transform: [tslib_1.__assign({ type: 'aggregate', groupby: this[channel].fields }, (fields.length ? { + fields: fields, ops: ops, as: as + } : {}))] + }; + }; + FacetNode.prototype.assemble = function () { + var data = []; + var crossedDataName = null; + var childIndependentFieldsWithStep = this.getChildIndependentFieldsWithStep(); + if (this.column && this.row && (childIndependentFieldsWithStep.x || childIndependentFieldsWithStep.y)) { + // Need to create a cross dataset to correctly calculate cardinality + crossedDataName = "cross_" + this.column.name + "_" + this.row.name; + var fields = [].concat(childIndependentFieldsWithStep.x ? [childIndependentFieldsWithStep.x] : [], childIndependentFieldsWithStep.y ? [childIndependentFieldsWithStep.y] : []); + var ops = fields.map(function () { return 'distinct'; }); + data.push({ + name: crossedDataName, + source: this.data, + transform: [{ + type: 'aggregate', + groupby: this.column.fields.concat(this.row.fields), + fields: fields, + ops: ops + }] + }); + } + for (var _i = 0, _a = [COLUMN, ROW]; _i < _a.length; _i++) { + var channel = _a[_i]; + if (this[channel]) { + data.push(this.assembleRowColumnData(channel, crossedDataName, childIndependentFieldsWithStep)); + } + } + return data; + }; + return FacetNode; +}(DataFlowNode)); +export { FacetNode }; +//# sourceMappingURL=facet.js.map \ No newline at end of file diff --git a/build/src/compile/data/facet.js.map b/build/src/compile/data/facet.js.map new file mode 100644 index 0000000000..f0dcf18790 --- /dev/null +++ b/build/src/compile/data/facet.js.map @@ -0,0 +1 @@ +{"version":3,"file":"facet.js","sourceRoot":"","sources":["../../../../src/compile/data/facet.ts"],"names":[],"mappings":"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","sourcesContent":["import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {COLUMN, ROW, ScaleChannel} from '../../channel';\nimport {vgField} from '../../fielddef';\nimport * as log from '../../log';\nimport {hasDiscreteDomain} from '../../scale';\nimport {EncodingSortField, isSortField} from '../../sort';\nimport {isVgRangeStep, VgData} from '../../vega.schema';\nimport {FacetModel} from '../facet';\nimport {Model} from '../model';\nimport {assembleDomain, getFieldFromDomain} from '../scale/domain';\nimport {sortArrayIndexField} from './calculate';\nimport {DataFlowNode} from './dataflow';\n\ntype ChildIndependentFieldsWithStep = {\n x?: string,\n y?: string\n};\n\ninterface FacetChannelInfo {\n name: string;\n fields: string[];\n sortField?: EncodingSortField;\n\n sortIndexField?: string;\n}\n\n/**\n * A node that helps us track what fields we are faceting by.\n */\nexport class FacetNode extends DataFlowNode {\n private readonly column: FacetChannelInfo;\n\n private readonly row: FacetChannelInfo;\n\n private readonly childModel: Model;\n\n /**\n * @param model The facet model.\n * @param name The name that this facet source will have.\n * @param data The source data for this facet data.\n */\n public constructor(parent: DataFlowNode, public readonly model: FacetModel, public readonly name: string, public data: string) {\n super(parent);\n\n for (const channel of [COLUMN, ROW]) {\n const fieldDef = model.facet[channel];\n if (fieldDef) {\n const {bin, sort} = fieldDef;\n this[channel] = {\n name: model.getName(`${channel}_domain`),\n fields: [\n vgField(fieldDef),\n ...(bin ? [vgField(fieldDef, {binSuffix: 'end'})] : [])\n ],\n ...(\n isSortField(sort) ? {sortField: sort} :\n isArray(sort) ? {sortIndexField: sortArrayIndexField(fieldDef, channel)} :\n {}\n )\n };\n }\n }\n this.childModel = model.child;\n }\n\n get fields() {\n return [\n ...(this.column && this.column.fields) || [],\n ...(this.row && this.row.fields) || []\n ];\n }\n\n /**\n * The name to reference this source is its name.\n */\n public getSource() {\n return this.name;\n }\n\n private getChildIndependentFieldsWithStep() {\n const childIndependentFieldsWithStep: ChildIndependentFieldsWithStep = {};\n\n for (const channel of ['x', 'y'] as ScaleChannel[]) {\n const childScaleComponent = this.childModel.component.scales[channel];\n if (childScaleComponent && !childScaleComponent.merged) {\n const type = childScaleComponent.get('type');\n const range = childScaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const domain = assembleDomain(this.childModel, channel);\n const field = getFieldFromDomain(domain);\n if (field) {\n childIndependentFieldsWithStep[channel] = field;\n } else {\n log.warn('Unknown field for ${channel}. Cannot calculate view size.');\n }\n }\n }\n }\n\n return childIndependentFieldsWithStep;\n }\n\n private assembleRowColumnData(channel: 'row' | 'column', crossedDataName: string, childIndependentFieldsWithStep: ChildIndependentFieldsWithStep): VgData {\n const childChannel = channel === 'row' ? 'y' : 'x';\n\n const fields: string[] = [];\n const ops: AggregateOp[] = [];\n const as: string[] = [];\n\n if (childIndependentFieldsWithStep[childChannel]) {\n if (crossedDataName) {\n // If there is a crossed data, calculate max\n fields.push(`distinct_${childIndependentFieldsWithStep[childChannel]}`);\n\n ops.push('max');\n } else {\n // If there is no crossed data, just calculate distinct\n fields.push(childIndependentFieldsWithStep[childChannel]);\n ops.push('distinct');\n }\n // Although it is technically a max, just name it distinct so it's easier to refer to it\n as.push(`distinct_${childIndependentFieldsWithStep[childChannel]}`);\n }\n\n const {sortField, sortIndexField} = this[channel];\n if (sortField) {\n const {op, field} = sortField;\n fields.push(field);\n ops.push(op);\n as.push(vgField(sortField));\n } else if (sortIndexField) {\n fields.push(sortIndexField);\n ops.push('max');\n as.push(sortIndexField);\n }\n\n return {\n name: this[channel].name,\n // Use data from the crossed one if it exist\n source: crossedDataName || this.data,\n transform: [{\n type: 'aggregate',\n groupby: this[channel].fields,\n ...(fields.length ? {\n fields, ops, as\n } : {})\n }]\n };\n }\n\n public assemble() {\n const data: VgData[] = [];\n let crossedDataName = null;\n const childIndependentFieldsWithStep = this.getChildIndependentFieldsWithStep();\n\n if (this.column && this.row && (childIndependentFieldsWithStep.x || childIndependentFieldsWithStep.y)) {\n // Need to create a cross dataset to correctly calculate cardinality\n crossedDataName = `cross_${this.column.name}_${this.row.name}`;\n\n const fields = [].concat(\n childIndependentFieldsWithStep.x ? [childIndependentFieldsWithStep.x] : [],\n childIndependentFieldsWithStep.y ? [childIndependentFieldsWithStep.y] : [],\n );\n const ops = fields.map((): AggregateOp => 'distinct');\n\n data.push({\n name: crossedDataName,\n source: this.data,\n transform: [{\n type: 'aggregate',\n groupby: [...this.column.fields, ...this.row.fields],\n fields,\n ops\n }]\n });\n }\n\n for (const channel of [COLUMN, ROW]) {\n if (this[channel]) {\n data.push(this.assembleRowColumnData(channel, crossedDataName, childIndependentFieldsWithStep));\n }\n }\n\n return data;\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/filter.d.ts b/build/src/compile/data/filter.d.ts new file mode 100644 index 0000000000..7a0ad03f01 --- /dev/null +++ b/build/src/compile/data/filter.d.ts @@ -0,0 +1,13 @@ +import { LogicalOperand } from '../../logical'; +import { Predicate } from '../../predicate'; +import { VgFilterTransform } from '../../vega.schema'; +import { Model } from '../model'; +import { DataFlowNode } from './dataflow'; +export declare class FilterNode extends DataFlowNode { + private readonly model; + private filter; + private expr; + clone(): FilterNode; + constructor(parent: DataFlowNode, model: Model, filter: LogicalOperand); + assemble(): VgFilterTransform; +} diff --git a/build/src/compile/data/filter.js b/build/src/compile/data/filter.js new file mode 100644 index 0000000000..8fc8160bab --- /dev/null +++ b/build/src/compile/data/filter.js @@ -0,0 +1,26 @@ +import * as tslib_1 from "tslib"; +import { expression } from '../../predicate'; +import { duplicate } from '../../util'; +import { DataFlowNode } from './dataflow'; +var FilterNode = /** @class */ (function (_super) { + tslib_1.__extends(FilterNode, _super); + function FilterNode(parent, model, filter) { + var _this = _super.call(this, parent) || this; + _this.model = model; + _this.filter = filter; + _this.expr = expression(_this.model, _this.filter, _this); + return _this; + } + FilterNode.prototype.clone = function () { + return new FilterNode(null, this.model, duplicate(this.filter)); + }; + FilterNode.prototype.assemble = function () { + return { + type: 'filter', + expr: this.expr + }; + }; + return FilterNode; +}(DataFlowNode)); +export { FilterNode }; +//# sourceMappingURL=filter.js.map \ No newline at end of file diff --git a/build/src/compile/data/filter.js.map b/build/src/compile/data/filter.js.map new file mode 100644 index 0000000000..8411d86561 --- /dev/null +++ b/build/src/compile/data/filter.js.map @@ -0,0 +1 @@ +{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../../../src/compile/data/filter.ts"],"names":[],"mappings":";AACA,OAAO,EAAC,UAAU,EAAY,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAC,SAAS,EAAC,MAAM,YAAY,CAAC;AAGrC,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAExC;IAAgC,sCAAY;IAM1C,oBAAY,MAAoB,EAAmB,KAAY,EAAU,MAAiC;QAA1G,YACE,kBAAM,MAAM,CAAC,SAEd;QAHkD,WAAK,GAAL,KAAK,CAAO;QAAU,YAAM,GAAN,MAAM,CAA2B;QAExG,KAAI,CAAC,IAAI,GAAG,UAAU,CAAC,KAAI,CAAC,KAAK,EAAE,KAAI,CAAC,MAAM,EAAE,KAAI,CAAC,CAAC;;IACxD,CAAC;IAPM,0BAAK,GAAZ;QACE,OAAO,IAAI,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAClE,CAAC;IAOM,6BAAQ,GAAf;QACE,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC;IACJ,CAAC;IACH,iBAAC;AAAD,CAAC,AAjBD,CAAgC,YAAY,GAiB3C","sourcesContent":["import {LogicalOperand} from '../../logical';\nimport {expression, Predicate} from '../../predicate';\nimport {duplicate} from '../../util';\nimport {VgFilterTransform} from '../../vega.schema';\nimport {Model} from '../model';\nimport {DataFlowNode} from './dataflow';\n\nexport class FilterNode extends DataFlowNode {\n private expr: string;\n public clone() {\n return new FilterNode(null, this.model, duplicate(this.filter));\n }\n\n constructor(parent: DataFlowNode, private readonly model: Model, private filter: LogicalOperand) {\n super(parent);\n this.expr = expression(this.model, this.filter, this);\n }\n\n public assemble(): VgFilterTransform {\n return {\n type: 'filter',\n expr: this.expr\n };\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/filterinvalid.d.ts b/build/src/compile/data/filterinvalid.d.ts new file mode 100644 index 0000000000..b98aea3db3 --- /dev/null +++ b/build/src/compile/data/filterinvalid.d.ts @@ -0,0 +1,13 @@ +import { FieldDef } from '../../fielddef'; +import { Dict } from '../../util'; +import { VgFilterTransform } from '../../vega.schema'; +import { UnitModel } from '../unit'; +import { DataFlowNode } from './dataflow'; +export declare class FilterInvalidNode extends DataFlowNode { + private fieldDefs; + clone(): FilterInvalidNode; + constructor(parent: DataFlowNode, fieldDefs: Dict>); + static make(parent: DataFlowNode, model: UnitModel): FilterInvalidNode; + readonly filter: Dict>; + assemble(): VgFilterTransform; +} diff --git a/build/src/compile/data/filterinvalid.js b/build/src/compile/data/filterinvalid.js new file mode 100644 index 0000000000..844dabc69c --- /dev/null +++ b/build/src/compile/data/filterinvalid.js @@ -0,0 +1,69 @@ +import * as tslib_1 from "tslib"; +import { isScaleChannel } from '../../channel'; +import { vgField as fieldRef } from '../../fielddef'; +import { isPathMark } from '../../mark'; +import { hasContinuousDomain } from '../../scale'; +import { keys } from '../../util'; +import { DataFlowNode } from './dataflow'; +var FilterInvalidNode = /** @class */ (function (_super) { + tslib_1.__extends(FilterInvalidNode, _super); + function FilterInvalidNode(parent, fieldDefs) { + var _this = _super.call(this, parent) || this; + _this.fieldDefs = fieldDefs; + return _this; + } + FilterInvalidNode.prototype.clone = function () { + return new FilterInvalidNode(null, tslib_1.__assign({}, this.fieldDefs)); + }; + FilterInvalidNode.make = function (parent, model) { + var config = model.config, mark = model.mark; + if (config.invalidValues !== 'filter') { + return null; + } + var filter = model.reduceFieldDef(function (aggregator, fieldDef, channel) { + var scaleComponent = isScaleChannel(channel) && model.getScaleComponent(channel); + if (scaleComponent) { + var scaleType = scaleComponent.get('type'); + // While discrete domain scales can handle invalid values, continuous scales can't. + // Thus, for non-path marks, we have to filter null for scales with continuous domains. + // (For path marks, we will use "defined" property and skip these values instead.) + if (hasContinuousDomain(scaleType) && !fieldDef.aggregate && !isPathMark(mark)) { + aggregator[fieldDef.field] = fieldDef; + } + } + return aggregator; + }, {}); + if (!keys(filter).length) { + return null; + } + return new FilterInvalidNode(parent, filter); + }; + Object.defineProperty(FilterInvalidNode.prototype, "filter", { + get: function () { + return this.fieldDefs; + }, + enumerable: true, + configurable: true + }); + // create the VgTransforms for each of the filtered fields + FilterInvalidNode.prototype.assemble = function () { + var _this = this; + var filters = keys(this.filter).reduce(function (vegaFilters, field) { + var fieldDef = _this.fieldDefs[field]; + var ref = fieldRef(fieldDef, { expr: 'datum' }); + if (fieldDef !== null) { + vegaFilters.push(ref + " !== null"); + vegaFilters.push("!isNaN(" + ref + ")"); + } + return vegaFilters; + }, []); + return filters.length > 0 ? + { + type: 'filter', + expr: filters.join(' && ') + } : null; + }; + return FilterInvalidNode; +}(DataFlowNode)); +export { FilterInvalidNode }; +//# sourceMappingURL=filterinvalid.js.map \ No newline at end of file diff --git a/build/src/compile/data/filterinvalid.js.map b/build/src/compile/data/filterinvalid.js.map new file mode 100644 index 0000000000..10c6f96686 --- /dev/null +++ b/build/src/compile/data/filterinvalid.js.map @@ -0,0 +1 @@ +{"version":3,"file":"filterinvalid.js","sourceRoot":"","sources":["../../../../src/compile/data/filterinvalid.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAW,OAAO,IAAI,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAC;AACtC,OAAO,EAAC,mBAAmB,EAAY,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAO,IAAI,EAAC,MAAM,YAAY,CAAC;AAGtC,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAExC;IAAuC,6CAAY;IAKjD,2BAAY,MAAoB,EAAU,SAAiC;QAA3E,YACC,kBAAM,MAAM,CAAC,SACb;QAFyC,eAAS,GAAT,SAAS,CAAwB;;IAE3E,CAAC;IANM,iCAAK,GAAZ;QACE,OAAO,IAAI,iBAAiB,CAAC,IAAI,uBAAM,IAAI,CAAC,SAAS,EAAE,CAAC;IAC1D,CAAC;IAMa,sBAAI,GAAlB,UAAmB,MAAoB,EAAE,KAAgB;QAChD,IAAA,qBAAM,EAAE,iBAAI,CAAU;QAC7B,IAAI,MAAM,CAAC,aAAa,KAAK,QAAQ,EAAG;YACtC,OAAO,IAAI,CAAC;SACb;QAED,IAAM,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC,UAAC,UAAkC,EAAE,QAAQ,EAAE,OAAO;YACxF,IAAM,cAAc,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;YACnF,IAAI,cAAc,EAAE;gBAClB,IAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAG7C,mFAAmF;gBACnF,uFAAuF;gBACvF,kFAAkF;gBAClF,IAAI,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;oBAC9E,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;iBACvC;aACF;YACD,OAAO,UAAU,CAAC;QACpB,CAAC,EAAE,EAA4B,CAAC,CAAC;QAEjC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE;YACxB,OAAO,IAAI,CAAC;SACb;QAED,OAAO,IAAI,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,sBAAI,qCAAM;aAAV;YACE,OAAO,IAAI,CAAC,SAAS,CAAC;QACxB,CAAC;;;OAAA;IAED,0DAA0D;IACnD,oCAAQ,GAAf;QAAA,iBAiBC;QAhBC,IAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,UAAC,WAAW,EAAE,KAAK;YAC1D,IAAM,QAAQ,GAAG,KAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACvC,IAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAC,IAAI,EAAE,OAAO,EAAC,CAAC,CAAC;YAEhD,IAAI,QAAQ,KAAK,IAAI,EAAE;gBACrB,WAAW,CAAC,IAAI,CAAI,GAAG,cAAW,CAAC,CAAC;gBACpC,WAAW,CAAC,IAAI,CAAC,YAAU,GAAG,MAAG,CAAC,CAAC;aACpC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC3B;gBACI,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;aAC7B,CAAC,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IACH,wBAAC;AAAD,CAAC,AA7DD,CAAuC,YAAY,GA6DlD","sourcesContent":["import {isScaleChannel} from '../../channel';\nimport {FieldDef, vgField as fieldRef} from '../../fielddef';\nimport {isPathMark} from '../../mark';\nimport {hasContinuousDomain, ScaleType} from '../../scale';\nimport {Dict, keys} from '../../util';\nimport {VgFilterTransform} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {DataFlowNode} from './dataflow';\n\nexport class FilterInvalidNode extends DataFlowNode {\n public clone() {\n return new FilterInvalidNode(null, {...this.fieldDefs});\n }\n\n constructor(parent: DataFlowNode, private fieldDefs: Dict>) {\n super(parent);\n }\n\n public static make(parent: DataFlowNode, model: UnitModel): FilterInvalidNode {\n const {config, mark} = model;\n if (config.invalidValues !== 'filter' ) {\n return null;\n }\n\n const filter = model.reduceFieldDef((aggregator: Dict>, fieldDef, channel) => {\n const scaleComponent = isScaleChannel(channel) && model.getScaleComponent(channel);\n if (scaleComponent) {\n const scaleType = scaleComponent.get('type');\n\n\n // While discrete domain scales can handle invalid values, continuous scales can't.\n // Thus, for non-path marks, we have to filter null for scales with continuous domains.\n // (For path marks, we will use \"defined\" property and skip these values instead.)\n if (hasContinuousDomain(scaleType) && !fieldDef.aggregate && !isPathMark(mark)) {\n aggregator[fieldDef.field] = fieldDef;\n }\n }\n return aggregator;\n }, {} as Dict>);\n\n if (!keys(filter).length) {\n return null;\n }\n\n return new FilterInvalidNode(parent, filter);\n }\n\n get filter() {\n return this.fieldDefs;\n }\n\n // create the VgTransforms for each of the filtered fields\n public assemble(): VgFilterTransform {\n const filters = keys(this.filter).reduce((vegaFilters, field) => {\n const fieldDef = this.fieldDefs[field];\n const ref = fieldRef(fieldDef, {expr: 'datum'});\n\n if (fieldDef !== null) {\n vegaFilters.push(`${ref} !== null`);\n vegaFilters.push(`!isNaN(${ref})`);\n }\n return vegaFilters;\n }, []);\n\n return filters.length > 0 ?\n {\n type: 'filter',\n expr: filters.join(' && ')\n } : null;\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/formatparse.d.ts b/build/src/compile/data/formatparse.d.ts new file mode 100644 index 0000000000..f71a33960a --- /dev/null +++ b/build/src/compile/data/formatparse.d.ts @@ -0,0 +1,33 @@ +import { AncestorParse } from '.'; +import { FilterTransform } from '../../transform'; +import { Dict, StringSet } from '../../util'; +import { VgFormulaTransform } from '../../vega.schema'; +import { Model } from '../model'; +import { DataFlowNode } from './dataflow'; +export declare class ParseNode extends DataFlowNode { + private _parse; + clone(): ParseNode; + constructor(parent: DataFlowNode, parse: Dict); + /** + * Creates a parse node from a data.format.parse and updates ancestorParse. + */ + static makeExplicit(parent: DataFlowNode, model: Model, ancestorParse: AncestorParse): ParseNode; + static makeImplicitFromFilterTransform(parent: DataFlowNode, transform: FilterTransform, ancestorParse: AncestorParse): ParseNode; + /** + * Creates a parse node for implicit parsing from a model and updates ancestorParse. + */ + static makeImplicitFromEncoding(parent: DataFlowNode, model: Model, ancestorParse: AncestorParse): ParseNode; + /** + * Creates a parse node from "explicit" parse and "implicit" parse and updates ancestorParse. + */ + private static makeWithAncestors; + readonly parse: Dict; + merge(other: ParseNode): void; + /** + * Assemble an object for Vega's format.parse property. + */ + assembleFormatParse(): {}; + producedFields(): StringSet; + dependentFields(): StringSet; + assembleTransforms(onlyNested?: boolean): VgFormulaTransform[]; +} diff --git a/build/src/compile/data/formatparse.js b/build/src/compile/data/formatparse.js new file mode 100644 index 0000000000..ce423904de --- /dev/null +++ b/build/src/compile/data/formatparse.js @@ -0,0 +1,243 @@ +import * as tslib_1 from "tslib"; +import { isNumber, isString, toSet } from 'vega-util'; +import { isCountingAggregateOp } from '../../aggregate'; +import { isDateTime } from '../../datetime'; +import { isNumberFieldDef, isScaleFieldDef, isTimeFieldDef } from '../../fielddef'; +import * as log from '../../log'; +import { forEachLeaf } from '../../logical'; +import { isFieldEqualPredicate, isFieldOneOfPredicate, isFieldPredicate, isFieldRangePredicate } from '../../predicate'; +import { isSortField } from '../../sort'; +import { accessPathDepth, accessPathWithDatum, duplicate, keys, removePathFromField } from '../../util'; +import { isFacetModel, isUnitModel } from '../model'; +import { Split } from '../split'; +import { DataFlowNode } from './dataflow'; +/** + * @param field The field. + * @param parse What to parse the field as. + */ +function parseExpression(field, parse) { + var f = accessPathWithDatum(field); + if (parse === 'number') { + return "toNumber(" + f + ")"; + } + else if (parse === 'boolean') { + return "toBoolean(" + f + ")"; + } + else if (parse === 'string') { + return "toString(" + f + ")"; + } + else if (parse === 'date') { + return "toDate(" + f + ")"; + } + else if (parse === 'flatten') { + return f; + } + else if (parse.indexOf('date:') === 0) { + var specifier = parse.slice(5, parse.length); + return "timeParse(" + f + "," + specifier + ")"; + } + else if (parse.indexOf('utc:') === 0) { + var specifier = parse.slice(4, parse.length); + return "utcParse(" + f + "," + specifier + ")"; + } + else { + log.warn(log.message.unrecognizedParse(parse)); + return null; + } +} +var ParseNode = /** @class */ (function (_super) { + tslib_1.__extends(ParseNode, _super); + function ParseNode(parent, parse) { + var _this = _super.call(this, parent) || this; + _this._parse = parse; + return _this; + } + ParseNode.prototype.clone = function () { + return new ParseNode(null, duplicate(this._parse)); + }; + /** + * Creates a parse node from a data.format.parse and updates ancestorParse. + */ + ParseNode.makeExplicit = function (parent, model, ancestorParse) { + // Custom parse + var explicit = {}; + var data = model.data; + if (data && data.format && data.format.parse) { + explicit = data.format.parse; + } + return this.makeWithAncestors(parent, explicit, {}, ancestorParse); + }; + ParseNode.makeImplicitFromFilterTransform = function (parent, transform, ancestorParse) { + var parse = {}; + forEachLeaf(transform.filter, function (filter) { + if (isFieldPredicate(filter)) { + // Automatically add a parse node for filters with filter objects + var val = null; + // For EqualFilter, just use the equal property. + // For RangeFilter and OneOfFilter, all array members should have + // the same type, so we only use the first one. + if (isFieldEqualPredicate(filter)) { + val = filter.equal; + } + else if (isFieldRangePredicate(filter)) { + val = filter.range[0]; + } + else if (isFieldOneOfPredicate(filter)) { + val = (filter.oneOf || filter['in'])[0]; + } // else -- for filter expression, we can't infer anything + if (val) { + if (isDateTime(val)) { + parse[filter.field] = 'date'; + } + else if (isNumber(val)) { + parse[filter.field] = 'number'; + } + else if (isString(val)) { + parse[filter.field] = 'string'; + } + } + if (filter.timeUnit) { + parse[filter.field] = 'date'; + } + } + }); + if (keys(parse).length === 0) { + return null; + } + return this.makeWithAncestors(parent, {}, parse, ancestorParse); + }; + /** + * Creates a parse node for implicit parsing from a model and updates ancestorParse. + */ + ParseNode.makeImplicitFromEncoding = function (parent, model, ancestorParse) { + var implicit = {}; + if (isUnitModel(model) || isFacetModel(model)) { + // Parse encoded fields + model.forEachFieldDef(function (fieldDef) { + if (isTimeFieldDef(fieldDef)) { + implicit[fieldDef.field] = 'date'; + } + else if (isNumberFieldDef(fieldDef)) { + if (!isCountingAggregateOp(fieldDef.aggregate)) { + implicit[fieldDef.field] = 'number'; + } + } + else if (accessPathDepth(fieldDef.field) > 1) { + // For non-date/non-number (strings and booleans), derive a flattened field for a referenced nested field. + // (Parsing numbers / dates already flattens numeric and temporal fields.) + if (!(fieldDef.field in implicit)) { + implicit[fieldDef.field] = 'flatten'; + } + } + else if (isScaleFieldDef(fieldDef) && isSortField(fieldDef.sort) && accessPathDepth(fieldDef.sort.field) > 1) { + // Flatten fields that we sort by but that are not otherwise flattened. + if (!(fieldDef.sort.field in implicit)) { + implicit[fieldDef.sort.field] = 'flatten'; + } + } + }); + } + return this.makeWithAncestors(parent, {}, implicit, ancestorParse); + }; + /** + * Creates a parse node from "explicit" parse and "implicit" parse and updates ancestorParse. + */ + ParseNode.makeWithAncestors = function (parent, explicit, implicit, ancestorParse) { + // We should not parse what has already been parsed in a parent (explicitly or implicitly) or what has been derived (maked as "derived"). We also don't need to flatten a field that has already been parsed. + for (var _i = 0, _a = keys(implicit); _i < _a.length; _i++) { + var field = _a[_i]; + var parsedAs = ancestorParse.getWithExplicit(field); + if (parsedAs.value !== undefined) { + // We always ignore derived fields even if they are implicitly defined because we expect users to create the right types. + if (parsedAs.explicit || parsedAs.value === implicit[field] || parsedAs.value === 'derived' || implicit[field] === 'flatten') { + delete implicit[field]; + } + else { + log.warn(log.message.differentParse(field, implicit[field], parsedAs.value)); + } + } + } + for (var _b = 0, _c = keys(explicit); _b < _c.length; _b++) { + var field = _c[_b]; + var parsedAs = ancestorParse.get(field); + if (parsedAs !== undefined) { + // Don't parse a field again if it has been parsed with the same type already. + if (parsedAs === explicit[field]) { + delete explicit[field]; + } + else { + log.warn(log.message.differentParse(field, explicit[field], parsedAs)); + } + } + } + var parse = new Split(explicit, implicit); + // add the format parse from this model so that children don't parse the same field again + ancestorParse.copyAll(parse); + // copy only non-null parses + var p = {}; + for (var _d = 0, _e = keys(parse.combine()); _d < _e.length; _d++) { + var key = _e[_d]; + var val = parse.get(key); + if (val !== null) { + p[key] = val; + } + } + if (keys(p).length === 0 || ancestorParse.parseNothing) { + return null; + } + return new ParseNode(parent, p); + }; + Object.defineProperty(ParseNode.prototype, "parse", { + get: function () { + return this._parse; + }, + enumerable: true, + configurable: true + }); + ParseNode.prototype.merge = function (other) { + this._parse = tslib_1.__assign({}, this._parse, other.parse); + other.remove(); + }; + /** + * Assemble an object for Vega's format.parse property. + */ + ParseNode.prototype.assembleFormatParse = function () { + var formatParse = {}; + for (var _i = 0, _a = keys(this._parse); _i < _a.length; _i++) { + var field = _a[_i]; + var p = this._parse[field]; + if (accessPathDepth(field) === 1) { + formatParse[field] = p; + } + } + return formatParse; + }; + // format parse depends and produces all fields in its parse + ParseNode.prototype.producedFields = function () { + return toSet(keys(this._parse)); + }; + ParseNode.prototype.dependentFields = function () { + return toSet(keys(this._parse)); + }; + ParseNode.prototype.assembleTransforms = function (onlyNested) { + var _this = this; + if (onlyNested === void 0) { onlyNested = false; } + return keys(this._parse) + .filter(function (field) { return onlyNested ? accessPathDepth(field) > 1 : true; }) + .map(function (field) { + var expr = parseExpression(field, _this._parse[field]); + if (!expr) { + return null; + } + var formula = { + type: 'formula', + expr: expr, + as: removePathFromField(field) // Vega output is always flattened + }; + return formula; + }).filter(function (t) { return t !== null; }); + }; + return ParseNode; +}(DataFlowNode)); +export { ParseNode }; +//# sourceMappingURL=formatparse.js.map \ No newline at end of file diff --git a/build/src/compile/data/formatparse.js.map b/build/src/compile/data/formatparse.js.map new file mode 100644 index 0000000000..2eef85a928 --- /dev/null +++ b/build/src/compile/data/formatparse.js.map @@ -0,0 +1 @@ +{"version":3,"file":"formatparse.js","sourceRoot":"","sources":["../../../../src/compile/data/formatparse.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAC,MAAM,WAAW,CAAC;AAEpD,OAAO,EAAC,qBAAqB,EAAC,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAW,UAAU,EAAC,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAC,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAC,MAAM,gBAAgB,CAAC;AACjF,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAC,qBAAqB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,qBAAqB,EAAC,MAAM,iBAAiB,CAAC;AACtH,OAAO,EAAC,WAAW,EAAC,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAC,eAAe,EAAE,mBAAmB,EAAQ,SAAS,EAAE,IAAI,EAAE,mBAAmB,EAAY,MAAM,YAAY,CAAC;AAEvH,OAAO,EAAC,YAAY,EAAE,WAAW,EAAQ,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAC,KAAK,EAAC,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAGxC;;;GAGG;AACH,yBAAyB,KAAa,EAAE,KAAa;IACnD,IAAM,CAAC,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,KAAK,KAAK,QAAQ,EAAE;QACtB,OAAO,cAAY,CAAC,MAAG,CAAC;KACzB;SAAM,IAAI,KAAK,KAAK,SAAS,EAAE;QAC9B,OAAO,eAAa,CAAC,MAAG,CAAC;KAC1B;SAAM,IAAI,KAAK,KAAK,QAAQ,EAAE;QAC7B,OAAO,cAAY,CAAC,MAAG,CAAC;KACzB;SAAM,IAAI,KAAK,KAAK,MAAM,EAAE;QAC3B,OAAO,YAAU,CAAC,MAAG,CAAC;KACvB;SAAM,IAAI,KAAK,KAAK,SAAS,EAAE;QAC9B,OAAO,CAAC,CAAC;KACV;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACvC,IAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,eAAa,CAAC,SAAI,SAAS,MAAG,CAAC;KACvC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;QACtC,IAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,cAAY,CAAC,SAAI,SAAS,MAAG,CAAC;KACtC;SAAM;QACL,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC;KACb;AACH,CAAC;AAED;IAA+B,qCAAY;IAOzC,mBAAY,MAAoB,EAAE,KAAmB;QAArD,YACE,kBAAM,MAAM,CAAC,SAGd;QADC,KAAI,CAAC,MAAM,GAAG,KAAK,CAAC;;IACtB,CAAC;IARM,yBAAK,GAAZ;QACE,OAAO,IAAI,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;IAQD;;OAEG;IACW,sBAAY,GAA1B,UAA2B,MAAoB,EAAE,KAAY,EAAE,aAA4B;QACzF,eAAe;QACf,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACxB,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;YAC5C,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9B;QAED,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,CAAC,CAAC;IACrE,CAAC;IAEa,yCAA+B,GAA7C,UAA8C,MAAoB,EAAE,SAA0B,EAAE,aAA4B;QAC1H,IAAM,KAAK,GAAG,EAAE,CAAC;QACjB,WAAW,CAAC,SAAS,CAAC,MAAM,EAAE,UAAA,MAAM;YAClC,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE;gBAC5B,iEAAiE;gBACjE,IAAI,GAAG,GAAyC,IAAI,CAAC;gBAErD,gDAAgD;gBAChD,iEAAiE;gBACjE,+CAA+C;gBAC/C,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE;oBACjC,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;iBACpB;qBAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE;oBACxC,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;iBACvB;qBAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE;oBACxC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;iBACzC,CAAC,yDAAyD;gBAC3D,IAAI,GAAG,EAAE;oBACP,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE;wBACnB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;qBAC9B;yBAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE;wBACxB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;qBAChC;yBAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE;wBACxB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;qBAChC;iBACF;gBAED,IAAI,MAAM,CAAC,QAAQ,EAAE;oBACnB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;iBAC9B;aACF;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;YAC5B,OAAO,IAAI,CAAC;SACb;QAED,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACW,kCAAwB,GAAtC,UAAuC,MAAoB,EAAE,KAAY,EAAE,aAA4B;QACrG,IAAM,QAAQ,GAAG,EAAE,CAAC;QAEpB,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE;YAC7C,uBAAuB;YACvB,KAAK,CAAC,eAAe,CAAC,UAAA,QAAQ;gBAC5B,IAAI,cAAc,CAAC,QAAQ,CAAC,EAAE;oBAC5B,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;iBACnC;qBAAM,IAAI,gBAAgB,CAAC,QAAQ,CAAC,EAAE;oBACrC,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;wBAC9C,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;qBACrC;iBACF;qBAAM,IAAI,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;oBAC9C,0GAA0G;oBAC1G,0EAA0E;oBAC1E,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,EAAE;wBACjC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;qBACtC;iBACF;qBAAM,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;oBAC9G,uEAAuE;oBACvE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,EAAE;wBACtC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;qBAC3C;iBACF;YACH,CAAC,CAAC,CAAC;SACJ;QAED,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IACrE,CAAC;IAED;;OAEG;IACY,2BAAiB,GAAhC,UAAiC,MAAoB,EAAE,QAAsB,EAAE,QAAsB,EAAE,aAA4B;QACjI,6MAA6M;QAC7M,KAAoB,UAAc,EAAd,KAAA,IAAI,CAAC,QAAQ,CAAC,EAAd,cAAc,EAAd,IAAc,EAAE;YAA/B,IAAM,KAAK,SAAA;YACd,IAAM,QAAQ,GAAG,aAAa,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YACtD,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE;gBAChC,yHAAyH;gBACzH,IAAI,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE;oBAC5H,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;iBACxB;qBAAM;oBACL,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;iBAC9E;aACF;SACF;QAED,KAAoB,UAAc,EAAd,KAAA,IAAI,CAAC,QAAQ,CAAC,EAAd,cAAc,EAAd,IAAc,EAAE;YAA/B,IAAM,KAAK,SAAA;YACd,IAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC1C,IAAI,QAAQ,KAAK,SAAS,EAAE;gBAC1B,8EAA8E;gBAC9E,IAAI,QAAQ,KAAK,QAAQ,CAAC,KAAK,CAAC,EAAE;oBAChC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;iBACxB;qBAAM;oBACL,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;iBACxE;aACF;SACF;QAED,IAAM,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAE5C,yFAAyF;QACzF,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAE7B,4BAA4B;QAC5B,IAAM,CAAC,GAAG,EAAE,CAAC;QACb,KAAkB,UAAqB,EAArB,KAAA,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,EAArB,cAAqB,EAArB,IAAqB,EAAE;YAApC,IAAM,GAAG,SAAA;YACZ,IAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,GAAG,KAAK,IAAI,EAAE;gBAChB,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;aACd;SACF;QAED,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,YAAY,EAAE;YACtD,OAAO,IAAI,CAAC;SACb;QAED,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,sBAAW,4BAAK;aAAhB;YACE,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;;;OAAA;IAEM,yBAAK,GAAZ,UAAa,KAAgB;QAC3B,IAAI,CAAC,MAAM,wBAAO,IAAI,CAAC,MAAM,EAAK,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/C,KAAK,CAAC,MAAM,EAAE,CAAC;IACjB,CAAC;IAED;;OAEG;IACI,uCAAmB,GAA1B;QACE,IAAM,WAAW,GAAG,EAAE,CAAC;QACvB,KAAoB,UAAiB,EAAjB,KAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAjB,cAAiB,EAAjB,IAAiB,EAAE;YAAlC,IAAM,KAAK,SAAA;YACd,IAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC7B,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;gBAChC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;aACxB;SACF;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,4DAA4D;IACrD,kCAAc,GAArB;QACE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAClC,CAAC;IAEM,mCAAe,GAAtB;QACE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAClC,CAAC;IAEM,sCAAkB,GAAzB,UAA0B,UAAkB;QAA5C,iBAgBC;QAhByB,2BAAA,EAAA,kBAAkB;QAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;aACrB,MAAM,CAAC,UAAA,KAAK,IAAI,OAAA,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAA9C,CAA8C,CAAC;aAC/D,GAAG,CAAC,UAAA,KAAK;YACR,IAAM,IAAI,GAAG,eAAe,CAAC,KAAK,EAAE,KAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACxD,IAAI,CAAC,IAAI,EAAE;gBACT,OAAO,IAAI,CAAC;aACb;YAED,IAAM,OAAO,GAAuB;gBAClC,IAAI,EAAE,SAAS;gBACf,IAAI,MAAA;gBACJ,EAAE,EAAE,mBAAmB,CAAC,KAAK,CAAC,CAAE,kCAAkC;aACnE,CAAC;YACF,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,KAAK,IAAI,EAAV,CAAU,CAAC,CAAC;IAC/B,CAAC;IACH,gBAAC;AAAD,CAAC,AAvMD,CAA+B,YAAY,GAuM1C","sourcesContent":["import {isNumber, isString, toSet} from 'vega-util';\nimport {AncestorParse} from '.';\nimport {isCountingAggregateOp} from '../../aggregate';\nimport {DateTime, isDateTime} from '../../datetime';\nimport {isNumberFieldDef, isScaleFieldDef, isTimeFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {forEachLeaf} from '../../logical';\nimport {isFieldEqualPredicate, isFieldOneOfPredicate, isFieldPredicate, isFieldRangePredicate} from '../../predicate';\nimport {isSortField} from '../../sort';\nimport {FilterTransform} from '../../transform';\nimport {accessPathDepth, accessPathWithDatum, Dict, duplicate, keys, removePathFromField, StringSet} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\nimport {isFacetModel, isUnitModel, Model} from '../model';\nimport {Split} from '../split';\nimport {DataFlowNode} from './dataflow';\n\n\n/**\n * @param field The field.\n * @param parse What to parse the field as.\n */\nfunction parseExpression(field: string, parse: string): string {\n const f = accessPathWithDatum(field);\n if (parse === 'number') {\n return `toNumber(${f})`;\n } else if (parse === 'boolean') {\n return `toBoolean(${f})`;\n } else if (parse === 'string') {\n return `toString(${f})`;\n } else if (parse === 'date') {\n return `toDate(${f})`;\n } else if (parse === 'flatten') {\n return f;\n } else if (parse.indexOf('date:') === 0) {\n const specifier = parse.slice(5, parse.length);\n return `timeParse(${f},${specifier})`;\n } else if (parse.indexOf('utc:') === 0) {\n const specifier = parse.slice(4, parse.length);\n return `utcParse(${f},${specifier})`;\n } else {\n log.warn(log.message.unrecognizedParse(parse));\n return null;\n }\n}\n\nexport class ParseNode extends DataFlowNode {\n private _parse: Dict;\n\n public clone() {\n return new ParseNode(null, duplicate(this._parse));\n }\n\n constructor(parent: DataFlowNode, parse: Dict) {\n super(parent);\n\n this._parse = parse;\n }\n\n /**\n * Creates a parse node from a data.format.parse and updates ancestorParse.\n */\n public static makeExplicit(parent: DataFlowNode, model: Model, ancestorParse: AncestorParse) {\n // Custom parse\n let explicit = {};\n const data = model.data;\n if (data && data.format && data.format.parse) {\n explicit = data.format.parse;\n }\n\n return this.makeWithAncestors(parent, explicit, {}, ancestorParse);\n }\n\n public static makeImplicitFromFilterTransform(parent: DataFlowNode, transform: FilterTransform, ancestorParse: AncestorParse) {\n const parse = {};\n forEachLeaf(transform.filter, filter => {\n if (isFieldPredicate(filter)) {\n // Automatically add a parse node for filters with filter objects\n let val: string | number | boolean | DateTime = null;\n\n // For EqualFilter, just use the equal property.\n // For RangeFilter and OneOfFilter, all array members should have\n // the same type, so we only use the first one.\n if (isFieldEqualPredicate(filter)) {\n val = filter.equal;\n } else if (isFieldRangePredicate(filter)) {\n val = filter.range[0];\n } else if (isFieldOneOfPredicate(filter)) {\n val = (filter.oneOf || filter['in'])[0];\n } // else -- for filter expression, we can't infer anything\n if (val) {\n if (isDateTime(val)) {\n parse[filter.field] = 'date';\n } else if (isNumber(val)) {\n parse[filter.field] = 'number';\n } else if (isString(val)) {\n parse[filter.field] = 'string';\n }\n }\n\n if (filter.timeUnit) {\n parse[filter.field] = 'date';\n }\n }\n });\n\n if (keys(parse).length === 0) {\n return null;\n }\n\n return this.makeWithAncestors(parent, {}, parse, ancestorParse);\n }\n\n /**\n * Creates a parse node for implicit parsing from a model and updates ancestorParse.\n */\n public static makeImplicitFromEncoding(parent: DataFlowNode, model: Model, ancestorParse: AncestorParse) {\n const implicit = {};\n\n if (isUnitModel(model) || isFacetModel(model)) {\n // Parse encoded fields\n model.forEachFieldDef(fieldDef => {\n if (isTimeFieldDef(fieldDef)) {\n implicit[fieldDef.field] = 'date';\n } else if (isNumberFieldDef(fieldDef)) {\n if (!isCountingAggregateOp(fieldDef.aggregate)) {\n implicit[fieldDef.field] = 'number';\n }\n } else if (accessPathDepth(fieldDef.field) > 1) {\n // For non-date/non-number (strings and booleans), derive a flattened field for a referenced nested field.\n // (Parsing numbers / dates already flattens numeric and temporal fields.)\n if (!(fieldDef.field in implicit)) {\n implicit[fieldDef.field] = 'flatten';\n }\n } else if (isScaleFieldDef(fieldDef) && isSortField(fieldDef.sort) && accessPathDepth(fieldDef.sort.field) > 1) {\n // Flatten fields that we sort by but that are not otherwise flattened.\n if (!(fieldDef.sort.field in implicit)) {\n implicit[fieldDef.sort.field] = 'flatten';\n }\n }\n });\n }\n\n return this.makeWithAncestors(parent, {}, implicit, ancestorParse);\n }\n\n /**\n * Creates a parse node from \"explicit\" parse and \"implicit\" parse and updates ancestorParse.\n */\n private static makeWithAncestors(parent: DataFlowNode, explicit: Dict, implicit: Dict, ancestorParse: AncestorParse) {\n // We should not parse what has already been parsed in a parent (explicitly or implicitly) or what has been derived (maked as \"derived\"). We also don't need to flatten a field that has already been parsed.\n for (const field of keys(implicit)) {\n const parsedAs = ancestorParse.getWithExplicit(field);\n if (parsedAs.value !== undefined) {\n // We always ignore derived fields even if they are implicitly defined because we expect users to create the right types.\n if (parsedAs.explicit || parsedAs.value === implicit[field] || parsedAs.value === 'derived' || implicit[field] === 'flatten') {\n delete implicit[field];\n } else {\n log.warn(log.message.differentParse(field, implicit[field], parsedAs.value));\n }\n }\n }\n\n for (const field of keys(explicit)) {\n const parsedAs = ancestorParse.get(field);\n if (parsedAs !== undefined) {\n // Don't parse a field again if it has been parsed with the same type already.\n if (parsedAs === explicit[field]) {\n delete explicit[field];\n } else {\n log.warn(log.message.differentParse(field, explicit[field], parsedAs));\n }\n }\n }\n\n const parse = new Split(explicit, implicit);\n\n // add the format parse from this model so that children don't parse the same field again\n ancestorParse.copyAll(parse);\n\n // copy only non-null parses\n const p = {};\n for (const key of keys(parse.combine())) {\n const val = parse.get(key);\n if (val !== null) {\n p[key] = val;\n }\n }\n\n if (keys(p).length === 0 || ancestorParse.parseNothing) {\n return null;\n }\n\n return new ParseNode(parent, p);\n }\n\n public get parse() {\n return this._parse;\n }\n\n public merge(other: ParseNode) {\n this._parse = {...this._parse, ...other.parse};\n other.remove();\n }\n\n /**\n * Assemble an object for Vega's format.parse property.\n */\n public assembleFormatParse() {\n const formatParse = {};\n for (const field of keys(this._parse)) {\n const p = this._parse[field];\n if (accessPathDepth(field) === 1) {\n formatParse[field] = p;\n }\n }\n return formatParse;\n }\n\n // format parse depends and produces all fields in its parse\n public producedFields(): StringSet {\n return toSet(keys(this._parse));\n }\n\n public dependentFields(): StringSet {\n return toSet(keys(this._parse));\n }\n\n public assembleTransforms(onlyNested = false): VgFormulaTransform[] {\n return keys(this._parse)\n .filter(field => onlyNested ? accessPathDepth(field) > 1 : true)\n .map(field => {\n const expr = parseExpression(field, this._parse[field]);\n if (!expr) {\n return null;\n }\n\n const formula: VgFormulaTransform = {\n type: 'formula',\n expr,\n as: removePathFromField(field) // Vega output is always flattened\n };\n return formula;\n }).filter(t => t !== null);\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/geojson.d.ts b/build/src/compile/data/geojson.d.ts new file mode 100644 index 0000000000..64120ef8ae --- /dev/null +++ b/build/src/compile/data/geojson.d.ts @@ -0,0 +1,12 @@ +import { VgGeoJSONTransform } from '../../vega.schema'; +import { UnitModel } from '../unit'; +import { DataFlowNode } from './dataflow'; +export declare class GeoJSONNode extends DataFlowNode { + private fields?; + private geojson?; + private signal?; + clone(): GeoJSONNode; + static parseAll(parent: DataFlowNode, model: UnitModel): DataFlowNode; + constructor(parent: DataFlowNode, fields?: string[], geojson?: string, signal?: string); + assemble(): VgGeoJSONTransform; +} diff --git a/build/src/compile/data/geojson.js b/build/src/compile/data/geojson.js new file mode 100644 index 0000000000..0620f51357 --- /dev/null +++ b/build/src/compile/data/geojson.js @@ -0,0 +1,40 @@ +import * as tslib_1 from "tslib"; +import { LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2, SHAPE } from '../../channel'; +import { GEOJSON } from '../../type'; +import { duplicate } from '../../util'; +import { DataFlowNode } from './dataflow'; +var GeoJSONNode = /** @class */ (function (_super) { + tslib_1.__extends(GeoJSONNode, _super); + function GeoJSONNode(parent, fields, geojson, signal) { + var _this = _super.call(this, parent) || this; + _this.fields = fields; + _this.geojson = geojson; + _this.signal = signal; + return _this; + } + GeoJSONNode.prototype.clone = function () { + return new GeoJSONNode(null, duplicate(this.fields), this.geojson, this.signal); + }; + GeoJSONNode.parseAll = function (parent, model) { + var geoJsonCounter = 0; + [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach(function (coordinates) { + var pair = coordinates.map(function (channel) { return model.channelHasField(channel) ? model.fieldDef(channel).field : undefined; }); + if (pair[0] || pair[1]) { + parent = new GeoJSONNode(parent, pair, null, model.getName("geojson_" + geoJsonCounter++)); + } + }); + if (model.channelHasField(SHAPE)) { + var fieldDef = model.fieldDef(SHAPE); + if (fieldDef.type === GEOJSON) { + parent = new GeoJSONNode(parent, null, fieldDef.field, model.getName("geojson_" + geoJsonCounter++)); + } + } + return parent; + }; + GeoJSONNode.prototype.assemble = function () { + return tslib_1.__assign({ type: 'geojson' }, (this.fields ? { fields: this.fields } : {}), (this.geojson ? { geojson: this.geojson } : {}), { signal: this.signal }); + }; + return GeoJSONNode; +}(DataFlowNode)); +export { GeoJSONNode }; +//# sourceMappingURL=geojson.js.map \ No newline at end of file diff --git a/build/src/compile/data/geojson.js.map b/build/src/compile/data/geojson.js.map new file mode 100644 index 0000000000..ddd837bf1b --- /dev/null +++ b/build/src/compile/data/geojson.js.map @@ -0,0 +1 @@ +{"version":3,"file":"geojson.js","sourceRoot":"","sources":["../../../../src/compile/data/geojson.ts"],"names":[],"mappings":";AAAA,OAAO,EAAqB,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAC,MAAM,eAAe,CAAC;AACpG,OAAO,EAAC,OAAO,EAAC,MAAM,YAAY,CAAC;AACnC,OAAO,EAAC,SAAS,EAAC,MAAM,YAAY,CAAC;AAGrC,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAExC;IAAiC,uCAAY;IA4B3C,qBAAY,MAAoB,EAAU,MAAiB,EAAU,OAAgB,EAAU,MAAe;QAA9G,YACE,kBAAM,MAAM,CAAC,SACd;QAFyC,YAAM,GAAN,MAAM,CAAW;QAAU,aAAO,GAAP,OAAO,CAAS;QAAU,YAAM,GAAN,MAAM,CAAS;;IAE9G,CAAC;IA7BM,2BAAK,GAAZ;QACE,OAAO,IAAI,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAClF,CAAC;IAEa,oBAAQ,GAAtB,UAAuB,MAAoB,EAAE,KAAgB;QAC3D,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,UAAC,WAAiC;YACzF,IAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAC1B,UAAA,OAAO,IAAI,OAAA,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAA1E,CAA0E,CACtF,CAAC;YAEF,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE;gBACtB,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,aAAW,cAAc,EAAI,CAAC,CAAC,CAAC;aAC5F;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE;YAChC,IAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACvC,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE;gBAC7B,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,aAAW,cAAc,EAAI,CAAC,CAAC,CAAC;aACtG;SACF;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAMM,8BAAQ,GAAf;QACE,0BACE,IAAI,EAAE,SAAS,IACZ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAC1C,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAChD,MAAM,EAAE,IAAI,CAAC,MAAM,IACnB;IACJ,CAAC;IACH,kBAAC;AAAD,CAAC,AAxCD,CAAiC,YAAY,GAwC5C","sourcesContent":["import {GeoPositionChannel, LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2, SHAPE} from '../../channel';\nimport {GEOJSON} from '../../type';\nimport {duplicate} from '../../util';\nimport {VgGeoJSONTransform} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {DataFlowNode} from './dataflow';\n\nexport class GeoJSONNode extends DataFlowNode {\n public clone() {\n return new GeoJSONNode(null, duplicate(this.fields), this.geojson, this.signal);\n }\n\n public static parseAll(parent: DataFlowNode, model: UnitModel): DataFlowNode {\n let geoJsonCounter = 0;\n\n [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach((coordinates: GeoPositionChannel[]) => {\n const pair = coordinates.map(\n channel => model.channelHasField(channel) ? model.fieldDef(channel).field : undefined\n );\n\n if (pair[0] || pair[1]) {\n parent = new GeoJSONNode(parent, pair, null, model.getName(`geojson_${geoJsonCounter++}`));\n }\n });\n\n if (model.channelHasField(SHAPE)) {\n const fieldDef = model.fieldDef(SHAPE);\n if (fieldDef.type === GEOJSON) {\n parent = new GeoJSONNode(parent, null, fieldDef.field, model.getName(`geojson_${geoJsonCounter++}`));\n }\n }\n\n return parent;\n }\n\n constructor(parent: DataFlowNode, private fields?: string[], private geojson?: string, private signal?: string) {\n super(parent);\n }\n\n public assemble(): VgGeoJSONTransform {\n return {\n type: 'geojson',\n ...(this.fields ? {fields: this.fields} : {}),\n ...(this.geojson ? {geojson: this.geojson} : {}),\n signal: this.signal\n };\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/geopoint.d.ts b/build/src/compile/data/geopoint.d.ts new file mode 100644 index 0000000000..d081cd9e6d --- /dev/null +++ b/build/src/compile/data/geopoint.d.ts @@ -0,0 +1,12 @@ +import { VgGeoPointTransform } from '../../vega.schema'; +import { UnitModel } from '../unit'; +import { DataFlowNode } from './dataflow'; +export declare class GeoPointNode extends DataFlowNode { + private projection; + private fields; + private as; + clone(): GeoPointNode; + constructor(parent: DataFlowNode, projection: string, fields: string[], as: string[]); + static parseAll(parent: DataFlowNode, model: UnitModel): DataFlowNode; + assemble(): VgGeoPointTransform; +} diff --git a/build/src/compile/data/geopoint.js b/build/src/compile/data/geopoint.js new file mode 100644 index 0000000000..7c6ff7375b --- /dev/null +++ b/build/src/compile/data/geopoint.js @@ -0,0 +1,41 @@ +import * as tslib_1 from "tslib"; +import { LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2 } from '../../channel'; +import { duplicate } from '../../util'; +import { DataFlowNode } from './dataflow'; +var GeoPointNode = /** @class */ (function (_super) { + tslib_1.__extends(GeoPointNode, _super); + function GeoPointNode(parent, projection, fields, as) { + var _this = _super.call(this, parent) || this; + _this.projection = projection; + _this.fields = fields; + _this.as = as; + return _this; + } + GeoPointNode.prototype.clone = function () { + return new GeoPointNode(null, this.projection, duplicate(this.fields), duplicate(this.as)); + }; + GeoPointNode.parseAll = function (parent, model) { + if (!model.projectionName()) { + return parent; + } + [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach(function (coordinates) { + var pair = coordinates.map(function (channel) { return model.channelHasField(channel) ? model.fieldDef(channel).field : undefined; }); + var suffix = coordinates[0] === LONGITUDE2 ? '2' : ''; + if (pair[0] || pair[1]) { + parent = new GeoPointNode(parent, model.projectionName(), pair, [model.getName('x' + suffix), model.getName('y' + suffix)]); + } + }); + return parent; + }; + GeoPointNode.prototype.assemble = function () { + return { + type: 'geopoint', + projection: this.projection, + fields: this.fields, + as: this.as + }; + }; + return GeoPointNode; +}(DataFlowNode)); +export { GeoPointNode }; +//# sourceMappingURL=geopoint.js.map \ No newline at end of file diff --git a/build/src/compile/data/geopoint.js.map b/build/src/compile/data/geopoint.js.map new file mode 100644 index 0000000000..b26fb3c174 --- /dev/null +++ b/build/src/compile/data/geopoint.js.map @@ -0,0 +1 @@ +{"version":3,"file":"geopoint.js","sourceRoot":"","sources":["../../../../src/compile/data/geopoint.ts"],"names":[],"mappings":";AAAA,OAAO,EAAqB,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAC,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAC,SAAS,EAAC,MAAM,YAAY,CAAC;AAGrC,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAGxC;IAAkC,wCAAY;IAK5C,sBAAY,MAAoB,EAAU,UAAkB,EAAU,MAAgB,EAAU,EAAY;QAA5G,YACE,kBAAM,MAAM,CAAC,SACd;QAFyC,gBAAU,GAAV,UAAU,CAAQ;QAAU,YAAM,GAAN,MAAM,CAAU;QAAU,QAAE,GAAF,EAAE,CAAU;;IAE5G,CAAC;IANM,4BAAK,GAAZ;QACE,OAAO,IAAI,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7F,CAAC;IAMa,qBAAQ,GAAtB,UAAuB,MAAoB,EAAE,KAAgB;QAC3D,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE;YAC3B,OAAO,MAAM,CAAC;SACf;QAED,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,UAAC,WAAiC;YACzF,IAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAC1B,UAAA,OAAO,IAAI,OAAA,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAA1E,CAA0E,CACtF,CAAC;YAEF,IAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAExD,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE;gBACtB,MAAM,GAAG,IAAI,YAAY,CACvB,MAAM,EACN,KAAK,CAAC,cAAc,EAAE,EACtB,IAAI,EACJ,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAC3D,CAAC;aACH;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAEM,+BAAQ,GAAf;QACE,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,EAAE,EAAE,IAAI,CAAC,EAAE;SACZ,CAAC;IACJ,CAAC;IACH,mBAAC;AAAD,CAAC,AA1CD,CAAkC,YAAY,GA0C7C","sourcesContent":["import {GeoPositionChannel, LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2} from '../../channel';\nimport {duplicate} from '../../util';\nimport {VgGeoPointTransform} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {DataFlowNode} from './dataflow';\n\n\nexport class GeoPointNode extends DataFlowNode {\n public clone() {\n return new GeoPointNode(null, this.projection, duplicate(this.fields), duplicate(this.as));\n }\n\n constructor(parent: DataFlowNode, private projection: string, private fields: string[], private as: string[]) {\n super(parent);\n }\n\n public static parseAll(parent: DataFlowNode, model: UnitModel): DataFlowNode {\n if (!model.projectionName()) {\n return parent;\n }\n\n [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach((coordinates: GeoPositionChannel[]) => {\n const pair = coordinates.map(\n channel => model.channelHasField(channel) ? model.fieldDef(channel).field : undefined\n );\n\n const suffix = coordinates[0] === LONGITUDE2 ? '2' : '';\n\n if (pair[0] || pair[1]) {\n parent = new GeoPointNode(\n parent,\n model.projectionName(),\n pair,\n [model.getName('x' + suffix), model.getName('y' + suffix)]\n );\n }\n });\n\n return parent;\n }\n\n public assemble(): VgGeoPointTransform {\n return {\n type: 'geopoint',\n projection: this.projection,\n fields: this.fields,\n as: this.as\n };\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/identifier.d.ts b/build/src/compile/data/identifier.d.ts new file mode 100644 index 0000000000..e5ac572e15 --- /dev/null +++ b/build/src/compile/data/identifier.d.ts @@ -0,0 +1,9 @@ +import { StringSet } from '../../util'; +import { VgIdentifierTransform } from '../../vega.schema'; +import { DataFlowNode } from './dataflow'; +export declare class IdentifierNode extends DataFlowNode { + clone(): IdentifierNode; + constructor(parent: DataFlowNode); + producedFields(): StringSet; + assemble(): VgIdentifierTransform; +} diff --git a/build/src/compile/data/identifier.js b/build/src/compile/data/identifier.js new file mode 100644 index 0000000000..91e69080d9 --- /dev/null +++ b/build/src/compile/data/identifier.js @@ -0,0 +1,22 @@ +import * as tslib_1 from "tslib"; +import { SELECTION_ID } from '../../selection'; +import { DataFlowNode } from './dataflow'; +var IdentifierNode = /** @class */ (function (_super) { + tslib_1.__extends(IdentifierNode, _super); + function IdentifierNode(parent) { + return _super.call(this, parent) || this; + } + IdentifierNode.prototype.clone = function () { + return new IdentifierNode(null); + }; + IdentifierNode.prototype.producedFields = function () { + var _a; + return _a = {}, _a[SELECTION_ID] = true, _a; + }; + IdentifierNode.prototype.assemble = function () { + return { type: 'identifier', as: SELECTION_ID }; + }; + return IdentifierNode; +}(DataFlowNode)); +export { IdentifierNode }; +//# sourceMappingURL=identifier.js.map \ No newline at end of file diff --git a/build/src/compile/data/identifier.js.map b/build/src/compile/data/identifier.js.map new file mode 100644 index 0000000000..37e62a8629 --- /dev/null +++ b/build/src/compile/data/identifier.js.map @@ -0,0 +1 @@ +{"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../../../src/compile/data/identifier.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAExC;IAAoC,0CAAY;IAK9C,wBAAY,MAAoB;eAC9B,kBAAM,MAAM,CAAC;IACf,CAAC;IANM,8BAAK,GAAZ;QACE,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAMM,uCAAc,GAArB;;QACE,gBAAQ,GAAC,YAAY,IAAG,IAAI,KAAE;IAChC,CAAC;IAEM,iCAAQ,GAAf;QACE,OAAO,EAAC,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAC,CAAC;IAChD,CAAC;IACH,qBAAC;AAAD,CAAC,AAhBD,CAAoC,YAAY,GAgB/C","sourcesContent":["import {SELECTION_ID} from '../../selection';\nimport {StringSet} from '../../util';\nimport {VgIdentifierTransform} from '../../vega.schema';\nimport {DataFlowNode} from './dataflow';\n\nexport class IdentifierNode extends DataFlowNode {\n public clone() {\n return new IdentifierNode(null);\n }\n\n constructor(parent: DataFlowNode) {\n super(parent);\n }\n\n public producedFields(): StringSet {\n return {[SELECTION_ID]: true};\n }\n\n public assemble(): VgIdentifierTransform {\n return {type: 'identifier', as: SELECTION_ID};\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/indentifier.d.ts b/build/src/compile/data/indentifier.d.ts new file mode 100644 index 0000000000..e5ac572e15 --- /dev/null +++ b/build/src/compile/data/indentifier.d.ts @@ -0,0 +1,9 @@ +import { StringSet } from '../../util'; +import { VgIdentifierTransform } from '../../vega.schema'; +import { DataFlowNode } from './dataflow'; +export declare class IdentifierNode extends DataFlowNode { + clone(): IdentifierNode; + constructor(parent: DataFlowNode); + producedFields(): StringSet; + assemble(): VgIdentifierTransform; +} diff --git a/build/src/compile/data/indentifier.js b/build/src/compile/data/indentifier.js new file mode 100644 index 0000000000..2d3944b776 --- /dev/null +++ b/build/src/compile/data/indentifier.js @@ -0,0 +1,22 @@ +import * as tslib_1 from "tslib"; +import { SELECTION_ID } from '../../selection'; +import { DataFlowNode } from './dataflow'; +var IdentifierNode = /** @class */ (function (_super) { + tslib_1.__extends(IdentifierNode, _super); + function IdentifierNode(parent) { + return _super.call(this, parent) || this; + } + IdentifierNode.prototype.clone = function () { + return new IdentifierNode(null); + }; + IdentifierNode.prototype.producedFields = function () { + return _a = {}, _a[SELECTION_ID] = true, _a; + var _a; + }; + IdentifierNode.prototype.assemble = function () { + return { type: 'identifier', as: SELECTION_ID }; + }; + return IdentifierNode; +}(DataFlowNode)); +export { IdentifierNode }; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZW50aWZpZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL2luZGVudGlmaWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFHN0MsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLFlBQVksQ0FBQztBQUV4QztJQUFvQywwQ0FBWTtJQUs5Qyx3QkFBWSxNQUFvQjtlQUM5QixrQkFBTSxNQUFNLENBQUM7SUFDZixDQUFDO0lBTk0sOEJBQUssR0FBWjtRQUNFLE9BQU8sSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQU1NLHVDQUFjLEdBQXJCO1FBQ0UsZ0JBQVEsR0FBQyxZQUFZLElBQUcsSUFBSSxLQUFFOztJQUNoQyxDQUFDO0lBRU0saUNBQVEsR0FBZjtRQUNFLE9BQU8sRUFBQyxJQUFJLEVBQUUsWUFBWSxFQUFFLEVBQUUsRUFBRSxZQUFZLEVBQUMsQ0FBQztJQUNoRCxDQUFDO0lBQ0gscUJBQUM7QUFBRCxDQUFDLEFBaEJELENBQW9DLFlBQVksR0FnQi9DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtTRUxFQ1RJT05fSUR9IGZyb20gJy4uLy4uL3NlbGVjdGlvbic7XG5pbXBvcnQge1N0cmluZ1NldH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1ZnSWRlbnRpZmllclRyYW5zZm9ybX0gZnJvbSAnLi4vLi4vdmVnYS5zY2hlbWEnO1xuaW1wb3J0IHtEYXRhRmxvd05vZGV9IGZyb20gJy4vZGF0YWZsb3cnO1xuXG5leHBvcnQgY2xhc3MgSWRlbnRpZmllck5vZGUgZXh0ZW5kcyBEYXRhRmxvd05vZGUge1xuICBwdWJsaWMgY2xvbmUoKSB7XG4gICAgcmV0dXJuIG5ldyBJZGVudGlmaWVyTm9kZShudWxsKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHBhcmVudDogRGF0YUZsb3dOb2RlKSB7XG4gICAgc3VwZXIocGFyZW50KTtcbiAgfVxuXG4gIHB1YmxpYyBwcm9kdWNlZEZpZWxkcygpOiBTdHJpbmdTZXQge1xuICAgIHJldHVybiB7W1NFTEVDVElPTl9JRF06IHRydWV9O1xuICB9XG5cbiAgcHVibGljIGFzc2VtYmxlKCk6IFZnSWRlbnRpZmllclRyYW5zZm9ybSB7XG4gICAgcmV0dXJuIHt0eXBlOiAnaWRlbnRpZmllcicsIGFzOiBTRUxFQ1RJT05fSUR9O1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/build/src/compile/data/index.d.ts b/build/src/compile/data/index.d.ts new file mode 100644 index 0000000000..dc01feff76 --- /dev/null +++ b/build/src/compile/data/index.d.ts @@ -0,0 +1,54 @@ +import { Dict } from '../../util'; +import { Split } from '../split'; +import { OutputNode } from './dataflow'; +import { FacetNode } from './facet'; +import { SourceNode } from './source'; +export interface DataComponent { + /** + * A dictionary of sources indexed by a hash. + */ + sources: Dict; + /** + * Registry of output nodes. + */ + outputNodes: Dict; + /** + * How often is an output node used. If it is not used, we don't need to + * instantiate it in the assemble step. + */ + outputNodeRefCounts: Dict; + /** + * The output node before aggregation. + */ + raw?: OutputNode; + /** + * The main output node. + */ + main?: OutputNode; + /** + * For facets, we store the reference to the root node. + */ + facetRoot?: FacetNode; + /** + * True if the data for this model is faceted. + * A dataset is faceted if a parent model is a facet and no new dataset is + * defined (which would make the data unfaceted again). + */ + isFaceted: boolean; + /** + * Parse properties passed down from ancestors. Helps us to keep track of what has been parsed or is derived. + */ + ancestorParse?: AncestorParse; +} +/** + * Class to track interesting properties (see https://15721.courses.cs.cmu.edu/spring2016/papers/graefe-ieee1995.pdf) + * about how fields have been parsed or whether they have been derived in a transforms. We use this to not parse the + * same field again (or differently). + */ +export declare class AncestorParse extends Split> { + readonly explicit: Partial>; + readonly implicit: Partial>; + parseNothing: boolean; + constructor(explicit?: Partial>, implicit?: Partial>, parseNothing?: boolean); + clone(): AncestorParse; +} diff --git a/build/src/compile/data/index.js b/build/src/compile/data/index.js new file mode 100644 index 0000000000..6ec12f03b7 --- /dev/null +++ b/build/src/compile/data/index.js @@ -0,0 +1,28 @@ +import * as tslib_1 from "tslib"; +import { Split } from '../split'; +/** + * Class to track interesting properties (see https://15721.courses.cs.cmu.edu/spring2016/papers/graefe-ieee1995.pdf) + * about how fields have been parsed or whether they have been derived in a transforms. We use this to not parse the + * same field again (or differently). + */ +var AncestorParse = /** @class */ (function (_super) { + tslib_1.__extends(AncestorParse, _super); + function AncestorParse(explicit, implicit, parseNothing) { + if (explicit === void 0) { explicit = {}; } + if (implicit === void 0) { implicit = {}; } + if (parseNothing === void 0) { parseNothing = false; } + var _this = _super.call(this, explicit, implicit) || this; + _this.explicit = explicit; + _this.implicit = implicit; + _this.parseNothing = parseNothing; + return _this; + } + AncestorParse.prototype.clone = function () { + var clone = _super.prototype.clone.call(this); + clone.parseNothing = this.parseNothing; + return clone; + }; + return AncestorParse; +}(Split)); +export { AncestorParse }; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/src/compile/data/index.js.map b/build/src/compile/data/index.js.map new file mode 100644 index 0000000000..0e074206a5 --- /dev/null +++ b/build/src/compile/data/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/compile/data/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAC,KAAK,EAAC,MAAM,UAAU,CAAC;AAkD/B;;;;GAIG;AACH;IAAmC,yCAAmB;IACpD,uBACkB,QAAoC,EACpC,QAAoC,EAC7C,YAAoB;QAFX,yBAAA,EAAA,aAAoC;QACpC,yBAAA,EAAA,aAAoC;QAC7C,6BAAA,EAAA,oBAAoB;QAH7B,YAKE,kBAAM,QAAQ,EAAE,QAAQ,CAAC,SAC1B;QALiB,cAAQ,GAAR,QAAQ,CAA4B;QACpC,cAAQ,GAAR,QAAQ,CAA4B;QAC7C,kBAAY,GAAZ,YAAY,CAAQ;;IAG7B,CAAC;IAEM,6BAAK,GAAZ;QACE,IAAM,KAAK,GAAG,iBAAM,KAAK,WAAmB,CAAC;QAC7C,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACvC,OAAO,KAAK,CAAC;IACf,CAAC;IACH,oBAAC;AAAD,CAAC,AAdD,CAAmC,KAAK,GAcvC","sourcesContent":["import {Dict} from '../../util';\nimport {Split} from '../split';\nimport {OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {SourceNode} from './source';\n\nexport interface DataComponent {\n /**\n * A dictionary of sources indexed by a hash.\n */\n sources: Dict;\n\n /**\n * Registry of output nodes.\n */\n outputNodes: Dict;\n\n /**\n * How often is an output node used. If it is not used, we don't need to\n * instantiate it in the assemble step.\n */\n outputNodeRefCounts: Dict;\n\n /**\n * The output node before aggregation.\n */\n raw?: OutputNode;\n\n /**\n * The main output node.\n */\n main?: OutputNode;\n\n /**\n * For facets, we store the reference to the root node.\n */\n facetRoot?: FacetNode;\n\n /**\n * True if the data for this model is faceted.\n * A dataset is faceted if a parent model is a facet and no new dataset is\n * defined (which would make the data unfaceted again).\n */\n isFaceted: boolean;\n\n /**\n * Parse properties passed down from ancestors. Helps us to keep track of what has been parsed or is derived.\n */\n ancestorParse?: AncestorParse;\n}\n\n/**\n * Class to track interesting properties (see https://15721.courses.cs.cmu.edu/spring2016/papers/graefe-ieee1995.pdf)\n * about how fields have been parsed or whether they have been derived in a transforms. We use this to not parse the\n * same field again (or differently).\n */\nexport class AncestorParse extends Split> {\n constructor(\n public readonly explicit: Partial> = {},\n public readonly implicit: Partial> = {},\n public parseNothing = false\n ) {\n super(explicit, implicit);\n }\n\n public clone(): AncestorParse {\n const clone = super.clone() as AncestorParse;\n clone.parseNothing = this.parseNothing;\n return clone;\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/lookup.d.ts b/build/src/compile/data/lookup.d.ts new file mode 100644 index 0000000000..a4ed24d0ca --- /dev/null +++ b/build/src/compile/data/lookup.d.ts @@ -0,0 +1,13 @@ +import { LookupTransform } from '../../transform'; +import { StringSet } from '../../util'; +import { VgLookupTransform } from '../../vega.schema'; +import { Model } from '../model'; +import { DataFlowNode } from './dataflow'; +export declare class LookupNode extends DataFlowNode { + readonly transform: LookupTransform; + readonly secondary: string; + constructor(parent: DataFlowNode, transform: LookupTransform, secondary: string); + static make(parent: DataFlowNode, model: Model, transform: LookupTransform, counter: number): LookupNode; + producedFields(): StringSet; + assemble(): VgLookupTransform; +} diff --git a/build/src/compile/data/lookup.js b/build/src/compile/data/lookup.js new file mode 100644 index 0000000000..108c7ae372 --- /dev/null +++ b/build/src/compile/data/lookup.js @@ -0,0 +1,52 @@ +import * as tslib_1 from "tslib"; +import { isString, toSet } from 'vega-util'; +import * as log from '../../log'; +import { DataFlowNode, OutputNode } from './dataflow'; +import { SourceNode } from './source'; +var LookupNode = /** @class */ (function (_super) { + tslib_1.__extends(LookupNode, _super); + function LookupNode(parent, transform, secondary) { + var _this = _super.call(this, parent) || this; + _this.transform = transform; + _this.secondary = secondary; + return _this; + } + LookupNode.make = function (parent, model, transform, counter) { + var sources = model.component.data.sources; + var s = new SourceNode(transform.from.data); + var fromSource = sources[s.hash()]; + if (!fromSource) { + sources[s.hash()] = s; + fromSource = s; + } + var fromOutputName = model.getName("lookup_" + counter); + var fromOutputNode = new OutputNode(fromSource, fromOutputName, 'lookup', model.component.data.outputNodeRefCounts); + model.component.data.outputNodes[fromOutputName] = fromOutputNode; + return new LookupNode(parent, transform, fromOutputNode.getSource()); + }; + LookupNode.prototype.producedFields = function () { + return toSet(this.transform.from.fields || ((this.transform.as instanceof Array) ? this.transform.as : [this.transform.as])); + }; + LookupNode.prototype.assemble = function () { + var foreign; + if (this.transform.from.fields) { + // lookup a few fields and add create a flat output + foreign = tslib_1.__assign({ values: this.transform.from.fields }, this.transform.as ? { as: ((this.transform.as instanceof Array) ? this.transform.as : [this.transform.as]) } : {}); + } + else { + // lookup full record and nest it + var asName = this.transform.as; + if (!isString(asName)) { + log.warn(log.message.NO_FIELDS_NEEDS_AS); + asName = '_lookup'; + } + foreign = { + as: [asName] + }; + } + return tslib_1.__assign({ type: 'lookup', from: this.secondary, key: this.transform.from.key, fields: [this.transform.lookup] }, foreign, (this.transform.default ? { default: this.transform.default } : {})); + }; + return LookupNode; +}(DataFlowNode)); +export { LookupNode }; +//# sourceMappingURL=lookup.js.map \ No newline at end of file diff --git a/build/src/compile/data/lookup.js.map b/build/src/compile/data/lookup.js.map new file mode 100644 index 0000000000..dfeb9bdf6e --- /dev/null +++ b/build/src/compile/data/lookup.js.map @@ -0,0 +1 @@ +{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../../../src/compile/data/lookup.ts"],"names":[],"mappings":"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","sourcesContent":["import {isString, toSet} from 'vega-util';\nimport * as log from '../../log';\nimport {LookupTransform} from '../../transform';\nimport {StringSet} from '../../util';\nimport {VgLookupTransform} from '../../vega.schema';\nimport {Model} from '../model';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {SourceNode} from './source';\n\nexport class LookupNode extends DataFlowNode {\n constructor(parent: DataFlowNode, public readonly transform: LookupTransform, public readonly secondary: string) {\n super(parent);\n }\n\n public static make(parent: DataFlowNode, model: Model, transform: LookupTransform, counter: number) {\n const sources = model.component.data.sources;\n const s = new SourceNode(transform.from.data);\n let fromSource = sources[s.hash()];\n if (!fromSource) {\n sources[s.hash()] = s;\n fromSource = s;\n }\n\n const fromOutputName = model.getName(`lookup_${counter}`);\n const fromOutputNode = new OutputNode(fromSource, fromOutputName, 'lookup', model.component.data.outputNodeRefCounts);\n\n model.component.data.outputNodes[fromOutputName] = fromOutputNode;\n\n return new LookupNode(parent, transform, fromOutputNode.getSource());\n }\n\n public producedFields(): StringSet {\n return toSet(this.transform.from.fields || ((this.transform.as instanceof Array) ? this.transform.as : [this.transform.as]));\n }\n\n public assemble(): VgLookupTransform {\n let foreign: Partial;\n\n if (this.transform.from.fields) {\n // lookup a few fields and add create a flat output\n foreign = {\n values: this.transform.from.fields,\n ... this.transform.as ? {as: ((this.transform.as instanceof Array) ? this.transform.as : [this.transform.as])} : {}\n };\n } else {\n // lookup full record and nest it\n let asName = this.transform.as;\n if (!isString(asName)) {\n log.warn(log.message.NO_FIELDS_NEEDS_AS);\n asName = '_lookup';\n }\n\n foreign = {\n as: [asName]\n };\n }\n\n return {\n type: 'lookup',\n from: this.secondary,\n key: this.transform.from.key,\n fields: [this.transform.lookup],\n ...foreign,\n ...(this.transform.default ? {default: this.transform.default} : {})\n };\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/optimize.d.ts b/build/src/compile/data/optimize.d.ts new file mode 100644 index 0000000000..38fea9125c --- /dev/null +++ b/build/src/compile/data/optimize.d.ts @@ -0,0 +1,6 @@ +import { DataComponent } from './index'; +export declare const FACET_SCALE_PREFIX = "scale_"; +/** + * Optimizes the dataflow of the passed in data component. + */ +export declare function optimizeDataflow(dataComponent: DataComponent): void; diff --git a/build/src/compile/data/optimize.js b/build/src/compile/data/optimize.js new file mode 100644 index 0000000000..8fb8becff8 --- /dev/null +++ b/build/src/compile/data/optimize.js @@ -0,0 +1,119 @@ +import { MAIN } from '../../data'; +import { every, flatten, keys, vals } from '../../util'; +import { AggregateNode } from './aggregate'; +import { OutputNode } from './dataflow'; +import { FacetNode } from './facet'; +import { FilterInvalidNode } from './filterinvalid'; +import * as optimizers from './optimizers'; +import { StackNode } from './stack'; +export var FACET_SCALE_PREFIX = 'scale_'; +/** + * Clones the subtree and ignores output nodes except for the leafs, which are renamed. + */ +function cloneSubtree(facet) { + function clone(node) { + if (!(node instanceof FacetNode)) { + var copy_1 = node.clone(); + if (copy_1 instanceof OutputNode) { + var newName = FACET_SCALE_PREFIX + copy_1.getSource(); + copy_1.setSource(newName); + facet.model.component.data.outputNodes[newName] = copy_1; + } + else if (copy_1 instanceof AggregateNode || copy_1 instanceof StackNode) { + copy_1.addDimensions(facet.fields); + } + flatten(node.children.map(clone)).forEach(function (n) { return n.parent = copy_1; }); + return [copy_1]; + } + return flatten(node.children.map(clone)); + } + return clone; +} +/** + * Move facet nodes down to the next fork or output node. Also pull the main output with the facet node. + * After moving down the facet node, make a copy of the subtree and make it a child of the main output. + */ +function moveFacetDown(node) { + if (node instanceof FacetNode) { + if (node.numChildren() === 1 && !(node.children[0] instanceof OutputNode)) { + // move down until we hit a fork or output node + var child = node.children[0]; + if (child instanceof AggregateNode || child instanceof StackNode) { + child.addDimensions(node.fields); + } + child.swapWithParent(); + moveFacetDown(node); + } + else { + // move main to facet + moveMainDownToFacet(node.model.component.data.main); + // replicate the subtree and place it before the facet's main node + var copy = flatten(node.children.map(cloneSubtree(node))); + copy.forEach(function (c) { return c.parent = node.model.component.data.main; }); + } + } + else { + node.children.forEach(moveFacetDown); + } +} +function moveMainDownToFacet(node) { + if (node instanceof OutputNode && node.type === MAIN) { + if (node.numChildren() === 1) { + var child = node.children[0]; + if (!(child instanceof FacetNode)) { + child.swapWithParent(); + moveMainDownToFacet(node); + } + } + } +} +/** + * Remove nodes that are not required starting from a root. + */ +function removeUnnecessaryNodes(node) { + // remove empty null filter nodes + if (node instanceof FilterInvalidNode && every(vals(node.filter), function (f) { return f === null; })) { + node.remove(); + } + // remove output nodes that are not required + if (node instanceof OutputNode && !node.isRequired()) { + node.remove(); + } + node.children.forEach(removeUnnecessaryNodes); +} +/** + * Return all leaf nodes. + */ +function getLeaves(roots) { + var leaves = []; + function append(node) { + if (node.numChildren() === 0) { + leaves.push(node); + } + else { + node.children.forEach(append); + } + } + roots.forEach(append); + return leaves; +} +/** + * Optimizes the dataflow of the passed in data component. + */ +export function optimizeDataflow(dataComponent) { + var roots = vals(dataComponent.sources); + roots.forEach(removeUnnecessaryNodes); + // remove source nodes that don't have any children because they also don't have output nodes + roots = roots.filter(function (r) { return r.numChildren() > 0; }); + getLeaves(roots).forEach(optimizers.iterateFromLeaves(optimizers.removeUnusedSubtrees)); + roots = roots.filter(function (r) { return r.numChildren() > 0; }); + getLeaves(roots).forEach(optimizers.iterateFromLeaves(optimizers.moveParseUp)); + getLeaves(roots).forEach(optimizers.removeDuplicateTimeUnits); + roots.forEach(moveFacetDown); + keys(dataComponent.sources).forEach(function (s) { + if (dataComponent.sources[s].numChildren() === 0) { + delete dataComponent.sources[s]; + } + }); +} +//# sourceMappingURL=optimize.js.map \ No newline at end of file diff --git a/build/src/compile/data/optimize.js.map b/build/src/compile/data/optimize.js.map new file mode 100644 index 0000000000..1fda6f5009 --- /dev/null +++ b/build/src/compile/data/optimize.js.map @@ -0,0 +1 @@ +{"version":3,"file":"optimize.js","sourceRoot":"","sources":["../../../../src/compile/data/optimize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAC;AAChC,OAAO,EAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAC,MAAM,YAAY,CAAC;AACtD,OAAO,EAAC,aAAa,EAAC,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAe,UAAU,EAAC,MAAM,YAAY,CAAC;AACpD,OAAO,EAAC,SAAS,EAAC,MAAM,SAAS,CAAC;AAClC,OAAO,EAAC,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AAElD,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAC,SAAS,EAAC,MAAM,SAAS,CAAC;AAElC,MAAM,CAAC,IAAM,kBAAkB,GAAG,QAAQ,CAAC;AAE3C;;GAEG;AACH,sBAAsB,KAAgB;IACpC,eAAe,IAAkB;QAC/B,IAAI,CAAC,CAAC,IAAI,YAAY,SAAS,CAAC,EAAE;YAChC,IAAM,MAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAE1B,IAAI,MAAI,YAAY,UAAU,EAAE;gBAC9B,IAAM,OAAO,GAAG,kBAAkB,GAAG,MAAI,CAAC,SAAS,EAAE,CAAC;gBACtD,MAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBAExB,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,MAAI,CAAC;aACxD;iBAAM,IAAI,MAAI,YAAY,aAAa,IAAI,MAAI,YAAY,SAAS,EAAE;gBACrE,MAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;aAClC;YACD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,UAAC,CAAe,IAAK,OAAA,CAAC,CAAC,MAAM,GAAG,MAAI,EAAf,CAAe,CAAC,CAAC;YAEhF,OAAO,CAAC,MAAI,CAAC,CAAC;SACf;QAED,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,uBAAuB,IAAkB;IACvC,IAAI,IAAI,YAAY,SAAS,EAAE;QAC7B,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,UAAU,CAAC,EAAE;YACzE,+CAA+C;YAE/C,IAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAE/B,IAAI,KAAK,YAAY,aAAa,IAAI,KAAK,YAAY,SAAS,EAAE;gBAChE,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aAClC;YAED,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,aAAa,CAAC,IAAI,CAAC,CAAC;SACrB;aAAM;YACL,qBAAqB;YACrB,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEpD,kEAAkE;YAClE,IAAM,IAAI,GAAmB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC5E,IAAI,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAzC,CAAyC,CAAC,CAAC;SAC9D;KACF;SAAM;QACL,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;KACtC;AACH,CAAC;AAED,6BAA6B,IAAkB;IAC7C,IAAI,IAAI,YAAY,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE;QACpD,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE;YAC5B,IAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAE/B,IAAI,CAAC,CAAC,KAAK,YAAY,SAAS,CAAC,EAAE;gBACjC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,mBAAmB,CAAC,IAAI,CAAC,CAAC;aAC3B;SACF;KACF;AACH,CAAC;AAED;;GAEG;AACH,gCAAgC,IAAkB;IAEhD,iCAAiC;IACjC,IAAI,IAAI,YAAY,iBAAiB,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,UAAA,CAAC,IAAI,OAAA,CAAC,KAAK,IAAI,EAAV,CAAU,CAAC,EAAE;QAClF,IAAI,CAAC,MAAM,EAAE,CAAC;KACf;IAED,4CAA4C;IAC5C,IAAI,IAAI,YAAY,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;QACpD,IAAI,CAAC,MAAM,EAAE,CAAC;KACf;IAED,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,mBAAmB,KAAqB;IACtC,IAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,gBAAgB,IAAkB;QAChC,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE;YAC5B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACnB;aAAM;YACL,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAC/B;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACtB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,2BAA2B,aAA4B;IAC3D,IAAI,KAAK,GAAiB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAEtD,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAEtC,6FAA6F;IAC7F,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,EAAnB,CAAmB,CAAC,CAAC;IAC/C,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC,CAAC;IACxF,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,EAAnB,CAAmB,CAAC,CAAC;IAE/C,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IAC/E,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;IAE9D,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAE7B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,UAAA,CAAC;QACnC,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE;YAChD,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;SACjC;IACH,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {MAIN} from '../../data';\nimport {every, flatten, keys, vals} from '../../util';\nimport {AggregateNode} from './aggregate';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {FilterInvalidNode} from './filterinvalid';\nimport {DataComponent} from './index';\nimport * as optimizers from './optimizers';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\n\nexport const FACET_SCALE_PREFIX = 'scale_';\n\n/**\n * Clones the subtree and ignores output nodes except for the leafs, which are renamed.\n */\nfunction cloneSubtree(facet: FacetNode) {\n function clone(node: DataFlowNode): DataFlowNode[] {\n if (!(node instanceof FacetNode)) {\n const copy = node.clone();\n\n if (copy instanceof OutputNode) {\n const newName = FACET_SCALE_PREFIX + copy.getSource();\n copy.setSource(newName);\n\n facet.model.component.data.outputNodes[newName] = copy;\n } else if (copy instanceof AggregateNode || copy instanceof StackNode) {\n copy.addDimensions(facet.fields);\n }\n flatten(node.children.map(clone)).forEach((n: DataFlowNode) => n.parent = copy);\n\n return [copy];\n }\n\n return flatten(node.children.map(clone));\n }\n return clone;\n}\n\n/**\n * Move facet nodes down to the next fork or output node. Also pull the main output with the facet node.\n * After moving down the facet node, make a copy of the subtree and make it a child of the main output.\n */\nfunction moveFacetDown(node: DataFlowNode) {\n if (node instanceof FacetNode) {\n if (node.numChildren() === 1 && !(node.children[0] instanceof OutputNode)) {\n // move down until we hit a fork or output node\n\n const child = node.children[0];\n\n if (child instanceof AggregateNode || child instanceof StackNode) {\n child.addDimensions(node.fields);\n }\n\n child.swapWithParent();\n moveFacetDown(node);\n } else {\n // move main to facet\n moveMainDownToFacet(node.model.component.data.main);\n\n // replicate the subtree and place it before the facet's main node\n const copy: DataFlowNode[] = flatten(node.children.map(cloneSubtree(node)));\n copy.forEach(c => c.parent = node.model.component.data.main);\n }\n } else {\n node.children.forEach(moveFacetDown);\n }\n}\n\nfunction moveMainDownToFacet(node: DataFlowNode) {\n if (node instanceof OutputNode && node.type === MAIN) {\n if (node.numChildren() === 1) {\n const child = node.children[0];\n\n if (!(child instanceof FacetNode)) {\n child.swapWithParent();\n moveMainDownToFacet(node);\n }\n }\n }\n}\n\n/**\n * Remove nodes that are not required starting from a root.\n */\nfunction removeUnnecessaryNodes(node: DataFlowNode) {\n\n // remove empty null filter nodes\n if (node instanceof FilterInvalidNode && every(vals(node.filter), f => f === null)) {\n node.remove();\n }\n\n // remove output nodes that are not required\n if (node instanceof OutputNode && !node.isRequired()) {\n node.remove();\n }\n\n node.children.forEach(removeUnnecessaryNodes);\n}\n\n/**\n * Return all leaf nodes.\n */\nfunction getLeaves(roots: DataFlowNode[]) {\n const leaves: DataFlowNode[] = [];\n function append(node: DataFlowNode) {\n if (node.numChildren() === 0) {\n leaves.push(node);\n } else {\n node.children.forEach(append);\n }\n }\n\n roots.forEach(append);\n return leaves;\n}\n\n/**\n * Optimizes the dataflow of the passed in data component.\n */\nexport function optimizeDataflow(dataComponent: DataComponent) {\n let roots: SourceNode[] = vals(dataComponent.sources);\n\n roots.forEach(removeUnnecessaryNodes);\n\n // remove source nodes that don't have any children because they also don't have output nodes\n roots = roots.filter(r => r.numChildren() > 0);\n getLeaves(roots).forEach(optimizers.iterateFromLeaves(optimizers.removeUnusedSubtrees));\n roots = roots.filter(r => r.numChildren() > 0);\n\n getLeaves(roots).forEach(optimizers.iterateFromLeaves(optimizers.moveParseUp));\n getLeaves(roots).forEach(optimizers.removeDuplicateTimeUnits);\n\n roots.forEach(moveFacetDown);\n\n keys(dataComponent.sources).forEach(s => {\n if (dataComponent.sources[s].numChildren() === 0) {\n delete dataComponent.sources[s];\n }\n });\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/optimizers.d.ts b/build/src/compile/data/optimizers.d.ts new file mode 100644 index 0000000000..a86176f2b3 --- /dev/null +++ b/build/src/compile/data/optimizers.d.ts @@ -0,0 +1,23 @@ +import { DataFlowNode } from './dataflow'; +/** + * Start optimization path at the leaves. Useful for merging up or removing things. + * + * If the callback returns true, the recursion continues. + */ +export declare function iterateFromLeaves(f: (node: DataFlowNode) => boolean): (node: DataFlowNode) => void; +/** + * Move parse nodes up to forks. + */ +export declare function moveParseUp(node: DataFlowNode): boolean; +/** + * Repeatedly remove leaf nodes that are not output or facet nodes. + * The reason is that we don't need subtrees that don't have any output nodes. + * Facet nodes are needed for the row or column domains. + */ +export declare function removeUnusedSubtrees(node: DataFlowNode): boolean; +/** + * Removes duplicate time unit nodes (as determined by the name of the + * output field) that may be generated due to selections projected over + * time units. + */ +export declare function removeDuplicateTimeUnits(leaf: DataFlowNode): void; diff --git a/build/src/compile/data/optimizers.js b/build/src/compile/data/optimizers.js new file mode 100644 index 0000000000..de13ce9aff --- /dev/null +++ b/build/src/compile/data/optimizers.js @@ -0,0 +1,88 @@ +import * as tslib_1 from "tslib"; +import { hasIntersection, keys } from '../../util'; +import { OutputNode } from './dataflow'; +import { FacetNode } from './facet'; +import { ParseNode } from './formatparse'; +import { SourceNode } from './source'; +import { TimeUnitNode } from './timeunit'; +/** + * Start optimization path at the leaves. Useful for merging up or removing things. + * + * If the callback returns true, the recursion continues. + */ +export function iterateFromLeaves(f) { + function optimizeNextFromLeaves(node) { + if (node instanceof SourceNode) { + return; + } + var next = node.parent; + if (f(node)) { + optimizeNextFromLeaves(next); + } + } + return optimizeNextFromLeaves; +} +/** + * Move parse nodes up to forks. + */ +export function moveParseUp(node) { + var parent = node.parent; + // move parse up by merging or swapping + if (node instanceof ParseNode) { + if (parent instanceof SourceNode) { + return false; + } + if (parent.numChildren() > 1) { + // don't move parse further up but continue with parent. + return true; + } + if (parent instanceof ParseNode) { + parent.merge(node); + } + else { + // don't swap with nodes that produce something that the parse node depends on (e.g. lookup) + if (hasIntersection(parent.producedFields(), node.dependentFields())) { + return true; + } + node.swapWithParent(); + } + } + return true; +} +/** + * Repeatedly remove leaf nodes that are not output or facet nodes. + * The reason is that we don't need subtrees that don't have any output nodes. + * Facet nodes are needed for the row or column domains. + */ +export function removeUnusedSubtrees(node) { + if (node instanceof OutputNode || node.numChildren() > 0 || node instanceof FacetNode) { + // no need to continue with parent because it is output node or will have children (there was a fork) + return false; + } + else { + node.remove(); + } + return true; +} +/** + * Removes duplicate time unit nodes (as determined by the name of the + * output field) that may be generated due to selections projected over + * time units. + */ +export function removeDuplicateTimeUnits(leaf) { + var fields = {}; + return iterateFromLeaves(function (node) { + if (node instanceof TimeUnitNode) { + var pfields = node.producedFields(); + var dupe = keys(pfields).every(function (k) { return !!fields[k]; }); + if (dupe) { + node.remove(); + } + else { + fields = tslib_1.__assign({}, fields, pfields); + } + } + return true; + })(leaf); +} +//# sourceMappingURL=optimizers.js.map \ No newline at end of file diff --git a/build/src/compile/data/optimizers.js.map b/build/src/compile/data/optimizers.js.map new file mode 100644 index 0000000000..eb8f17f879 --- /dev/null +++ b/build/src/compile/data/optimizers.js.map @@ -0,0 +1 @@ +{"version":3,"file":"optimizers.js","sourceRoot":"","sources":["../../../../src/compile/data/optimizers.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,eAAe,EAAE,IAAI,EAAC,MAAM,YAAY,CAAC;AACjD,OAAO,EAAe,UAAU,EAAC,MAAM,YAAY,CAAC;AACpD,OAAO,EAAC,SAAS,EAAC,MAAM,SAAS,CAAC;AAClC,OAAO,EAAC,SAAS,EAAC,MAAM,eAAe,CAAC;AACxC,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACpC,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAGxC;;;;GAIG;AACH,MAAM,4BAA4B,CAAkC;IAClE,gCAAgC,IAAkB;QAChD,IAAI,IAAI,YAAY,UAAU,EAAE;YAC9B,OAAO;SACR;QAED,IAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;QACzB,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;YACX,sBAAsB,CAAC,IAAI,CAAC,CAAC;SAC9B;IACH,CAAC;IAED,OAAO,sBAAsB,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,sBAAsB,IAAkB;IAC5C,IAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAE3B,uCAAuC;IACvC,IAAI,IAAI,YAAY,SAAS,EAAE;QAC7B,IAAI,MAAM,YAAY,UAAU,EAAE;YAChC,OAAO,KAAK,CAAC;SACd;QAED,IAAI,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE;YAC5B,wDAAwD;YACxD,OAAO,IAAI,CAAC;SACb;QAED,IAAI,MAAM,YAAY,SAAS,EAAE;YAC/B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SACpB;aAAM;YACL,4FAA4F;YAC5F,IAAI,eAAe,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,EAAE;gBACpE,OAAO,IAAI,CAAC;aACb;YAED,IAAI,CAAC,cAAc,EAAE,CAAC;SACvB;KACF;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,+BAA+B,IAAkB;IACrD,IAAI,IAAI,YAAY,UAAU,IAAI,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,IAAI,YAAY,SAAS,EAAE;QACrF,qGAAqG;QACrG,OAAO,KAAK,CAAC;KACd;SAAM;QACL,IAAI,CAAC,MAAM,EAAE,CAAC;KACf;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,mCAAmC,IAAkB;IACzD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,OAAO,iBAAiB,CAAC,UAAC,IAAkB;QAC1C,IAAI,IAAI,YAAY,YAAY,EAAE;YAChC,IAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACtC,IAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAX,CAAW,CAAC,CAAC;YAErD,IAAI,IAAI,EAAE;gBACR,IAAI,CAAC,MAAM,EAAE,CAAC;aACf;iBAAM;gBACL,MAAM,wBAAO,MAAM,EAAK,OAAO,CAAC,CAAC;aAClC;SACF;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACX,CAAC","sourcesContent":["import {hasIntersection, keys} from '../../util';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {ParseNode} from './formatparse';\nimport {SourceNode} from './source';\nimport {TimeUnitNode} from './timeunit';\n\n\n/**\n * Start optimization path at the leaves. Useful for merging up or removing things.\n *\n * If the callback returns true, the recursion continues.\n */\nexport function iterateFromLeaves(f: (node: DataFlowNode) => boolean) {\n function optimizeNextFromLeaves(node: DataFlowNode) {\n if (node instanceof SourceNode) {\n return;\n }\n\n const next = node.parent;\n if (f(node)) {\n optimizeNextFromLeaves(next);\n }\n }\n\n return optimizeNextFromLeaves;\n}\n\n/**\n * Move parse nodes up to forks.\n */\nexport function moveParseUp(node: DataFlowNode) {\n const parent = node.parent;\n\n // move parse up by merging or swapping\n if (node instanceof ParseNode) {\n if (parent instanceof SourceNode) {\n return false;\n }\n\n if (parent.numChildren() > 1) {\n // don't move parse further up but continue with parent.\n return true;\n }\n\n if (parent instanceof ParseNode) {\n parent.merge(node);\n } else {\n // don't swap with nodes that produce something that the parse node depends on (e.g. lookup)\n if (hasIntersection(parent.producedFields(), node.dependentFields())) {\n return true;\n }\n\n node.swapWithParent();\n }\n }\n\n return true;\n}\n\n/**\n * Repeatedly remove leaf nodes that are not output or facet nodes.\n * The reason is that we don't need subtrees that don't have any output nodes.\n * Facet nodes are needed for the row or column domains.\n */\nexport function removeUnusedSubtrees(node: DataFlowNode) {\n if (node instanceof OutputNode || node.numChildren() > 0 || node instanceof FacetNode) {\n // no need to continue with parent because it is output node or will have children (there was a fork)\n return false;\n } else {\n node.remove();\n }\n return true;\n}\n\n/**\n * Removes duplicate time unit nodes (as determined by the name of the\n * output field) that may be generated due to selections projected over\n * time units.\n */\nexport function removeDuplicateTimeUnits(leaf: DataFlowNode) {\n let fields = {};\n return iterateFromLeaves((node: DataFlowNode) => {\n if (node instanceof TimeUnitNode) {\n const pfields = node.producedFields();\n const dupe = keys(pfields).every((k) => !!fields[k]);\n\n if (dupe) {\n node.remove();\n } else {\n fields = {...fields, ...pfields};\n }\n }\n\n return true;\n })(leaf);\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/parse.d.ts b/build/src/compile/data/parse.d.ts new file mode 100644 index 0000000000..aad97bc622 --- /dev/null +++ b/build/src/compile/data/parse.d.ts @@ -0,0 +1,8 @@ +import { Model } from '../model'; +import { DataFlowNode } from './dataflow'; +import { AncestorParse, DataComponent } from './index'; +/** + * Parses a transforms array into a chain of connected dataflow nodes. + */ +export declare function parseTransformArray(head: DataFlowNode, model: Model, ancestorParse: AncestorParse): DataFlowNode; +export declare function parseData(model: Model): DataComponent; diff --git a/build/src/compile/data/parse.js b/build/src/compile/data/parse.js new file mode 100644 index 0000000000..24504ae3b7 --- /dev/null +++ b/build/src/compile/data/parse.js @@ -0,0 +1,247 @@ +import * as tslib_1 from "tslib"; +import { MAIN, RAW } from '../../data'; +import * as log from '../../log'; +import { isAggregate, isBin, isCalculate, isFilter, isLookup, isStack, isTimeUnit, isWindow } from '../../transform'; +import { keys } from '../../util'; +import { isFacetModel, isLayerModel, isUnitModel } from '../model'; +import { requiresSelectionId } from '../selection/selection'; +import { AggregateNode } from './aggregate'; +import { BinNode } from './bin'; +import { CalculateNode } from './calculate'; +import { OutputNode } from './dataflow'; +import { FacetNode } from './facet'; +import { FilterNode } from './filter'; +import { FilterInvalidNode } from './filterinvalid'; +import { ParseNode } from './formatparse'; +import { GeoJSONNode } from './geojson'; +import { GeoPointNode } from './geopoint'; +import { IdentifierNode } from './identifier'; +import { AncestorParse } from './index'; +import { LookupNode } from './lookup'; +import { SourceNode } from './source'; +import { StackNode } from './stack'; +import { TimeUnitNode } from './timeunit'; +import { WindowTransformNode } from './window'; +function parseRoot(model, sources) { + if (model.data || !model.parent) { + // if the model defines a data source or is the root, create a source node + var source = new SourceNode(model.data); + var hash = source.hash(); + if (hash in sources) { + // use a reference if we already have a source + return sources[hash]; + } + else { + // otherwise add a new one + sources[hash] = source; + return source; + } + } + else { + // If we don't have a source defined (overriding parent's data), use the parent's facet root or main. + return model.parent.component.data.facetRoot ? model.parent.component.data.facetRoot : model.parent.component.data.main; + } +} +/** + * Parses a transforms array into a chain of connected dataflow nodes. + */ +export function parseTransformArray(head, model, ancestorParse) { + var lookupCounter = 0; + model.transforms.forEach(function (t) { + if (isCalculate(t)) { + head = new CalculateNode(head, t); + ancestorParse.set(t.as, 'derived', false); + } + else if (isFilter(t)) { + head = ParseNode.makeImplicitFromFilterTransform(head, t, ancestorParse) || head; + head = new FilterNode(head, model, t.filter); + } + else if (isBin(t)) { + var bin = head = BinNode.makeFromTransform(head, t, model); + for (var _i = 0, _a = keys(bin.producedFields()); _i < _a.length; _i++) { + var field = _a[_i]; + ancestorParse.set(field, 'number', false); + } + } + else if (isTimeUnit(t)) { + head = TimeUnitNode.makeFromTransform(head, t); + ancestorParse.set(t.as, 'date', false); + } + else if (isAggregate(t)) { + var agg = head = AggregateNode.makeFromTransform(head, t); + if (requiresSelectionId(model)) { + head = new IdentifierNode(head); + } + for (var _b = 0, _c = keys(agg.producedFields()); _b < _c.length; _b++) { + var field = _c[_b]; + ancestorParse.set(field, 'derived', false); + } + } + else if (isLookup(t)) { + var lookup = head = LookupNode.make(head, model, t, lookupCounter++); + for (var _d = 0, _e = keys(lookup.producedFields()); _d < _e.length; _d++) { + var field = _e[_d]; + ancestorParse.set(field, 'derived', false); + } + } + else if (isWindow(t)) { + var window_1 = head = new WindowTransformNode(head, t); + for (var _f = 0, _g = keys(window_1.producedFields()); _f < _g.length; _f++) { + var field = _g[_f]; + ancestorParse.set(field, 'derived', false); + } + } + else if (isStack(t)) { + var stack = head = StackNode.makeFromTransform(head, t); + for (var _h = 0, _j = keys(stack.producedFields()); _h < _j.length; _h++) { + var field = _j[_h]; + ancestorParse.set(field, 'derived', false); + } + } + else { + log.warn(log.message.invalidTransformIgnored(t)); + return; + } + }); + return head; +} +/* +Description of the dataflow (http://asciiflow.com/): + +--------+ + | Source | + +---+----+ + | + v + FormatParse + (explicit) + | + v + Transforms +(Filter, Calculate, Binning, TimeUnit, Aggregate, Window, ...) + | + v + FormatParse + (implicit) + | + v + Binning (in `encoding`) + | + v + Timeunit (in `encoding`) + | + v +Formula From Sort Array + | + v + +--+--+ + | Raw | + +-----+ + | + v + Aggregate (in `encoding`) + | + v + Stack (in `encoding`) + | + v + Invalid Filter + | + v + +----------+ + | Main | + +----------+ + | + v + +-------+ + | Facet |----> "column", "column-layout", and "row" + +-------+ + | + v + ...Child data... +*/ +export function parseData(model) { + var head = parseRoot(model, model.component.data.sources); + var _a = model.component.data, outputNodes = _a.outputNodes, outputNodeRefCounts = _a.outputNodeRefCounts; + var ancestorParse = model.parent ? model.parent.component.data.ancestorParse.clone() : new AncestorParse(); + // format.parse: null means disable parsing + if (model.data && model.data.format && model.data.format.parse === null) { + ancestorParse.parseNothing = true; + } + head = ParseNode.makeExplicit(head, model, ancestorParse) || head; + // Default discrete selections require an identifier transform to + // uniquely identify data points as the _id field is volatile. Add + // this transform at the head of our pipeline such that the identifier + // field is available for all subsequent datasets. Additional identifier + // transforms will be necessary when new tuples are constructed + // (e.g., post-aggregation). + if (requiresSelectionId(model) && (isUnitModel(model) || isLayerModel(model))) { + head = new IdentifierNode(head); + } + // HACK: This is equivalent for merging bin extent for union scale. + // FIXME(https://github.com/vega/vega-lite/issues/2270): Correctly merge extent / bin node for shared bin scale + var parentIsLayer = model.parent && isLayerModel(model.parent); + if (isUnitModel(model) || isFacetModel(model)) { + if (parentIsLayer) { + head = BinNode.makeFromEncoding(head, model) || head; + } + } + if (model.transforms.length > 0) { + head = parseTransformArray(head, model, ancestorParse); + } + head = ParseNode.makeImplicitFromEncoding(head, model, ancestorParse) || head; + if (isUnitModel(model)) { + head = GeoJSONNode.parseAll(head, model); + head = GeoPointNode.parseAll(head, model); + } + if (isUnitModel(model) || isFacetModel(model)) { + if (!parentIsLayer) { + head = BinNode.makeFromEncoding(head, model) || head; + } + head = TimeUnitNode.makeFromEncoding(head, model) || head; + head = CalculateNode.parseAllForSortIndex(head, model); + } + // add an output node pre aggregation + var rawName = model.getName(RAW); + var raw = new OutputNode(head, rawName, RAW, outputNodeRefCounts); + outputNodes[rawName] = raw; + head = raw; + if (isUnitModel(model)) { + var agg = AggregateNode.makeFromEncoding(head, model); + if (agg) { + head = agg; + if (requiresSelectionId(model)) { + head = new IdentifierNode(head); + } + } + head = StackNode.makeFromEncoding(head, model) || head; + } + if (isUnitModel(model)) { + head = FilterInvalidNode.make(head, model) || head; + } + // output node for marks + var mainName = model.getName(MAIN); + var main = new OutputNode(head, mainName, MAIN, outputNodeRefCounts); + outputNodes[mainName] = main; + head = main; + // add facet marker + var facetRoot = null; + if (isFacetModel(model)) { + var facetName = model.getName('facet'); + // Derive new sort index field for facet's sort array + head = CalculateNode.parseAllForSortIndex(head, model); + // Derive new aggregate (via window) for facet's sort field + // TODO: use JoinAggregate once we have it + // augment data source with new fields for crossed facet + head = WindowTransformNode.makeFromFacet(head, model.facet) || head; + facetRoot = new FacetNode(head, model, facetName, main.getSource()); + outputNodes[facetName] = facetRoot; + head = facetRoot; + } + return tslib_1.__assign({}, model.component.data, { outputNodes: outputNodes, + outputNodeRefCounts: outputNodeRefCounts, + raw: raw, + main: main, + facetRoot: facetRoot, + ancestorParse: ancestorParse }); +} +//# sourceMappingURL=parse.js.map \ No newline at end of file diff --git a/build/src/compile/data/parse.js.map b/build/src/compile/data/parse.js.map new file mode 100644 index 0000000000..602a57c030 --- /dev/null +++ b/build/src/compile/data/parse.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../src/compile/data/parse.ts"],"names":[],"mappings":"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","sourcesContent":["import {MAIN, RAW} from '../../data';\nimport * as log from '../../log';\nimport {isAggregate, isBin, isCalculate, isFilter, isLookup, isStack, isTimeUnit, isWindow} from '../../transform';\nimport {Dict, keys} from '../../util';\nimport {isFacetModel, isLayerModel, isUnitModel, Model} from '../model';\nimport {requiresSelectionId} from '../selection/selection';\nimport {AggregateNode} from './aggregate';\nimport {BinNode} from './bin';\nimport {CalculateNode} from './calculate';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {FilterNode} from './filter';\nimport {FilterInvalidNode} from './filterinvalid';\nimport {ParseNode} from './formatparse';\nimport {GeoJSONNode} from './geojson';\nimport {GeoPointNode} from './geopoint';\nimport {IdentifierNode} from './identifier';\nimport {AncestorParse, DataComponent} from './index';\nimport {LookupNode} from './lookup';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\nimport {TimeUnitNode} from './timeunit';\nimport {WindowTransformNode} from './window';\n\nfunction parseRoot(model: Model, sources: Dict): DataFlowNode {\n if (model.data || !model.parent) {\n // if the model defines a data source or is the root, create a source node\n const source = new SourceNode(model.data);\n const hash = source.hash();\n if (hash in sources) {\n // use a reference if we already have a source\n return sources[hash];\n } else {\n // otherwise add a new one\n sources[hash] = source;\n return source;\n }\n } else {\n // If we don't have a source defined (overriding parent's data), use the parent's facet root or main.\n return model.parent.component.data.facetRoot ? model.parent.component.data.facetRoot : model.parent.component.data.main;\n }\n}\n\n\n/**\n * Parses a transforms array into a chain of connected dataflow nodes.\n */\nexport function parseTransformArray(head: DataFlowNode, model: Model, ancestorParse: AncestorParse): DataFlowNode {\n let lookupCounter = 0;\n\n model.transforms.forEach(t => {\n if (isCalculate(t)) {\n head = new CalculateNode(head, t);\n ancestorParse.set(t.as, 'derived', false);\n } else if (isFilter(t)) {\n head = ParseNode.makeImplicitFromFilterTransform(head, t, ancestorParse) || head;\n\n head = new FilterNode(head, model, t.filter);\n } else if (isBin(t)) {\n const bin = head = BinNode.makeFromTransform(head, t, model);\n\n for (const field of keys(bin.producedFields())) {\n ancestorParse.set(field, 'number', false);\n }\n\n } else if (isTimeUnit(t)) {\n head = TimeUnitNode.makeFromTransform(head, t);\n\n ancestorParse.set(t.as, 'date', false);\n } else if (isAggregate(t)) {\n const agg = head = AggregateNode.makeFromTransform(head, t);\n\n if (requiresSelectionId(model)) {\n head = new IdentifierNode(head);\n }\n\n for (const field of keys(agg.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else if (isLookup(t)) {\n const lookup = head = LookupNode.make(head, model, t, lookupCounter++);\n\n for (const field of keys(lookup.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else if (isWindow(t)) {\n const window = head = new WindowTransformNode(head, t);\n\n for (const field of keys(window.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else if (isStack(t)) {\n const stack = head = StackNode.makeFromTransform(head, t);\n\n for (const field of keys(stack.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else {\n log.warn(log.message.invalidTransformIgnored(t));\n return;\n }\n });\n\n return head;\n}\n\n/*\nDescription of the dataflow (http://asciiflow.com/):\n +--------+\n | Source |\n +---+----+\n |\n v\n FormatParse\n (explicit)\n |\n v\n Transforms\n(Filter, Calculate, Binning, TimeUnit, Aggregate, Window, ...)\n |\n v\n FormatParse\n (implicit)\n |\n v\n Binning (in `encoding`)\n |\n v\n Timeunit (in `encoding`)\n |\n v\nFormula From Sort Array\n |\n v\n +--+--+\n | Raw |\n +-----+\n |\n v\n Aggregate (in `encoding`)\n |\n v\n Stack (in `encoding`)\n |\n v\n Invalid Filter\n |\n v\n +----------+\n | Main |\n +----------+\n |\n v\n +-------+\n | Facet |----> \"column\", \"column-layout\", and \"row\"\n +-------+\n |\n v\n ...Child data...\n*/\n\nexport function parseData(model: Model): DataComponent {\n let head = parseRoot(model, model.component.data.sources);\n\n const {outputNodes, outputNodeRefCounts} = model.component.data;\n const ancestorParse = model.parent ? model.parent.component.data.ancestorParse.clone() : new AncestorParse();\n\n // format.parse: null means disable parsing\n if (model.data && model.data.format && model.data.format.parse === null) {\n ancestorParse.parseNothing = true;\n }\n\n head = ParseNode.makeExplicit(head, model, ancestorParse) || head;\n\n // Default discrete selections require an identifier transform to\n // uniquely identify data points as the _id field is volatile. Add\n // this transform at the head of our pipeline such that the identifier\n // field is available for all subsequent datasets. Additional identifier\n // transforms will be necessary when new tuples are constructed\n // (e.g., post-aggregation).\n if (requiresSelectionId(model) && (isUnitModel(model) || isLayerModel(model))) {\n head = new IdentifierNode(head);\n }\n\n // HACK: This is equivalent for merging bin extent for union scale.\n // FIXME(https://github.com/vega/vega-lite/issues/2270): Correctly merge extent / bin node for shared bin scale\n const parentIsLayer = model.parent && isLayerModel(model.parent);\n if (isUnitModel(model) || isFacetModel(model)) {\n if (parentIsLayer) {\n head = BinNode.makeFromEncoding(head, model) || head;\n }\n }\n\n if (model.transforms.length > 0) {\n head = parseTransformArray(head, model, ancestorParse);\n }\n\n head = ParseNode.makeImplicitFromEncoding(head, model, ancestorParse) || head;\n\n if (isUnitModel(model)) {\n head = GeoJSONNode.parseAll(head, model);\n head = GeoPointNode.parseAll(head, model);\n }\n\n if (isUnitModel(model) || isFacetModel(model)) {\n\n if (!parentIsLayer) {\n head = BinNode.makeFromEncoding(head, model) || head;\n }\n\n head = TimeUnitNode.makeFromEncoding(head, model) || head;\n head = CalculateNode.parseAllForSortIndex(head, model);\n }\n\n // add an output node pre aggregation\n const rawName = model.getName(RAW);\n const raw = new OutputNode(head, rawName, RAW, outputNodeRefCounts);\n outputNodes[rawName] = raw;\n head = raw;\n\n if (isUnitModel(model)) {\n const agg = AggregateNode.makeFromEncoding(head, model);\n if (agg) {\n head = agg;\n\n if (requiresSelectionId(model)) {\n head = new IdentifierNode(head);\n }\n }\n\n head = StackNode.makeFromEncoding(head, model) || head;\n }\n\n if (isUnitModel(model)) {\n head = FilterInvalidNode.make(head, model) || head;\n }\n\n // output node for marks\n const mainName = model.getName(MAIN);\n const main = new OutputNode(head, mainName, MAIN, outputNodeRefCounts);\n outputNodes[mainName] = main;\n head = main;\n\n // add facet marker\n let facetRoot = null;\n if (isFacetModel(model)) {\n const facetName = model.getName('facet');\n\n // Derive new sort index field for facet's sort array\n head = CalculateNode.parseAllForSortIndex(head, model);\n\n // Derive new aggregate (via window) for facet's sort field\n // TODO: use JoinAggregate once we have it\n // augment data source with new fields for crossed facet\n head = WindowTransformNode.makeFromFacet(head, model.facet) || head;\n\n facetRoot = new FacetNode(head, model, facetName, main.getSource());\n outputNodes[facetName] = facetRoot;\n head = facetRoot;\n }\n\n return {\n ...model.component.data,\n outputNodes,\n outputNodeRefCounts,\n raw,\n main,\n facetRoot,\n ancestorParse\n };\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/source.d.ts b/build/src/compile/data/source.d.ts new file mode 100644 index 0000000000..cf5123d046 --- /dev/null +++ b/build/src/compile/data/source.d.ts @@ -0,0 +1,19 @@ +import { Data } from '../../data'; +import { VgData } from '../../vega.schema'; +import { DataFlowNode } from './dataflow'; +export declare class SourceNode extends DataFlowNode { + private _data; + private _name; + private _hash; + constructor(data: Data); + readonly data: Partial; + hasName(): boolean; + dataName: string; + parent: DataFlowNode; + remove(): void; + /** + * Return a unique identifier for this data source. + */ + hash(): string | number; + assemble(): VgData; +} diff --git a/build/src/compile/data/source.js b/build/src/compile/data/source.js new file mode 100644 index 0000000000..504418c79d --- /dev/null +++ b/build/src/compile/data/source.js @@ -0,0 +1,96 @@ +import * as tslib_1 from "tslib"; +import { isInlineData, isNamedData, isUrlData } from '../../data'; +import { contains, hash } from '../../util'; +import { DataFlowNode } from './dataflow'; +var SourceNode = /** @class */ (function (_super) { + tslib_1.__extends(SourceNode, _super); + function SourceNode(data) { + var _this = _super.call(this, null) || this; + data = data || { name: 'source' }; + if (isInlineData(data)) { + _this._data = { values: data.values }; + } + else if (isUrlData(data)) { + _this._data = { url: data.url }; + if (!data.format) { + data.format = {}; + } + if (!data.format || !data.format.type) { + // Extract extension from URL using snippet from + // http://stackoverflow.com/questions/680929/how-to-extract-extension-from-filename-string-in-javascript + var defaultExtension = /(?:\.([^.]+))?$/.exec(data.url)[1]; + if (!contains(['json', 'csv', 'tsv', 'dsv', 'topojson'], defaultExtension)) { + defaultExtension = 'json'; + } + // defaultExtension has type string but we ensure that it is DataFormatType above + data.format.type = defaultExtension; + } + } + else if (isNamedData(data)) { + _this._data = {}; + } + // any dataset can be named + if (data.name) { + _this._name = data.name; + } + if (data.format) { + var _a = data.format, _b = _a.parse, parse = _b === void 0 ? null : _b, format = tslib_1.__rest(_a, ["parse"]); + _this._data.format = format; + } + return _this; + } + Object.defineProperty(SourceNode.prototype, "data", { + get: function () { + return this._data; + }, + enumerable: true, + configurable: true + }); + SourceNode.prototype.hasName = function () { + return !!this._name; + }; + Object.defineProperty(SourceNode.prototype, "dataName", { + get: function () { + return this._name; + }, + set: function (name) { + this._name = name; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SourceNode.prototype, "parent", { + set: function (parent) { + throw new Error('Source nodes have to be roots.'); + }, + enumerable: true, + configurable: true + }); + SourceNode.prototype.remove = function () { + throw new Error('Source nodes are roots and cannot be removed.'); + }; + /** + * Return a unique identifier for this data source. + */ + SourceNode.prototype.hash = function () { + if (isInlineData(this._data)) { + if (!this._hash) { + // Hashing can be expensive for large inline datasets. + this._hash = hash(this._data); + } + return this._hash; + } + else if (isUrlData(this._data)) { + return hash([this._data.url, this._data.format]); + } + else { + return this._name; + } + }; + SourceNode.prototype.assemble = function () { + return tslib_1.__assign({ name: this._name }, this._data, { transform: [] }); + }; + return SourceNode; +}(DataFlowNode)); +export { SourceNode }; +//# sourceMappingURL=source.js.map \ No newline at end of file diff --git a/build/src/compile/data/source.js.map b/build/src/compile/data/source.js.map new file mode 100644 index 0000000000..0f9b873180 --- /dev/null +++ b/build/src/compile/data/source.js.map @@ -0,0 +1 @@ +{"version":3,"file":"source.js","sourceRoot":"","sources":["../../../../src/compile/data/source.ts"],"names":[],"mappings":"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","sourcesContent":["import {Data, DataFormatType, isInlineData, isNamedData, isUrlData} from '../../data';\nimport {contains, hash} from '../../util';\nimport {VgData} from '../../vega.schema';\nimport {DataFlowNode} from './dataflow';\n\nexport class SourceNode extends DataFlowNode {\n private _data: Partial;\n\n private _name: string;\n\n private _hash: string | number;\n\n constructor(data: Data) {\n super(null); // source cannot have parent\n\n data = data || {name: 'source'};\n\n if (isInlineData(data)) {\n this._data = {values: data.values};\n } else if (isUrlData(data)) {\n this._data = {url: data.url};\n\n if (!data.format) {\n data.format = {};\n }\n\n if (!data.format || !data.format.type) {\n // Extract extension from URL using snippet from\n // http://stackoverflow.com/questions/680929/how-to-extract-extension-from-filename-string-in-javascript\n let defaultExtension = /(?:\\.([^.]+))?$/.exec(data.url)[1];\n if (!contains(['json', 'csv', 'tsv', 'dsv', 'topojson'], defaultExtension)) {\n defaultExtension = 'json';\n }\n\n // defaultExtension has type string but we ensure that it is DataFormatType above\n data.format.type = defaultExtension as DataFormatType;\n }\n } else if (isNamedData(data)) {\n this._data = {};\n }\n\n // any dataset can be named\n if (data.name) {\n this._name = data.name;\n }\n\n if (data.format) {\n const {parse = null, ...format} = data.format;\n this._data.format = format;\n }\n }\n\n get data() {\n return this._data;\n }\n\n public hasName(): boolean {\n return !!this._name;\n }\n\n get dataName() {\n return this._name;\n }\n\n set dataName(name: string) {\n this._name = name;\n }\n\n set parent(parent: DataFlowNode) {\n throw new Error('Source nodes have to be roots.');\n }\n\n public remove() {\n throw new Error('Source nodes are roots and cannot be removed.');\n }\n\n /**\n * Return a unique identifier for this data source.\n */\n public hash() {\n if (isInlineData(this._data)) {\n if (!this._hash) {\n // Hashing can be expensive for large inline datasets.\n this._hash = hash(this._data);\n }\n return this._hash;\n } else if (isUrlData(this._data)) {\n return hash([this._data.url, this._data.format]);\n } else {\n return this._name;\n }\n }\n\n public assemble(): VgData {\n return {\n name: this._name,\n ...this._data,\n transform: []\n };\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/stack.d.ts b/build/src/compile/data/stack.d.ts new file mode 100644 index 0000000000..b1b2b277aa --- /dev/null +++ b/build/src/compile/data/stack.d.ts @@ -0,0 +1,55 @@ +import { FieldDef } from '../../fielddef'; +import { StackOffset } from '../../stack'; +import { StackTransform } from '../../transform'; +import { VgSort, VgTransform } from '../../vega.schema'; +import { UnitModel } from './../unit'; +import { DataFlowNode } from './dataflow'; +export interface StackComponent { + /** + * Faceted field. + */ + facetby: string[]; + dimensionFieldDef?: FieldDef; + /** + * Stack measure's field. Used in makeFromEncoding. + */ + stackField: string; + /** + * Level of detail fields for each level in the stacked charts such as color or detail. + * Used in makeFromEncoding. + */ + stackby?: string[]; + /** + * Field that determines order of levels in the stacked charts. + * Used in both but optional in transform. + */ + sort: VgSort; + /** Mode for stacking marks. + */ + offset: StackOffset; + /** + * Whether to impute the data before stacking. Used only in makeFromEncoding. + */ + impute?: boolean; + /** + * The data fields to group by. + */ + groupby?: string[]; + /** + * Output field names of each stack field. + */ + as: string[]; +} +export declare class StackNode extends DataFlowNode { + private _stack; + clone(): StackNode; + constructor(parent: DataFlowNode, stack: StackComponent); + static makeFromTransform(parent: DataFlowNode, stackTransform: StackTransform): StackNode; + static makeFromEncoding(parent: DataFlowNode, model: UnitModel): StackNode; + readonly stack: StackComponent; + addDimensions(fields: string[]): void; + dependentFields(): {}; + producedFields(): {}; + private getGroupbyFields; + assemble(): VgTransform[]; +} diff --git a/build/src/compile/data/stack.js b/build/src/compile/data/stack.js new file mode 100644 index 0000000000..4a9cea8f6c --- /dev/null +++ b/build/src/compile/data/stack.js @@ -0,0 +1,188 @@ +import * as tslib_1 from "tslib"; +import { isArray, isString } from 'vega-util'; +import { isFieldDef, vgField } from '../../fielddef'; +import { duplicate } from '../../util'; +import { sortParams } from '../common'; +import { DataFlowNode } from './dataflow'; +function getStackByFields(model) { + return model.stack.stackBy.reduce(function (fields, by) { + var fieldDef = by.fieldDef; + var _field = vgField(fieldDef); + if (_field) { + fields.push(_field); + } + return fields; + }, []); +} +function isValidAsArray(as) { + return isArray(as) && as.every(function (s) { return isString(s); }) && as.length > 1; +} +var StackNode = /** @class */ (function (_super) { + tslib_1.__extends(StackNode, _super); + function StackNode(parent, stack) { + var _this = _super.call(this, parent) || this; + _this._stack = stack; + return _this; + } + StackNode.prototype.clone = function () { + return new StackNode(null, duplicate(this._stack)); + }; + StackNode.makeFromTransform = function (parent, stackTransform) { + var stack = stackTransform.stack, groupby = stackTransform.groupby, as = stackTransform.as, _a = stackTransform.offset, offset = _a === void 0 ? 'zero' : _a; + var sortFields = []; + var sortOrder = []; + if (stackTransform.sort !== undefined) { + for (var _i = 0, _b = stackTransform.sort; _i < _b.length; _i++) { + var sortField = _b[_i]; + sortFields.push(sortField.field); + sortOrder.push(sortField.order === undefined ? 'ascending' : sortField.order); + } + } + var sort = { + field: sortFields, + order: sortOrder, + }; + var normalizedAs; + if (isValidAsArray(as)) { + normalizedAs = as; + } + else if (isString(as)) { + normalizedAs = [as, as + '_end']; + } + else { + normalizedAs = [stackTransform.stack + '_start', stackTransform.stack + '_end']; + } + return new StackNode(parent, { + stackField: stack, + groupby: groupby, + offset: offset, + sort: sort, + facetby: [], + as: normalizedAs + }); + }; + StackNode.makeFromEncoding = function (parent, model) { + var stackProperties = model.stack; + if (!stackProperties) { + return null; + } + var dimensionFieldDef; + if (stackProperties.groupbyChannel) { + dimensionFieldDef = model.fieldDef(stackProperties.groupbyChannel); + } + var stackby = getStackByFields(model); + var orderDef = model.encoding.order; + var sort; + if (isArray(orderDef) || isFieldDef(orderDef)) { + sort = sortParams(orderDef); + } + else { + // default = descending by stackFields + // FIXME is the default here correct for binned fields? + sort = stackby.reduce(function (s, field) { + s.field.push(field); + s.order.push('descending'); + return s; + }, { field: [], order: [] }); + } + // Refactored to add "as" in the make phase so that we can get producedFields + // from the as property + var field = model.vgField(stackProperties.fieldChannel); + return new StackNode(parent, { + dimensionFieldDef: dimensionFieldDef, + stackField: field, + facetby: [], + stackby: stackby, + sort: sort, + offset: stackProperties.offset, + impute: stackProperties.impute, + as: [field + '_start', field + '_end'] + }); + }; + Object.defineProperty(StackNode.prototype, "stack", { + get: function () { + return this._stack; + }, + enumerable: true, + configurable: true + }); + StackNode.prototype.addDimensions = function (fields) { + this._stack.facetby = this._stack.facetby.concat(fields); + }; + StackNode.prototype.dependentFields = function () { + var out = {}; + out[this._stack.stackField] = true; + this.getGroupbyFields().forEach(function (f) { return out[f] = true; }); + this._stack.facetby.forEach(function (f) { return out[f] = true; }); + var field = this._stack.sort.field; + isArray(field) ? field.forEach(function (f) { return out[f] = true; }) : out[field] = true; + return out; + }; + StackNode.prototype.producedFields = function () { + return this._stack.as.reduce(function (result, item) { + result[item] = true; + return result; + }, {}); + }; + StackNode.prototype.getGroupbyFields = function () { + var _a = this._stack, dimensionFieldDef = _a.dimensionFieldDef, impute = _a.impute, groupby = _a.groupby; + if (dimensionFieldDef) { + if (dimensionFieldDef.bin) { + if (impute) { + // For binned group by field with impute, we calculate bin_mid + // as we cannot impute two fields simultaneously + return [vgField(dimensionFieldDef, { binSuffix: 'mid' })]; + } + return [ + // For binned group by field without impute, we need both bin (start) and bin_end + vgField(dimensionFieldDef, {}), + vgField(dimensionFieldDef, { binSuffix: 'end' }) + ]; + } + return [vgField(dimensionFieldDef)]; + } + return groupby || []; + }; + StackNode.prototype.assemble = function () { + var transform = []; + var _a = this._stack, facetby = _a.facetby, dimensionFieldDef = _a.dimensionFieldDef, field = _a.stackField, stackby = _a.stackby, sort = _a.sort, offset = _a.offset, impute = _a.impute, as = _a.as; + // Impute + if (impute && dimensionFieldDef) { + var dimensionField = dimensionFieldDef ? vgField(dimensionFieldDef, { binSuffix: 'mid' }) : undefined; + if (dimensionFieldDef.bin) { + // As we can only impute one field at a time, we need to calculate + // mid point for a binned field + transform.push({ + type: 'formula', + expr: '(' + + vgField(dimensionFieldDef, { expr: 'datum' }) + + '+' + + vgField(dimensionFieldDef, { expr: 'datum', binSuffix: 'end' }) + + ')/2', + as: dimensionField + }); + } + transform.push({ + type: 'impute', + field: field, + groupby: stackby, + key: dimensionField, + method: 'value', + value: 0 + }); + } + // Stack + transform.push({ + type: 'stack', + groupby: this.getGroupbyFields().concat(facetby), + field: field, + sort: sort, + as: as, + offset: offset + }); + return transform; + }; + return StackNode; +}(DataFlowNode)); +export { StackNode }; +//# sourceMappingURL=stack.js.map \ No newline at end of file diff --git a/build/src/compile/data/stack.js.map b/build/src/compile/data/stack.js.map new file mode 100644 index 0000000000..d6d4dc2657 --- /dev/null +++ b/build/src/compile/data/stack.js.map @@ -0,0 +1 @@ +{"version":3,"file":"stack.js","sourceRoot":"","sources":["../../../../src/compile/data/stack.ts"],"names":[],"mappings":"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","sourcesContent":["import {isArray, isString} from 'vega-util';\nimport {FieldDef, isFieldDef, vgField} from '../../fielddef';\nimport {StackOffset} from '../../stack';\nimport {StackTransform} from '../../transform';\nimport {duplicate} from '../../util';\nimport {VgComparatorOrder, VgSort, VgTransform} from '../../vega.schema';\nimport {sortParams} from '../common';\nimport {UnitModel} from './../unit';\nimport {DataFlowNode} from './dataflow';\n\nfunction getStackByFields(model: UnitModel): string[] {\n return model.stack.stackBy.reduce((fields, by) => {\n const fieldDef = by.fieldDef;\n\n const _field = vgField(fieldDef);\n if (_field) {\n fields.push(_field);\n }\n return fields;\n }, [] as string[]);\n}\n\nexport interface StackComponent {\n\n /**\n * Faceted field.\n */\n facetby: string[];\n\n dimensionFieldDef?: FieldDef;\n\n /**\n * Stack measure's field. Used in makeFromEncoding.\n */\n stackField: string;\n\n /**\n * Level of detail fields for each level in the stacked charts such as color or detail.\n * Used in makeFromEncoding.\n */\n stackby?: string[];\n\n /**\n * Field that determines order of levels in the stacked charts.\n * Used in both but optional in transform.\n */\n sort: VgSort;\n\n /** Mode for stacking marks.\n */\n offset: StackOffset;\n\n /**\n * Whether to impute the data before stacking. Used only in makeFromEncoding.\n */\n impute?: boolean;\n\n /**\n * The data fields to group by.\n */\n groupby?: string[];\n /**\n * Output field names of each stack field.\n */\n as: string[];\n\n}\n\nfunction isValidAsArray(as: string[] | string): as is string[] {\n return isArray(as) && as.every(s => isString(s)) && as.length >1;\n}\n\nexport class StackNode extends DataFlowNode {\n private _stack: StackComponent;\n\n public clone() {\n return new StackNode(null, duplicate(this._stack));\n }\n\n constructor(parent: DataFlowNode, stack: StackComponent) {\n super(parent);\n\n this._stack = stack;\n }\n\n public static makeFromTransform(parent: DataFlowNode, stackTransform: StackTransform) {\n\n const {stack, groupby, as, offset='zero'} = stackTransform;\n\n const sortFields: string[] = [];\n const sortOrder: VgComparatorOrder[] = [];\n if (stackTransform.sort !== undefined) {\n for (const sortField of stackTransform.sort) {\n sortFields.push(sortField.field);\n sortOrder.push(sortField.order === undefined ? 'ascending' : sortField.order as VgComparatorOrder);\n }\n }\n const sort: VgSort = {\n field: sortFields,\n order: sortOrder,\n };\n let normalizedAs: Array;\n if (isValidAsArray(as)) {\n normalizedAs = as;\n } else if(isString(as)) {\n normalizedAs = [as, as + '_end'];\n } else {\n normalizedAs = [stackTransform.stack + '_start', stackTransform.stack + '_end'];\n }\n\n return new StackNode (parent, {\n stackField: stack,\n groupby,\n offset,\n sort,\n facetby: [],\n as: normalizedAs\n });\n\n }\n public static makeFromEncoding(parent: DataFlowNode, model: UnitModel) {\n\n const stackProperties = model.stack;\n\n if (!stackProperties) {\n return null;\n }\n\n let dimensionFieldDef: FieldDef;\n if (stackProperties.groupbyChannel) {\n dimensionFieldDef = model.fieldDef(stackProperties.groupbyChannel);\n }\n\n const stackby = getStackByFields(model);\n const orderDef = model.encoding.order;\n\n let sort: VgSort;\n if (isArray(orderDef) || isFieldDef(orderDef)) {\n sort = sortParams(orderDef);\n } else {\n // default = descending by stackFields\n // FIXME is the default here correct for binned fields?\n sort = stackby.reduce((s, field) => {\n s.field.push(field);\n s.order.push('descending');\n return s;\n }, {field:[], order: []});\n }\n // Refactored to add \"as\" in the make phase so that we can get producedFields\n // from the as property\n const field = model.vgField(stackProperties.fieldChannel);\n\n return new StackNode(parent, {\n dimensionFieldDef,\n stackField:field,\n facetby: [],\n stackby,\n sort,\n offset: stackProperties.offset,\n impute: stackProperties.impute,\n as: [field + '_start', field + '_end']\n });\n }\n\n get stack(): StackComponent {\n return this._stack;\n }\n\n public addDimensions(fields: string[]) {\n this._stack.facetby = this._stack.facetby.concat(fields);\n }\n\n public dependentFields() {\n const out = {};\n\n out[this._stack.stackField] = true;\n\n this.getGroupbyFields().forEach(f => out[f] = true);\n this._stack.facetby.forEach(f => out[f] = true);\n const field = this._stack.sort.field;\n isArray(field) ? field.forEach(f => out[f] = true) : out[field] = true;\n\n return out;\n }\n\n public producedFields() {\n return this._stack.as.reduce((result, item) => {\n result[item] = true;\n return result;\n }, {});\n }\n\n private getGroupbyFields() {\n const {dimensionFieldDef, impute, groupby} = this._stack;\n if (dimensionFieldDef) {\n if (dimensionFieldDef.bin) {\n if (impute) {\n // For binned group by field with impute, we calculate bin_mid\n // as we cannot impute two fields simultaneously\n return [vgField(dimensionFieldDef, {binSuffix: 'mid'})];\n }\n return [\n // For binned group by field without impute, we need both bin (start) and bin_end\n vgField(dimensionFieldDef, {}),\n vgField(dimensionFieldDef, {binSuffix: 'end'})\n ];\n }\n return [vgField(dimensionFieldDef)];\n }\n return groupby || [];\n }\n\n public assemble(): VgTransform[] {\n const transform: VgTransform[] = [];\n const {facetby, dimensionFieldDef, stackField: field, stackby, sort, offset, impute, as} = this._stack;\n\n // Impute\n if (impute && dimensionFieldDef) {\n const dimensionField = dimensionFieldDef ? vgField(dimensionFieldDef, {binSuffix: 'mid'}): undefined;\n\n if (dimensionFieldDef.bin) {\n // As we can only impute one field at a time, we need to calculate\n // mid point for a binned field\n transform.push({\n type: 'formula',\n expr: '(' +\n vgField(dimensionFieldDef, {expr: 'datum'}) +\n '+' +\n vgField(dimensionFieldDef, {expr: 'datum', binSuffix: 'end'}) +\n ')/2',\n as: dimensionField\n });\n }\n\n transform.push({\n type: 'impute',\n field,\n groupby: stackby,\n key: dimensionField,\n method: 'value',\n value: 0\n });\n }\n\n // Stack\n transform.push({\n type: 'stack',\n groupby: this.getGroupbyFields().concat(facetby),\n field,\n sort,\n as,\n offset\n });\n\n return transform;\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/timeunit.d.ts b/build/src/compile/data/timeunit.d.ts new file mode 100644 index 0000000000..c46bd79708 --- /dev/null +++ b/build/src/compile/data/timeunit.d.ts @@ -0,0 +1,22 @@ +import { TimeUnit } from '../../timeunit'; +import { TimeUnitTransform } from '../../transform'; +import { Dict } from '../../util'; +import { VgFormulaTransform } from '../../vega.schema'; +import { ModelWithField } from '../model'; +import { DataFlowNode } from './dataflow'; +export interface TimeUnitComponent { + as: string; + timeUnit: TimeUnit; + field: string; +} +export declare class TimeUnitNode extends DataFlowNode { + private formula; + clone(): TimeUnitNode; + constructor(parent: DataFlowNode, formula: Dict); + static makeFromEncoding(parent: DataFlowNode, model: ModelWithField): TimeUnitNode; + static makeFromTransform(parent: DataFlowNode, t: TimeUnitTransform): TimeUnitNode; + merge(other: TimeUnitNode): void; + producedFields(): {}; + dependentFields(): {}; + assemble(): VgFormulaTransform[]; +} diff --git a/build/src/compile/data/timeunit.js b/build/src/compile/data/timeunit.js new file mode 100644 index 0000000000..6b6d5899f6 --- /dev/null +++ b/build/src/compile/data/timeunit.js @@ -0,0 +1,73 @@ +import * as tslib_1 from "tslib"; +import { vgField } from '../../fielddef'; +import { fieldExpr } from '../../timeunit'; +import { duplicate, keys, vals } from '../../util'; +import { DataFlowNode } from './dataflow'; +var TimeUnitNode = /** @class */ (function (_super) { + tslib_1.__extends(TimeUnitNode, _super); + function TimeUnitNode(parent, formula) { + var _this = _super.call(this, parent) || this; + _this.formula = formula; + return _this; + } + TimeUnitNode.prototype.clone = function () { + return new TimeUnitNode(null, duplicate(this.formula)); + }; + TimeUnitNode.makeFromEncoding = function (parent, model) { + var formula = model.reduceFieldDef(function (timeUnitComponent, fieldDef) { + if (fieldDef.timeUnit) { + var f = vgField(fieldDef); + timeUnitComponent[f] = { + as: f, + timeUnit: fieldDef.timeUnit, + field: fieldDef.field + }; + } + return timeUnitComponent; + }, {}); + if (keys(formula).length === 0) { + return null; + } + return new TimeUnitNode(parent, formula); + }; + TimeUnitNode.makeFromTransform = function (parent, t) { + var _a; + return new TimeUnitNode(parent, (_a = {}, + _a[t.field] = { + as: t.as, + timeUnit: t.timeUnit, + field: t.field + }, + _a)); + }; + TimeUnitNode.prototype.merge = function (other) { + this.formula = tslib_1.__assign({}, this.formula, other.formula); + other.remove(); + }; + TimeUnitNode.prototype.producedFields = function () { + var out = {}; + vals(this.formula).forEach(function (f) { + out[f.as] = true; + }); + return out; + }; + TimeUnitNode.prototype.dependentFields = function () { + var out = {}; + vals(this.formula).forEach(function (f) { + out[f.field] = true; + }); + return out; + }; + TimeUnitNode.prototype.assemble = function () { + return vals(this.formula).map(function (c) { + return { + type: 'formula', + as: c.as, + expr: fieldExpr(c.timeUnit, c.field) + }; + }); + }; + return TimeUnitNode; +}(DataFlowNode)); +export { TimeUnitNode }; +//# sourceMappingURL=timeunit.js.map \ No newline at end of file diff --git a/build/src/compile/data/timeunit.js.map b/build/src/compile/data/timeunit.js.map new file mode 100644 index 0000000000..b1b6c4747f --- /dev/null +++ b/build/src/compile/data/timeunit.js.map @@ -0,0 +1 @@ +{"version":3,"file":"timeunit.js","sourceRoot":"","sources":["../../../../src/compile/data/timeunit.ts"],"names":[],"mappings":"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","sourcesContent":["import {vgField} from '../../fielddef';\nimport {fieldExpr, TimeUnit} from '../../timeunit';\nimport {TimeUnitTransform} from '../../transform';\nimport {Dict, duplicate, keys, vals} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\nimport {ModelWithField} from '../model';\nimport {DataFlowNode} from './dataflow';\n\n\nexport interface TimeUnitComponent {\n as: string;\n timeUnit: TimeUnit;\n field: string;\n}\n\nexport class TimeUnitNode extends DataFlowNode {\n public clone() {\n return new TimeUnitNode(null, duplicate(this.formula));\n }\n\n constructor(parent: DataFlowNode, private formula: Dict) {\n super(parent);\n }\n\n public static makeFromEncoding(parent: DataFlowNode, model: ModelWithField) {\n const formula = model.reduceFieldDef((timeUnitComponent: TimeUnitComponent, fieldDef) => {\n if (fieldDef.timeUnit) {\n const f = vgField(fieldDef);\n timeUnitComponent[f] = {\n as: f,\n timeUnit: fieldDef.timeUnit,\n field: fieldDef.field\n };\n }\n return timeUnitComponent;\n }, {} as Dict);\n\n if (keys(formula).length === 0) {\n return null;\n }\n\n return new TimeUnitNode(parent, formula);\n }\n\n public static makeFromTransform(parent: DataFlowNode, t: TimeUnitTransform) {\n return new TimeUnitNode(parent, {\n [t.field]: {\n as: t.as,\n timeUnit: t.timeUnit,\n field: t.field\n }\n });\n }\n\n public merge(other: TimeUnitNode) {\n this.formula = {...this.formula, ...other.formula};\n other.remove();\n }\n\n public producedFields() {\n const out = {};\n\n vals(this.formula).forEach(f => {\n out[f.as] = true;\n });\n\n return out;\n }\n\n public dependentFields() {\n const out = {};\n\n vals(this.formula).forEach(f => {\n out[f.field] = true;\n });\n\n return out;\n }\n\n public assemble() {\n return vals(this.formula).map(c => {\n return {\n type: 'formula',\n as: c.as,\n expr: fieldExpr(c.timeUnit, c.field)\n } as VgFormulaTransform;\n });\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/data/window.d.ts b/build/src/compile/data/window.d.ts new file mode 100644 index 0000000000..169ba9afe3 --- /dev/null +++ b/build/src/compile/data/window.d.ts @@ -0,0 +1,16 @@ +import { FacetMapping } from '../../facet'; +import { WindowTransform } from '../../transform'; +import { VgWindowTransform } from '../../vega.schema'; +import { DataFlowNode } from './dataflow'; +/** + * A class for the window transform nodes + */ +export declare class WindowTransformNode extends DataFlowNode { + private transform; + static makeFromFacet(parent: DataFlowNode, facet: FacetMapping): WindowTransformNode; + clone(): WindowTransformNode; + constructor(parent: DataFlowNode, transform: WindowTransform); + producedFields(): {}; + private getDefaultName; + assemble(): VgWindowTransform; +} diff --git a/build/src/compile/data/window.js b/build/src/compile/data/window.js new file mode 100644 index 0000000000..319189513d --- /dev/null +++ b/build/src/compile/data/window.js @@ -0,0 +1,105 @@ +import * as tslib_1 from "tslib"; +import { vgField } from '../../fielddef'; +import { isSortField } from '../../sort'; +import { duplicate } from '../../util'; +import { facetSortFieldName } from '../facet'; +import { DataFlowNode } from './dataflow'; +/** + * A class for the window transform nodes + */ +var WindowTransformNode = /** @class */ (function (_super) { + tslib_1.__extends(WindowTransformNode, _super); + function WindowTransformNode(parent, transform) { + var _this = _super.call(this, parent) || this; + _this.transform = transform; + return _this; + } + WindowTransformNode.makeFromFacet = function (parent, facet) { + var row = facet.row, column = facet.column; + if (row && column) { + var newParent = null; + // only need to make one for crossed facet + for (var _i = 0, _a = [row, column]; _i < _a.length; _i++) { + var fieldDef = _a[_i]; + if (isSortField(fieldDef.sort)) { + var _b = fieldDef.sort, field = _b.field, op = _b.op; + parent = newParent = new WindowTransformNode(parent, { + window: [{ + op: op, + field: field, + as: facetSortFieldName(fieldDef, fieldDef.sort) + }], + groupby: [vgField(fieldDef)], + frame: [null, null] + }); + } + } + return newParent; + } + return null; + }; + WindowTransformNode.prototype.clone = function () { + return new WindowTransformNode(this.parent, duplicate(this.transform)); + }; + WindowTransformNode.prototype.producedFields = function () { + var _this = this; + var out = {}; + this.transform.window.forEach(function (windowFieldDef) { + out[_this.getDefaultName(windowFieldDef)] = true; + }); + return out; + }; + WindowTransformNode.prototype.getDefaultName = function (windowFieldDef) { + return windowFieldDef.as || vgField(windowFieldDef); + }; + WindowTransformNode.prototype.assemble = function () { + var fields = []; + var ops = []; + var as = []; + var params = []; + for (var _i = 0, _a = this.transform.window; _i < _a.length; _i++) { + var window_1 = _a[_i]; + ops.push(window_1.op); + as.push(this.getDefaultName(window_1)); + params.push(window_1.param === undefined ? null : window_1.param); + fields.push(window_1.field === undefined ? null : window_1.field); + } + var frame = this.transform.frame; + var groupby = this.transform.groupby; + var sortFields = []; + var sortOrder = []; + if (this.transform.sort !== undefined) { + for (var _b = 0, _c = this.transform.sort; _b < _c.length; _b++) { + var sortField = _c[_b]; + sortFields.push(sortField.field); + sortOrder.push(sortField.order || 'ascending'); + } + } + var sort = { + field: sortFields, + order: sortOrder, + }; + var ignorePeers = this.transform.ignorePeers; + var result = { + type: 'window', + params: params, + as: as, + ops: ops, + fields: fields, + sort: sort, + }; + if (ignorePeers !== undefined) { + result.ignorePeers = ignorePeers; + } + if (groupby !== undefined) { + result.groupby = groupby; + } + if (frame !== undefined) { + result.frame = frame; + } + return result; + }; + return WindowTransformNode; +}(DataFlowNode)); +export { WindowTransformNode }; +//# sourceMappingURL=window.js.map \ No newline at end of file diff --git a/build/src/compile/data/window.js.map b/build/src/compile/data/window.js.map new file mode 100644 index 0000000000..643088de8d --- /dev/null +++ b/build/src/compile/data/window.js.map @@ -0,0 +1 @@ +{"version":3,"file":"window.js","sourceRoot":"","sources":["../../../../src/compile/data/window.ts"],"names":[],"mappings":"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","sourcesContent":["import {AggregateOp} from 'vega';\nimport {FacetMapping} from '../../facet';\nimport {vgField} from '../../fielddef';\nimport {isSortField} from '../../sort';\nimport {WindowFieldDef, WindowOnlyOp, WindowTransform} from '../../transform';\nimport {duplicate} from '../../util';\nimport {VgComparator, VgComparatorOrder, VgWindowTransform} from '../../vega.schema';\nimport {facetSortFieldName} from '../facet';\nimport {DataFlowNode} from './dataflow';\n\n/**\n * A class for the window transform nodes\n */\nexport class WindowTransformNode extends DataFlowNode {\n public static makeFromFacet(parent: DataFlowNode, facet: FacetMapping): WindowTransformNode {\n const {row, column} = facet;\n if (row && column) {\n let newParent = null;\n // only need to make one for crossed facet\n for (const fieldDef of [row, column]) {\n if (isSortField(fieldDef.sort)) {\n const {field, op} = fieldDef.sort;\n parent = newParent = new WindowTransformNode(parent, {\n window: [{\n op,\n field,\n as: facetSortFieldName(fieldDef, fieldDef.sort)\n }],\n groupby: [vgField(fieldDef)],\n frame: [null, null]\n });\n }\n }\n return newParent;\n }\n return null;\n }\n\n\n public clone() {\n return new WindowTransformNode(this.parent, duplicate(this.transform));\n }\n\n constructor(parent: DataFlowNode, private transform: WindowTransform) {\n super(parent);\n }\n\n public producedFields() {\n const out = {};\n this.transform.window.forEach(windowFieldDef => {\n out[this.getDefaultName(windowFieldDef)] = true;\n });\n\n return out;\n }\n\n private getDefaultName(windowFieldDef: WindowFieldDef): string {\n return windowFieldDef.as || vgField(windowFieldDef);\n }\n\n public assemble(): VgWindowTransform {\n const fields: string[] = [];\n const ops: (AggregateOp | WindowOnlyOp)[] = [];\n const as = [];\n const params = [];\n for (const window of this.transform.window) {\n ops.push(window.op);\n as.push(this.getDefaultName(window));\n params.push(window.param === undefined ? null : window.param);\n fields.push(window.field === undefined ? null : window.field);\n }\n\n const frame = this.transform.frame;\n const groupby = this.transform.groupby;\n const sortFields: string[] = [];\n const sortOrder: VgComparatorOrder[] = [];\n if (this.transform.sort !== undefined) {\n for (const sortField of this.transform.sort) {\n sortFields.push(sortField.field);\n sortOrder.push(sortField.order || 'ascending');\n }\n }\n const sort: VgComparator = {\n field: sortFields,\n order: sortOrder,\n };\n const ignorePeers = this.transform.ignorePeers;\n\n const result: VgWindowTransform = {\n type: 'window',\n params,\n as,\n ops,\n fields,\n sort,\n };\n\n if (ignorePeers !== undefined) {\n result.ignorePeers = ignorePeers;\n }\n\n if (groupby !== undefined) {\n result.groupby = groupby;\n }\n\n if (frame !== undefined) {\n result.frame = frame;\n }\n\n return result;\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/facet.d.ts b/build/src/compile/facet.d.ts new file mode 100644 index 0000000000..a874c7f2b0 --- /dev/null +++ b/build/src/compile/facet.d.ts @@ -0,0 +1,45 @@ +import { Channel } from '../channel'; +import { Config } from '../config'; +import { FacetFieldDef, FacetMapping } from '../facet'; +import { FieldDef } from '../fielddef'; +import { EncodingSortField } from '../sort'; +import { NormalizedFacetSpec } from '../spec'; +import { VgData, VgLayout, VgMarkGroup, VgSignal } from '../vega.schema'; +import { Model, ModelWithField } from './model'; +import { RepeaterValue } from './repeater'; +export declare function facetSortFieldName(fieldDef: FacetFieldDef, sort: EncodingSortField, expr?: 'datum'): string; +export declare class FacetModel extends ModelWithField { + readonly type: 'facet'; + readonly facet: FacetMapping; + readonly child: Model; + readonly children: Model[]; + constructor(spec: NormalizedFacetSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config); + private initFacet; + channelHasField(channel: Channel): boolean; + fieldDef(channel: Channel): FieldDef; + parseData(): void; + parseLayoutSize(): void; + parseSelection(): void; + parseMarkGroup(): void; + parseAxisAndHeader(): void; + private parseHeader; + private makeHeaderComponent; + private mergeChildAxis; + assembleSelectionTopLevelSignals(signals: any[]): VgSignal[]; + assembleSelectionSignals(): VgSignal[]; + assembleSelectionData(data: VgData[]): VgData[]; + private getHeaderLayoutMixins; + protected assembleDefaultLayout(): VgLayout; + assembleLayoutSignals(): VgSignal[]; + private columnDistinctSignal; + assembleGroup(signals: VgSignal[]): any; + /** + * Aggregate cardinality for calculating size + */ + private getCardinalityAggregateForChild; + private assembleFacet; + private headerSortFields; + private headerSortOrder; + assembleMarks(): VgMarkGroup[]; + protected getMapping(): FacetMapping; +} diff --git a/build/src/compile/facet.js b/build/src/compile/facet.js new file mode 100644 index 0000000000..d5ef187a91 --- /dev/null +++ b/build/src/compile/facet.js @@ -0,0 +1,340 @@ +import * as tslib_1 from "tslib"; +import { isArray } from 'vega-util'; +import { COLUMN, ROW } from '../channel'; +import { reduce } from '../encoding'; +import { normalize, title as fieldDefTitle, vgField } from '../fielddef'; +import * as log from '../log'; +import { hasDiscreteDomain } from '../scale'; +import { isSortField } from '../sort'; +import { contains } from '../util'; +import { isVgRangeStep } from '../vega.schema'; +import { assembleAxis } from './axis/assemble'; +import { buildModel } from './buildmodel'; +import { assembleFacetData } from './data/assemble'; +import { sortArrayIndexField } from './data/calculate'; +import { parseData } from './data/parse'; +import { getHeaderType } from './header/index'; +import { parseChildrenLayoutSize } from './layoutsize/parse'; +import { ModelWithField } from './model'; +import { replaceRepeaterInFacet } from './repeater'; +import { parseGuideResolve } from './resolve'; +import { assembleDomain, getFieldFromDomain } from './scale/domain'; +export function facetSortFieldName(fieldDef, sort, expr) { + return vgField(sort, { expr: expr, suffix: "by_" + vgField(fieldDef) }); +} +var FacetModel = /** @class */ (function (_super) { + tslib_1.__extends(FacetModel, _super); + function FacetModel(spec, parent, parentGivenName, repeater, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, repeater, spec.resolve) || this; + _this.type = 'facet'; + _this.child = buildModel(spec.spec, _this, _this.getName('child'), undefined, repeater, config, false); + _this.children = [_this.child]; + var facet = replaceRepeaterInFacet(spec.facet, repeater); + _this.facet = _this.initFacet(facet); + return _this; + } + FacetModel.prototype.initFacet = function (facet) { + // clone to prevent side effect to the original spec + return reduce(facet, function (normalizedFacet, fieldDef, channel) { + if (!contains([ROW, COLUMN], channel)) { + // Drop unsupported channel + log.warn(log.message.incompatibleChannel(channel, 'facet')); + return normalizedFacet; + } + if (fieldDef.field === undefined) { + log.warn(log.message.emptyFieldDef(fieldDef, channel)); + return normalizedFacet; + } + // Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + normalizedFacet[channel] = normalize(fieldDef, channel); + return normalizedFacet; + }, {}); + }; + FacetModel.prototype.channelHasField = function (channel) { + return !!this.facet[channel]; + }; + FacetModel.prototype.fieldDef = function (channel) { + return this.facet[channel]; + }; + FacetModel.prototype.parseData = function () { + this.component.data = parseData(this); + this.child.parseData(); + }; + FacetModel.prototype.parseLayoutSize = function () { + parseChildrenLayoutSize(this); + }; + FacetModel.prototype.parseSelection = function () { + // As a facet has a single child, the selection components are the same. + // The child maintains its selections to assemble signals, which remain + // within its unit. + this.child.parseSelection(); + this.component.selection = this.child.component.selection; + }; + FacetModel.prototype.parseMarkGroup = function () { + this.child.parseMarkGroup(); + }; + FacetModel.prototype.parseAxisAndHeader = function () { + this.child.parseAxisAndHeader(); + this.parseHeader('column'); + this.parseHeader('row'); + this.mergeChildAxis('x'); + this.mergeChildAxis('y'); + }; + FacetModel.prototype.parseHeader = function (channel) { + if (this.channelHasField(channel)) { + var fieldDef = this.facet[channel]; + var header = fieldDef.header || {}; + var title = fieldDef.title !== undefined ? fieldDef.title : + header.title !== undefined ? header.title : fieldDefTitle(fieldDef, this.config); + if (this.child.component.layoutHeaders[channel].title) { + // merge title with child to produce "Title / Subtitle / Sub-subtitle" + title += ' / ' + this.child.component.layoutHeaders[channel].title; + this.child.component.layoutHeaders[channel].title = null; + } + this.component.layoutHeaders[channel] = { + title: title, + facetFieldDef: fieldDef, + // TODO: support adding label to footer as well + header: [this.makeHeaderComponent(channel, true)] + }; + } + }; + FacetModel.prototype.makeHeaderComponent = function (channel, labels) { + var sizeType = channel === 'row' ? 'height' : 'width'; + return { + labels: labels, + sizeSignal: this.child.component.layoutSize.get(sizeType) ? this.child.getSizeSignalRef(sizeType) : undefined, + axes: [] + }; + }; + FacetModel.prototype.mergeChildAxis = function (channel) { + var child = this.child; + if (child.component.axes[channel]) { + var _a = this.component, layoutHeaders = _a.layoutHeaders, resolve = _a.resolve; + resolve.axis[channel] = parseGuideResolve(resolve, channel); + if (resolve.axis[channel] === 'shared') { + // For shared axis, move the axes to facet's header or footer + var headerChannel = channel === 'x' ? 'column' : 'row'; + var layoutHeader = layoutHeaders[headerChannel]; + for (var _i = 0, _b = child.component.axes[channel]; _i < _b.length; _i++) { + var axisComponent = _b[_i]; + var headerType = getHeaderType(axisComponent.get('orient')); + layoutHeader[headerType] = layoutHeader[headerType] || + [this.makeHeaderComponent(headerChannel, false)]; + var mainAxis = assembleAxis(axisComponent, 'main', this.config, { header: true }); + // LayoutHeader no longer keep track of property precedence, thus let's combine. + layoutHeader[headerType][0].axes.push(mainAxis); + axisComponent.mainExtracted = true; + } + } + else { + // Otherwise do nothing for independent axes + } + } + }; + FacetModel.prototype.assembleSelectionTopLevelSignals = function (signals) { + return this.child.assembleSelectionTopLevelSignals(signals); + }; + FacetModel.prototype.assembleSelectionSignals = function () { + this.child.assembleSelectionSignals(); + return []; + }; + FacetModel.prototype.assembleSelectionData = function (data) { + return this.child.assembleSelectionData(data); + }; + FacetModel.prototype.getHeaderLayoutMixins = function () { + var _this = this; + var layoutMixins = {}; + ['row', 'column'].forEach(function (channel) { + ['header', 'footer'].forEach(function (headerType) { + var layoutHeaderComponent = _this.component.layoutHeaders[channel]; + var headerComponent = layoutHeaderComponent[headerType]; + if (headerComponent && headerComponent[0]) { + // set header/footerBand + var sizeType = channel === 'row' ? 'height' : 'width'; + var bandType = headerType === 'header' ? 'headerBand' : 'footerBand'; + if (!_this.child.component.layoutSize.get(sizeType)) { + // If facet child does not have size signal, then apply headerBand + layoutMixins[bandType] = layoutMixins[bandType] || {}; + layoutMixins[bandType][channel] = 0.5; + } + if (layoutHeaderComponent.title) { + layoutMixins.offset = layoutMixins.offset || {}; + layoutMixins.offset[channel === 'row' ? 'rowTitle' : 'columnTitle'] = 10; + } + } + }); + }); + return layoutMixins; + }; + FacetModel.prototype.assembleDefaultLayout = function () { + var columns = this.channelHasField('column') ? this.columnDistinctSignal() : 1; + // TODO: determine default align based on shared / independent scales + return tslib_1.__assign({}, this.getHeaderLayoutMixins(), { columns: columns, bounds: 'full', align: 'all' }); + }; + FacetModel.prototype.assembleLayoutSignals = function () { + // FIXME(https://github.com/vega/vega-lite/issues/1193): this can be incorrect if we have independent scales. + return this.child.assembleLayoutSignals(); + }; + FacetModel.prototype.columnDistinctSignal = function () { + if (this.parent && (this.parent instanceof FacetModel)) { + // For nested facet, we will add columns to group mark instead + // See discussion in https://github.com/vega/vega/issues/952 + // and https://github.com/vega/vega-view/releases/tag/v1.2.6 + return undefined; + } + else { + // In facetNode.assemble(), the name is always this.getName('column') + '_layout'. + var facetLayoutDataName = this.getName('column_domain'); + return { signal: "length(data('" + facetLayoutDataName + "'))" }; + } + }; + FacetModel.prototype.assembleGroup = function (signals) { + if (this.parent && (this.parent instanceof FacetModel)) { + // Provide number of columns for layout. + // See discussion in https://github.com/vega/vega/issues/952 + // and https://github.com/vega/vega-view/releases/tag/v1.2.6 + return tslib_1.__assign({}, (this.channelHasField('column') ? { + encode: { + update: { + // TODO(https://github.com/vega/vega-lite/issues/2759): + // Correct the signal for facet of concat of facet_column + columns: { field: vgField(this.facet.column, { prefix: 'distinct' }) } + } + } + } : {}), _super.prototype.assembleGroup.call(this, signals)); + } + return _super.prototype.assembleGroup.call(this, signals); + }; + /** + * Aggregate cardinality for calculating size + */ + FacetModel.prototype.getCardinalityAggregateForChild = function () { + var fields = []; + var ops = []; + var as = []; + if (this.child instanceof FacetModel) { + if (this.child.channelHasField('column')) { + var field = vgField(this.child.facet.column); + fields.push(field); + ops.push('distinct'); + as.push("distinct_" + field); + } + } + else { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var channel = _a[_i]; + var childScaleComponent = this.child.component.scales[channel]; + if (childScaleComponent && !childScaleComponent.merged) { + var type = childScaleComponent.get('type'); + var range = childScaleComponent.get('range'); + if (hasDiscreteDomain(type) && isVgRangeStep(range)) { + var domain = assembleDomain(this.child, channel); + var field = getFieldFromDomain(domain); + if (field) { + fields.push(field); + ops.push('distinct'); + as.push("distinct_" + field); + } + else { + log.warn('Unknown field for ${channel}. Cannot calculate view size.'); + } + } + } + } + } + return { fields: fields, ops: ops, as: as }; + }; + FacetModel.prototype.assembleFacet = function () { + var _this = this; + var _a = this.component.data.facetRoot, name = _a.name, data = _a.data; + var _b = this.facet, row = _b.row, column = _b.column; + var _c = this.getCardinalityAggregateForChild(), fields = _c.fields, ops = _c.ops, as = _c.as; + var groupby = []; + ['row', 'column'].forEach(function (channel) { + var fieldDef = _this.facet[channel]; + if (fieldDef) { + groupby.push(vgField(fieldDef)); + var sort = fieldDef.sort; + if (isSortField(sort)) { + var field = sort.field, op = sort.op; + var outputName = facetSortFieldName(fieldDef, sort); + if (row && column) { + // For crossed facet, use pre-calculate field as it requires a different groupby + // For each calculated field, apply max and assign them to the same name as + // all values of the same group should be the same anyway. + fields.push(outputName); + ops.push('max'); + as.push(outputName); + } + else { + fields.push(field); + ops.push(op); + as.push(outputName); + } + } + else if (isArray(sort)) { + var outputName = sortArrayIndexField(fieldDef, channel); + fields.push(outputName); + ops.push('max'); + as.push(outputName); + } + } + }); + var cross = !!row && !!column; + return tslib_1.__assign({ name: name, + data: data, + groupby: groupby }, (cross || fields.length ? { + aggregate: tslib_1.__assign({}, (cross ? { cross: cross } : {}), (fields.length ? { fields: fields, ops: ops, as: as } : {})) + } : {})); + }; + FacetModel.prototype.headerSortFields = function (channel) { + var facet = this.facet; + var fieldDef = facet[channel]; + if (fieldDef) { + if (isSortField(fieldDef.sort)) { + return [facetSortFieldName(fieldDef, fieldDef.sort, 'datum')]; + } + else if (isArray(fieldDef.sort)) { + return [sortArrayIndexField(fieldDef, channel, 'datum')]; + } + return [vgField(fieldDef, { expr: 'datum' })]; + } + return []; + }; + FacetModel.prototype.headerSortOrder = function (channel) { + var facet = this.facet; + var fieldDef = facet[channel]; + if (fieldDef) { + var sort = fieldDef.sort; + var order = (isSortField(sort) ? sort.order : !isArray(sort) && sort) || 'ascending'; + return [order]; + } + return []; + }; + FacetModel.prototype.assembleMarks = function () { + var child = this.child; + var facetRoot = this.component.data.facetRoot; + var data = assembleFacetData(facetRoot); + // If we facet by two dimensions, we need to add a cross operator to the aggregation + // so that we create all groups + var layoutSizeEncodeEntry = child.assembleLayoutSize(); + var title = child.assembleTitle(); + var style = child.assembleGroupStyle(); + var markGroup = tslib_1.__assign({ name: this.getName('cell'), type: 'group' }, (title ? { title: title } : {}), (style ? { style: style } : {}), { from: { + facet: this.assembleFacet() + }, + // TODO: move this to after data + sort: { + field: this.headerSortFields('row').concat(this.headerSortFields('column')), + order: this.headerSortOrder('row').concat(this.headerSortOrder('column')) + } }, (data.length > 0 ? { data: data } : {}), (layoutSizeEncodeEntry ? { encode: { update: layoutSizeEncodeEntry } } : {}), child.assembleGroup()); + return [markGroup]; + }; + FacetModel.prototype.getMapping = function () { + return this.facet; + }; + return FacetModel; +}(ModelWithField)); +export { FacetModel }; +//# sourceMappingURL=facet.js.map \ No newline at end of file diff --git a/build/src/compile/facet.js.map b/build/src/compile/facet.js.map new file mode 100644 index 0000000000..75b4780774 --- /dev/null +++ b/build/src/compile/facet.js.map @@ -0,0 +1 @@ +{"version":3,"file":"facet.js","sourceRoot":"","sources":["../../../src/compile/facet.ts"],"names":[],"mappings":"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","sourcesContent":["import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {Channel, COLUMN, ROW, ScaleChannel} from '../channel';\nimport {Config} from '../config';\nimport {reduce} from '../encoding';\nimport {FacetFieldDef, FacetMapping} from '../facet';\nimport {FieldDef, normalize, title as fieldDefTitle, vgField} from '../fielddef';\nimport * as log from '../log';\nimport {hasDiscreteDomain} from '../scale';\nimport {EncodingSortField, isSortField, SortOrder} from '../sort';\nimport {NormalizedFacetSpec} from '../spec';\nimport {contains} from '../util';\nimport {isVgRangeStep, VgData, VgLayout, VgMarkGroup, VgSignal} from '../vega.schema';\nimport {assembleAxis} from './axis/assemble';\nimport {buildModel} from './buildmodel';\nimport {assembleFacetData} from './data/assemble';\nimport {sortArrayIndexField} from './data/calculate';\nimport {parseData} from './data/parse';\nimport {getHeaderType, HeaderChannel, HeaderComponent} from './header/index';\nimport {parseChildrenLayoutSize} from './layoutsize/parse';\nimport {Model, ModelWithField} from './model';\nimport {RepeaterValue, replaceRepeaterInFacet} from './repeater';\nimport {parseGuideResolve} from './resolve';\nimport {assembleDomain, getFieldFromDomain} from './scale/domain';\n\nexport function facetSortFieldName(fieldDef: FacetFieldDef, sort: EncodingSortField, expr?: 'datum') {\n return vgField(sort, {expr, suffix: `by_${vgField(fieldDef)}`});\n}\n\nexport class FacetModel extends ModelWithField {\n public readonly type: 'facet' = 'facet';\n public readonly facet: FacetMapping;\n\n public readonly child: Model;\n\n public readonly children: Model[];\n\n constructor(spec: NormalizedFacetSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, repeater, spec.resolve);\n\n\n this.child = buildModel(spec.spec, this, this.getName('child'), undefined, repeater, config, false);\n this.children = [this.child];\n\n const facet: FacetMapping = replaceRepeaterInFacet(spec.facet, repeater);\n\n this.facet = this.initFacet(facet);\n }\n\n private initFacet(facet: FacetMapping): FacetMapping {\n // clone to prevent side effect to the original spec\n return reduce(facet, function(normalizedFacet, fieldDef: FieldDef, channel: Channel) {\n if (!contains([ROW, COLUMN], channel)) {\n // Drop unsupported channel\n log.warn(log.message.incompatibleChannel(channel, 'facet'));\n return normalizedFacet;\n }\n\n if (fieldDef.field === undefined) {\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n return normalizedFacet;\n }\n\n // Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n normalizedFacet[channel] = normalize(fieldDef, channel);\n return normalizedFacet;\n }, {});\n }\n\n public channelHasField(channel: Channel): boolean {\n return !!this.facet[channel];\n }\n\n public fieldDef(channel: Channel): FieldDef {\n return this.facet[channel];\n }\n\n public parseData() {\n this.component.data = parseData(this);\n this.child.parseData();\n }\n\n public parseLayoutSize() {\n parseChildrenLayoutSize(this);\n }\n\n public parseSelection() {\n // As a facet has a single child, the selection components are the same.\n // The child maintains its selections to assemble signals, which remain\n // within its unit.\n this.child.parseSelection();\n this.component.selection = this.child.component.selection;\n }\n\n public parseMarkGroup() {\n this.child.parseMarkGroup();\n }\n\n public parseAxisAndHeader() {\n this.child.parseAxisAndHeader();\n\n this.parseHeader('column');\n this.parseHeader('row');\n\n this.mergeChildAxis('x');\n this.mergeChildAxis('y');\n }\n\n private parseHeader(channel: HeaderChannel) {\n\n if (this.channelHasField(channel)) {\n const fieldDef = this.facet[channel];\n const header = fieldDef.header || {};\n let title = fieldDef.title !== undefined ? fieldDef.title :\n header.title !== undefined ? header.title : fieldDefTitle(fieldDef, this.config);\n\n if (this.child.component.layoutHeaders[channel].title) {\n // merge title with child to produce \"Title / Subtitle / Sub-subtitle\"\n title += ' / ' + this.child.component.layoutHeaders[channel].title;\n this.child.component.layoutHeaders[channel].title = null;\n }\n\n this.component.layoutHeaders[channel] = {\n title,\n facetFieldDef: fieldDef,\n // TODO: support adding label to footer as well\n header: [this.makeHeaderComponent(channel, true)]\n };\n }\n }\n\n private makeHeaderComponent(channel: HeaderChannel, labels: boolean): HeaderComponent {\n const sizeType = channel === 'row' ? 'height' : 'width';\n\n return {\n labels,\n sizeSignal: this.child.component.layoutSize.get(sizeType) ? this.child.getSizeSignalRef(sizeType) : undefined,\n axes: []\n };\n }\n\n private mergeChildAxis(channel: 'x' | 'y') {\n const {child} = this;\n if (child.component.axes[channel]) {\n const {layoutHeaders, resolve} = this.component;\n resolve.axis[channel] = parseGuideResolve(resolve, channel);\n\n if (resolve.axis[channel] === 'shared') {\n // For shared axis, move the axes to facet's header or footer\n const headerChannel = channel === 'x' ? 'column' : 'row';\n\n const layoutHeader = layoutHeaders[headerChannel];\n for (const axisComponent of child.component.axes[channel]) {\n const headerType = getHeaderType(axisComponent.get('orient'));\n layoutHeader[headerType] = layoutHeader[headerType] ||\n [this.makeHeaderComponent(headerChannel, false)];\n\n const mainAxis = assembleAxis(axisComponent, 'main', this.config, {header: true});\n // LayoutHeader no longer keep track of property precedence, thus let's combine.\n layoutHeader[headerType][0].axes.push(mainAxis);\n axisComponent.mainExtracted = true;\n }\n } else {\n // Otherwise do nothing for independent axes\n }\n }\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return this.child.assembleSelectionTopLevelSignals(signals);\n }\n\n public assembleSelectionSignals(): VgSignal[] {\n this.child.assembleSelectionSignals();\n return [];\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return this.child.assembleSelectionData(data);\n }\n\n private getHeaderLayoutMixins(): VgLayout {\n const layoutMixins: VgLayout = {};\n\n ['row', 'column'].forEach((channel: 'row' | 'column') => {\n ['header', 'footer'].forEach((headerType: 'header' | 'footer') => {\n const layoutHeaderComponent = this.component.layoutHeaders[channel];\n const headerComponent = layoutHeaderComponent[headerType];\n if (headerComponent && headerComponent[0]) {\n // set header/footerBand\n const sizeType = channel === 'row' ? 'height' : 'width';\n const bandType = headerType === 'header' ? 'headerBand' : 'footerBand';\n if (!this.child.component.layoutSize.get(sizeType)) {\n // If facet child does not have size signal, then apply headerBand\n layoutMixins[bandType] = layoutMixins[bandType] || {};\n layoutMixins[bandType][channel] = 0.5;\n }\n\n if (layoutHeaderComponent.title) {\n layoutMixins.offset = layoutMixins.offset || {};\n layoutMixins.offset[channel === 'row' ? 'rowTitle' : 'columnTitle'] = 10;\n }\n }\n });\n });\n return layoutMixins;\n }\n\n protected assembleDefaultLayout(): VgLayout {\n const columns = this.channelHasField('column') ? this.columnDistinctSignal() : 1;\n\n // TODO: determine default align based on shared / independent scales\n\n return {\n ...this.getHeaderLayoutMixins(),\n\n columns,\n bounds: 'full',\n align: 'all'\n };\n }\n\n public assembleLayoutSignals(): VgSignal[] {\n // FIXME(https://github.com/vega/vega-lite/issues/1193): this can be incorrect if we have independent scales.\n return this.child.assembleLayoutSignals();\n }\n\n private columnDistinctSignal() {\n if (this.parent && (this.parent instanceof FacetModel)) {\n // For nested facet, we will add columns to group mark instead\n // See discussion in https://github.com/vega/vega/issues/952\n // and https://github.com/vega/vega-view/releases/tag/v1.2.6\n return undefined;\n } else {\n // In facetNode.assemble(), the name is always this.getName('column') + '_layout'.\n const facetLayoutDataName = this.getName('column_domain');\n return {signal: `length(data('${facetLayoutDataName}'))`};\n }\n }\n\n public assembleGroup(signals: VgSignal[]) {\n if (this.parent && (this.parent instanceof FacetModel)) {\n // Provide number of columns for layout.\n // See discussion in https://github.com/vega/vega/issues/952\n // and https://github.com/vega/vega-view/releases/tag/v1.2.6\n return {\n ...(this.channelHasField('column') ? {\n encode: {\n update: {\n // TODO(https://github.com/vega/vega-lite/issues/2759):\n // Correct the signal for facet of concat of facet_column\n columns: {field: vgField(this.facet.column, {prefix: 'distinct'})}\n }\n }\n } : {}),\n ...super.assembleGroup(signals)\n };\n }\n return super.assembleGroup(signals);\n }\n\n /**\n * Aggregate cardinality for calculating size\n */\n private getCardinalityAggregateForChild() {\n const fields: string[] = [];\n const ops: AggregateOp[] = [];\n const as: string[] = [];\n\n if (this.child instanceof FacetModel) {\n if (this.child.channelHasField('column')) {\n const field = vgField(this.child.facet.column);\n fields.push(field);\n ops.push('distinct');\n as.push(`distinct_${field}`);\n }\n } else {\n for (const channel of ['x', 'y'] as ScaleChannel[]) {\n const childScaleComponent = this.child.component.scales[channel];\n if (childScaleComponent && !childScaleComponent.merged) {\n const type = childScaleComponent.get('type');\n const range = childScaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const domain = assembleDomain(this.child, channel);\n const field = getFieldFromDomain(domain);\n if (field) {\n fields.push(field);\n ops.push('distinct');\n as.push(`distinct_${field}`);\n } else {\n log.warn('Unknown field for ${channel}. Cannot calculate view size.');\n }\n }\n }\n }\n }\n return {fields, ops, as};\n }\n\n\n private assembleFacet() {\n const {name, data} = this.component.data.facetRoot;\n const {row, column} = this.facet;\n const {fields, ops, as} = this.getCardinalityAggregateForChild();\n const groupby: string[] = [];\n\n ['row', 'column'].forEach((channel: 'row' | 'column') => {\n const fieldDef = this.facet[channel];\n if (fieldDef) {\n groupby.push(vgField(fieldDef));\n const {sort} = fieldDef;\n if (isSortField(sort)) {\n const {field, op} = sort;\n const outputName = facetSortFieldName(fieldDef, sort);\n if (row && column) {\n // For crossed facet, use pre-calculate field as it requires a different groupby\n // For each calculated field, apply max and assign them to the same name as\n // all values of the same group should be the same anyway.\n fields.push(outputName);\n ops.push('max');\n as.push(outputName);\n } else {\n fields.push(field);\n ops.push(op);\n as.push(outputName);\n }\n } else if (isArray(sort)) {\n const outputName = sortArrayIndexField(fieldDef, channel);\n fields.push(outputName);\n ops.push('max');\n as.push(outputName);\n }\n }\n });\n\n const cross = !!row && !!column;\n\n return {\n name,\n data,\n groupby,\n ...(cross || fields.length ? {\n aggregate: {\n ...(cross ? {cross} : {}),\n ...(fields.length ? {fields, ops, as} : {})\n }\n } : {})\n };\n }\n\n\n private headerSortFields(channel: 'row' | 'column'): string[] {\n const {facet} = this;\n const fieldDef = facet[channel];\n\n if (fieldDef) {\n if (isSortField(fieldDef.sort)) {\n return [facetSortFieldName(fieldDef, fieldDef.sort, 'datum')];\n } else if (isArray(fieldDef.sort)) {\n return [sortArrayIndexField(fieldDef, channel, 'datum')];\n }\n return [vgField(fieldDef, {expr: 'datum'})];\n }\n return [];\n }\n\n private headerSortOrder(channel: 'row' | 'column'): SortOrder[] {\n const {facet} = this;\n const fieldDef = facet[channel];\n if (fieldDef) {\n const {sort} = fieldDef;\n const order = (isSortField(sort) ? sort.order : !isArray(sort) && sort) || 'ascending';\n return [order];\n }\n return [];\n }\n\n public assembleMarks(): VgMarkGroup[] {\n const {child} = this;\n const facetRoot = this.component.data.facetRoot;\n const data = assembleFacetData(facetRoot);\n\n // If we facet by two dimensions, we need to add a cross operator to the aggregation\n // so that we create all groups\n const layoutSizeEncodeEntry = child.assembleLayoutSize();\n\n const title = child.assembleTitle();\n const style = child.assembleGroupStyle();\n\n const markGroup = {\n name: this.getName('cell'),\n type: 'group',\n ...(title? {title} : {}),\n ...(style? {style} : {}),\n from: {\n facet: this.assembleFacet()\n },\n // TODO: move this to after data\n sort: {\n field: [\n ...this.headerSortFields('row'),\n ...this.headerSortFields('column')\n ],\n order: [\n ...this.headerSortOrder('row'),\n ...this.headerSortOrder('column')\n ]\n },\n ...(data.length > 0 ? {data: data} : {}),\n ...(layoutSizeEncodeEntry ? {encode: {update: layoutSizeEncodeEntry}} : {}),\n ...child.assembleGroup()\n };\n\n return [markGroup];\n }\n\n\n protected getMapping() {\n return this.facet;\n }\n}\n\n"]} \ No newline at end of file diff --git a/build/src/compile/header/index.d.ts b/build/src/compile/header/index.d.ts new file mode 100644 index 0000000000..2e0d3b7406 --- /dev/null +++ b/build/src/compile/header/index.d.ts @@ -0,0 +1,417 @@ +import { Config } from '../../config'; +import { FacetFieldDef } from '../../facet'; +import { HeaderConfig } from '../../header'; +import { AxisOrient, VgAxis, VgComparator, VgMarkGroup, VgTitleConfig } from '../../vega.schema'; +import { Model } from '../model'; +export declare type HeaderChannel = 'row' | 'column'; +export declare const HEADER_CHANNELS: HeaderChannel[]; +export declare type HeaderType = 'header' | 'footer'; +export declare const HEADER_TYPES: HeaderType[]; +/** + * A component that represents all header, footers and title of a Vega group with layout directive. + */ +export interface LayoutHeaderComponent { + title?: string; + facetFieldDef?: FacetFieldDef; + /** + * An array of header components for headers. + * For facet, there should be only one header component, which is data-driven. + * For repeat and concat, there can be multiple header components that explicitly list different axes. + */ + header?: HeaderComponent[]; + /** + * An array of header components for footers. + * For facet, there should be only one header component, which is data-driven. + * For repeat and concat, there can be multiple header components that explicitly list different axes. + */ + footer?: HeaderComponent[]; +} +/** + * A component that represents one group of row/column-header/footer. + */ +export interface HeaderComponent { + labels: boolean; + sizeSignal: { + signal: string; + }; + axes: VgAxis[]; +} +export declare function getHeaderType(orient: AxisOrient): "header" | "footer"; +export declare function getTitleGroup(model: Model, channel: HeaderChannel): { + name: string; + type: string; + role: string; + title: { + text: string; + offset: number; + orient: string; + style: string; + }; +}; +export declare function getHeaderGroups(model: Model, channel: HeaderChannel): VgMarkGroup[]; +export declare function labelAlign(angle: number): { + align?: undefined; +} | { + align: { + value: string; + }; +}; +export declare function labelBaseline(angle: number): { + baseline: string; +}; +export declare function getHeaderGroup(model: Model, channel: HeaderChannel, headerType: HeaderType, layoutHeader: LayoutHeaderComponent, headerCmpt: HeaderComponent): { + axes: VgAxis[]; + encode: { + update: { + [x: string]: { + signal: string; + }; + }; + }; + title: { + encode: { + update: { + align?: undefined; + } | { + align: { + value: string; + }; + }; + }; + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + } | { + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + }; + from: { + data: string; + }; + sort: VgComparator; + name: string; + type: string; + role: string; +} | { + encode: { + update: { + [x: string]: { + signal: string; + }; + }; + }; + title: { + encode: { + update: { + align?: undefined; + } | { + align: { + value: string; + }; + }; + }; + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + } | { + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + }; + from: { + data: string; + }; + sort: VgComparator; + name: string; + type: string; + role: string; +} | { + axes: VgAxis[]; + title: { + encode: { + update: { + align?: undefined; + } | { + align: { + value: string; + }; + }; + }; + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + } | { + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + }; + from: { + data: string; + }; + sort: VgComparator; + name: string; + type: string; + role: string; +} | { + title: { + encode: { + update: { + align?: undefined; + } | { + align: { + value: string; + }; + }; + }; + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + } | { + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + }; + from: { + data: string; + }; + sort: VgComparator; + name: string; + type: string; + role: string; +} | { + axes: VgAxis[]; + encode: { + update: { + [x: string]: { + signal: string; + }; + }; + }; + from: { + data: string; + }; + sort: VgComparator; + name: string; + type: string; + role: string; +} | { + encode: { + update: { + [x: string]: { + signal: string; + }; + }; + }; + from: { + data: string; + }; + sort: VgComparator; + name: string; + type: string; + role: string; +} | { + axes: VgAxis[]; + from: { + data: string; + }; + sort: VgComparator; + name: string; + type: string; + role: string; +} | { + from: { + data: string; + }; + sort: VgComparator; + name: string; + type: string; + role: string; +} | { + axes: VgAxis[]; + encode: { + update: { + [x: string]: { + signal: string; + }; + }; + }; + title: { + encode: { + update: { + align?: undefined; + } | { + align: { + value: string; + }; + }; + }; + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + } | { + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + }; + name: string; + type: string; + role: string; +} | { + encode: { + update: { + [x: string]: { + signal: string; + }; + }; + }; + title: { + encode: { + update: { + align?: undefined; + } | { + align: { + value: string; + }; + }; + }; + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + } | { + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + }; + name: string; + type: string; + role: string; +} | { + axes: VgAxis[]; + title: { + encode: { + update: { + align?: undefined; + } | { + align: { + value: string; + }; + }; + }; + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + } | { + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + }; + name: string; + type: string; + role: string; +} | { + title: { + encode: { + update: { + align?: undefined; + } | { + align: { + value: string; + }; + }; + }; + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + } | { + text: { + signal: string; + }; + offset: number; + orient: string; + style: string; + }; + name: string; + type: string; + role: string; +} | { + axes: VgAxis[]; + encode: { + update: { + [x: string]: { + signal: string; + }; + }; + }; + name: string; + type: string; + role: string; +} | { + encode: { + update: { + [x: string]: { + signal: string; + }; + }; + }; + name: string; + type: string; + role: string; +} | { + axes: VgAxis[]; + name: string; + type: string; + role: string; +} | { + name: string; + type: string; + role: string; +}; +export declare function getHeaderProperties(config: Config, facetFieldDef: FacetFieldDef, properties: string[], propertiesMap: { + [k in keyof HeaderConfig]: keyof VgTitleConfig; +}): {}; diff --git a/build/src/compile/header/index.js b/build/src/compile/header/index.js new file mode 100644 index 0000000000..54ca90eb82 --- /dev/null +++ b/build/src/compile/header/index.js @@ -0,0 +1,137 @@ +import * as tslib_1 from "tslib"; +/** + * Utility for generating row / column headers + */ +import { isArray } from 'vega-util'; +import { vgField } from '../../fielddef'; +import { HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP } from '../../header'; +import { isSortField } from '../../sort'; +import { keys } from '../../util'; +import { formatSignalRef } from '../common'; +import { sortArrayIndexField } from '../data/calculate'; +export var HEADER_CHANNELS = ['row', 'column']; +export var HEADER_TYPES = ['header', 'footer']; +export function getHeaderType(orient) { + if (orient === 'top' || orient === 'left') { + return 'header'; + } + return 'footer'; +} +export function getTitleGroup(model, channel) { + var title = model.component.layoutHeaders[channel].title; + var textOrient = channel === 'row' ? 'left' : undefined; + var config = model.config ? model.config : undefined; + var facetFieldDef = model.component.layoutHeaders[channel].facetFieldDef ? model.component.layoutHeaders[channel].facetFieldDef : undefined; + return { + name: channel + "-title", + type: 'group', + role: channel + "-title", + title: tslib_1.__assign({ text: title, offset: 10, orient: textOrient, style: 'guide-title' }, getHeaderProperties(config, facetFieldDef, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP)) + }; +} +export function getHeaderGroups(model, channel) { + var layoutHeader = model.component.layoutHeaders[channel]; + var groups = []; + for (var _i = 0, HEADER_TYPES_1 = HEADER_TYPES; _i < HEADER_TYPES_1.length; _i++) { + var headerType = HEADER_TYPES_1[_i]; + if (layoutHeader[headerType]) { + for (var _a = 0, _b = layoutHeader[headerType]; _a < _b.length; _a++) { + var headerCmpt = _b[_a]; + groups.push(getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt)); + } + } + } + return groups; +} +// 0, (0,90), 90, (90, 180), 180, (180, 270), 270, (270, 0) +export function labelAlign(angle) { + // to keep angle in [0, 360) + angle = ((angle % 360) + 360) % 360; + if ((angle + 90) % 180 === 0) { // for 90 and 270 + return {}; // default center + } + else if (angle < 90 || 270 < angle) { + return { align: { value: 'right' } }; + } + else if (135 <= angle && angle < 225) { + return { align: { value: 'left' } }; + } + return {}; +} +export function labelBaseline(angle) { + // to keep angle in [0, 360) + angle = ((angle % 360) + 360) % 360; + if (45 <= angle && angle <= 135) { + return { baseline: 'top' }; + } + return { baseline: 'middle' }; +} +function getSort(facetFieldDef, channel) { + var sort = facetFieldDef.sort; + if (isSortField(sort)) { + return { + field: vgField(sort, { expr: 'datum' }), + order: sort.order || 'ascending' + }; + } + else if (isArray(sort)) { + return { + field: sortArrayIndexField(facetFieldDef, channel, 'datum'), + order: 'ascending' + }; + } + else { + return { + field: vgField(facetFieldDef, { expr: 'datum' }), + order: sort || 'ascending' + }; + } +} +export function getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt) { + var _a; + if (headerCmpt) { + var title = null; + var facetFieldDef = layoutHeader.facetFieldDef; + if (facetFieldDef && headerCmpt.labels) { + var _b = facetFieldDef.header, header = _b === void 0 ? {} : _b; + var format = header.format, labelAngle = header.labelAngle; + var config = model.config ? model.config : undefined; + var update = tslib_1.__assign({}, labelAlign(labelAngle)); + title = tslib_1.__assign({ text: formatSignalRef(facetFieldDef, format, 'parent', model.config), offset: 10, orient: channel === 'row' ? 'left' : 'top', style: 'guide-label' }, getHeaderProperties(config, facetFieldDef, HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP), (keys(update).length > 0 ? { encode: { update: update } } : {})); + } + var axes = headerCmpt.axes; + var hasAxes = axes && axes.length > 0; + if (title || hasAxes) { + var sizeChannel = channel === 'row' ? 'height' : 'width'; + return tslib_1.__assign({ name: model.getName(channel + "_" + headerType), type: 'group', role: channel + "-" + headerType }, (layoutHeader.facetFieldDef ? { + from: { data: model.getName(channel + '_domain') }, + sort: getSort(facetFieldDef, channel) + } : {}), (title ? { title: title } : {}), (headerCmpt.sizeSignal ? { + encode: { + update: (_a = {}, + _a[sizeChannel] = headerCmpt.sizeSignal, + _a) + } + } : {}), (hasAxes ? { axes: axes } : {})); + } + } + return null; +} +export function getHeaderProperties(config, facetFieldDef, properties, propertiesMap) { + var props = {}; + for (var _i = 0, properties_1 = properties; _i < properties_1.length; _i++) { + var prop = properties_1[_i]; + if (config && config.header) { + if (config.header[prop]) { + props[propertiesMap[prop]] = config.header[prop]; + } + } + if (facetFieldDef && facetFieldDef.header) { + if (facetFieldDef.header[prop]) { + props[propertiesMap[prop]] = facetFieldDef.header[prop]; + } + } + } + return props; +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/src/compile/header/index.js.map b/build/src/compile/header/index.js.map new file mode 100644 index 0000000000..215d7e05d9 --- /dev/null +++ b/build/src/compile/header/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/compile/header/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Utility for generating row / column headers\n */\nimport {isArray} from 'vega-util';\nimport {Config} from '../../config';\nimport {FacetFieldDef} from '../../facet';\nimport {vgField} from '../../fielddef';\nimport {HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP, HeaderConfig} from '../../header';\nimport {isSortField} from '../../sort';\nimport {keys} from '../../util';\nimport {AxisOrient, VgAxis, VgComparator, VgMarkGroup, VgTitleConfig} from '../../vega.schema';\nimport {formatSignalRef} from '../common';\nimport {sortArrayIndexField} from '../data/calculate';\nimport {Model} from '../model';\n\n\nexport type HeaderChannel = 'row' | 'column';\nexport const HEADER_CHANNELS: HeaderChannel[] = ['row', 'column'];\n\nexport type HeaderType = 'header' | 'footer';\nexport const HEADER_TYPES: HeaderType[] = ['header', 'footer'];\n\n/**\n * A component that represents all header, footers and title of a Vega group with layout directive.\n */\nexport interface LayoutHeaderComponent {\n title?: string;\n\n // TODO: repeat and concat can have multiple header / footer.\n // Need to redesign this part a bit.\n\n facetFieldDef?: FacetFieldDef;\n\n /**\n * An array of header components for headers.\n * For facet, there should be only one header component, which is data-driven.\n * For repeat and concat, there can be multiple header components that explicitly list different axes.\n */\n header?: HeaderComponent[];\n\n /**\n * An array of header components for footers.\n * For facet, there should be only one header component, which is data-driven.\n * For repeat and concat, there can be multiple header components that explicitly list different axes.\n */\n footer?: HeaderComponent[];\n}\n\n/**\n * A component that represents one group of row/column-header/footer.\n */\nexport interface HeaderComponent {\n\n labels: boolean;\n\n sizeSignal: {signal: string};\n\n axes: VgAxis[];\n}\n\nexport function getHeaderType(orient: AxisOrient) {\n if (orient === 'top' || orient === 'left') {\n return 'header';\n }\n return 'footer';\n}\n\nexport function getTitleGroup(model: Model, channel: HeaderChannel) {\n const title = model.component.layoutHeaders[channel].title;\n const textOrient = channel === 'row' ? 'left' : undefined;\n const config = model.config? model.config : undefined;\n const facetFieldDef = model.component.layoutHeaders[channel].facetFieldDef? model.component.layoutHeaders[channel].facetFieldDef : undefined;\n\n return {\n name: `${channel}-title`,\n type: 'group',\n role: `${channel}-title`,\n title: {\n text: title,\n offset: 10,\n orient: textOrient,\n style: 'guide-title',\n ...getHeaderProperties(config, facetFieldDef, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP)\n }\n };\n}\n\nexport function getHeaderGroups(model: Model, channel: HeaderChannel): VgMarkGroup[] {\n const layoutHeader = model.component.layoutHeaders[channel];\n const groups = [];\n for (const headerType of HEADER_TYPES) {\n if (layoutHeader[headerType]) {\n for (const headerCmpt of layoutHeader[headerType]) {\n groups.push(getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt));\n }\n }\n }\n return groups;\n}\n\n// 0, (0,90), 90, (90, 180), 180, (180, 270), 270, (270, 0)\n\nexport function labelAlign(angle: number) {\n // to keep angle in [0, 360)\n angle = ((angle % 360) + 360) % 360;\n if ((angle + 90) % 180 === 0) { // for 90 and 270\n return {}; // default center\n } else if (angle < 90 || 270 < angle) {\n return {align: {value: 'right'}};\n } else if (135 <= angle && angle < 225) {\n return {align: {value: 'left'}};\n }\n return {};\n}\n\nexport function labelBaseline(angle: number) {\n // to keep angle in [0, 360)\n angle = ((angle % 360) + 360) % 360;\n if (45 <= angle && angle <= 135) {\n return {baseline: 'top'};\n }\n return {baseline: 'middle'};\n}\n\nfunction getSort(facetFieldDef: FacetFieldDef, channel: 'row' | 'column'): VgComparator {\n const {sort} = facetFieldDef;\n if (isSortField(sort)) {\n return {\n field: vgField(sort, {expr: 'datum'}),\n order: sort.order || 'ascending'\n };\n } else if (isArray(sort)) {\n return {\n field: sortArrayIndexField(facetFieldDef, channel, 'datum'),\n order: 'ascending'\n };\n } else {\n return {\n field: vgField(facetFieldDef, {expr: 'datum'}),\n order: sort || 'ascending'\n };\n }\n}\n\nexport function getHeaderGroup(model: Model, channel: HeaderChannel, headerType: HeaderType, layoutHeader: LayoutHeaderComponent, headerCmpt: HeaderComponent) {\n if (headerCmpt) {\n let title = null;\n const {facetFieldDef} = layoutHeader;\n if (facetFieldDef && headerCmpt.labels) {\n const {header = {}} = facetFieldDef;\n const {format, labelAngle} = header;\n const config = model.config? model.config : undefined;\n\n const update = {\n ...labelAlign(labelAngle)\n };\n\n title = {\n text: formatSignalRef(facetFieldDef, format, 'parent', model.config),\n offset: 10,\n orient: channel === 'row' ? 'left' : 'top',\n style: 'guide-label',\n ...getHeaderProperties(config, facetFieldDef, HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP),\n ...(keys(update).length > 0 ? {encode: {update}} : {})\n };\n }\n\n const axes = headerCmpt.axes;\n\n const hasAxes = axes && axes.length > 0;\n if (title || hasAxes) {\n const sizeChannel = channel === 'row' ? 'height' : 'width';\n\n\n\n return {\n name: model.getName(`${channel}_${headerType}`),\n type: 'group',\n role: `${channel}-${headerType}`,\n ...(layoutHeader.facetFieldDef ? {\n from: {data: model.getName(channel + '_domain')},\n sort: getSort(facetFieldDef, channel)\n } : {}),\n ...(title ? {title} : {}),\n ...(headerCmpt.sizeSignal ? {\n encode: {\n update: {\n [sizeChannel]: headerCmpt.sizeSignal\n }\n }\n }: {}),\n ...(hasAxes ? {axes} : {})\n };\n }\n }\n return null;\n}\n\nexport function getHeaderProperties(config: Config, facetFieldDef: FacetFieldDef, properties: string[], propertiesMap: {[k in keyof HeaderConfig]: keyof VgTitleConfig}) {\n const props = {};\n for (const prop of properties) {\n if (config && config.header) {\n if (config.header[prop]) {\n props[propertiesMap[prop]] = config.header[prop];\n }\n }\n if (facetFieldDef && facetFieldDef.header) {\n if (facetFieldDef.header[prop]) {\n props[propertiesMap[prop]] = facetFieldDef.header[prop];\n }\n }\n }\n return props;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/layer.d.ts b/build/src/compile/layer.d.ts new file mode 100644 index 0000000000..05edcbac91 --- /dev/null +++ b/build/src/compile/layer.d.ts @@ -0,0 +1,23 @@ +import { Config } from '../config'; +import { LayoutSizeMixins, NormalizedLayerSpec } from '../spec'; +import { VgData, VgLayout, VgLegend, VgSignal, VgTitle } from '../vega.schema'; +import { Model } from './model'; +import { RepeaterValue } from './repeater'; +export declare class LayerModel extends Model { + readonly type: 'layer'; + readonly children: Model[]; + constructor(spec: NormalizedLayerSpec, parent: Model, parentGivenName: string, parentGivenSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean); + parseData(): void; + parseLayoutSize(): void; + parseSelection(): void; + parseMarkGroup(): void; + parseAxisAndHeader(): void; + assembleSelectionTopLevelSignals(signals: any[]): VgSignal[]; + assembleSelectionSignals(): VgSignal[]; + assembleLayoutSignals(): VgSignal[]; + assembleSelectionData(data: VgData[]): VgData[]; + assembleTitle(): VgTitle; + assembleLayout(): VgLayout; + assembleMarks(): any[]; + assembleLegends(): VgLegend[]; +} diff --git a/build/src/compile/layer.js b/build/src/compile/layer.js new file mode 100644 index 0000000000..e5c6b94093 --- /dev/null +++ b/build/src/compile/layer.js @@ -0,0 +1,115 @@ +import * as tslib_1 from "tslib"; +import * as log from '../log'; +import { isLayerSpec, isUnitSpec } from '../spec'; +import { flatten, keys } from '../util'; +import { parseLayerAxis } from './axis/parse'; +import { parseData } from './data/parse'; +import { assembleLayoutSignals } from './layoutsize/assemble'; +import { parseLayerLayoutSize } from './layoutsize/parse'; +import { assembleLegends } from './legend/assemble'; +import { Model } from './model'; +import { assembleLayerSelectionMarks } from './selection/selection'; +import { UnitModel } from './unit'; +var LayerModel = /** @class */ (function (_super) { + tslib_1.__extends(LayerModel, _super); + function LayerModel(spec, parent, parentGivenName, parentGivenSize, repeater, config, fit) { + var _this = _super.call(this, spec, parent, parentGivenName, config, repeater, spec.resolve) || this; + _this.type = 'layer'; + var layoutSize = tslib_1.__assign({}, parentGivenSize, (spec.width ? { width: spec.width } : {}), (spec.height ? { height: spec.height } : {})); + _this.initSize(layoutSize); + _this.children = spec.layer.map(function (layer, i) { + if (isLayerSpec(layer)) { + return new LayerModel(layer, _this, _this.getName('layer_' + i), layoutSize, repeater, config, fit); + } + if (isUnitSpec(layer)) { + return new UnitModel(layer, _this, _this.getName('layer_' + i), layoutSize, repeater, config, fit); + } + throw new Error(log.message.INVALID_SPEC); + }); + return _this; + } + LayerModel.prototype.parseData = function () { + this.component.data = parseData(this); + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseData(); + } + }; + LayerModel.prototype.parseLayoutSize = function () { + parseLayerLayoutSize(this); + }; + LayerModel.prototype.parseSelection = function () { + var _this = this; + // Merge selections up the hierarchy so that they may be referenced + // across unit specs. Persist their definitions within each child + // to assemble signals which remain within output Vega unit groups. + this.component.selection = {}; + var _loop_1 = function (child) { + child.parseSelection(); + keys(child.component.selection).forEach(function (key) { + _this.component.selection[key] = child.component.selection[key]; + }); + }; + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + _loop_1(child); + } + }; + LayerModel.prototype.parseMarkGroup = function () { + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseMarkGroup(); + } + }; + LayerModel.prototype.parseAxisAndHeader = function () { + parseLayerAxis(this); + }; + LayerModel.prototype.assembleSelectionTopLevelSignals = function (signals) { + return this.children.reduce(function (sg, child) { return child.assembleSelectionTopLevelSignals(sg); }, signals); + }; + // TODO: Support same named selections across children. + LayerModel.prototype.assembleSelectionSignals = function () { + return this.children.reduce(function (signals, child) { + return signals.concat(child.assembleSelectionSignals()); + }, []); + }; + LayerModel.prototype.assembleLayoutSignals = function () { + return this.children.reduce(function (signals, child) { + return signals.concat(child.assembleLayoutSignals()); + }, assembleLayoutSignals(this)); + }; + LayerModel.prototype.assembleSelectionData = function (data) { + return this.children.reduce(function (db, child) { return child.assembleSelectionData(db); }, data); + }; + LayerModel.prototype.assembleTitle = function () { + var title = _super.prototype.assembleTitle.call(this); + if (title) { + return title; + } + // If title does not provide layer, look into children + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + title = child.assembleTitle(); + if (title) { + return title; + } + } + return undefined; + }; + LayerModel.prototype.assembleLayout = function () { + return null; + }; + LayerModel.prototype.assembleMarks = function () { + return assembleLayerSelectionMarks(this, flatten(this.children.map(function (child) { + return child.assembleMarks(); + }))); + }; + LayerModel.prototype.assembleLegends = function () { + return this.children.reduce(function (legends, child) { + return legends.concat(child.assembleLegends()); + }, assembleLegends(this)); + }; + return LayerModel; +}(Model)); +export { LayerModel }; +//# sourceMappingURL=layer.js.map \ No newline at end of file diff --git a/build/src/compile/layer.js.map b/build/src/compile/layer.js.map new file mode 100644 index 0000000000..b07c0a0a99 --- /dev/null +++ b/build/src/compile/layer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"layer.js","sourceRoot":"","sources":["../../../src/compile/layer.ts"],"names":[],"mappings":"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","sourcesContent":["import {Config} from '../config';\nimport * as log from '../log';\nimport {isLayerSpec, isUnitSpec, LayoutSizeMixins, NormalizedLayerSpec} from '../spec';\nimport {flatten, keys} from '../util';\nimport {VgData, VgLayout, VgLegend, VgSignal, VgTitle} from '../vega.schema';\nimport {parseLayerAxis} from './axis/parse';\nimport {parseData} from './data/parse';\nimport {assembleLayoutSignals} from './layoutsize/assemble';\nimport {parseLayerLayoutSize} from './layoutsize/parse';\nimport {assembleLegends} from './legend/assemble';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\nimport {assembleLayerSelectionMarks} from './selection/selection';\nimport {UnitModel} from './unit';\n\n\nexport class LayerModel extends Model {\n public readonly type: 'layer' = 'layer';\n\n // HACK: This should be (LayerModel | UnitModel)[], but setting the correct type leads to weird error.\n // So I'm just putting generic Model for now.\n public readonly children: Model[];\n\n\n\n constructor(spec: NormalizedLayerSpec, parent: Model, parentGivenName: string,\n parentGivenSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean) {\n\n super(spec, parent, parentGivenName, config, repeater, spec.resolve);\n\n const layoutSize = {\n ...parentGivenSize,\n ...(spec.width ? {width: spec.width} : {}),\n ...(spec.height ? {height: spec.height} : {})\n };\n\n this.initSize(layoutSize);\n\n this.children = spec.layer.map((layer, i) => {\n if (isLayerSpec(layer)) {\n return new LayerModel(layer, this, this.getName('layer_'+i), layoutSize, repeater, config, fit);\n }\n\n if (isUnitSpec(layer)) {\n return new UnitModel(layer, this, this.getName('layer_'+i), layoutSize, repeater, config, fit);\n }\n\n throw new Error(log.message.INVALID_SPEC);\n });\n }\n\n public parseData() {\n this.component.data = parseData(this);\n for (const child of this.children) {\n child.parseData();\n }\n }\n\n public parseLayoutSize() {\n parseLayerLayoutSize(this);\n }\n\n public parseSelection() {\n // Merge selections up the hierarchy so that they may be referenced\n // across unit specs. Persist their definitions within each child\n // to assemble signals which remain within output Vega unit groups.\n this.component.selection = {};\n for (const child of this.children) {\n child.parseSelection();\n keys(child.component.selection).forEach((key) => {\n this.component.selection[key] = child.component.selection[key];\n });\n }\n }\n\n public parseMarkGroup() {\n for (const child of this.children) {\n child.parseMarkGroup();\n }\n }\n\n public parseAxisAndHeader() {\n parseLayerAxis(this);\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return this.children.reduce((sg, child) => child.assembleSelectionTopLevelSignals(sg), signals);\n }\n\n // TODO: Support same named selections across children.\n public assembleSelectionSignals(): VgSignal[] {\n return this.children.reduce((signals, child) => {\n return signals.concat(child.assembleSelectionSignals());\n }, []);\n }\n\n\n public assembleLayoutSignals(): VgSignal[] {\n return this.children.reduce((signals, child) => {\n return signals.concat(child.assembleLayoutSignals());\n }, assembleLayoutSignals(this));\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return this.children.reduce((db, child) => child.assembleSelectionData(db), data);\n }\n\n public assembleTitle(): VgTitle {\n let title = super.assembleTitle();\n if (title) {\n return title;\n }\n // If title does not provide layer, look into children\n for (const child of this.children) {\n title = child.assembleTitle();\n if (title) {\n return title;\n }\n }\n return undefined;\n }\n\n public assembleLayout(): VgLayout {\n return null;\n }\n\n public assembleMarks(): any[] {\n return assembleLayerSelectionMarks(this, flatten(this.children.map((child) => {\n return child.assembleMarks();\n })));\n }\n\n public assembleLegends(): VgLegend[] {\n return this.children.reduce((legends, child) => {\n return legends.concat(child.assembleLegends());\n }, assembleLegends(this));\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/layout/header.d.ts b/build/src/compile/layout/header.d.ts new file mode 100644 index 0000000000..ffe6b03d33 --- /dev/null +++ b/build/src/compile/layout/header.d.ts @@ -0,0 +1,87 @@ +/** + * Utility for generating row / column headers + */ +import { FacetFieldDef } from '../../facet'; +import { AxisOrient, VgAxis, VgMarkGroup } from '../../vega.schema'; +import { Model } from '../model'; +export declare type HeaderChannel = 'row' | 'column'; +export declare const HEADER_CHANNELS: HeaderChannel[]; +export declare type HeaderType = 'header' | 'footer'; +export declare const HEADER_TYPES: HeaderType[]; +/** + * A component that represents all header, footers and title of a Vega group with layout directive. + */ +export interface LayoutHeaderComponent { + title?: string; + facetFieldDef?: FacetFieldDef; + /** + * An array of header components for headers. + * For facet, there should be only one header component, which is data-driven. + * For repeat and concat, there can be multiple header components that explicitly list different axes. + */ + header?: HeaderComponent[]; + /** + * An array of header components for footers. + * For facet, there should be only one header component, which is data-driven. + * For repeat and concat, there can be multiple header components that explicitly list different axes. + */ + footer?: HeaderComponent[]; +} +/** + * A component that represents one group of row/column-header/footer. + */ +export interface HeaderComponent { + labels: boolean; + sizeSignal: { + signal: string; + }; + axes: VgAxis[]; +} +export declare function getHeaderType(orient: AxisOrient): "header" | "footer"; +export declare function getTitleGroup(model: Model, channel: HeaderChannel): { + name: string; + role: string; + type: string; + marks: ({ + encode: { + update: { + angle: { + value: number; + }; + align: { + value: string; + }; + text: { + value: string; + }; + } | { + align: { + value: string; + }; + text: { + value: string; + }; + }; + }; + type: string; + role: string; + style: string; + } | { + type: string; + role: string; + style: string; + })[]; +}; +export declare function getHeaderGroups(model: Model, channel: HeaderChannel): VgMarkGroup[]; +export declare function labelAlign(angle: number): { + align?: undefined; +} | { + align: { + value: string; + }; +}; +export declare function labelBaseline(angle: number): { + baseline: { + value: string; + }; +}; diff --git a/build/src/compile/layout/header.js b/build/src/compile/layout/header.js new file mode 100644 index 0000000000..14e3a4e5dc --- /dev/null +++ b/build/src/compile/layout/header.js @@ -0,0 +1,106 @@ +import * as tslib_1 from "tslib"; +import { vgField } from '../../fielddef'; +import { isSortField } from '../../sort'; +import { keys } from '../../util'; +import { formatSignalRef } from '../common'; +export var HEADER_CHANNELS = ['row', 'column']; +export var HEADER_TYPES = ['header', 'footer']; +export function getHeaderType(orient) { + if (orient === 'top' || orient === 'left') { + return 'header'; + } + return 'footer'; +} +export function getTitleGroup(model, channel) { + var title = model.component.layoutHeaders[channel].title; + var textOrient = channel === 'row' ? 'vertical' : undefined; + var update = tslib_1.__assign({ align: { value: 'center' }, text: { value: title } }, (textOrient === 'vertical' ? { angle: { value: 270 } } : {})); + return { + name: model.getName(channel + "_title"), + role: channel + "-title", + type: 'group', + marks: [tslib_1.__assign({ type: 'text', role: channel + "-title-text", style: 'guide-title' }, (keys(update).length > 0 ? { encode: { update: update } } : {}))] + }; +} +export function getHeaderGroups(model, channel) { + var layoutHeader = model.component.layoutHeaders[channel]; + var groups = []; + for (var _i = 0, HEADER_TYPES_1 = HEADER_TYPES; _i < HEADER_TYPES_1.length; _i++) { + var headerType = HEADER_TYPES_1[_i]; + if (layoutHeader[headerType]) { + for (var _a = 0, _b = layoutHeader[headerType]; _a < _b.length; _a++) { + var headerCmpt = _b[_a]; + groups.push(getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt)); + } + } + } + return groups; +} +// 0, (0,90), 90, (90, 180), 180, (180, 270), 270, (270, 0) +export function labelAlign(angle) { + // to keep angle in [0, 360) + angle = ((angle % 360) + 360) % 360; + if ((angle + 90) % 180 === 0) { // for 90 and 270 + return {}; // default center + } + else if (angle < 90 || 270 < angle) { + return { align: { value: 'right' } }; + } + else if (135 <= angle && angle < 225) { + return { align: { value: 'left' } }; + } + return {}; +} +export function labelBaseline(angle) { + // to keep angle in [0, 360) + angle = ((angle % 360) + 360) % 360; + if (45 <= angle && angle <= 135) { + return { baseline: { value: 'top' } }; + } + return { baseline: { value: 'middle' } }; +} +function getSort(facetFieldDef) { + var sort = facetFieldDef.sort; + if (isSortField(sort)) { + return { + field: vgField(sort, { expr: 'datum' }), + order: sort.order || 'ascending' + }; + } + else { + return { + field: vgField(facetFieldDef, { expr: 'datum' }), + order: sort || 'ascending' + }; + } +} +function getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt) { + var _a; + if (headerCmpt) { + var title = null; + var facetFieldDef = layoutHeader.facetFieldDef; + if (facetFieldDef && headerCmpt.labels) { + var _b = facetFieldDef.header, header = _b === void 0 ? {} : _b; + var format = header.format, labelAngle = header.labelAngle; + var update = tslib_1.__assign({}, (labelAngle !== undefined ? { angle: { value: labelAngle } } : {}), labelAlign(labelAngle), labelBaseline(labelAngle)); + title = tslib_1.__assign({ text: formatSignalRef(facetFieldDef, format, 'parent', model.config), offset: 10, orient: channel === 'row' ? 'left' : 'top', style: 'guide-label' }, (keys(update).length > 0 ? { encode: { update: update } } : {})); + } + var axes = headerCmpt.axes; + var hasAxes = axes && axes.length > 0; + if (title || hasAxes) { + var sizeChannel = channel === 'row' ? 'height' : 'width'; + return tslib_1.__assign({ name: model.getName(channel + "_" + headerType), type: 'group', role: channel + "-" + headerType }, (layoutHeader.facetFieldDef ? { + from: { data: model.getName(channel + '_domain') }, + sort: getSort(facetFieldDef) + } : {}), (title ? { title: title } : {}), (headerCmpt.sizeSignal ? { + encode: { + update: (_a = {}, + _a[sizeChannel] = headerCmpt.sizeSignal, + _a) + } + } : {}), (hasAxes ? { axes: axes } : {})); + } + } + return null; +} +//# sourceMappingURL=header.js.map \ No newline at end of file diff --git a/build/src/compile/layout/header.js.map b/build/src/compile/layout/header.js.map new file mode 100644 index 0000000000..5a2150e6bc --- /dev/null +++ b/build/src/compile/layout/header.js.map @@ -0,0 +1 @@ +{"version":3,"file":"header.js","sourceRoot":"","sources":["../../../../src/compile/layout/header.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Utility for generating row / column headers\n */\nimport {FacetFieldDef} from '../../facet';\nimport {vgField} from '../../fielddef';\nimport {isSortField} from '../../sort';\nimport {keys} from '../../util';\nimport {AxisOrient, VgAxis, VgComparator, VgMarkGroup} from '../../vega.schema';\nimport {formatSignalRef} from '../common';\nimport {Model} from '../model';\n\nexport type HeaderChannel = 'row' | 'column';\nexport const HEADER_CHANNELS: HeaderChannel[] = ['row', 'column'];\n\nexport type HeaderType = 'header' | 'footer';\nexport const HEADER_TYPES: HeaderType[] = ['header', 'footer'];\n\n/**\n * A component that represents all header, footers and title of a Vega group with layout directive.\n */\nexport interface LayoutHeaderComponent {\n title?: string;\n\n // TODO: repeat and concat can have multiple header / footer.\n // Need to redesign this part a bit.\n\n facetFieldDef?: FacetFieldDef;\n\n /**\n * An array of header components for headers.\n * For facet, there should be only one header component, which is data-driven.\n * For repeat and concat, there can be multiple header components that explicitly list different axes.\n */\n header?: HeaderComponent[];\n\n /**\n * An array of header components for footers.\n * For facet, there should be only one header component, which is data-driven.\n * For repeat and concat, there can be multiple header components that explicitly list different axes.\n */\n footer?: HeaderComponent[];\n}\n\n/**\n * A component that represents one group of row/column-header/footer.\n */\nexport interface HeaderComponent {\n\n labels: boolean;\n\n sizeSignal: {signal: string};\n\n axes: VgAxis[];\n}\n\nexport function getHeaderType(orient: AxisOrient) {\n if (orient === 'top' || orient === 'left') {\n return 'header';\n }\n return 'footer';\n}\n\nexport function getTitleGroup(model: Model, channel: HeaderChannel) {\n const title = model.component.layoutHeaders[channel].title;\n const textOrient = channel === 'row' ? 'vertical' : undefined;\n\n const update = {\n align: {value: 'center'},\n text: {value: title},\n ...(textOrient === 'vertical' ? {angle: {value: 270}}: {}),\n // TODO*https://github.com/vega/vega-lite/issues/2446): add title* properties (e.g., titleAlign)\n // also make sure that guide-title config override these Vega-lite default\n };\n\n return {\n name: model.getName(`${channel}_title`),\n role: `${channel}-title`,\n type: 'group',\n marks: [{\n type: 'text',\n role: `${channel}-title-text`,\n style: 'guide-title',\n ...(keys(update).length > 0 ? {encode: {update}} : {})\n }]\n };\n}\n\nexport function getHeaderGroups(model: Model, channel: HeaderChannel): VgMarkGroup[] {\n const layoutHeader = model.component.layoutHeaders[channel];\n const groups = [];\n for (const headerType of HEADER_TYPES) {\n if (layoutHeader[headerType]) {\n for (const headerCmpt of layoutHeader[headerType]) {\n groups.push(getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt));\n }\n }\n }\n return groups;\n}\n\n// 0, (0,90), 90, (90, 180), 180, (180, 270), 270, (270, 0)\n\nexport function labelAlign(angle: number) {\n // to keep angle in [0, 360)\n angle = ((angle % 360) + 360) % 360;\n if ((angle + 90) % 180 === 0) { // for 90 and 270\n return {}; // default center\n } else if (angle < 90 || 270 < angle) {\n return {align: {value: 'right'}};\n } else if (135 <= angle && angle < 225) {\n return {align: {value: 'left'}};\n }\n return {};\n}\n\nexport function labelBaseline(angle: number) {\n // to keep angle in [0, 360)\n angle = ((angle % 360) + 360) % 360;\n if (45 <= angle && angle <= 135) {\n return {baseline: {value: 'top'}};\n }\n return {baseline: {value: 'middle'}};\n}\n\nfunction getSort(facetFieldDef: FacetFieldDef): VgComparator {\n const {sort} = facetFieldDef;\n if (isSortField(sort)) {\n return {\n field: vgField(sort, {expr: 'datum'}),\n order: sort.order || 'ascending'\n };\n } else {\n return {\n field: vgField(facetFieldDef, {expr: 'datum'}),\n order: sort || 'ascending'\n };\n }\n}\n\nfunction getHeaderGroup(model: Model, channel: HeaderChannel, headerType: HeaderType, layoutHeader: LayoutHeaderComponent, headerCmpt: HeaderComponent) {\n if (headerCmpt) {\n let title = null;\n const {facetFieldDef} = layoutHeader;\n if (facetFieldDef && headerCmpt.labels) {\n const {header = {}} = facetFieldDef;\n const {format, labelAngle} = header;\n\n const update = {\n ...(\n labelAngle !== undefined ? {angle: {value: labelAngle}} : {}\n ),\n ...labelAlign(labelAngle),\n ...labelBaseline(labelAngle)\n\n };\n\n title = {\n text: formatSignalRef(facetFieldDef, format, 'parent', model.config),\n offset: 10,\n orient: channel === 'row' ? 'left' : 'top',\n style: 'guide-label',\n ...(keys(update).length > 0 ? {encode: {update}} : {})\n };\n }\n\n const axes = headerCmpt.axes;\n\n const hasAxes = axes && axes.length > 0;\n if (title || hasAxes) {\n const sizeChannel = channel === 'row' ? 'height' : 'width';\n\n\n\n return {\n name: model.getName(`${channel}_${headerType}`),\n type: 'group',\n role: `${channel}-${headerType}`,\n ...(layoutHeader.facetFieldDef ? {\n from: {data: model.getName(channel + '_domain')},\n sort: getSort(facetFieldDef)\n } : {}),\n ...(title ? {title} : {}),\n ...(headerCmpt.sizeSignal ? {\n encode: {\n update: {\n [sizeChannel]: headerCmpt.sizeSignal\n }\n }\n }: {}),\n ...(hasAxes ? {axes} : {})\n };\n }\n }\n return null;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/layoutsize/assemble.d.ts b/build/src/compile/layoutsize/assemble.d.ts new file mode 100644 index 0000000000..45fa2eedcb --- /dev/null +++ b/build/src/compile/layoutsize/assemble.d.ts @@ -0,0 +1,6 @@ +import { VgSignal } from '../../vega.schema'; +import { Model } from '../model'; +import { ScaleComponent } from '../scale/component'; +export declare function assembleLayoutSignals(model: Model): VgSignal[]; +export declare function sizeSignals(model: Model, sizeType: 'width' | 'height'): VgSignal[]; +export declare function sizeExpr(scaleName: string, scaleComponent: ScaleComponent, cardinality: string): string; diff --git a/build/src/compile/layoutsize/assemble.js b/build/src/compile/layoutsize/assemble.js new file mode 100644 index 0000000000..5d9789ee42 --- /dev/null +++ b/build/src/compile/layoutsize/assemble.js @@ -0,0 +1,70 @@ +import { hasDiscreteDomain } from '../../scale'; +import { isVgRangeStep } from '../../vega.schema'; +import { isFacetModel } from '../model'; +export function assembleLayoutSignals(model) { + return [].concat(sizeSignals(model, 'width'), sizeSignals(model, 'height')); +} +export function sizeSignals(model, sizeType) { + var channel = sizeType === 'width' ? 'x' : 'y'; + var size = model.component.layoutSize.get(sizeType); + if (!size || size === 'merged') { + return []; + } + // Read size signal name from name map, just in case it is the top-level size signal that got renamed. + var name = model.getSizeSignalRef(sizeType).signal; + if (size === 'range-step') { + var scaleComponent = model.getScaleComponent(channel); + if (scaleComponent) { + var type = scaleComponent.get('type'); + var range = scaleComponent.get('range'); + if (hasDiscreteDomain(type) && isVgRangeStep(range)) { + var scaleName = model.scaleName(channel); + if (isFacetModel(model.parent)) { + // If parent is facet and this is an independent scale, return only signal signal + // as the width/height will be calculated using the cardinality from + // facet's aggregate rather than reading from scale domain + var parentResolve = model.parent.component.resolve; + if (parentResolve.scale[channel] === 'independent') { + return [stepSignal(scaleName, range)]; + } + } + return [ + stepSignal(scaleName, range), + { + name: name, + update: sizeExpr(scaleName, scaleComponent, "domain('" + scaleName + "').length") + } + ]; + } + } + /* istanbul ignore next: Condition should not happen -- only for warning in development. */ + throw new Error('layout size is range step although there is no rangeStep.'); + } + else { + return [{ + name: name, + value: size + }]; + } +} +function stepSignal(scaleName, range) { + return { + name: scaleName + '_step', + value: range.step, + }; +} +export function sizeExpr(scaleName, scaleComponent, cardinality) { + var type = scaleComponent.get('type'); + var padding = scaleComponent.get('padding'); + var paddingOuter = scaleComponent.get('paddingOuter'); + paddingOuter = paddingOuter !== undefined ? paddingOuter : padding; + var paddingInner = scaleComponent.get('paddingInner'); + paddingInner = type === 'band' ? + // only band has real paddingInner + (paddingInner !== undefined ? paddingInner : padding) : + // For point, as calculated in https://github.com/vega/vega-scale/blob/master/src/band.js#L128, + // it's equivalent to have paddingInner = 1 since there is only n-1 steps between n points. + 1; + return "bandspace(" + cardinality + ", " + paddingInner + ", " + paddingOuter + ") * " + scaleName + "_step"; +} +//# sourceMappingURL=assemble.js.map \ No newline at end of file diff --git a/build/src/compile/layoutsize/assemble.js.map b/build/src/compile/layoutsize/assemble.js.map new file mode 100644 index 0000000000..eccd19e58a --- /dev/null +++ b/build/src/compile/layoutsize/assemble.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../../../src/compile/layoutsize/assemble.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport {hasDiscreteDomain} from '../../scale';\nimport {isVgRangeStep, VgRangeStep, VgSignal} from '../../vega.schema';\nimport {isFacetModel, Model} from '../model';\nimport {ScaleComponent} from '../scale/component';\n\nexport function assembleLayoutSignals(model: Model): VgSignal[] {\n return [].concat(\n sizeSignals(model, 'width'),\n sizeSignals(model, 'height')\n );\n}\n\nexport function sizeSignals(model: Model, sizeType: 'width' | 'height'): VgSignal[] {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const size = model.component.layoutSize.get(sizeType);\n if (!size || size === 'merged') {\n return [];\n }\n\n // Read size signal name from name map, just in case it is the top-level size signal that got renamed.\n const name = model.getSizeSignalRef(sizeType).signal;\n\n if (size === 'range-step') {\n const scaleComponent = model.getScaleComponent(channel);\n\n if (scaleComponent) {\n const type = scaleComponent.get('type');\n const range = scaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const scaleName = model.scaleName(channel);\n\n if (isFacetModel(model.parent)) {\n // If parent is facet and this is an independent scale, return only signal signal\n // as the width/height will be calculated using the cardinality from\n // facet's aggregate rather than reading from scale domain\n const parentResolve = model.parent.component.resolve;\n if (parentResolve.scale[channel] === 'independent') {\n return [stepSignal(scaleName, range)];\n }\n }\n\n return [\n stepSignal(scaleName, range),\n {\n name,\n update: sizeExpr(scaleName, scaleComponent, `domain('${scaleName}').length`)\n }\n ];\n }\n }\n /* istanbul ignore next: Condition should not happen -- only for warning in development. */\n throw new Error('layout size is range step although there is no rangeStep.');\n } else {\n return [{\n name,\n value: size\n }];\n }\n}\n\nfunction stepSignal(scaleName: string, range: VgRangeStep): VgSignal {\n return {\n name: scaleName + '_step',\n value: range.step,\n };\n}\n\nexport function sizeExpr(scaleName: string, scaleComponent: ScaleComponent, cardinality: string) {\n const type = scaleComponent.get('type');\n const padding = scaleComponent.get('padding');\n let paddingOuter = scaleComponent.get('paddingOuter');\n paddingOuter = paddingOuter !== undefined ? paddingOuter : padding;\n\n let paddingInner = scaleComponent.get('paddingInner');\n paddingInner = type === 'band' ?\n // only band has real paddingInner\n (paddingInner !== undefined ? paddingInner : padding) :\n // For point, as calculated in https://github.com/vega/vega-scale/blob/master/src/band.js#L128,\n // it's equivalent to have paddingInner = 1 since there is only n-1 steps between n points.\n 1;\n return `bandspace(${cardinality}, ${paddingInner}, ${paddingOuter}) * ${scaleName}_step`;\n}\n\n\n"]} \ No newline at end of file diff --git a/build/src/compile/layoutsize/component.d.ts b/build/src/compile/layoutsize/component.d.ts new file mode 100644 index 0000000000..eaeae294ec --- /dev/null +++ b/build/src/compile/layoutsize/component.d.ts @@ -0,0 +1,7 @@ +import { Split } from '../split'; +export declare type LayoutSize = number | 'range-step' | 'merged'; +export interface LayoutSizeIndex { + width?: LayoutSize; + height?: LayoutSize; +} +export declare type LayoutSizeComponent = Split; diff --git a/build/src/compile/layoutsize/component.js b/build/src/compile/layoutsize/component.js new file mode 100644 index 0000000000..c2cf809143 --- /dev/null +++ b/build/src/compile/layoutsize/component.js @@ -0,0 +1 @@ +//# sourceMappingURL=component.js.map \ No newline at end of file diff --git a/build/src/compile/layoutsize/component.js.map b/build/src/compile/layoutsize/component.js.map new file mode 100644 index 0000000000..8df0cd019d --- /dev/null +++ b/build/src/compile/layoutsize/component.js.map @@ -0,0 +1 @@ +{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../src/compile/layoutsize/component.ts"],"names":[],"mappings":"","sourcesContent":["import {Split} from '../split';\n\nexport type LayoutSize = number | 'range-step' | 'merged';\n\nexport interface LayoutSizeIndex {\n width?: LayoutSize;\n height?: LayoutSize;\n}\n\nexport type LayoutSizeComponent = Split;\n"]} \ No newline at end of file diff --git a/build/src/compile/layoutsize/parse.d.ts b/build/src/compile/layoutsize/parse.d.ts new file mode 100644 index 0000000000..59db26ea9e --- /dev/null +++ b/build/src/compile/layoutsize/parse.d.ts @@ -0,0 +1,8 @@ +import { ConcatModel } from '../concat'; +import { Model } from '../model'; +import { UnitModel } from '../unit'; +export declare function parseLayerLayoutSize(model: Model): void; +export declare const parseRepeatLayoutSize: typeof parseLayerLayoutSize; +export declare function parseConcatLayoutSize(model: ConcatModel): void; +export declare function parseChildrenLayoutSize(model: Model): void; +export declare function parseUnitLayoutSize(model: UnitModel): void; diff --git a/build/src/compile/layoutsize/parse.js b/build/src/compile/layoutsize/parse.js new file mode 100644 index 0000000000..ad27ea27dc --- /dev/null +++ b/build/src/compile/layoutsize/parse.js @@ -0,0 +1,107 @@ +import { defaultScaleConfig, hasDiscreteDomain } from '../../scale'; +import { isVgRangeStep } from '../../vega.schema'; +import { mergeValuesWithExplicit } from '../split'; +export function parseLayerLayoutSize(model) { + parseChildrenLayoutSize(model); + var layoutSizeCmpt = model.component.layoutSize; + layoutSizeCmpt.setWithExplicit('width', parseNonUnitLayoutSizeForChannel(model, 'width')); + layoutSizeCmpt.setWithExplicit('height', parseNonUnitLayoutSizeForChannel(model, 'height')); +} +export var parseRepeatLayoutSize = parseLayerLayoutSize; +export function parseConcatLayoutSize(model) { + parseChildrenLayoutSize(model); + var layoutSizeCmpt = model.component.layoutSize; + var sizeTypeToMerge = model.isVConcat ? 'width' : 'height'; + layoutSizeCmpt.setWithExplicit(sizeTypeToMerge, parseNonUnitLayoutSizeForChannel(model, sizeTypeToMerge)); +} +export function parseChildrenLayoutSize(model) { + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseLayoutSize(); + } +} +function parseNonUnitLayoutSizeForChannel(model, sizeType) { + var channel = sizeType === 'width' ? 'x' : 'y'; + var resolve = model.component.resolve; + var mergedSize; + // Try to merge layout size + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + var childSize = child.component.layoutSize.getWithExplicit(sizeType); + var scaleResolve = resolve.scale[channel]; + if (scaleResolve === 'independent' && childSize.value === 'range-step') { + // Do not merge independent scales with range-step as their size depends + // on the scale domains, which can be different between scales. + mergedSize = undefined; + break; + } + if (mergedSize) { + if (scaleResolve === 'independent' && mergedSize.value !== childSize.value) { + // For independent scale, only merge if all the sizes are the same. + // If the values are different, abandon the merge! + mergedSize = undefined; + break; + } + mergedSize = mergeValuesWithExplicit(mergedSize, childSize, sizeType, ''); + } + else { + mergedSize = childSize; + } + } + if (mergedSize) { + // If merged, rename size and set size of all children. + for (var _b = 0, _c = model.children; _b < _c.length; _b++) { + var child = _c[_b]; + model.renameLayoutSize(child.getName(sizeType), model.getName(sizeType)); + child.component.layoutSize.set(sizeType, 'merged', false); + } + return mergedSize; + } + else { + // Otherwise, there is no merged size. + return { + explicit: false, + value: undefined + }; + } +} +export function parseUnitLayoutSize(model) { + var layoutSizeComponent = model.component.layoutSize; + if (!layoutSizeComponent.explicit.width) { + var width = defaultUnitSize(model, 'width'); + layoutSizeComponent.set('width', width, false); + } + if (!layoutSizeComponent.explicit.height) { + var height = defaultUnitSize(model, 'height'); + layoutSizeComponent.set('height', height, false); + } +} +function defaultUnitSize(model, sizeType) { + var channel = sizeType === 'width' ? 'x' : 'y'; + var config = model.config; + var scaleComponent = model.getScaleComponent(channel); + if (scaleComponent) { + var scaleType = scaleComponent.get('type'); + var range = scaleComponent.get('range'); + if (hasDiscreteDomain(scaleType) && isVgRangeStep(range)) { + // For discrete domain with range.step, use dynamic width/height + return 'range-step'; + } + else { + return config.view[sizeType]; + } + } + else if (model.hasProjection) { + return config.view[sizeType]; + } + else { + // No scale - set default size + if (sizeType === 'width' && model.mark === 'text') { + // width for text mark without x-field is a bit wider than typical range step + return config.scale.textXRangeStep; + } + // Set width/height equal to rangeStep config or if rangeStep is null, use value from default scale config. + return config.scale.rangeStep || defaultScaleConfig.rangeStep; + } +} +//# sourceMappingURL=parse.js.map \ No newline at end of file diff --git a/build/src/compile/layoutsize/parse.js.map b/build/src/compile/layoutsize/parse.js.map new file mode 100644 index 0000000000..f748d5c066 --- /dev/null +++ b/build/src/compile/layoutsize/parse.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../src/compile/layoutsize/parse.ts"],"names":[],"mappings":"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","sourcesContent":["import {defaultScaleConfig, hasDiscreteDomain} from '../../scale';\nimport {isVgRangeStep} from '../../vega.schema';\nimport {ConcatModel} from '../concat';\nimport {Model} from '../model';\nimport {Explicit, mergeValuesWithExplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {LayoutSize, LayoutSizeIndex} from './component';\n\nexport function parseLayerLayoutSize(model: Model) {\n parseChildrenLayoutSize(model);\n\n const layoutSizeCmpt = model.component.layoutSize;\n layoutSizeCmpt.setWithExplicit('width', parseNonUnitLayoutSizeForChannel(model, 'width'));\n layoutSizeCmpt.setWithExplicit('height', parseNonUnitLayoutSizeForChannel(model, 'height'));\n}\n\nexport const parseRepeatLayoutSize = parseLayerLayoutSize;\n\nexport function parseConcatLayoutSize(model: ConcatModel) {\n parseChildrenLayoutSize(model);\n const layoutSizeCmpt = model.component.layoutSize;\n\n const sizeTypeToMerge = model.isVConcat ? 'width' : 'height';\n layoutSizeCmpt.setWithExplicit(sizeTypeToMerge, parseNonUnitLayoutSizeForChannel(model, sizeTypeToMerge));\n}\n\nexport function parseChildrenLayoutSize(model: Model) {\n for (const child of model.children) {\n child.parseLayoutSize();\n }\n}\n\nfunction parseNonUnitLayoutSizeForChannel(model: Model, sizeType: 'width' | 'height'): Explicit {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const resolve = model.component.resolve;\n\n let mergedSize: Explicit;\n // Try to merge layout size\n for (const child of model.children) {\n const childSize = child.component.layoutSize.getWithExplicit(sizeType);\n const scaleResolve = resolve.scale[channel];\n if (scaleResolve === 'independent' && childSize.value === 'range-step') {\n // Do not merge independent scales with range-step as their size depends\n // on the scale domains, which can be different between scales.\n mergedSize = undefined;\n break;\n }\n\n if (mergedSize) {\n if (scaleResolve === 'independent' && mergedSize.value !== childSize.value) {\n // For independent scale, only merge if all the sizes are the same.\n // If the values are different, abandon the merge!\n mergedSize = undefined;\n break;\n }\n mergedSize = mergeValuesWithExplicit(\n mergedSize, childSize, sizeType, ''\n );\n } else {\n mergedSize = childSize;\n }\n }\n\n if (mergedSize) {\n // If merged, rename size and set size of all children.\n for (const child of model.children) {\n model.renameLayoutSize(child.getName(sizeType), model.getName(sizeType));\n child.component.layoutSize.set(sizeType, 'merged', false);\n }\n return mergedSize;\n } else {\n // Otherwise, there is no merged size.\n return {\n explicit: false,\n value: undefined\n };\n }\n}\n\nexport function parseUnitLayoutSize(model: UnitModel) {\n const layoutSizeComponent = model.component.layoutSize;\n if (!layoutSizeComponent.explicit.width) {\n const width = defaultUnitSize(model, 'width');\n layoutSizeComponent.set('width', width, false);\n }\n\n if (!layoutSizeComponent.explicit.height) {\n const height = defaultUnitSize(model, 'height');\n layoutSizeComponent.set('height', height, false);\n }\n}\n\nfunction defaultUnitSize(model: UnitModel, sizeType: 'width' | 'height'): LayoutSize {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const config = model.config;\n const scaleComponent = model.getScaleComponent(channel);\n\n if (scaleComponent) {\n const scaleType = scaleComponent.get('type');\n const range = scaleComponent.get('range');\n\n if (hasDiscreteDomain(scaleType) && isVgRangeStep(range)) {\n // For discrete domain with range.step, use dynamic width/height\n return 'range-step';\n } else {\n return config.view[sizeType];\n }\n } else if (model.hasProjection) {\n return config.view[sizeType];\n } else {\n // No scale - set default size\n if (sizeType === 'width' && model.mark === 'text') {\n // width for text mark without x-field is a bit wider than typical range step\n return config.scale.textXRangeStep;\n }\n\n // Set width/height equal to rangeStep config or if rangeStep is null, use value from default scale config.\n return config.scale.rangeStep || defaultScaleConfig.rangeStep;\n }\n\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/legend/assemble.d.ts b/build/src/compile/legend/assemble.d.ts new file mode 100644 index 0000000000..8da565fcf9 --- /dev/null +++ b/build/src/compile/legend/assemble.d.ts @@ -0,0 +1,3 @@ +import { VgLegend } from '../../vega.schema'; +import { Model } from '../model'; +export declare function assembleLegends(model: Model): VgLegend[]; diff --git a/build/src/compile/legend/assemble.js b/build/src/compile/legend/assemble.js new file mode 100644 index 0000000000..ea8af9689f --- /dev/null +++ b/build/src/compile/legend/assemble.js @@ -0,0 +1,26 @@ +import { flatten, keys, stringify, vals } from '../../util'; +import { mergeLegendComponent } from './parse'; +export function assembleLegends(model) { + var legendComponentIndex = model.component.legends; + var legendByDomain = {}; + for (var _i = 0, _a = keys(legendComponentIndex); _i < _a.length; _i++) { + var channel = _a[_i]; + var scaleComponent = model.getScaleComponent(channel); + var domainHash = stringify(scaleComponent.domains); + if (legendByDomain[domainHash]) { + for (var _b = 0, _c = legendByDomain[domainHash]; _b < _c.length; _b++) { + var mergedLegendComponent = _c[_b]; + var merged = mergeLegendComponent(mergedLegendComponent, legendComponentIndex[channel]); + if (!merged) { + // If cannot merge, need to add this legend separately + legendByDomain[domainHash].push(legendComponentIndex[channel]); + } + } + } + else { + legendByDomain[domainHash] = [legendComponentIndex[channel].clone()]; + } + } + return flatten(vals(legendByDomain)).map(function (legendCmpt) { return legendCmpt.combine(); }); +} +//# sourceMappingURL=assemble.js.map \ No newline at end of file diff --git a/build/src/compile/legend/assemble.js.map b/build/src/compile/legend/assemble.js.map new file mode 100644 index 0000000000..7b9100c078 --- /dev/null +++ b/build/src/compile/legend/assemble.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../../../src/compile/legend/assemble.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAC,MAAM,YAAY,CAAC;AAI1D,OAAO,EAAC,oBAAoB,EAAC,MAAM,SAAS,CAAC;AAE7C,MAAM,0BAA0B,KAAY;IAC1C,IAAM,oBAAoB,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC;IACrD,IAAM,cAAc,GAA8C,EAAE,CAAC;IAErE,KAAsB,UAA0B,EAA1B,KAAA,IAAI,CAAC,oBAAoB,CAAC,EAA1B,cAA0B,EAA1B,IAA0B,EAAE;QAA7C,IAAM,OAAO,SAAA;QAChB,IAAM,cAAc,GAAG,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACxD,IAAM,UAAU,GAAG,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,cAAc,CAAC,UAAU,CAAC,EAAE;YAC9B,KAAoC,UAA0B,EAA1B,KAAA,cAAc,CAAC,UAAU,CAAC,EAA1B,cAA0B,EAA1B,IAA0B,EAAE;gBAA3D,IAAM,qBAAqB,SAAA;gBAC9B,IAAM,MAAM,GAAG,oBAAoB,CAAC,qBAAqB,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC1F,IAAI,CAAC,MAAM,EAAE;oBACX,sDAAsD;oBACtD,cAAc,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;iBAChE;aACF;SAEF;aAAM;YACL,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;SACtE;KACF;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,UAAC,UAA2B,IAAK,OAAA,UAAU,CAAC,OAAO,EAAE,EAApB,CAAoB,CAAC,CAAC;AAClG,CAAC","sourcesContent":["import {flatten, keys, stringify, vals} from '../../util';\nimport {VgLegend} from '../../vega.schema';\nimport {Model} from '../model';\nimport {LegendComponent} from './component';\nimport {mergeLegendComponent} from './parse';\n\nexport function assembleLegends(model: Model): VgLegend[] {\n const legendComponentIndex = model.component.legends;\n const legendByDomain: {[domainHash: string]: LegendComponent[]} = {};\n\n for (const channel of keys(legendComponentIndex)) {\n const scaleComponent = model.getScaleComponent(channel);\n const domainHash = stringify(scaleComponent.domains);\n if (legendByDomain[domainHash]) {\n for (const mergedLegendComponent of legendByDomain[domainHash]) {\n const merged = mergeLegendComponent(mergedLegendComponent, legendComponentIndex[channel]);\n if (!merged) {\n // If cannot merge, need to add this legend separately\n legendByDomain[domainHash].push(legendComponentIndex[channel]);\n }\n }\n\n } else {\n legendByDomain[domainHash] = [legendComponentIndex[channel].clone()];\n }\n }\n\n return flatten(vals(legendByDomain)).map((legendCmpt: LegendComponent) => legendCmpt.combine());\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/legend/component.d.ts b/build/src/compile/legend/component.d.ts new file mode 100644 index 0000000000..dece1d8075 --- /dev/null +++ b/build/src/compile/legend/component.d.ts @@ -0,0 +1,12 @@ +import { Legend } from '../..//legend'; +import { NonPositionScaleChannel } from '../../channel'; +import { VgLegend } from '../../vega.schema'; +import { Split } from '../split'; +export declare class LegendComponent extends Split { +} +export declare type LegendComponentIndex = { + [P in NonPositionScaleChannel]?: LegendComponent; +}; +export declare type LegendIndex = { + [P in NonPositionScaleChannel]?: Legend; +}; diff --git a/build/src/compile/legend/component.js b/build/src/compile/legend/component.js new file mode 100644 index 0000000000..986f7c49a1 --- /dev/null +++ b/build/src/compile/legend/component.js @@ -0,0 +1,11 @@ +import * as tslib_1 from "tslib"; +import { Split } from '../split'; +var LegendComponent = /** @class */ (function (_super) { + tslib_1.__extends(LegendComponent, _super); + function LegendComponent() { + return _super !== null && _super.apply(this, arguments) || this; + } + return LegendComponent; +}(Split)); +export { LegendComponent }; +//# sourceMappingURL=component.js.map \ No newline at end of file diff --git a/build/src/compile/legend/component.js.map b/build/src/compile/legend/component.js.map new file mode 100644 index 0000000000..0e4ab98cfe --- /dev/null +++ b/build/src/compile/legend/component.js.map @@ -0,0 +1 @@ +{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../src/compile/legend/component.ts"],"names":[],"mappings":";AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,UAAU,CAAC;AAG/B;IAAqC,2CAAe;IAApD;;IAAsD,CAAC;IAAD,sBAAC;AAAD,CAAC,AAAvD,CAAqC,KAAK,GAAa","sourcesContent":["import {Legend} from '../..//legend';\nimport {NonPositionScaleChannel} from '../../channel';\nimport {VgLegend} from '../../vega.schema';\nimport {Split} from '../split';\n\n\nexport class LegendComponent extends Split {}\n\n// Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\nexport type LegendComponentIndex = {[P in NonPositionScaleChannel]?: LegendComponent};\n\nexport type LegendIndex = {[P in NonPositionScaleChannel]?: Legend};\n"]} \ No newline at end of file diff --git a/build/src/compile/legend/encode.d.ts b/build/src/compile/legend/encode.d.ts new file mode 100644 index 0000000000..35cd84a725 --- /dev/null +++ b/build/src/compile/legend/encode.d.ts @@ -0,0 +1,7 @@ +import { Channel, NonPositionScaleChannel } from '../../channel'; +import { FieldDef } from '../../fielddef'; +import { LegendType, VgEncodeEntry } from '../../vega.schema'; +import { UnitModel } from '../unit'; +export declare function symbols(fieldDef: FieldDef, symbolsSpec: any, model: UnitModel, channel: Channel, type: LegendType): VgEncodeEntry; +export declare function gradient(fieldDef: FieldDef, gradientSpec: any, model: UnitModel, channel: Channel, type: LegendType): any; +export declare function labels(fieldDef: FieldDef, labelsSpec: any, model: UnitModel, channel: NonPositionScaleChannel, type: LegendType): any; diff --git a/build/src/compile/legend/encode.js b/build/src/compile/legend/encode.js new file mode 100644 index 0000000000..229ab64ddb --- /dev/null +++ b/build/src/compile/legend/encode.js @@ -0,0 +1,127 @@ +import * as tslib_1 from "tslib"; +import { isArray } from 'vega-util'; +import { COLOR, OPACITY, SHAPE } from '../../channel'; +import { hasConditionalValueDef, isTimeFieldDef, isValueDef, } from '../../fielddef'; +import { AREA, BAR, CIRCLE, FILL_STROKE_CONFIG, GEOSHAPE, LINE, POINT, SQUARE, TEXT, TICK } from '../../mark'; +import { ScaleType } from '../../scale'; +import { keys } from '../../util'; +import { applyMarkConfig, timeFormatExpression } from '../common'; +import * as mixins from '../mark/mixins'; +export function symbols(fieldDef, symbolsSpec, model, channel, type) { + if (type === 'gradient') { + return undefined; + } + var out = tslib_1.__assign({}, applyMarkConfig({}, model, FILL_STROKE_CONFIG), mixins.color(model)); + switch (model.mark) { + case BAR: + case TICK: + case TEXT: + out.shape = { value: 'square' }; + break; + case CIRCLE: + case SQUARE: + out.shape = { value: model.mark }; + break; + case POINT: + case LINE: + case GEOSHAPE: + case AREA: + // use default circle + break; + } + var markDef = model.markDef, encoding = model.encoding; + var filled = markDef.filled; + if (out.fill) { + // for fill legend, we don't want any fill in symbol + if (channel === 'fill' || (filled && channel === COLOR)) { + delete out.fill; + } + else { + if (out.fill['field']) { + // For others, remove fill field + delete out.fill; + } + else if (isArray(out.fill)) { + var fill = getFirstConditionValue(encoding.fill || encoding.color) || markDef.fill || (filled && markDef.color); + if (fill) { + out.fill = { value: fill }; + } + } + } + } + if (out.stroke) { + if (channel === 'stroke' || (!filled && channel === COLOR)) { + delete out.stroke; + } + else { + if (out.stroke['field']) { + // For others, remove stroke field + delete out.stroke; + } + else if (isArray(out.stroke)) { + var stroke = getFirstConditionValue(encoding.stroke || encoding.color) || markDef.stroke || (!filled && markDef.color); + if (stroke) { + out.stroke = { value: stroke }; + } + } + } + } + if (out.fill && out.fill['value'] !== 'transparent' && !out.stroke) { + // for non color channel's legend, we need to override symbol stroke config from Vega config + out.stroke = { value: 'transparent' }; + } + if (channel !== SHAPE) { + var shape = getFirstConditionValue(encoding.shape) || markDef.shape; + if (shape) { + out.shape = { value: shape }; + } + } + if (channel !== OPACITY) { + var opacity = getMaxValue(encoding.opacity) || markDef.opacity; + if (opacity) { // only apply opacity if it is neither zero or undefined + out.opacity = { value: opacity }; + } + } + out = tslib_1.__assign({}, out, symbolsSpec); + return keys(out).length > 0 ? out : undefined; +} +export function gradient(fieldDef, gradientSpec, model, channel, type) { + var out = {}; + if (type === 'gradient') { + var opacity = getMaxValue(model.encoding.opacity) || model.markDef.opacity; + if (opacity) { // only apply opacity if it is neither zero or undefined + out.opacity = { value: opacity }; + } + } + out = tslib_1.__assign({}, out, gradientSpec); + return keys(out).length > 0 ? out : undefined; +} +export function labels(fieldDef, labelsSpec, model, channel, type) { + var legend = model.legend(channel); + var config = model.config; + var out = {}; + if (isTimeFieldDef(fieldDef)) { + var isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC; + var expr = timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat, isUTCScale); + labelsSpec = tslib_1.__assign({}, (expr ? { text: { signal: expr } } : {}), labelsSpec); + } + out = tslib_1.__assign({}, out, labelsSpec); + return keys(out).length > 0 ? out : undefined; +} +function getMaxValue(channelDef) { + return getConditionValue(channelDef, function (v, conditionalDef) { return Math.max(v, conditionalDef.value); }); +} +function getFirstConditionValue(channelDef) { + return getConditionValue(channelDef, function (v, conditionalDef) { return v !== undefined ? v : conditionalDef.value; }); +} +function getConditionValue(channelDef, reducer) { + if (hasConditionalValueDef(channelDef)) { + return (isArray(channelDef.condition) ? channelDef.condition : [channelDef.condition]) + .reduce(reducer, channelDef.value); + } + else if (isValueDef(channelDef)) { + return channelDef.value; + } + return undefined; +} +//# sourceMappingURL=encode.js.map \ No newline at end of file diff --git a/build/src/compile/legend/encode.js.map b/build/src/compile/legend/encode.js.map new file mode 100644 index 0000000000..e27921914a --- /dev/null +++ b/build/src/compile/legend/encode.js.map @@ -0,0 +1 @@ +{"version":3,"file":"encode.js","sourceRoot":"","sources":["../../../../src/compile/legend/encode.ts"],"names":[],"mappings":"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","sourcesContent":["import {isArray} from 'vega-util';\n\nimport {Channel, COLOR, NonPositionScaleChannel, OPACITY, SHAPE} from '../../channel';\nimport {\n Conditional,\n FieldDef,\n FieldDefWithCondition,\n hasConditionalValueDef,\n isTimeFieldDef,\n isValueDef,\n MarkPropFieldDef,\n ValueDef,\n ValueDefWithCondition,\n} from '../../fielddef';\nimport {AREA, BAR, CIRCLE, FILL_STROKE_CONFIG, GEOSHAPE, LINE, POINT, SQUARE, TEXT, TICK} from '../../mark';\nimport {ScaleType} from '../../scale';\nimport {keys} from '../../util';\nimport {LegendType, VgEncodeEntry} from '../../vega.schema';\nimport {applyMarkConfig, timeFormatExpression} from '../common';\nimport * as mixins from '../mark/mixins';\nimport {UnitModel} from '../unit';\n\nexport function symbols(fieldDef: FieldDef, symbolsSpec: any, model: UnitModel, channel: Channel, type: LegendType): VgEncodeEntry {\n if (type === 'gradient') {\n return undefined;\n }\n\n let out = {\n ...applyMarkConfig({}, model, FILL_STROKE_CONFIG),\n ...mixins.color(model)\n };\n\n switch (model.mark) {\n case BAR:\n case TICK:\n case TEXT:\n out.shape = {value: 'square'};\n break;\n case CIRCLE:\n case SQUARE:\n out.shape = {value: model.mark};\n break;\n case POINT:\n case LINE:\n case GEOSHAPE:\n case AREA:\n // use default circle\n break;\n }\n\n const {markDef, encoding} = model;\n const filled = markDef.filled;\n\n if (out.fill) {\n // for fill legend, we don't want any fill in symbol\n if (channel === 'fill' || (filled && channel === COLOR)) {\n delete out.fill;\n } else {\n if (out.fill['field']) {\n // For others, remove fill field\n delete out.fill;\n } else if (isArray(out.fill)) {\n const fill = getFirstConditionValue(encoding.fill || encoding.color) || markDef.fill || (filled && markDef.color);\n if (fill) {\n out.fill = {value: fill};\n }\n }\n }\n }\n\n if (out.stroke) {\n if (channel === 'stroke' || (!filled && channel === COLOR)) {\n delete out.stroke;\n } else {\n if (out.stroke['field']) {\n // For others, remove stroke field\n delete out.stroke;\n } else if (isArray(out.stroke)) {\n const stroke = getFirstConditionValue(encoding.stroke || encoding.color) || markDef.stroke || (!filled && markDef.color);\n if (stroke) {\n out.stroke = {value: stroke};\n }\n }\n }\n }\n\n if (out.fill && out.fill['value'] !== 'transparent' && !out.stroke) {\n // for non color channel's legend, we need to override symbol stroke config from Vega config\n out.stroke = {value: 'transparent'};\n }\n\n if (channel !== SHAPE) {\n const shape = getFirstConditionValue(encoding.shape) || markDef.shape;\n if (shape) {\n out.shape = {value: shape};\n }\n }\n\n if (channel !== OPACITY) {\n const opacity = getMaxValue(encoding.opacity) || markDef.opacity;\n if (opacity) { // only apply opacity if it is neither zero or undefined\n out.opacity = {value: opacity};\n }\n }\n\n out = {...out, ...symbolsSpec};\n\n return keys(out).length > 0 ? out : undefined;\n}\n\nexport function gradient(fieldDef: FieldDef, gradientSpec: any, model: UnitModel, channel: Channel, type: LegendType) {\n let out: any = {};\n\n if (type === 'gradient') {\n const opacity = getMaxValue(model.encoding.opacity) || model.markDef.opacity;\n if (opacity) { // only apply opacity if it is neither zero or undefined\n out.opacity = {value: opacity};\n }\n }\n\n out = {...out, ...gradientSpec};\n return keys(out).length > 0 ? out : undefined;\n}\n\nexport function labels(fieldDef: FieldDef, labelsSpec: any, model: UnitModel, channel: NonPositionScaleChannel, type: LegendType) {\n const legend = model.legend(channel);\n const config = model.config;\n\n let out: any = {};\n\n if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC;\n const expr = timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat, isUTCScale);\n labelsSpec = {\n ...(expr ? {text: {signal: expr}} : {}),\n ...labelsSpec,\n };\n }\n\n out = {...out, ...labelsSpec};\n\n return keys(out).length > 0 ? out : undefined;\n}\n\nfunction getMaxValue(channelDef: FieldDefWithCondition> | ValueDefWithCondition>) {\n return getConditionValue(channelDef,\n (v: number, conditionalDef) => Math.max(v, conditionalDef.value as any)\n );\n}\n\nfunction getFirstConditionValue(channelDef: FieldDefWithCondition> | ValueDefWithCondition>) {\n return getConditionValue(channelDef,\n (v: number, conditionalDef) => v !== undefined ? v : conditionalDef.value\n );\n}\n\nfunction getConditionValue(\n channelDef: FieldDefWithCondition> | ValueDefWithCondition>,\n reducer: (val: T, conditionalDef: Conditional) => T\n): T {\n\n if (hasConditionalValueDef(channelDef)) {\n return (isArray(channelDef.condition) ? channelDef.condition : [channelDef.condition])\n .reduce(reducer, channelDef.value as any);\n } else if (isValueDef(channelDef)) {\n return channelDef.value as any;\n }\n return undefined;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/legend/parse.d.ts b/build/src/compile/legend/parse.d.ts new file mode 100644 index 0000000000..02ab7678f3 --- /dev/null +++ b/build/src/compile/legend/parse.d.ts @@ -0,0 +1,7 @@ +import { NonPositionScaleChannel } from '../../channel'; +import { Model } from '../model'; +import { UnitModel } from '../unit'; +import { LegendComponent } from './component'; +export declare function parseLegend(model: Model): void; +export declare function parseLegendForChannel(model: UnitModel, channel: NonPositionScaleChannel): LegendComponent; +export declare function mergeLegendComponent(mergedLegend: LegendComponent, childLegend: LegendComponent): LegendComponent; diff --git a/build/src/compile/legend/parse.js b/build/src/compile/legend/parse.js new file mode 100644 index 0000000000..926968d550 --- /dev/null +++ b/build/src/compile/legend/parse.js @@ -0,0 +1,184 @@ +import { COLOR, FILL, OPACITY, SHAPE, SIZE, STROKE } from '../../channel'; +import { isFieldDef, title as fieldDefTitle } from '../../fielddef'; +import { LEGEND_PROPERTIES, VG_LEGEND_PROPERTIES } from '../../legend'; +import { GEOJSON } from '../../type'; +import { deleteNestedProperty, keys } from '../../util'; +import { getSpecifiedOrDefaultValue, guideEncodeEntry, mergeTitleComponent, numberFormat } from '../common'; +import { isUnitModel } from '../model'; +import { parseGuideResolve } from '../resolve'; +import { defaultTieBreaker, makeImplicit, mergeValuesWithExplicit } from '../split'; +import { LegendComponent } from './component'; +import * as encode from './encode'; +import * as properties from './properties'; +export function parseLegend(model) { + if (isUnitModel(model)) { + model.component.legends = parseUnitLegend(model); + } + else { + model.component.legends = parseNonUnitLegend(model); + } +} +function parseUnitLegend(model) { + var encoding = model.encoding; + return [COLOR, FILL, STROKE, SIZE, SHAPE, OPACITY].reduce(function (legendComponent, channel) { + var def = encoding[channel]; + if (model.legend(channel) && model.getScaleComponent(channel) && !(isFieldDef(def) && (channel === SHAPE && def.type === GEOJSON))) { + legendComponent[channel] = parseLegendForChannel(model, channel); + } + return legendComponent; + }, {}); +} +function getLegendDefWithScale(model, channel) { + var _a; + // For binned field with continuous scale, use a special scale so we can overrride the mark props and labels + switch (channel) { + case COLOR: + var scale = model.scaleName(COLOR); + return model.markDef.filled ? { fill: scale } : { stroke: scale }; + case FILL: + case STROKE: + case SIZE: + case SHAPE: + case OPACITY: + return _a = {}, _a[channel] = model.scaleName(channel), _a; + } +} +export function parseLegendForChannel(model, channel) { + var fieldDef = model.fieldDef(channel); + var legend = model.legend(channel); + var legendCmpt = new LegendComponent({}, getLegendDefWithScale(model, channel)); + LEGEND_PROPERTIES.forEach(function (property) { + var value = getProperty(property, legend, channel, model); + if (value !== undefined) { + var explicit = + // specified legend.values is already respected, but may get transformed. + property === 'values' ? !!legend.values : + // title can be explicit if fieldDef.title is set + property === 'title' && value === model.fieldDef(channel).title ? true : + // Otherwise, things are explicit if the returned value matches the specified property + value === legend[property]; + if (explicit || model.config.legend[property] === undefined) { + legendCmpt.set(property, value, explicit); + } + } + }); + // 2) Add mark property definition groups + var legendEncoding = legend.encoding || {}; + var legendEncode = ['labels', 'legend', 'title', 'symbols', 'gradient'].reduce(function (e, part) { + var legendEncodingPart = guideEncodeEntry(legendEncoding[part] || {}, model); + var value = encode[part] ? + // TODO: replace legendCmpt with type is sufficient + encode[part](fieldDef, legendEncodingPart, model, channel, legendCmpt.get('type')) : // apply rule + legendEncodingPart; // no rule -- just default values + if (value !== undefined && keys(value).length > 0) { + e[part] = { update: value }; + } + return e; + }, {}); + if (keys(legendEncode).length > 0) { + legendCmpt.set('encode', legendEncode, !!legend.encoding); + } + return legendCmpt; +} +function getProperty(property, specifiedLegend, channel, model) { + var fieldDef = model.fieldDef(channel); + switch (property) { + case 'format': + // We don't include temporal field here as we apply format in encode block + return numberFormat(fieldDef, specifiedLegend.format, model.config); + case 'title': + // For falsy value, keep undefined so we use default, + // but use null for '', null, and false to hide the title + var specifiedTitle = fieldDef.title !== undefined ? fieldDef.title : + specifiedLegend.title || (specifiedLegend.title === undefined ? undefined : null); + return getSpecifiedOrDefaultValue(specifiedTitle, fieldDefTitle(fieldDef, model.config)) || undefined; // make falsy value undefined so output Vega spec is shorter + case 'values': + return properties.values(specifiedLegend, fieldDef); + case 'type': + return getSpecifiedOrDefaultValue(specifiedLegend.type, properties.type(fieldDef.type, channel, model.getScaleComponent(channel).get('type'))); + } + // Otherwise, return specified property. + return specifiedLegend[property]; +} +function parseNonUnitLegend(model) { + var _a = model.component, legends = _a.legends, resolve = _a.resolve; + var _loop_1 = function (child) { + parseLegend(child); + keys(child.component.legends).forEach(function (channel) { + resolve.legend[channel] = parseGuideResolve(model.component.resolve, channel); + if (resolve.legend[channel] === 'shared') { + // If the resolve says shared (and has not been overridden) + // We will try to merge and see if there is a conflict + legends[channel] = mergeLegendComponent(legends[channel], child.component.legends[channel]); + if (!legends[channel]) { + // If merge returns nothing, there is a conflict so we cannot make the legend shared. + // Thus, mark legend as independent and remove the legend component. + resolve.legend[channel] = 'independent'; + delete legends[channel]; + } + } + }); + }; + for (var _i = 0, _b = model.children; _i < _b.length; _i++) { + var child = _b[_i]; + _loop_1(child); + } + keys(legends).forEach(function (channel) { + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + if (!child.component.legends[channel]) { + // skip if the child does not have a particular legend + continue; + } + if (resolve.legend[channel] === 'shared') { + // After merging shared legend, make sure to remove legend from child + delete child.component.legends[channel]; + } + } + }); + return legends; +} +export function mergeLegendComponent(mergedLegend, childLegend) { + if (!mergedLegend) { + return childLegend.clone(); + } + var mergedOrient = mergedLegend.getWithExplicit('orient'); + var childOrient = childLegend.getWithExplicit('orient'); + if (mergedOrient.explicit && childOrient.explicit && mergedOrient.value !== childOrient.value) { + // TODO: throw warning if resolve is explicit (We don't have info about explicit/implicit resolve yet.) + // Cannot merge due to inconsistent orient + return undefined; + } + var typeMerged = false; + var _loop_2 = function (prop) { + var mergedValueWithExplicit = mergeValuesWithExplicit(mergedLegend.getWithExplicit(prop), childLegend.getWithExplicit(prop), prop, 'legend', + // Tie breaker function + function (v1, v2) { + switch (prop) { + case 'title': + return mergeTitleComponent(v1, v2); + case 'type': + // There are only two types. If we have different types, then prefer symbol over gradient. + typeMerged = true; + return makeImplicit('symbol'); + } + return defaultTieBreaker(v1, v2, prop, 'legend'); + }); + mergedLegend.setWithExplicit(prop, mergedValueWithExplicit); + }; + // Otherwise, let's merge + for (var _i = 0, VG_LEGEND_PROPERTIES_1 = VG_LEGEND_PROPERTIES; _i < VG_LEGEND_PROPERTIES_1.length; _i++) { + var prop = VG_LEGEND_PROPERTIES_1[_i]; + _loop_2(prop); + } + if (typeMerged) { + if (((mergedLegend.implicit || {}).encode || {}).gradient) { + deleteNestedProperty(mergedLegend.implicit, ['encode', 'gradient']); + } + if (((mergedLegend.explicit || {}).encode || {}).gradient) { + deleteNestedProperty(mergedLegend.explicit, ['encode', 'gradient']); + } + } + return mergedLegend; +} +//# sourceMappingURL=parse.js.map \ No newline at end of file diff --git a/build/src/compile/legend/parse.js.map b/build/src/compile/legend/parse.js.map new file mode 100644 index 0000000000..b927e77f73 --- /dev/null +++ b/build/src/compile/legend/parse.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../src/compile/legend/parse.ts"],"names":[],"mappings":"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","sourcesContent":["import {COLOR, FILL, NonPositionScaleChannel, OPACITY, SHAPE, SIZE, STROKE} from '../../channel';\nimport {isFieldDef, title as fieldDefTitle} from '../../fielddef';\nimport {Legend, LEGEND_PROPERTIES, VG_LEGEND_PROPERTIES} from '../../legend';\nimport {GEOJSON} from '../../type';\nimport {deleteNestedProperty, keys} from '../../util';\nimport {VgLegend, VgLegendEncode} from '../../vega.schema';\nimport {getSpecifiedOrDefaultValue, guideEncodeEntry, mergeTitleComponent, numberFormat} from '../common';\nimport {isUnitModel, Model} from '../model';\nimport {parseGuideResolve} from '../resolve';\nimport {defaultTieBreaker, Explicit, makeImplicit, mergeValuesWithExplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {LegendComponent, LegendComponentIndex} from './component';\nimport * as encode from './encode';\nimport * as properties from './properties';\n\n\nexport function parseLegend(model: Model) {\n if (isUnitModel(model)) {\n model.component.legends = parseUnitLegend(model);\n } else {\n model.component.legends = parseNonUnitLegend(model);\n }\n}\n\nfunction parseUnitLegend(model: UnitModel): LegendComponentIndex {\n const {encoding} = model;\n return [COLOR, FILL, STROKE, SIZE, SHAPE, OPACITY].reduce(function (legendComponent, channel) {\n const def = encoding[channel];\n if (model.legend(channel) && model.getScaleComponent(channel) && !(isFieldDef(def) && (channel === SHAPE && def.type === GEOJSON))) {\n legendComponent[channel] = parseLegendForChannel(model, channel);\n }\n return legendComponent;\n }, {});\n}\n\nfunction getLegendDefWithScale(model: UnitModel, channel: NonPositionScaleChannel): VgLegend {\n // For binned field with continuous scale, use a special scale so we can overrride the mark props and labels\n switch (channel) {\n case COLOR:\n const scale = model.scaleName(COLOR);\n return model.markDef.filled ? {fill: scale} : {stroke: scale};\n case FILL:\n case STROKE:\n case SIZE:\n case SHAPE:\n case OPACITY:\n return {[channel]: model.scaleName(channel)};\n }\n}\n\nexport function parseLegendForChannel(model: UnitModel, channel: NonPositionScaleChannel): LegendComponent {\n const fieldDef = model.fieldDef(channel);\n const legend = model.legend(channel);\n\n const legendCmpt = new LegendComponent({}, getLegendDefWithScale(model, channel));\n\n LEGEND_PROPERTIES.forEach(function(property) {\n const value = getProperty(property, legend, channel, model);\n if (value !== undefined) {\n const explicit =\n // specified legend.values is already respected, but may get transformed.\n property === 'values' ? !!legend.values :\n // title can be explicit if fieldDef.title is set\n property === 'title' && value === model.fieldDef(channel).title ? true :\n // Otherwise, things are explicit if the returned value matches the specified property\n value === legend[property];\n if (explicit || model.config.legend[property] === undefined) {\n legendCmpt.set(property, value, explicit);\n }\n }\n });\n\n // 2) Add mark property definition groups\n const legendEncoding = legend.encoding || {};\n const legendEncode = ['labels', 'legend', 'title', 'symbols', 'gradient'].reduce((e: VgLegendEncode, part) => {\n const legendEncodingPart = guideEncodeEntry(legendEncoding[part] || {}, model);\n const value = encode[part] ?\n // TODO: replace legendCmpt with type is sufficient\n encode[part](fieldDef, legendEncodingPart, model, channel, legendCmpt.get('type')) : // apply rule\n legendEncodingPart; // no rule -- just default values\n if (value !== undefined && keys(value).length > 0) {\n e[part] = {update: value};\n }\n return e;\n }, {} as VgLegendEncode);\n\n if (keys(legendEncode).length > 0) {\n legendCmpt.set('encode', legendEncode, !!legend.encoding);\n }\n\n return legendCmpt;\n}\n\nfunction getProperty(property: keyof (Legend | VgLegend), specifiedLegend: Legend, channel: NonPositionScaleChannel, model: UnitModel) {\n const fieldDef = model.fieldDef(channel);\n\n switch (property) {\n case 'format':\n // We don't include temporal field here as we apply format in encode block\n return numberFormat(fieldDef, specifiedLegend.format, model.config);\n case 'title':\n // For falsy value, keep undefined so we use default,\n // but use null for '', null, and false to hide the title\n const specifiedTitle = fieldDef.title !== undefined ? fieldDef.title :\n specifiedLegend.title || (specifiedLegend.title === undefined ? undefined : null);\n\n return getSpecifiedOrDefaultValue(\n specifiedTitle,\n fieldDefTitle(fieldDef, model.config)\n ) || undefined; // make falsy value undefined so output Vega spec is shorter\n case 'values':\n return properties.values(specifiedLegend, fieldDef);\n case 'type':\n return getSpecifiedOrDefaultValue(specifiedLegend.type, properties.type(fieldDef.type, channel, model.getScaleComponent(channel).get('type')));\n }\n\n // Otherwise, return specified property.\n return specifiedLegend[property];\n}\n\nfunction parseNonUnitLegend(model: Model) {\n const {legends, resolve} = model.component;\n\n for (const child of model.children) {\n parseLegend(child);\n\n keys(child.component.legends).forEach((channel: NonPositionScaleChannel) => {\n resolve.legend[channel] = parseGuideResolve(model.component.resolve, channel);\n\n if (resolve.legend[channel] === 'shared') {\n // If the resolve says shared (and has not been overridden)\n // We will try to merge and see if there is a conflict\n\n legends[channel] = mergeLegendComponent(legends[channel], child.component.legends[channel]);\n\n if (!legends[channel]) {\n // If merge returns nothing, there is a conflict so we cannot make the legend shared.\n // Thus, mark legend as independent and remove the legend component.\n resolve.legend[channel] = 'independent';\n delete legends[channel];\n }\n }\n });\n }\n\n keys(legends).forEach((channel: NonPositionScaleChannel) => {\n for (const child of model.children) {\n if (!child.component.legends[channel]) {\n // skip if the child does not have a particular legend\n continue;\n }\n\n if (resolve.legend[channel] === 'shared') {\n // After merging shared legend, make sure to remove legend from child\n delete child.component.legends[channel];\n }\n }\n });\n return legends;\n}\n\nexport function mergeLegendComponent(mergedLegend: LegendComponent, childLegend: LegendComponent): LegendComponent {\n if (!mergedLegend) {\n return childLegend.clone();\n }\n const mergedOrient = mergedLegend.getWithExplicit('orient');\n const childOrient = childLegend.getWithExplicit('orient');\n\n\n if (mergedOrient.explicit && childOrient.explicit && mergedOrient.value !== childOrient.value) {\n // TODO: throw warning if resolve is explicit (We don't have info about explicit/implicit resolve yet.)\n // Cannot merge due to inconsistent orient\n return undefined;\n }\n let typeMerged = false;\n // Otherwise, let's merge\n for (const prop of VG_LEGEND_PROPERTIES) {\n const mergedValueWithExplicit = mergeValuesWithExplicit(\n mergedLegend.getWithExplicit(prop),\n childLegend.getWithExplicit(prop),\n prop, 'legend',\n\n // Tie breaker function\n (v1: Explicit, v2: Explicit): any => {\n switch (prop) {\n case 'title':\n return mergeTitleComponent(v1, v2);\n case 'type':\n // There are only two types. If we have different types, then prefer symbol over gradient.\n typeMerged = true;\n return makeImplicit('symbol');\n }\n return defaultTieBreaker(v1, v2, prop, 'legend');\n }\n );\n mergedLegend.setWithExplicit(prop, mergedValueWithExplicit);\n }\n if (typeMerged) {\n if(((mergedLegend.implicit || {}).encode || {}).gradient) {\n deleteNestedProperty(mergedLegend.implicit, ['encode', 'gradient']);\n }\n if (((mergedLegend.explicit || {}).encode || {}).gradient) {\n deleteNestedProperty(mergedLegend.explicit, ['encode', 'gradient']);\n }\n }\n\n\n return mergedLegend;\n}\n\n"]} \ No newline at end of file diff --git a/build/src/compile/legend/properties.d.ts b/build/src/compile/legend/properties.d.ts new file mode 100644 index 0000000000..5980951b8d --- /dev/null +++ b/build/src/compile/legend/properties.d.ts @@ -0,0 +1,9 @@ +import { Channel } from '../../channel'; +import { FieldDef } from '../../fielddef'; +import { Legend } from '../../legend'; +import { ScaleType } from '../../scale'; +import { Type } from '../../type'; +export declare function values(legend: Legend, fieldDef: FieldDef): (string | number | boolean | import("../../../../../../../../../../Users/kanitw/Documents/_code/_idl/_visrec/vega-lite/src/datetime").DateTime | { + signal: string; +})[]; +export declare function type(t: Type, channel: Channel, scaleType: ScaleType): 'gradient'; diff --git a/build/src/compile/legend/properties.js b/build/src/compile/legend/properties.js new file mode 100644 index 0000000000..f0a941328b --- /dev/null +++ b/build/src/compile/legend/properties.js @@ -0,0 +1,19 @@ +import { isColorChannel } from '../../channel'; +import { valueArray } from '../../fielddef'; +import { isBinScale } from '../../scale'; +import { contains } from '../../util'; +export function values(legend, fieldDef) { + var vals = legend.values; + if (vals) { + return valueArray(fieldDef, vals); + } + return undefined; +} +export function type(t, channel, scaleType) { + if (isColorChannel(channel) && ((t === 'quantitative' && !isBinScale(scaleType)) || + (t === 'temporal' && contains(['time', 'utc'], scaleType)))) { + return 'gradient'; + } + return undefined; +} +//# sourceMappingURL=properties.js.map \ No newline at end of file diff --git a/build/src/compile/legend/properties.js.map b/build/src/compile/legend/properties.js.map new file mode 100644 index 0000000000..d5a7e7f450 --- /dev/null +++ b/build/src/compile/legend/properties.js.map @@ -0,0 +1 @@ +{"version":3,"file":"properties.js","sourceRoot":"","sources":["../../../../src/compile/legend/properties.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,cAAc,EAAC,MAAM,eAAe,CAAC;AACtD,OAAO,EAAW,UAAU,EAAC,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAC,UAAU,EAAY,MAAM,aAAa,CAAC;AAElD,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AAEpC,MAAM,iBAAiB,MAAc,EAAE,QAA0B;IAC/D,IAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;IAE3B,IAAI,IAAI,EAAE;QACR,OAAO,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;KACnC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,eAAe,CAAO,EAAE,OAAgB,EAAE,SAAoB;IAClE,IACI,cAAc,CAAC,OAAO,CAAC,IAAI,CACzB,CAAC,CAAC,KAAK,cAAc,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAChD,CAAC,CAAC,KAAK,UAAU,IAAI,QAAQ,CAAY,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC,CACtE,EACD;QACF,OAAO,UAAU,CAAC;KACnB;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import {Channel, isColorChannel} from '../../channel';\nimport {FieldDef, valueArray} from '../../fielddef';\nimport {Legend} from '../../legend';\nimport {isBinScale, ScaleType} from '../../scale';\nimport {Type} from '../../type';\nimport {contains} from '../../util';\n\nexport function values(legend: Legend, fieldDef: FieldDef) {\n const vals = legend.values;\n\n if (vals) {\n return valueArray(fieldDef, vals);\n }\n return undefined;\n}\n\nexport function type(t: Type, channel: Channel, scaleType: ScaleType): 'gradient' {\n if (\n isColorChannel(channel) && (\n (t === 'quantitative' && !isBinScale(scaleType)) ||\n (t === 'temporal' && contains(['time', 'utc'], scaleType))\n )\n ) {\n return 'gradient';\n }\n return undefined;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/area.d.ts b/build/src/compile/mark/area.d.ts new file mode 100644 index 0000000000..92ee281df3 --- /dev/null +++ b/build/src/compile/mark/area.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const area: MarkCompiler; diff --git a/build/src/compile/mark/area.js b/build/src/compile/mark/area.js new file mode 100644 index 0000000000..a624829cb8 --- /dev/null +++ b/build/src/compile/mark/area.js @@ -0,0 +1,9 @@ +import * as tslib_1 from "tslib"; +import * as mixins from './mixins'; +export var area = { + vgMark: 'area', + encodeEntry: function (model) { + return tslib_1.__assign({}, mixins.baseEncodeEntry(model, { size: 'ignore', orient: 'include' }), mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin', model.markDef.orient === 'horizontal' ? 'x2' : 'y2'), mixins.defined(model)); + } +}; +//# sourceMappingURL=area.js.map \ No newline at end of file diff --git a/build/src/compile/mark/area.js.map b/build/src/compile/mark/area.js.map new file mode 100644 index 0000000000..bcf6064b73 --- /dev/null +++ b/build/src/compile/mark/area.js.map @@ -0,0 +1 @@ +{"version":3,"file":"area.js","sourceRoot":"","sources":["../../../../src/compile/mark/area.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAGnC,MAAM,CAAC,IAAM,IAAI,GAAiB;IAChC,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,UAAC,KAAgB;QAC5B,4BACK,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC,CAAC,EAClE,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,CAAC,EAC7C,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,CAAC,EAC7C,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAC9F,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EACxB;IACJ,CAAC;CACF,CAAC","sourcesContent":["import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\n\n\nexport const area: MarkCompiler = {\n vgMark: 'area',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'include'}),\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin', model.markDef.orient === 'horizontal' ? 'x2' : 'y2'),\n ...mixins.defined(model)\n };\n }\n};\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/bar.d.ts b/build/src/compile/mark/bar.d.ts new file mode 100644 index 0000000000..577df12005 --- /dev/null +++ b/build/src/compile/mark/bar.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const bar: MarkCompiler; diff --git a/build/src/compile/mark/bar.js b/build/src/compile/mark/bar.js new file mode 100644 index 0000000000..fe2140970a --- /dev/null +++ b/build/src/compile/mark/bar.js @@ -0,0 +1,97 @@ +import * as tslib_1 from "tslib"; +import { isNumber } from 'vega-util'; +import { X, Y } from '../../channel'; +import { isFieldDef } from '../../fielddef'; +import * as log from '../../log'; +import { hasDiscreteDomain, ScaleType } from '../../scale'; +import { isVgRangeStep } from '../../vega.schema'; +import * as mixins from './mixins'; +import * as ref from './valueref'; +export var bar = { + vgMark: 'rect', + encodeEntry: function (model) { + return tslib_1.__assign({}, mixins.baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), x(model), y(model)); + } +}; +function x(model) { + var config = model.config, encoding = model.encoding, markDef = model.markDef, width = model.width; + var orient = markDef.orient; + var sizeDef = encoding.size; + var xDef = encoding.x; + var x2Def = encoding.x2; + var xScaleName = model.scaleName(X); + var xScale = model.getScaleComponent(X); + // x, x2, and width -- we must specify two of these in all conditions + if (orient === 'horizontal' || x2Def) { + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin', 'x2')); + } + else { // vertical + if (isFieldDef(xDef)) { + var xScaleType = xScale.get('type'); + if (xDef.bin && !sizeDef && !hasDiscreteDomain(xScaleType)) { + return mixins.binnedPosition(xDef, 'x', model.scaleName('x'), markDef.binSpacing === undefined ? config.bar.binSpacing : markDef.binSpacing, xScale.get('reverse')); + } + else { + if (xScaleType === ScaleType.BAND) { + return mixins.bandPosition(xDef, 'x', model); + } + } + } + // sized bin, normal point-ordinal axis, quantitative x-axis, or no x + return mixins.centeredBandPosition('x', model, tslib_1.__assign({}, ref.mid(width)), defaultSizeRef(markDef, xScaleName, xScale, config)); + } +} +function y(model) { + var config = model.config, encoding = model.encoding, height = model.height, markDef = model.markDef; + var orient = markDef.orient; + var sizeDef = encoding.size; + var yDef = encoding.y; + var y2Def = encoding.y2; + var yScaleName = model.scaleName(Y); + var yScale = model.getScaleComponent(Y); + // y, y2 & height -- we must specify two of these in all conditions + if (orient === 'vertical' || y2Def) { + return tslib_1.__assign({}, mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin', 'y2')); + } + else { + if (isFieldDef(yDef)) { + var yScaleType = yScale.get('type'); + if (yDef.bin && !sizeDef && !hasDiscreteDomain(yScaleType)) { + return mixins.binnedPosition(yDef, 'y', model.scaleName('y'), markDef.binSpacing === undefined ? config.bar.binSpacing : markDef.binSpacing, yScale.get('reverse')); + } + else if (yScaleType === ScaleType.BAND) { + return mixins.bandPosition(yDef, 'y', model); + } + } + return mixins.centeredBandPosition('y', model, ref.mid(height), defaultSizeRef(markDef, yScaleName, yScale, config)); + } +} +function defaultSizeRef(markDef, scaleName, scale, config) { + if (markDef.size !== undefined) { + return { value: markDef.size }; + } + else if (config.bar.discreteBandSize) { + return { value: config.bar.discreteBandSize }; + } + else if (scale) { + var scaleType = scale.get('type'); + if (scaleType === ScaleType.POINT) { + var scaleRange = scale.get('range'); + if (isVgRangeStep(scaleRange) && isNumber(scaleRange.step)) { + return { value: scaleRange.step - 1 }; + } + log.warn(log.message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL); + } + else if (scaleType === ScaleType.BAND) { + return ref.bandRef(scaleName); + } + else { // non-ordinal scale + return { value: config.bar.continuousBandSize }; + } + } + else if (config.scale.rangeStep && config.scale.rangeStep !== null) { + return { value: config.scale.rangeStep - 1 }; + } + return { value: 20 }; +} +//# sourceMappingURL=bar.js.map \ No newline at end of file diff --git a/build/src/compile/mark/bar.js.map b/build/src/compile/mark/bar.js.map new file mode 100644 index 0000000000..7184496022 --- /dev/null +++ b/build/src/compile/mark/bar.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bar.js","sourceRoot":"","sources":["../../../../src/compile/mark/bar.ts"],"names":[],"mappings":"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","sourcesContent":["import {isNumber} from 'vega-util';\nimport {X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {isFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {MarkDef} from '../../mark';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {isVgRangeStep, VgEncodeEntry} from '../../vega.schema';\nimport {VgValueRef} from '../../vega.schema';\nimport {ScaleComponent} from '../scale/component';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nexport const bar: MarkCompiler = {\n vgMark: 'rect',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...x(model),\n ...y(model),\n };\n }\n};\n\nfunction x(model: UnitModel): VgEncodeEntry {\n const {config, encoding, markDef, width} = model;\n const orient = markDef.orient;\n const sizeDef = encoding.size;\n\n const xDef = encoding.x;\n const x2Def = encoding.x2;\n const xScaleName = model.scaleName(X);\n const xScale = model.getScaleComponent(X);\n // x, x2, and width -- we must specify two of these in all conditions\n if (orient === 'horizontal' || x2Def) {\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'x2'),\n };\n } else { // vertical\n if (isFieldDef(xDef)) {\n const xScaleType = xScale.get('type');\n if (xDef.bin && !sizeDef && !hasDiscreteDomain(xScaleType)) {\n return mixins.binnedPosition(\n xDef, 'x', model.scaleName('x'), markDef.binSpacing === undefined ? config.bar.binSpacing : markDef.binSpacing,\n xScale.get('reverse')\n );\n } else {\n if (xScaleType === ScaleType.BAND) {\n return mixins.bandPosition(xDef, 'x', model);\n }\n }\n }\n // sized bin, normal point-ordinal axis, quantitative x-axis, or no x\n\n return mixins.centeredBandPosition('x', model,\n {...ref.mid(width)},\n defaultSizeRef(markDef, xScaleName, xScale, config)\n );\n }\n}\n\nfunction y(model: UnitModel) {\n const {config, encoding, height, markDef} = model;\n const orient = markDef.orient;\n const sizeDef = encoding.size;\n\n const yDef = encoding.y;\n const y2Def = encoding.y2;\n const yScaleName = model.scaleName(Y);\n const yScale = model.getScaleComponent(Y);\n\n // y, y2 & height -- we must specify two of these in all conditions\n if (orient === 'vertical' || y2Def) {\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'y2'),\n };\n } else {\n if (isFieldDef(yDef)) {\n const yScaleType = yScale.get('type');\n if (yDef.bin && !sizeDef && !hasDiscreteDomain(yScaleType)) {\n return mixins.binnedPosition(\n yDef, 'y', model.scaleName('y'),\n markDef.binSpacing === undefined ? config.bar.binSpacing : markDef.binSpacing,\n yScale.get('reverse')\n );\n } else if (yScaleType === ScaleType.BAND) {\n return mixins.bandPosition(yDef, 'y', model);\n }\n }\n return mixins.centeredBandPosition('y', model, ref.mid(height),\n defaultSizeRef(markDef, yScaleName, yScale, config)\n );\n }\n}\n\nfunction defaultSizeRef(markDef: MarkDef, scaleName: string, scale: ScaleComponent, config: Config): VgValueRef {\n if (markDef.size !== undefined) {\n return {value: markDef.size};\n } else if (config.bar.discreteBandSize) {\n return {value: config.bar.discreteBandSize};\n } else if (scale) {\n const scaleType = scale.get('type');\n if (scaleType === ScaleType.POINT) {\n const scaleRange = scale.get('range');\n if (isVgRangeStep(scaleRange) && isNumber(scaleRange.step)) {\n return {value: scaleRange.step - 1};\n }\n log.warn(log.message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL);\n } else if (scaleType === ScaleType.BAND) {\n return ref.bandRef(scaleName);\n } else { // non-ordinal scale\n return {value: config.bar.continuousBandSize};\n }\n } else if (config.scale.rangeStep && config.scale.rangeStep !== null) {\n return {value: config.scale.rangeStep - 1};\n }\n return {value: 20};\n}\n\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/base.d.ts b/build/src/compile/mark/base.d.ts new file mode 100644 index 0000000000..ce4b302c73 --- /dev/null +++ b/build/src/compile/mark/base.d.ts @@ -0,0 +1,16 @@ +import { VgEncodeEntry, VgPostEncodingTransform } from '../../vega.schema'; +import { UnitModel } from '../unit'; +/** + * Abstract interface for compiling a Vega-Lite primitive mark type. + */ +export interface MarkCompiler { + /** + * Underlying vega Mark type for the Vega-Lite mark. + */ + vgMark: 'area' | 'line' | 'symbol' | 'rect' | 'rule' | 'text' | 'trail' | 'shape'; + encodeEntry: (model: UnitModel) => VgEncodeEntry; + /** + * Transform on a mark after render, used for layout and projections + */ + postEncodingTransform?: (model: UnitModel) => VgPostEncodingTransform[]; +} diff --git a/build/src/compile/mark/base.js b/build/src/compile/mark/base.js new file mode 100644 index 0000000000..c96e397970 --- /dev/null +++ b/build/src/compile/mark/base.js @@ -0,0 +1 @@ +//# sourceMappingURL=base.js.map \ No newline at end of file diff --git a/build/src/compile/mark/base.js.map b/build/src/compile/mark/base.js.map new file mode 100644 index 0000000000..91cbe3bac5 --- /dev/null +++ b/build/src/compile/mark/base.js.map @@ -0,0 +1 @@ +{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../src/compile/mark/base.ts"],"names":[],"mappings":"","sourcesContent":["import {VgEncodeEntry, VgPostEncodingTransform} from '../../vega.schema';\nimport {UnitModel} from '../unit';\n\n/**\n * Abstract interface for compiling a Vega-Lite primitive mark type.\n */\nexport interface MarkCompiler {\n /**\n * Underlying vega Mark type for the Vega-Lite mark.\n */\n vgMark: 'area' | 'line' | 'symbol' | 'rect' | 'rule' | 'text' | 'trail' | 'shape';\n\n encodeEntry: (model: UnitModel) => VgEncodeEntry;\n\n /**\n * Transform on a mark after render, used for layout and projections\n */\n postEncodingTransform?: (model: UnitModel) => VgPostEncodingTransform[];\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/geoshape.d.ts b/build/src/compile/mark/geoshape.d.ts new file mode 100644 index 0000000000..eaf46e5a40 --- /dev/null +++ b/build/src/compile/mark/geoshape.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const geoshape: MarkCompiler; diff --git a/build/src/compile/mark/geoshape.js b/build/src/compile/mark/geoshape.js new file mode 100644 index 0000000000..089d2933ae --- /dev/null +++ b/build/src/compile/mark/geoshape.js @@ -0,0 +1,17 @@ +import * as tslib_1 from "tslib"; +import * as mixins from './mixins'; +import { isFieldDef, vgField } from '../../fielddef'; +import { GEOJSON } from '../../type'; +export var geoshape = { + vgMark: 'shape', + encodeEntry: function (model) { + return tslib_1.__assign({}, mixins.baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' })); + }, + postEncodingTransform: function (model) { + var encoding = model.encoding; + var shapeDef = encoding.shape; + var transform = tslib_1.__assign({ type: 'geoshape', projection: model.projectionName() }, (shapeDef && isFieldDef(shapeDef) && shapeDef.type === GEOJSON ? { field: vgField(shapeDef, { expr: 'datum' }) } : {})); + return [transform]; + } +}; +//# sourceMappingURL=geoshape.js.map \ No newline at end of file diff --git a/build/src/compile/mark/geoshape.js.map b/build/src/compile/mark/geoshape.js.map new file mode 100644 index 0000000000..262a357474 --- /dev/null +++ b/build/src/compile/mark/geoshape.js.map @@ -0,0 +1 @@ +{"version":3,"file":"geoshape.js","sourceRoot":"","sources":["../../../../src/compile/mark/geoshape.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAEnC,OAAO,EAAC,UAAU,EAAE,OAAO,EAAC,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAC,OAAO,EAAC,MAAM,YAAY,CAAC;AAInC,MAAM,CAAC,IAAM,QAAQ,GAAiB;IACpC,MAAM,EAAE,OAAO;IACf,WAAW,EAAE,UAAC,KAAgB;QAC5B,4BACK,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAC,CAAC,EACpE;IACJ,CAAC;IACD,qBAAqB,EAAE,UAAC,KAAgB;QAC/B,IAAA,yBAAQ,CAAU;QACzB,IAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC;QAEhC,IAAM,SAAS,sBACb,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,KAAK,CAAC,cAAc,EAAE,IAE/B,CAAC,QAAQ,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAC,IAAI,EAAE,OAAO,EAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CACtH,CAAC;QACF,OAAO,CAAC,SAAS,CAAC,CAAC;IACrB,CAAC;CACF,CAAC","sourcesContent":["import {UnitModel} from '../unit';\nimport * as mixins from './mixins';\n\nimport {isFieldDef, vgField} from '../../fielddef';\nimport {GEOJSON} from '../../type';\nimport {VgGeoShapeTransform, VgPostEncodingTransform} from '../../vega.schema';\nimport {MarkCompiler} from './base';\n\nexport const geoshape: MarkCompiler = {\n vgMark: 'shape',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'})\n };\n },\n postEncodingTransform: (model: UnitModel): VgPostEncodingTransform[] => {\n const {encoding} = model;\n const shapeDef = encoding.shape;\n\n const transform: VgGeoShapeTransform = {\n type: 'geoshape',\n projection: model.projectionName(),\n // as: 'shape',\n ...(shapeDef && isFieldDef(shapeDef) && shapeDef.type === GEOJSON ? {field: vgField(shapeDef, {expr: 'datum'})} : {})\n };\n return [transform];\n }\n};\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/init.d.ts b/build/src/compile/mark/init.d.ts new file mode 100644 index 0000000000..5fedbc8d15 --- /dev/null +++ b/build/src/compile/mark/init.d.ts @@ -0,0 +1,4 @@ +import { Config } from '../../config'; +import { Encoding } from '../../encoding'; +import { Mark, MarkDef } from '../../mark'; +export declare function normalizeMarkDef(mark: Mark | MarkDef, encoding: Encoding, config: Config): MarkDef; diff --git a/build/src/compile/mark/init.js b/build/src/compile/mark/init.js new file mode 100644 index 0000000000..442fad6c6b --- /dev/null +++ b/build/src/compile/mark/init.js @@ -0,0 +1,151 @@ +import * as tslib_1 from "tslib"; +import { isAggregate } from '../../encoding'; +import { isContinuous, isFieldDef } from '../../fielddef'; +import * as log from '../../log'; +import { AREA, BAR, CIRCLE, isMarkDef, LINE, POINT, RECT, RULE, SQUARE, TEXT, TICK } from '../../mark'; +import { QUANTITATIVE, TEMPORAL } from '../../type'; +import { contains } from '../../util'; +import { getMarkConfig } from '../common'; +export function normalizeMarkDef(mark, encoding, config) { + var markDef = isMarkDef(mark) ? tslib_1.__assign({}, mark) : { type: mark }; + // set orient, which can be overridden by rules as sometimes the specified orient is invalid. + var specifiedOrient = markDef.orient || getMarkConfig('orient', markDef, config); + markDef.orient = orient(markDef.type, encoding, specifiedOrient); + if (specifiedOrient !== undefined && specifiedOrient !== markDef.orient) { + log.warn(log.message.orientOverridden(markDef.orient, specifiedOrient)); + } + // set opacity and filled if not specified in mark config + var specifiedOpacity = markDef.opacity !== undefined ? markDef.opacity : getMarkConfig('opacity', markDef, config); + if (specifiedOpacity === undefined) { + markDef.opacity = opacity(markDef.type, encoding); + } + var specifiedFilled = markDef.filled; + if (specifiedFilled === undefined) { + markDef.filled = filled(markDef, config); + } + // set cursor, which should be pointer if href channel is present unless otherwise specified + var specifiedCursor = markDef.cursor || getMarkConfig('cursor', markDef, config); + if (specifiedCursor === undefined) { + markDef.cursor = cursor(markDef, encoding, config); + } + return markDef; +} +function cursor(markDef, encoding, config) { + if (encoding.href || markDef.href || getMarkConfig('href', markDef, config)) { + return 'pointer'; + } + return markDef.cursor; +} +function opacity(mark, encoding) { + if (contains([POINT, TICK, CIRCLE, SQUARE], mark)) { + // point-based marks + if (!isAggregate(encoding)) { + return 0.7; + } + } + return undefined; +} +function filled(markDef, config) { + var filledConfig = getMarkConfig('filled', markDef, config); + var mark = markDef.type; + return filledConfig !== undefined ? filledConfig : mark !== POINT && mark !== LINE && mark !== RULE; +} +function orient(mark, encoding, specifiedOrient) { + switch (mark) { + case POINT: + case CIRCLE: + case SQUARE: + case TEXT: + case RECT: + // orient is meaningless for these marks. + return undefined; + } + var yIsRange = encoding.y2; + var xIsRange = encoding.x2; + switch (mark) { + case BAR: + if (yIsRange || xIsRange) { + // Ranged bar does not always have clear orientation, so we allow overriding + if (specifiedOrient) { + return specifiedOrient; + } + // If y is range and x is non-range, non-bin Q, y is likely a prebinned field + var xDef = encoding.x; + if (!xIsRange && isFieldDef(xDef) && xDef.type === QUANTITATIVE && !xDef.bin) { + return 'horizontal'; + } + // If x is range and y is non-range, non-bin Q, x is likely a prebinned field + var yDef = encoding.y; + if (!yIsRange && isFieldDef(yDef) && yDef.type === QUANTITATIVE && !yDef.bin) { + return 'vertical'; + } + } + /* tslint:disable */ + case RULE: // intentionally fall through + // return undefined for line segment rule and bar with both axis ranged + if (xIsRange && yIsRange) { + return undefined; + } + case AREA: // intentionally fall through + // If there are range for both x and y, y (vertical) has higher precedence. + if (yIsRange) { + return 'vertical'; + } + else if (xIsRange) { + return 'horizontal'; + } + else if (mark === RULE) { + if (encoding.x && !encoding.y) { + return 'vertical'; + } + else if (encoding.y && !encoding.x) { + return 'horizontal'; + } + } + case LINE: // intentional fall through + case TICK: // Tick is opposite to bar, line, area and never have ranged mark. + /* tslint:enable */ + var xIsContinuous = isFieldDef(encoding.x) && isContinuous(encoding.x); + var yIsContinuous = isFieldDef(encoding.y) && isContinuous(encoding.y); + if (xIsContinuous && !yIsContinuous) { + return mark !== 'tick' ? 'horizontal' : 'vertical'; + } + else if (!xIsContinuous && yIsContinuous) { + return mark !== 'tick' ? 'vertical' : 'horizontal'; + } + else if (xIsContinuous && yIsContinuous) { + var xDef = encoding.x; // we can cast here since they are surely fieldDef + var yDef = encoding.y; + var xIsTemporal = xDef.type === TEMPORAL; + var yIsTemporal = yDef.type === TEMPORAL; + // temporal without timeUnit is considered continuous, but better serves as dimension + if (xIsTemporal && !yIsTemporal) { + return mark !== 'tick' ? 'vertical' : 'horizontal'; + } + else if (!xIsTemporal && yIsTemporal) { + return mark !== 'tick' ? 'horizontal' : 'vertical'; + } + if (!xDef.aggregate && yDef.aggregate) { + return mark !== 'tick' ? 'vertical' : 'horizontal'; + } + else if (xDef.aggregate && !yDef.aggregate) { + return mark !== 'tick' ? 'horizontal' : 'vertical'; + } + if (specifiedOrient) { + // When ambiguous, use user specified one. + return specifiedOrient; + } + return 'vertical'; + } + else { + // Discrete x Discrete case + if (specifiedOrient) { + // When ambiguous, use user specified one. + return specifiedOrient; + } + return undefined; + } + } + return 'vertical'; +} +//# sourceMappingURL=init.js.map \ No newline at end of file diff --git a/build/src/compile/mark/init.js.map b/build/src/compile/mark/init.js.map new file mode 100644 index 0000000000..ab0d1504d1 --- /dev/null +++ b/build/src/compile/mark/init.js.map @@ -0,0 +1 @@ +{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../../src/compile/mark/init.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport {Config} from '../../config';\nimport {Encoding, isAggregate} from '../../encoding';\nimport {FieldDef, isContinuous, isFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {AREA, BAR, CIRCLE, isMarkDef, LINE, Mark, MarkDef, POINT, RECT, RULE, SQUARE, TEXT, TICK} from '../../mark';\nimport {QUANTITATIVE, TEMPORAL} from '../../type';\nimport {contains} from '../../util';\nimport {getMarkConfig} from '../common';\nimport {Orient} from './../../vega.schema';\n\n\nexport function normalizeMarkDef(mark: Mark | MarkDef, encoding: Encoding, config: Config) {\n const markDef: MarkDef = isMarkDef(mark) ? {...mark} : {type: mark};\n\n // set orient, which can be overridden by rules as sometimes the specified orient is invalid.\n const specifiedOrient = markDef.orient || getMarkConfig('orient', markDef, config);\n markDef.orient = orient(markDef.type, encoding, specifiedOrient);\n if (specifiedOrient !== undefined && specifiedOrient !== markDef.orient) {\n log.warn(log.message.orientOverridden(markDef.orient,specifiedOrient));\n }\n\n // set opacity and filled if not specified in mark config\n const specifiedOpacity = markDef.opacity !== undefined ? markDef.opacity : getMarkConfig('opacity', markDef, config);\n if (specifiedOpacity === undefined) {\n markDef.opacity = opacity(markDef.type, encoding);\n }\n\n const specifiedFilled = markDef.filled;\n if (specifiedFilled === undefined) {\n markDef.filled = filled(markDef, config);\n }\n\n // set cursor, which should be pointer if href channel is present unless otherwise specified\n const specifiedCursor = markDef.cursor || getMarkConfig('cursor', markDef, config);\n if (specifiedCursor === undefined) {\n markDef.cursor = cursor(markDef, encoding, config);\n }\n\n return markDef;\n}\n\nfunction cursor(markDef: MarkDef, encoding: Encoding, config: Config) {\n if (encoding.href || markDef.href || getMarkConfig('href', markDef, config)) {\n return 'pointer';\n }\n return markDef.cursor;\n}\n\nfunction opacity(mark: Mark, encoding: Encoding) {\n if (contains([POINT, TICK, CIRCLE, SQUARE], mark)) {\n // point-based marks\n if (!isAggregate(encoding)) {\n return 0.7;\n }\n }\n return undefined;\n}\n\nfunction filled(markDef: MarkDef, config: Config) {\n const filledConfig = getMarkConfig('filled', markDef, config);\n const mark = markDef.type;\n return filledConfig !== undefined ? filledConfig : mark !== POINT && mark !== LINE && mark !== RULE;\n}\n\nfunction orient(mark: Mark, encoding: Encoding, specifiedOrient: Orient): Orient {\n switch (mark) {\n case POINT:\n case CIRCLE:\n case SQUARE:\n case TEXT:\n case RECT:\n // orient is meaningless for these marks.\n return undefined;\n }\n\n const yIsRange = encoding.y2;\n const xIsRange = encoding.x2;\n\n switch (mark) {\n case BAR:\n if (yIsRange || xIsRange) {\n // Ranged bar does not always have clear orientation, so we allow overriding\n if (specifiedOrient) {\n return specifiedOrient;\n }\n\n // If y is range and x is non-range, non-bin Q, y is likely a prebinned field\n const xDef = encoding.x;\n if (!xIsRange && isFieldDef(xDef) && xDef.type === QUANTITATIVE && !xDef.bin) {\n return 'horizontal';\n }\n\n // If x is range and y is non-range, non-bin Q, x is likely a prebinned field\n const yDef = encoding.y;\n if (!yIsRange && isFieldDef(yDef) && yDef.type === QUANTITATIVE && !yDef.bin) {\n return 'vertical';\n }\n }\n /* tslint:disable */\n case RULE: // intentionally fall through\n // return undefined for line segment rule and bar with both axis ranged\n if (xIsRange && yIsRange) {\n return undefined;\n }\n\n case AREA: // intentionally fall through\n // If there are range for both x and y, y (vertical) has higher precedence.\n if (yIsRange) {\n return 'vertical';\n } else if (xIsRange) {\n return 'horizontal';\n } else if (mark === RULE) {\n if (encoding.x && !encoding.y) {\n return 'vertical';\n } else if (encoding.y && !encoding.x) {\n return 'horizontal';\n }\n }\n\n\n case LINE: // intentional fall through\n case TICK: // Tick is opposite to bar, line, area and never have ranged mark.\n\n /* tslint:enable */\n const xIsContinuous = isFieldDef(encoding.x) && isContinuous(encoding.x);\n const yIsContinuous = isFieldDef(encoding.y) && isContinuous(encoding.y);\n if (xIsContinuous && !yIsContinuous) {\n return mark !== 'tick' ? 'horizontal' : 'vertical';\n } else if (!xIsContinuous && yIsContinuous) {\n return mark !== 'tick' ? 'vertical' : 'horizontal';\n } else if (xIsContinuous && yIsContinuous) {\n const xDef = encoding.x as FieldDef; // we can cast here since they are surely fieldDef\n const yDef = encoding.y as FieldDef;\n\n const xIsTemporal = xDef.type === TEMPORAL;\n const yIsTemporal = yDef.type === TEMPORAL;\n\n // temporal without timeUnit is considered continuous, but better serves as dimension\n if (xIsTemporal && !yIsTemporal) {\n return mark !== 'tick' ? 'vertical' : 'horizontal';\n } else if (!xIsTemporal && yIsTemporal) {\n return mark !== 'tick' ? 'horizontal' : 'vertical';\n }\n\n if (!xDef.aggregate && yDef.aggregate) {\n return mark !== 'tick' ? 'vertical' : 'horizontal';\n } else if (xDef.aggregate && !yDef.aggregate) {\n return mark !== 'tick' ? 'horizontal' : 'vertical';\n }\n\n if (specifiedOrient) {\n // When ambiguous, use user specified one.\n return specifiedOrient;\n }\n\n return 'vertical';\n } else {\n // Discrete x Discrete case\n if (specifiedOrient) {\n // When ambiguous, use user specified one.\n return specifiedOrient;\n }\n\n return undefined;\n }\n }\n return 'vertical';\n}\n\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/line.d.ts b/build/src/compile/mark/line.d.ts new file mode 100644 index 0000000000..6c886c6377 --- /dev/null +++ b/build/src/compile/mark/line.d.ts @@ -0,0 +1,3 @@ +import { MarkCompiler } from './base'; +export declare const line: MarkCompiler; +export declare const trail: MarkCompiler; diff --git a/build/src/compile/mark/line.js b/build/src/compile/mark/line.js new file mode 100644 index 0000000000..70c953673c --- /dev/null +++ b/build/src/compile/mark/line.js @@ -0,0 +1,20 @@ +import * as tslib_1 from "tslib"; +import * as mixins from './mixins'; +import * as ref from './valueref'; +export var line = { + vgMark: 'line', + encodeEntry: function (model) { + var width = model.width, height = model.height; + return tslib_1.__assign({}, mixins.baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), mixins.pointPosition('x', model, ref.mid(width)), mixins.pointPosition('y', model, ref.mid(height)), mixins.nonPosition('size', model, { + vgChannel: 'strokeWidth' // VL's line size is strokeWidth + }), mixins.defined(model)); + } +}; +export var trail = { + vgMark: 'trail', + encodeEntry: function (model) { + var width = model.width, height = model.height; + return tslib_1.__assign({}, mixins.baseEncodeEntry(model, { size: 'include', orient: 'ignore' }), mixins.pointPosition('x', model, ref.mid(width)), mixins.pointPosition('y', model, ref.mid(height)), mixins.nonPosition('size', model), mixins.defined(model)); + } +}; +//# sourceMappingURL=line.js.map \ No newline at end of file diff --git a/build/src/compile/mark/line.js.map b/build/src/compile/mark/line.js.map new file mode 100644 index 0000000000..5285962d51 --- /dev/null +++ b/build/src/compile/mark/line.js.map @@ -0,0 +1 @@ +{"version":3,"file":"line.js","sourceRoot":"","sources":["../../../../src/compile/mark/line.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,IAAM,IAAI,GAAiB;IAChC,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,UAAC,KAAgB;QACrB,IAAA,mBAAK,EAAE,qBAAM,CAAU;QAE9B,4BACK,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAC,CAAC,EACjE,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAChD,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EACjD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE;YACnC,SAAS,EAAE,aAAa,CAAE,gCAAgC;SAC3D,CAAC,EACC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EACxB;IACJ,CAAC;CACF,CAAC;AAGF,MAAM,CAAC,IAAM,KAAK,GAAiB;IACjC,MAAM,EAAE,OAAO;IACf,WAAW,EAAE,UAAC,KAAgB;QACrB,IAAA,mBAAK,EAAE,qBAAM,CAAU;QAE9B,4BACK,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAC,CAAC,EAClE,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAChD,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EACjD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,EACjC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EACxB;IACJ,CAAC;CACF,CAAC","sourcesContent":["import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\nexport const line: MarkCompiler = {\n vgMark: 'line',\n encodeEntry: (model: UnitModel) => {\n const {width, height} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth' // VL's line size is strokeWidth\n }),\n ...mixins.defined(model)\n };\n }\n};\n\n\nexport const trail: MarkCompiler = {\n vgMark: 'trail',\n encodeEntry: (model: UnitModel) => {\n const {width, height} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'include', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.nonPosition('size', model),\n ...mixins.defined(model)\n };\n }\n};\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/mark.d.ts b/build/src/compile/mark/mark.d.ts new file mode 100644 index 0000000000..663552953e --- /dev/null +++ b/build/src/compile/mark/mark.d.ts @@ -0,0 +1,19 @@ +import { Encoding } from '../../encoding'; +import { Mark } from '../../mark'; +import { UnitModel } from '../unit'; +export declare function parseMarkGroup(model: UnitModel): any[]; +export declare function getSort(model: UnitModel): { + field: string; + order?: import("../../../../../../../../../../Users/kanitw/Documents/_code/_idl/_visrec/vega-lite/node_modules/vega-util").Order; +} | { + field: string[]; + order?: import("../../../../../../../../../../Users/kanitw/Documents/_code/_idl/_visrec/vega-lite/node_modules/vega-util").Order[]; +} | { + field: string; + order: string; +}; +/** + * Returns list of path grouping fields + * that the model's spec contains. + */ +export declare function pathGroupingFields(mark: Mark, encoding: Encoding): string[]; diff --git a/build/src/compile/mark/mark.js b/build/src/compile/mark/mark.js new file mode 100644 index 0000000000..76d95d09c4 --- /dev/null +++ b/build/src/compile/mark/mark.js @@ -0,0 +1,194 @@ +import * as tslib_1 from "tslib"; +import { isArray } from 'vega-util'; +import { MAIN } from '../../data'; +import { isAggregate } from '../../encoding'; +import { getFieldDef, isFieldDef, isValueDef, vgField } from '../../fielddef'; +import { AREA, isPathMark, LINE, TRAIL } from '../../mark'; +import { isSortField } from '../../sort'; +import { contains, keys } from '../../util'; +import { getStyles, sortParams } from '../common'; +import { area } from './area'; +import { bar } from './bar'; +import { geoshape } from './geoshape'; +import { line, trail } from './line'; +import { circle, point, square } from './point'; +import { rect } from './rect'; +import { rule } from './rule'; +import { text } from './text'; +import { tick } from './tick'; +var markCompiler = { + area: area, + bar: bar, + circle: circle, + geoshape: geoshape, + line: line, + point: point, + rect: rect, + rule: rule, + square: square, + text: text, + tick: tick, + trail: trail +}; +export function parseMarkGroup(model) { + if (contains([LINE, AREA, TRAIL], model.mark)) { + return parsePathMark(model); + } + else { + return getMarkGroups(model); + } +} +var FACETED_PATH_PREFIX = 'faceted_path_'; +function parsePathMark(model) { + var details = pathGroupingFields(model.mark, model.encoding); + var pathMarks = getMarkGroups(model, { + // If has subfacet for line/area group, need to use faceted data from below. + fromPrefix: (details.length > 0 ? FACETED_PATH_PREFIX : '') + }); + if (details.length > 0) { // have level of details - need to facet line into subgroups + // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?) + return [{ + name: model.getName('pathgroup'), + type: 'group', + from: { + facet: { + name: FACETED_PATH_PREFIX + model.requestDataName(MAIN), + data: model.requestDataName(MAIN), + groupby: details, + } + }, + encode: { + update: { + width: { field: { group: 'width' } }, + height: { field: { group: 'height' } } + } + }, + marks: pathMarks + }]; + } + else { + return pathMarks; + } +} +export function getSort(model) { + var encoding = model.encoding, stack = model.stack, mark = model.mark, markDef = model.markDef; + var order = encoding.order; + if (!isArray(order) && isValueDef(order)) { + return undefined; + } + else if ((isArray(order) || isFieldDef(order)) && !stack) { + // Sort by the order field if it is specified and the field is not stacked. (For stacked field, order specify stack order.) + return sortParams(order, { expr: 'datum' }); + } + else if (isPathMark(mark)) { + // For both line and area, we sort values based on dimension by default + var dimensionChannelDef = encoding[markDef.orient === 'horizontal' ? 'y' : 'x']; + if (isFieldDef(dimensionChannelDef)) { + var s = dimensionChannelDef.sort; + var sortField = isSortField(s) ? + vgField({ + // FIXME: this op might not already exist? + // FIXME: what if dimensionChannel (x or y) contains custom domain? + aggregate: isAggregate(model.encoding) ? s.op : undefined, + field: s.field + }, { expr: 'datum' }) : + vgField(dimensionChannelDef, { + // For stack with imputation, we only have bin_mid + binSuffix: model.stack && model.stack.impute ? 'mid' : undefined, + expr: 'datum' + }); + return { + field: sortField, + order: 'descending' + }; + } + return undefined; + } + return undefined; +} +function getMarkGroups(model, opt) { + if (opt === void 0) { opt = { fromPrefix: '' }; } + var mark = model.mark; + var clip = model.markDef.clip !== undefined ? + !!model.markDef.clip : scaleClip(model); + var style = getStyles(model.markDef); + var key = model.encoding.key; + var sort = getSort(model); + var postEncodingTransform = markCompiler[mark].postEncodingTransform ? markCompiler[mark].postEncodingTransform(model) : null; + return [tslib_1.__assign({ name: model.getName('marks'), type: markCompiler[mark].vgMark }, (clip ? { clip: true } : {}), (style ? { style: style } : {}), (key ? { key: { field: key.field } } : {}), (sort ? { sort: sort } : {}), { from: { data: opt.fromPrefix + model.requestDataName(MAIN) }, encode: { + update: markCompiler[mark].encodeEntry(model) + } }, (postEncodingTransform ? { + transform: postEncodingTransform + } : {}))]; +} +/** + * Returns list of path grouping fields + * that the model's spec contains. + */ +export function pathGroupingFields(mark, encoding) { + return keys(encoding).reduce(function (details, channel) { + switch (channel) { + // x, y, x2, y2, lat, long, lat1, long2, order, tooltip, href, cursor should not cause lines to group + case 'x': + case 'y': + case 'order': + case 'tooltip': + case 'href': + case 'x2': + case 'y2': + case 'latitude': + case 'longitude': + case 'latitude2': + case 'longitude2': + // TODO: case 'cursor': + // text, shape, shouldn't be a part of line/trail/area + case 'text': + case 'shape': + return details; + case 'detail': + case 'key': + var channelDef = encoding[channel]; + if (channelDef) { + (isArray(channelDef) ? channelDef : [channelDef]).forEach(function (fieldDef) { + if (!fieldDef.aggregate) { + details.push(vgField(fieldDef, {})); + } + }); + } + return details; + case 'size': + if (mark === 'trail') { + // For trail, size should not group trail lines. + return details; + } + // For line, it should group lines. + /* tslint:disable */ + // intentional fall through + case 'color': + case 'fill': + case 'stroke': + case 'opacity': + // TODO strokeDashOffset: + /* tslint:enable */ + var fieldDef = getFieldDef(encoding[channel]); + if (fieldDef && !fieldDef.aggregate) { + details.push(vgField(fieldDef, {})); + } + return details; + default: + throw new Error("Bug: Channel " + channel + " unimplemented for line mark"); + } + }, []); +} +/** + * If scales are bound to interval selections, we want to automatically clip + * marks to account for panning/zooming interactions. We identify bound scales + * by the domainRaw property, which gets added during scale parsing. + */ +function scaleClip(model) { + var xScale = model.getScaleComponent('x'); + var yScale = model.getScaleComponent('y'); + return (xScale && xScale.get('domainRaw')) || + (yScale && yScale.get('domainRaw')) ? true : false; +} +//# sourceMappingURL=mark.js.map \ No newline at end of file diff --git a/build/src/compile/mark/mark.js.map b/build/src/compile/mark/mark.js.map new file mode 100644 index 0000000000..3dd835f081 --- /dev/null +++ b/build/src/compile/mark/mark.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mark.js","sourceRoot":"","sources":["../../../../src/compile/mark/mark.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAC;AAChC,OAAO,EAAW,WAAW,EAAC,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAC,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAC,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAQ,KAAK,EAAC,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAC,WAAW,EAAC,MAAM,YAAY,CAAC;AACvC,OAAO,EAAC,QAAQ,EAAE,IAAI,EAAC,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAC,SAAS,EAAE,UAAU,EAAC,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,EAAC,IAAI,EAAE,KAAK,EAAC,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAC;AAG5B,IAAM,YAAY,GAAgC;IAChD,IAAI,MAAA;IACJ,GAAG,KAAA;IACH,MAAM,QAAA;IACN,QAAQ,UAAA;IACR,IAAI,MAAA;IACJ,KAAK,OAAA;IACL,IAAI,MAAA;IACJ,IAAI,MAAA;IACJ,MAAM,QAAA;IACN,IAAI,MAAA;IACJ,IAAI,MAAA;IACJ,KAAK,OAAA;CACN,CAAC;AAEF,MAAM,yBAAyB,KAAgB;IAC7C,IAAI,QAAQ,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE;QAC7C,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;KAC7B;SAAM;QACL,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;KAC7B;AACH,CAAC;AAED,IAAM,mBAAmB,GAAG,eAAe,CAAC;AAE5C,uBAAuB,KAAgB;IACrC,IAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAE/D,IAAM,SAAS,GAAG,aAAa,CAAC,KAAK,EAAE;QACrC,4EAA4E;QAC5E,UAAU,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5D,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,4DAA4D;QACpF,6FAA6F;QAE7F,OAAO,CAAC;gBACN,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;gBAChC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE;oBACJ,KAAK,EAAE;wBACL,IAAI,EAAE,mBAAmB,GAAG,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC;wBACvD,IAAI,EAAE,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC;wBACjC,OAAO,EAAE,OAAO;qBACjB;iBACF;gBACD,MAAM,EAAE;oBACN,MAAM,EAAE;wBACN,KAAK,EAAE,EAAC,KAAK,EAAE,EAAC,KAAK,EAAE,OAAO,EAAC,EAAC;wBAChC,MAAM,EAAE,EAAC,KAAK,EAAE,EAAC,KAAK,EAAE,QAAQ,EAAC,EAAC;qBACnC;iBACF;gBACD,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;KACJ;SAAM;QACL,OAAO,SAAS,CAAC;KAClB;AACH,CAAC;AAED,MAAM,kBAAkB,KAAgB;IAC/B,IAAA,yBAAQ,EAAE,mBAAK,EAAE,iBAAI,EAAE,uBAAO,CAAU;IAC/C,IAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC7B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE;QACxC,OAAO,SAAS,CAAC;KAClB;SAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE;QAC1D,2HAA2H;QAC3H,OAAO,UAAU,CAAC,KAAK,EAAE,EAAC,IAAI,EAAE,OAAO,EAAC,CAAC,CAAC;KAC3C;SAAM,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE;QAC3B,uEAAuE;QACvE,IAAM,mBAAmB,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAClF,IAAI,UAAU,CAAC,mBAAmB,CAAC,EAAE;YACnC,IAAM,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC;YACnC,IAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChC,OAAO,CAAC;oBACN,0CAA0C;oBAC1C,mEAAmE;oBACnE,SAAS,EAAE,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;oBACzD,KAAK,EAAE,CAAC,CAAC,KAAK;iBACf,EAAE,EAAC,IAAI,EAAE,OAAO,EAAC,CAAC,CAAC,CAAC;gBACrB,OAAO,CAAC,mBAAmB,EAAE;oBAC3B,kDAAkD;oBAClD,SAAS,EAAE,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;oBAChE,IAAI,EAAE,OAAO;iBACd,CAAC,CAAC;YAEL,OAAO;gBACL,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,YAAY;aACpB,CAAC;SACH;QACD,OAAO,SAAS,CAAC;KAClB;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,uBAAuB,KAAgB,EAAE,GAErB;IAFqB,oBAAA,EAAA,QAEpC,UAAU,EAAE,EAAE,EAAC;IAClB,IAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IAExB,IAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAC7C,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvC,IAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;IAC/B,IAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAE5B,IAAM,qBAAqB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEhI,OAAO,oBACL,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAC5B,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,IAC5B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAC1B,CAAC,KAAK,CAAC,CAAC,CAAC,EAAC,KAAK,OAAA,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EACtB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,GAAG,EAAE,EAAC,KAAK,EAAE,GAAG,CAAC,KAAK,EAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EACtC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,IAAI,MAAA,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IACvB,IAAI,EAAE,EAAC,IAAI,EAAE,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,EAAC,EAC1D,MAAM,EAAE;gBACN,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC;aAC9C,IACE,CAAC,qBAAqB,CAAC,CAAC,CAAC;YAC1B,SAAS,EAAE,qBAAqB;SACjC,CAAC,CAAC,CAAC,EAAE,CAAC,EACP,CAAC;AAEL,CAAC;AAED;;;GAGG;AACH,MAAM,6BAA6B,IAAU,EAAE,QAA0B;IACvE,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAC,OAAO,EAAE,OAAO;QAC5C,QAAQ,OAAO,EAAE;YACf,qGAAqG;YACrG,KAAK,GAAG,CAAC;YACT,KAAK,GAAG,CAAC;YACT,KAAK,OAAO,CAAC;YACb,KAAK,SAAS,CAAC;YACf,KAAK,MAAM,CAAC;YACZ,KAAK,IAAI,CAAC;YACV,KAAK,IAAI,CAAC;YAEV,KAAK,UAAU,CAAC;YAChB,KAAK,WAAW,CAAC;YACjB,KAAK,WAAW,CAAC;YACjB,KAAK,YAAY,CAAC;YAClB,uBAAuB;YAEvB,sDAAsD;YACtD,KAAK,MAAM,CAAC;YACZ,KAAK,OAAO;gBACV,OAAO,OAAO,CAAC;YAEjB,KAAK,QAAQ,CAAC;YACd,KAAK,KAAK;gBACR,IAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACrC,IAAI,UAAU,EAAE;oBACd,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,UAAC,QAAQ;wBACjE,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE;4BACvB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;yBACrC;oBACH,CAAC,CAAC,CAAC;iBACJ;gBACD,OAAO,OAAO,CAAC;YAEjB,KAAK,MAAM;gBACT,IAAI,IAAI,KAAK,OAAO,EAAE;oBACpB,gDAAgD;oBAChD,OAAO,OAAO,CAAC;iBAChB;YACD,mCAAmC;YAErC,oBAAoB;YACpB,2BAA2B;YAE3B,KAAK,OAAO,CAAC;YACb,KAAK,MAAM,CAAC;YACZ,KAAK,QAAQ,CAAC;YACd,KAAK,SAAS;gBACd,yBAAyB;gBAEzB,mBAAmB;gBACjB,IAAM,QAAQ,GAAG,WAAW,CAAS,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;gBACxD,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE;oBACnC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;iBACrC;gBACD,OAAO,OAAO,CAAC;YACjB;gBACE,MAAM,IAAI,KAAK,CAAC,kBAAgB,OAAO,iCAA8B,CAAC,CAAC;SAC1E;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED;;;;GAIG;AACH,mBAAmB,KAAgB;IACjC,IAAM,MAAM,GAAG,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAM,MAAM,GAAG,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC5C,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AACvD,CAAC","sourcesContent":["import {isArray} from 'vega-util';\nimport {MAIN} from '../../data';\nimport {Encoding, isAggregate} from '../../encoding';\nimport {getFieldDef, isFieldDef, isValueDef, vgField} from '../../fielddef';\nimport {AREA, isPathMark, LINE, Mark, TRAIL} from '../../mark';\nimport {isSortField} from '../../sort';\nimport {contains, keys} from '../../util';\nimport {getStyles, sortParams} from '../common';\nimport {UnitModel} from '../unit';\nimport {area} from './area';\nimport {bar} from './bar';\nimport {MarkCompiler} from './base';\nimport {geoshape} from './geoshape';\nimport {line, trail} from './line';\nimport {circle, point, square} from './point';\nimport {rect} from './rect';\nimport {rule} from './rule';\nimport {text} from './text';\nimport {tick} from './tick';\n\n\nconst markCompiler: {[m in Mark]: MarkCompiler} = {\n area,\n bar,\n circle,\n geoshape,\n line,\n point,\n rect,\n rule,\n square,\n text,\n tick,\n trail\n};\n\nexport function parseMarkGroup(model: UnitModel): any[] {\n if (contains([LINE, AREA, TRAIL], model.mark)) {\n return parsePathMark(model);\n } else {\n return getMarkGroups(model);\n }\n}\n\nconst FACETED_PATH_PREFIX = 'faceted_path_';\n\nfunction parsePathMark(model: UnitModel) {\n const details = pathGroupingFields(model.mark, model.encoding);\n\n const pathMarks = getMarkGroups(model, {\n // If has subfacet for line/area group, need to use faceted data from below.\n fromPrefix: (details.length > 0 ? FACETED_PATH_PREFIX : '')\n });\n\n if (details.length > 0) { // have level of details - need to facet line into subgroups\n // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?)\n\n return [{\n name: model.getName('pathgroup'),\n type: 'group',\n from: {\n facet: {\n name: FACETED_PATH_PREFIX + model.requestDataName(MAIN),\n data: model.requestDataName(MAIN),\n groupby: details,\n }\n },\n encode: {\n update: {\n width: {field: {group: 'width'}},\n height: {field: {group: 'height'}}\n }\n },\n marks: pathMarks\n }];\n } else {\n return pathMarks;\n }\n}\n\nexport function getSort(model: UnitModel) {\n const {encoding, stack, mark, markDef} = model;\n const order = encoding.order;\n if (!isArray(order) && isValueDef(order)) {\n return undefined;\n } else if ((isArray(order) || isFieldDef(order)) && !stack) {\n // Sort by the order field if it is specified and the field is not stacked. (For stacked field, order specify stack order.)\n return sortParams(order, {expr: 'datum'});\n } else if (isPathMark(mark)) {\n // For both line and area, we sort values based on dimension by default\n const dimensionChannelDef = encoding[markDef.orient === 'horizontal' ? 'y' : 'x'];\n if (isFieldDef(dimensionChannelDef)) {\n const s = dimensionChannelDef.sort;\n const sortField = isSortField(s) ?\n vgField({\n // FIXME: this op might not already exist?\n // FIXME: what if dimensionChannel (x or y) contains custom domain?\n aggregate: isAggregate(model.encoding) ? s.op : undefined,\n field: s.field\n }, {expr: 'datum'}) :\n vgField(dimensionChannelDef, {\n // For stack with imputation, we only have bin_mid\n binSuffix: model.stack && model.stack.impute ? 'mid' : undefined,\n expr: 'datum'\n });\n\n return {\n field: sortField,\n order: 'descending'\n };\n }\n return undefined;\n }\n return undefined;\n}\n\nfunction getMarkGroups(model: UnitModel, opt: {\n fromPrefix: string\n} = {fromPrefix: ''}) {\n const mark = model.mark;\n\n const clip = model.markDef.clip !== undefined ?\n !!model.markDef.clip : scaleClip(model);\n const style = getStyles(model.markDef);\n const key = model.encoding.key;\n const sort = getSort(model);\n\n const postEncodingTransform = markCompiler[mark].postEncodingTransform ? markCompiler[mark].postEncodingTransform(model) : null;\n\n return [{\n name: model.getName('marks'),\n type: markCompiler[mark].vgMark,\n ...(clip ? {clip: true} : {}),\n ...(style ? {style} : {}),\n ...(key ? {key: {field: key.field}} : {}),\n ...(sort ? {sort} : {}),\n from: {data: opt.fromPrefix + model.requestDataName(MAIN)},\n encode: {\n update: markCompiler[mark].encodeEntry(model)\n },\n ...(postEncodingTransform ? {\n transform: postEncodingTransform\n } : {})\n }];\n\n}\n\n/**\n * Returns list of path grouping fields\n * that the model's spec contains.\n */\nexport function pathGroupingFields(mark: Mark, encoding: Encoding): string[] {\n return keys(encoding).reduce((details, channel) => {\n switch (channel) {\n // x, y, x2, y2, lat, long, lat1, long2, order, tooltip, href, cursor should not cause lines to group\n case 'x':\n case 'y':\n case 'order':\n case 'tooltip':\n case 'href':\n case 'x2':\n case 'y2':\n\n case 'latitude':\n case 'longitude':\n case 'latitude2':\n case 'longitude2':\n // TODO: case 'cursor':\n\n // text, shape, shouldn't be a part of line/trail/area\n case 'text':\n case 'shape':\n return details;\n\n case 'detail':\n case 'key':\n const channelDef = encoding[channel];\n if (channelDef) {\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((fieldDef) => {\n if (!fieldDef.aggregate) {\n details.push(vgField(fieldDef, {}));\n }\n });\n }\n return details;\n\n case 'size':\n if (mark === 'trail') {\n // For trail, size should not group trail lines.\n return details;\n }\n // For line, it should group lines.\n\n /* tslint:disable */\n // intentional fall through\n\n case 'color':\n case 'fill':\n case 'stroke':\n case 'opacity':\n // TODO strokeDashOffset:\n\n /* tslint:enable */\n const fieldDef = getFieldDef(encoding[channel]);\n if (fieldDef && !fieldDef.aggregate) {\n details.push(vgField(fieldDef, {}));\n }\n return details;\n default:\n throw new Error(`Bug: Channel ${channel} unimplemented for line mark`);\n }\n }, []);\n}\n\n/**\n * If scales are bound to interval selections, we want to automatically clip\n * marks to account for panning/zooming interactions. We identify bound scales\n * by the domainRaw property, which gets added during scale parsing.\n */\nfunction scaleClip(model: UnitModel) {\n const xScale = model.getScaleComponent('x');\n const yScale = model.getScaleComponent('y');\n return (xScale && xScale.get('domainRaw')) ||\n (yScale && yScale.get('domainRaw')) ? true : false;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/mixins.d.ts b/build/src/compile/mark/mixins.d.ts new file mode 100644 index 0000000000..2759904c5b --- /dev/null +++ b/build/src/compile/mark/mixins.d.ts @@ -0,0 +1,562 @@ +import { NONPOSITION_SCALE_CHANNELS } from '../../channel'; +import { ChannelDef, FieldDef } from '../../fielddef'; +import { VgEncodeEntry, VgValueRef } from '../../vega.schema'; +import { UnitModel } from '../unit'; +export declare function color(model: UnitModel, opt?: { + valueOnly: boolean; +}): VgEncodeEntry; +export declare type Ignore = Record<'size' | 'orient', 'ignore' | 'include'>; +export declare function baseEncodeEntry(model: UnitModel, ignore: Ignore): { + dir?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + font?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + path?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + text?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + shape?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + width?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + height?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + orient?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + x?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + y?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + x2?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + y2?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fill?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + stroke?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + opacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + size?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + tooltip?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + href?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + interpolate?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + angle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + baseline?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontSize?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontWeight?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + limit?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeWidth?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeDash?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeDashOffset?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeOpacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeJoin?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeMiterLimit?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fillOpacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeCap?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + tension?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + align?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + dx?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + dy?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + radius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + ellipsis?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + theta?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontStyle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + cursor?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + cornerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + url?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + clip?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + xc?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + yc?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + innerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + outerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + startAngle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + endAngle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + defined?: VgValueRef | (VgValueRef & { + test?: string; + })[]; +}; +export declare function valueIfDefined(prop: string, value: string | number | boolean): VgEncodeEntry; +export declare function defined(model: UnitModel): VgEncodeEntry; +/** + * Return mixins for non-positional channels with scales. (Text doesn't have scale.) + */ +export declare function nonPosition(channel: typeof NONPOSITION_SCALE_CHANNELS[0], model: UnitModel, opt?: { + defaultValue?: number | string | boolean; + vgChannel?: string; + defaultRef?: VgValueRef; +}): VgEncodeEntry; +/** + * Return a mixin that include a Vega production rule for a Vega-Lite conditional channel definition. + * or a simple mixin if channel def has no condition. + */ +export declare function wrapCondition(model: UnitModel, channelDef: ChannelDef, vgChannel: string, refFn: (cDef: ChannelDef) => VgValueRef): VgEncodeEntry; +export declare function tooltip(model: UnitModel): VgEncodeEntry; +export declare function text(model: UnitModel, channel?: 'text' | 'href'): VgEncodeEntry; +export declare function bandPosition(fieldDef: FieldDef, channel: 'x' | 'y', model: UnitModel): { + dir?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + font?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + path?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + text?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + shape?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + width?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + height?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + orient?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + x?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + y?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + x2?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + y2?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fill?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + stroke?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + opacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + size?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + tooltip?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + href?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + interpolate?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + angle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + baseline?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontSize?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontWeight?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + limit?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeWidth?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeDash?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeDashOffset?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeOpacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeJoin?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeMiterLimit?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fillOpacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeCap?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + tension?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + align?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + dx?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + dy?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + radius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + ellipsis?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + theta?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontStyle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + cursor?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + cornerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + url?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + clip?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + xc?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + yc?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + innerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + outerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + startAngle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + endAngle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + defined?: VgValueRef | (VgValueRef & { + test?: string; + })[]; +}; +export declare function centeredBandPosition(channel: 'x' | 'y', model: UnitModel, defaultPosRef: VgValueRef, defaultSizeRef: VgValueRef): { + dir?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + font?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + path?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + text?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + shape?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + width?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + height?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + orient?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + x?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + y?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + x2?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + y2?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fill?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + stroke?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + opacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + size?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + tooltip?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + href?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + interpolate?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + angle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + baseline?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontSize?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontWeight?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + limit?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeWidth?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeDash?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeDashOffset?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeOpacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeJoin?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeMiterLimit?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fillOpacity?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + strokeCap?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + tension?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + align?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + dx?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + dy?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + radius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + ellipsis?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + theta?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + fontStyle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + cursor?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + cornerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + url?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + clip?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + xc?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + yc?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + innerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + outerRadius?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + startAngle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + endAngle?: VgValueRef | (VgValueRef & { + test?: string; + })[]; + defined?: VgValueRef | (VgValueRef & { + test?: string; + })[]; +}; +export declare function binnedPosition(fieldDef: FieldDef, channel: 'x' | 'y', scaleName: string, spacing: number, reverse: boolean): { + x2: VgValueRef; + x: VgValueRef; + y2?: undefined; + y?: undefined; +} | { + y2: VgValueRef; + y: VgValueRef; + x2?: undefined; + x?: undefined; +}; +/** + * Return mixins for point (non-band) position channels. + */ +export declare function pointPosition(channel: 'x' | 'y', model: UnitModel, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax', vgChannel?: 'x' | 'y' | 'xc' | 'yc'): { + [x: string]: { + offset: any; + value?: string | number | boolean; + field?: string | { + datum?: string; + group?: string; + parent?: string; + }; + signal?: string; + scale?: string; + mult?: number; + band?: number | boolean | VgValueRef; + } | { + value?: string | number | boolean; + field?: string | { + datum?: string; + group?: string; + parent?: string; + }; + signal?: string; + scale?: string; + mult?: number; + offset?: number | VgValueRef; + band?: number | boolean | VgValueRef; + }; +}; +/** + * Return mixins for x2, y2. + * If channel is not specified, return one channel based on orientation. + */ +export declare function pointPosition2(model: UnitModel, defaultRef: 'zeroOrMin' | 'zeroOrMax', channel: 'x2' | 'y2'): { + [x: string]: { + offset: any; + value?: string | number | boolean; + field?: string | { + datum?: string; + group?: string; + parent?: string; + }; + signal?: string; + scale?: string; + mult?: number; + band?: number | boolean | VgValueRef; + } | { + value?: string | number | boolean; + field?: string | { + datum?: string; + group?: string; + parent?: string; + }; + signal?: string; + scale?: string; + mult?: number; + offset?: number | VgValueRef; + band?: number | boolean | VgValueRef; + }; +}; diff --git a/build/src/compile/mark/mixins.js b/build/src/compile/mark/mixins.js new file mode 100644 index 0000000000..8f06c88b19 --- /dev/null +++ b/build/src/compile/mark/mixins.js @@ -0,0 +1,259 @@ +import * as tslib_1 from "tslib"; +import { isArray } from 'vega-util'; +import { getFieldDef, isConditionalSelection, isValueDef, vgField, } from '../../fielddef'; +import * as log from '../../log'; +import { expression } from '../../predicate'; +import { hasContinuousDomain } from '../../scale'; +import { contains } from '../../util'; +import { VG_MARK_CONFIGS } from '../../vega.schema'; +import { getMarkConfig } from '../common'; +import { selectionPredicate } from '../selection/selection'; +import * as ref from './valueref'; +export function color(model, opt) { + if (opt === void 0) { opt = { valueOnly: false }; } + var _a, _b; + var markDef = model.markDef, encoding = model.encoding, config = model.config; + var filled = markDef.filled, markType = markDef.type; + var configValue = { + fill: getMarkConfig('fill', markDef, config), + stroke: getMarkConfig('stroke', markDef, config), + color: getMarkConfig('color', markDef, config) + }; + var transparentIfNeeded = contains(['bar', 'point', 'circle', 'square', 'geoshape'], markType) ? 'transparent' : undefined; + var defaultValue = { + fill: markDef.fill || configValue.fill || + // If there is no fill, always fill symbols, bar, geoshape + // with transparent fills https://github.com/vega/vega-lite/issues/1316 + transparentIfNeeded, + stroke: markDef.stroke || configValue.stroke + }; + var colorVgChannel = filled ? 'fill' : 'stroke'; + var fillStrokeMarkDefAndConfig = tslib_1.__assign({}, (defaultValue.fill ? { + fill: { value: defaultValue.fill } + } : {}), (defaultValue.stroke ? { + stroke: { value: defaultValue.stroke } + } : {})); + if (encoding.fill || encoding.stroke) { + // ignore encoding.color, markDef.color, config.color + if (markDef.color) { + // warn for markDef.color (no need to warn encoding.color as it will be dropped in normalized already) + log.warn(log.message.droppingColor('property', { fill: 'fill' in encoding, stroke: 'stroke' in encoding })); + } + return tslib_1.__assign({}, nonPosition('fill', model, { defaultValue: defaultValue.fill || transparentIfNeeded }), nonPosition('stroke', model, { defaultValue: defaultValue.stroke })); + } + else if (encoding.color) { + return tslib_1.__assign({}, fillStrokeMarkDefAndConfig, nonPosition('color', model, { + vgChannel: colorVgChannel, + // apply default fill/stroke first, then color config, then transparent if needed. + defaultValue: markDef[colorVgChannel] || markDef.color || configValue[colorVgChannel] || configValue.color || (filled ? transparentIfNeeded : undefined) + })); + } + else if (markDef.fill || markDef.stroke) { + // Ignore markDef.color, config.color + if (markDef.color) { + log.warn(log.message.droppingColor('property', { fill: 'fill' in markDef, stroke: 'stroke' in markDef })); + } + return fillStrokeMarkDefAndConfig; + } + else if (markDef.color) { + return tslib_1.__assign({}, fillStrokeMarkDefAndConfig, (_a = {}, _a[colorVgChannel] = { value: markDef.color }, _a)); + } + else if (configValue.fill || configValue.stroke) { + // ignore config.color + return fillStrokeMarkDefAndConfig; + } + else if (configValue.color) { + return tslib_1.__assign({}, (transparentIfNeeded ? { fill: { value: 'transparent' } } : {}), (_b = {}, _b[colorVgChannel] = { value: configValue.color }, _b)); + } + return {}; +} +export function baseEncodeEntry(model, ignore) { + return tslib_1.__assign({}, markDefProperties(model.markDef, ignore), color(model), nonPosition('opacity', model), tooltip(model), text(model, 'href')); +} +function markDefProperties(mark, ignore) { + return VG_MARK_CONFIGS.reduce(function (m, prop) { + if (mark[prop] !== undefined && ignore[prop] !== 'ignore') { + m[prop] = { value: mark[prop] }; + } + return m; + }, {}); +} +export function valueIfDefined(prop, value) { + var _a; + if (value !== undefined) { + return _a = {}, _a[prop] = { value: value }, _a; + } + return undefined; +} +function validPredicate(vgRef) { + return vgRef + " !== null && !isNaN(" + vgRef + ")"; +} +export function defined(model) { + if (model.config.invalidValues === 'filter') { + var fields = ['x', 'y'].map(function (channel) { + var scaleComponent = model.getScaleComponent(channel); + if (scaleComponent) { + var scaleType = scaleComponent.get('type'); + // Discrete domain scales can handle invalid values, but continuous scales can't. + if (hasContinuousDomain(scaleType)) { + return model.vgField(channel, { expr: 'datum' }); + } + } + return undefined; + }) + .filter(function (field) { return !!field; }) + .map(validPredicate); + if (fields.length > 0) { + return { + defined: { signal: fields.join(' && ') } + }; + } + } + return {}; +} +/** + * Return mixins for non-positional channels with scales. (Text doesn't have scale.) + */ +export function nonPosition(channel, model, opt) { + if (opt === void 0) { opt = {}; } + var defaultValue = opt.defaultValue, vgChannel = opt.vgChannel; + var defaultRef = opt.defaultRef || (defaultValue !== undefined ? { value: defaultValue } : undefined); + var channelDef = model.encoding[channel]; + return wrapCondition(model, channelDef, vgChannel || channel, function (cDef) { + return ref.midPoint(channel, cDef, model.scaleName(channel), model.getScaleComponent(channel), null, // No need to provide stack for non-position as it does not affect mid point + defaultRef); + }); +} +/** + * Return a mixin that include a Vega production rule for a Vega-Lite conditional channel definition. + * or a simple mixin if channel def has no condition. + */ +export function wrapCondition(model, channelDef, vgChannel, refFn) { + var _a, _b; + var condition = channelDef && channelDef.condition; + var valueRef = refFn(channelDef); + if (condition) { + var conditions = isArray(condition) ? condition : [condition]; + var vgConditions = conditions.map(function (c) { + var conditionValueRef = refFn(c); + var test = isConditionalSelection(c) ? selectionPredicate(model, c.selection) : expression(model, c.test); + return tslib_1.__assign({ test: test }, conditionValueRef); + }); + return _a = {}, + _a[vgChannel] = vgConditions.concat((valueRef !== undefined ? [valueRef] : [])), + _a; + } + else { + return valueRef !== undefined ? (_b = {}, _b[vgChannel] = valueRef, _b) : {}; + } +} +export function tooltip(model) { + var channel = 'tooltip'; + var channelDef = model.encoding[channel]; + if (isArray(channelDef)) { + var keyValues = channelDef.map(function (fieldDef) { + var key = fieldDef.title !== undefined ? fieldDef.title : vgField(fieldDef, { binSuffix: 'range' }); + var value = ref.text(fieldDef, model.config).signal; + return "\"" + key + "\": " + value; + }); + return { tooltip: { signal: "{" + keyValues.join(', ') + "}" } }; + } + else { + // if not an array, behave just like text + return textCommon(model, channel, channelDef); + } +} +export function text(model, channel) { + if (channel === void 0) { channel = 'text'; } + var channelDef = model.encoding[channel]; + return textCommon(model, channel, channelDef); +} +function textCommon(model, channel, channelDef) { + return wrapCondition(model, channelDef, channel, function (cDef) { return ref.text(cDef, model.config); }); +} +export function bandPosition(fieldDef, channel, model) { + var _a, _b, _c; + var scaleName = model.scaleName(channel); + var sizeChannel = channel === 'x' ? 'width' : 'height'; + if (model.encoding.size || model.markDef.size !== undefined) { + var orient = model.markDef.orient; + if (orient) { + var centeredBandPositionMixins = (_a = {}, + // Use xc/yc and place the mark at the middle of the band + // This way we never have to deal with size's condition for x/y position. + _a[channel + 'c'] = ref.fieldRef(fieldDef, scaleName, {}, { band: 0.5 }), + _a); + if (getFieldDef(model.encoding.size)) { + return tslib_1.__assign({}, centeredBandPositionMixins, nonPosition('size', model, { vgChannel: sizeChannel })); + } + else if (isValueDef(model.encoding.size)) { + return tslib_1.__assign({}, centeredBandPositionMixins, nonPosition('size', model, { vgChannel: sizeChannel })); + } + else if (model.markDef.size !== undefined) { + return tslib_1.__assign({}, centeredBandPositionMixins, (_b = {}, _b[sizeChannel] = { value: model.markDef.size }, _b)); + } + } + else { + log.warn(log.message.cannotApplySizeToNonOrientedMark(model.markDef.type)); + } + } + return _c = {}, + _c[channel] = ref.fieldRef(fieldDef, scaleName, { binSuffix: 'range' }), + _c[sizeChannel] = ref.bandRef(scaleName), + _c; +} +export function centeredBandPosition(channel, model, defaultPosRef, defaultSizeRef) { + var centerChannel = channel === 'x' ? 'xc' : 'yc'; + var sizeChannel = channel === 'x' ? 'width' : 'height'; + return tslib_1.__assign({}, pointPosition(channel, model, defaultPosRef, centerChannel), nonPosition('size', model, { defaultRef: defaultSizeRef, vgChannel: sizeChannel })); +} +export function binnedPosition(fieldDef, channel, scaleName, spacing, reverse) { + if (channel === 'x') { + return { + x2: ref.bin(fieldDef, scaleName, 'start', reverse ? 0 : spacing), + x: ref.bin(fieldDef, scaleName, 'end', reverse ? spacing : 0) + }; + } + else { + return { + y2: ref.bin(fieldDef, scaleName, 'start', reverse ? spacing : 0), + y: ref.bin(fieldDef, scaleName, 'end', reverse ? 0 : spacing) + }; + } +} +/** + * Return mixins for point (non-band) position channels. + */ +export function pointPosition(channel, model, defaultRef, vgChannel) { + // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613 + var _a; + var encoding = model.encoding, mark = model.mark, stack = model.stack; + var channelDef = encoding[channel]; + var scaleName = model.scaleName(channel); + var scale = model.getScaleComponent(channel); + var offset = ref.getOffset(channel, model.markDef); + var valueRef = !channelDef && (encoding.latitude || encoding.longitude) ? + // use geopoint output if there are lat/long and there is no point position overriding lat/long. + { field: model.getName(channel) } : tslib_1.__assign({}, ref.position(channel, encoding[channel], scaleName, scale, stack, ref.getDefaultRef(defaultRef, channel, scaleName, scale, mark)), (offset ? { offset: offset } : {})); + return _a = {}, + _a[vgChannel || channel] = valueRef, + _a; +} +/** + * Return mixins for x2, y2. + * If channel is not specified, return one channel based on orientation. + */ +export function pointPosition2(model, defaultRef, channel) { + var _a; + var encoding = model.encoding, mark = model.mark, stack = model.stack; + var baseChannel = channel === 'x2' ? 'x' : 'y'; + var channelDef = encoding[baseChannel]; + var scaleName = model.scaleName(baseChannel); + var scale = model.getScaleComponent(baseChannel); + var offset = ref.getOffset(channel, model.markDef); + var valueRef = !channelDef && (encoding.latitude || encoding.longitude) ? + // use geopoint output if there are lat2/long2 and there is no point position2 overriding lat2/long2. + { field: model.getName(channel) } : tslib_1.__assign({}, ref.position2(channel, channelDef, encoding[channel], scaleName, scale, stack, ref.getDefaultRef(defaultRef, baseChannel, scaleName, scale, mark)), (offset ? { offset: offset } : {})); + return _a = {}, _a[channel] = valueRef, _a; +} +//# sourceMappingURL=mixins.js.map \ No newline at end of file diff --git a/build/src/compile/mark/mixins.js.map b/build/src/compile/mark/mixins.js.map new file mode 100644 index 0000000000..df46c6ea3b --- /dev/null +++ b/build/src/compile/mark/mixins.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mixins.js","sourceRoot":"","sources":["../../../../src/compile/mark/mixins.ts"],"names":[],"mappings":"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","sourcesContent":["import {isArray} from 'vega-util';\n\nimport {NONPOSITION_SCALE_CHANNELS, PositionScaleChannel} from '../../channel';\nimport {\n ChannelDef,\n FieldDef,\n FieldDefWithCondition,\n getFieldDef,\n isConditionalSelection,\n isValueDef,\n TextFieldDef,\n ValueDefWithCondition,\n vgField,\n} from '../../fielddef';\nimport * as log from '../../log';\nimport {MarkDef} from '../../mark';\nimport {expression} from '../../predicate';\nimport {hasContinuousDomain} from '../../scale';\nimport {contains} from '../../util';\nimport {VG_MARK_CONFIGS, VgEncodeEntry, VgValueRef} from '../../vega.schema';\nimport {getMarkConfig} from '../common';\nimport {selectionPredicate} from '../selection/selection';\nimport {UnitModel} from '../unit';\nimport * as ref from './valueref';\n\nexport function color(model: UnitModel, opt: {valueOnly: boolean} = {valueOnly: false}): VgEncodeEntry {\n const {markDef, encoding, config} = model;\n const {filled, type: markType} = markDef;\n\n const configValue = {\n fill: getMarkConfig('fill', markDef, config),\n stroke: getMarkConfig('stroke', markDef, config),\n color: getMarkConfig('color', markDef, config)\n };\n\n const transparentIfNeeded = contains(['bar', 'point', 'circle', 'square', 'geoshape'], markType) ? 'transparent' : undefined;\n\n const defaultValue = {\n fill: markDef.fill || configValue.fill ||\n // If there is no fill, always fill symbols, bar, geoshape\n // with transparent fills https://github.com/vega/vega-lite/issues/1316\n transparentIfNeeded,\n stroke: markDef.stroke || configValue.stroke\n };\n\n const colorVgChannel = filled ? 'fill' : 'stroke';\n\n const fillStrokeMarkDefAndConfig: VgEncodeEntry = {\n ...(defaultValue.fill ? {\n fill: {value: defaultValue.fill}\n } : {}),\n ...(defaultValue.stroke ? {\n stroke: {value: defaultValue.stroke}\n } : {}),\n };\n\n if (encoding.fill || encoding.stroke) {\n // ignore encoding.color, markDef.color, config.color\n if (markDef.color) {\n // warn for markDef.color (no need to warn encoding.color as it will be dropped in normalized already)\n log.warn(log.message.droppingColor('property', {fill: 'fill' in encoding, stroke: 'stroke' in encoding}));\n }\n\n return {\n ...nonPosition('fill', model, {defaultValue: defaultValue.fill || transparentIfNeeded}),\n ...nonPosition('stroke', model, {defaultValue: defaultValue.stroke})\n };\n } else if (encoding.color) {\n\n return {\n ...fillStrokeMarkDefAndConfig,\n // override them with encoded color field\n ...nonPosition('color', model, {\n vgChannel: colorVgChannel,\n // apply default fill/stroke first, then color config, then transparent if needed.\n defaultValue: markDef[colorVgChannel] || markDef.color || configValue[colorVgChannel] || configValue.color || (filled ? transparentIfNeeded : undefined)\n })\n };\n } else if (markDef.fill || markDef.stroke) {\n // Ignore markDef.color, config.color\n if (markDef.color) {\n log.warn(log.message.droppingColor('property', {fill: 'fill' in markDef, stroke: 'stroke' in markDef}));\n }\n return fillStrokeMarkDefAndConfig;\n } else if (markDef.color) {\n return {\n ...fillStrokeMarkDefAndConfig, // in this case, fillStrokeMarkDefAndConfig only include config\n\n // override config with markDef.color\n [colorVgChannel]: {value: markDef.color}\n };\n } else if (configValue.fill || configValue.stroke) {\n // ignore config.color\n return fillStrokeMarkDefAndConfig;\n } else if (configValue.color) {\n return {\n ...(transparentIfNeeded ? {fill: {value: 'transparent'}} : {}),\n [colorVgChannel]: {value: configValue.color}\n };\n }\n return {};\n}\n\nexport type Ignore = Record<'size' | 'orient', 'ignore' | 'include'>;\n\nexport function baseEncodeEntry(model: UnitModel, ignore: Ignore) {\n return {\n ...markDefProperties(model.markDef, ignore),\n ...color(model),\n ...nonPosition('opacity', model),\n ...tooltip(model),\n ...text(model, 'href')\n };\n}\n\nfunction markDefProperties(mark: MarkDef, ignore: Ignore) {\n return VG_MARK_CONFIGS.reduce((m, prop) => {\n if (mark[prop] !== undefined && ignore[prop] !== 'ignore') {\n m[prop] = {value: mark[prop]};\n }\n return m;\n }, {});\n}\n\nexport function valueIfDefined(prop: string, value: string | number | boolean): VgEncodeEntry {\n if (value !== undefined) {\n return {[prop]: {value: value}};\n }\n return undefined;\n}\n\nfunction validPredicate(vgRef: string) {\n return `${vgRef} !== null && !isNaN(${vgRef})`;\n}\n\nexport function defined(model: UnitModel): VgEncodeEntry {\n if (model.config.invalidValues === 'filter') {\n const fields = ['x', 'y'].map((channel: PositionScaleChannel) => {\n const scaleComponent = model.getScaleComponent(channel);\n if (scaleComponent) {\n const scaleType = scaleComponent.get('type');\n\n // Discrete domain scales can handle invalid values, but continuous scales can't.\n if (hasContinuousDomain(scaleType)) {\n return model.vgField(channel, {expr: 'datum'});\n }\n }\n return undefined;\n })\n .filter(field => !!field)\n .map(validPredicate);\n\n if (fields.length > 0) {\n return {\n defined: {signal: fields.join(' && ')}\n };\n }\n }\n\n return {};\n}\n\n/**\n * Return mixins for non-positional channels with scales. (Text doesn't have scale.)\n */\nexport function nonPosition(channel: typeof NONPOSITION_SCALE_CHANNELS[0], model: UnitModel, opt: {defaultValue?: number | string | boolean, vgChannel?: string, defaultRef?: VgValueRef} = {}): VgEncodeEntry {\n const {defaultValue, vgChannel} = opt;\n const defaultRef = opt.defaultRef || (defaultValue !== undefined ? {value: defaultValue} : undefined);\n\n const channelDef = model.encoding[channel];\n\n return wrapCondition(model, channelDef, vgChannel || channel, (cDef) => {\n return ref.midPoint(\n channel, cDef, model.scaleName(channel),\n model.getScaleComponent(channel),\n null, // No need to provide stack for non-position as it does not affect mid point\n defaultRef\n );\n });\n}\n\n/**\n * Return a mixin that include a Vega production rule for a Vega-Lite conditional channel definition.\n * or a simple mixin if channel def has no condition.\n */\nexport function wrapCondition(\n model: UnitModel, channelDef: ChannelDef, vgChannel: string,\n refFn: (cDef: ChannelDef) => VgValueRef\n ): VgEncodeEntry {\n const condition = channelDef && channelDef.condition;\n const valueRef = refFn(channelDef);\n if (condition) {\n const conditions = isArray(condition) ? condition : [condition];\n const vgConditions = conditions.map((c) => {\n const conditionValueRef = refFn(c);\n const test = isConditionalSelection(c) ? selectionPredicate(model, c.selection) : expression(model, c.test);\n return {\n test,\n ...conditionValueRef\n };\n });\n return {\n [vgChannel]: [\n ...vgConditions,\n ...(valueRef !== undefined ? [valueRef] : [])\n ]\n };\n } else {\n return valueRef !== undefined ? {[vgChannel]: valueRef} : {};\n }\n}\n\nexport function tooltip(model: UnitModel) {\n const channel = 'tooltip';\n const channelDef = model.encoding[channel];\n if (isArray(channelDef)) {\n const keyValues = channelDef.map((fieldDef) => {\n const key = fieldDef.title !== undefined ? fieldDef.title : vgField(fieldDef, {binSuffix: 'range'});\n const value = ref.text(fieldDef, model.config).signal;\n return `\"${key}\": ${value}`;\n });\n return {tooltip: {signal: `{${keyValues.join(', ')}}`}};\n } else {\n // if not an array, behave just like text\n return textCommon(model, channel, channelDef);\n }\n}\n\nexport function text(model: UnitModel, channel: 'text' | 'href' = 'text') {\n const channelDef = model.encoding[channel];\n return textCommon(model, channel, channelDef);\n}\n\nfunction textCommon(model: UnitModel, channel: 'text' | 'href' | 'tooltip', channelDef: FieldDefWithCondition> | ValueDefWithCondition>) {\n return wrapCondition(model, channelDef, channel, (cDef) => ref.text(cDef, model.config));\n}\n\nexport function bandPosition(fieldDef: FieldDef, channel: 'x'|'y', model: UnitModel) {\n const scaleName = model.scaleName(channel);\n const sizeChannel = channel === 'x' ? 'width' : 'height';\n\n if (model.encoding.size || model.markDef.size !== undefined) {\n const orient = model.markDef.orient;\n if (orient) {\n const centeredBandPositionMixins = {\n // Use xc/yc and place the mark at the middle of the band\n // This way we never have to deal with size's condition for x/y position.\n [channel+'c']: ref.fieldRef(fieldDef, scaleName, {}, {band: 0.5})\n };\n\n if (getFieldDef(model.encoding.size)) {\n return {\n ...centeredBandPositionMixins,\n ...nonPosition('size', model, {vgChannel: sizeChannel})\n };\n } else if (isValueDef(model.encoding.size)) {\n return {\n ...centeredBandPositionMixins,\n ...nonPosition('size', model, {vgChannel: sizeChannel})\n };\n } else if (model.markDef.size !== undefined) {\n return {\n ...centeredBandPositionMixins,\n [sizeChannel]: {value: model.markDef.size}\n };\n }\n } else {\n log.warn(log.message.cannotApplySizeToNonOrientedMark(model.markDef.type));\n }\n }\n return {\n [channel]: ref.fieldRef(fieldDef, scaleName, {binSuffix: 'range'}),\n [sizeChannel]: ref.bandRef(scaleName)\n };\n}\n\nexport function centeredBandPosition(channel: 'x' | 'y', model: UnitModel, defaultPosRef: VgValueRef, defaultSizeRef: VgValueRef) {\n const centerChannel: 'xc' | 'yc' = channel === 'x' ? 'xc' : 'yc';\n const sizeChannel = channel === 'x' ? 'width' : 'height';\n return {\n ...pointPosition(channel, model, defaultPosRef, centerChannel),\n ...nonPosition('size', model, {defaultRef: defaultSizeRef, vgChannel: sizeChannel})\n };\n}\n\nexport function binnedPosition(fieldDef: FieldDef, channel: 'x'|'y', scaleName: string, spacing: number, reverse: boolean) {\n if (channel === 'x') {\n return {\n x2: ref.bin(fieldDef, scaleName, 'start', reverse ? 0 : spacing),\n x: ref.bin(fieldDef, scaleName, 'end', reverse ? spacing : 0)\n };\n } else {\n return {\n y2: ref.bin(fieldDef, scaleName, 'start', reverse ? spacing : 0),\n y: ref.bin(fieldDef, scaleName, 'end', reverse ? 0 : spacing)\n };\n }\n}\n\n\n/**\n * Return mixins for point (non-band) position channels.\n */\nexport function pointPosition(channel: 'x'|'y', model: UnitModel, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax', vgChannel?: 'x'|'y'|'xc'|'yc') {\n // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613\n\n const {encoding, mark, stack} = model;\n\n const channelDef = encoding[channel];\n const scaleName = model.scaleName(channel);\n const scale = model.getScaleComponent(channel);\n\n\n const offset = ref.getOffset(channel, model.markDef);\n\n\n const valueRef = !channelDef && (encoding.latitude || encoding.longitude) ?\n // use geopoint output if there are lat/long and there is no point position overriding lat/long.\n {field: model.getName(channel)} :\n {\n ...ref.position(channel, encoding[channel], scaleName, scale, stack,\n ref.getDefaultRef(defaultRef, channel, scaleName, scale, mark)\n ),\n ...(offset ? {offset}: {})\n };\n\n return {\n [vgChannel || channel]: valueRef\n };\n}\n\n/**\n * Return mixins for x2, y2.\n * If channel is not specified, return one channel based on orientation.\n */\nexport function pointPosition2(model: UnitModel, defaultRef: 'zeroOrMin' | 'zeroOrMax', channel: 'x2' | 'y2') {\n const {encoding, mark, stack} = model;\n\n const baseChannel = channel === 'x2' ? 'x' : 'y';\n const channelDef = encoding[baseChannel];\n const scaleName = model.scaleName(baseChannel);\n const scale = model.getScaleComponent(baseChannel);\n\n const offset = ref.getOffset(channel, model.markDef);\n\n const valueRef = !channelDef && (encoding.latitude || encoding.longitude) ?\n // use geopoint output if there are lat2/long2 and there is no point position2 overriding lat2/long2.\n {field: model.getName(channel)}:\n {\n ...ref.position2(channel, channelDef, encoding[channel], scaleName, scale, stack,\n ref.getDefaultRef(defaultRef, baseChannel, scaleName, scale, mark)\n ),\n ...(offset ? {offset} : {})\n };\n\n return {[channel]: valueRef};\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/point.d.ts b/build/src/compile/mark/point.d.ts new file mode 100644 index 0000000000..23c1a43b81 --- /dev/null +++ b/build/src/compile/mark/point.d.ts @@ -0,0 +1,8 @@ +import { Config } from '../../config'; +import { VgEncodeEntry } from '../../vega.schema'; +import { UnitModel } from '../unit'; +import { MarkCompiler } from './base'; +export declare function shapeMixins(model: UnitModel, config: Config, fixedShape?: 'circle' | 'square'): VgEncodeEntry; +export declare const point: MarkCompiler; +export declare const circle: MarkCompiler; +export declare const square: MarkCompiler; diff --git a/build/src/compile/mark/point.js b/build/src/compile/mark/point.js new file mode 100644 index 0000000000..38a4b811e7 --- /dev/null +++ b/build/src/compile/mark/point.js @@ -0,0 +1,33 @@ +import * as tslib_1 from "tslib"; +import { getMarkConfig } from '../common'; +import * as mixins from './mixins'; +import * as ref from './valueref'; +function encodeEntry(model, fixedShape) { + var config = model.config, width = model.width, height = model.height; + return tslib_1.__assign({}, mixins.baseEncodeEntry(model, { size: 'include', orient: 'ignore' }), mixins.pointPosition('x', model, ref.mid(width)), mixins.pointPosition('y', model, ref.mid(height)), mixins.nonPosition('size', model), shapeMixins(model, config, fixedShape)); +} +export function shapeMixins(model, config, fixedShape) { + if (fixedShape) { + return { shape: { value: fixedShape } }; + } + return mixins.nonPosition('shape', model, { defaultValue: getMarkConfig('shape', model.markDef, config) }); +} +export var point = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model); + } +}; +export var circle = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model, 'circle'); + } +}; +export var square = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model, 'square'); + } +}; +//# sourceMappingURL=point.js.map \ No newline at end of file diff --git a/build/src/compile/mark/point.js.map b/build/src/compile/mark/point.js.map new file mode 100644 index 0000000000..d9643cb61d --- /dev/null +++ b/build/src/compile/mark/point.js.map @@ -0,0 +1 @@ +{"version":3,"file":"point.js","sourceRoot":"","sources":["../../../../src/compile/mark/point.ts"],"names":[],"mappings":";AAEA,OAAO,EAAC,aAAa,EAAC,MAAM,WAAW,CAAC;AAGxC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAGlC,qBAAqB,KAAgB,EAAE,UAAgC;IAC9D,IAAA,qBAAM,EAAE,mBAAK,EAAE,qBAAM,CAAU;IAEtC,4BACK,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAC,CAAC,EAClE,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAChD,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EACjD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,EACjC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EACzC;AACJ,CAAC;AAED,MAAM,sBAAsB,KAAgB,EAAE,MAAc,EAAE,UAAgC;IAC5F,IAAI,UAAU,EAAE;QACd,OAAO,EAAC,KAAK,EAAE,EAAC,KAAK,EAAE,UAAU,EAAC,EAAC,CAAC;KACrC;IACD,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,EAAC,YAAY,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAW,EAAC,CAAC,CAAC;AACrH,CAAC;AAED,MAAM,CAAC,IAAM,KAAK,GAAiB;IACjC,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,UAAC,KAAgB;QAC5B,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,IAAM,MAAM,GAAiB;IAClC,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,UAAC,KAAgB;QAC5B,OAAO,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,IAAM,MAAM,GAAiB;IAClC,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,UAAC,KAAgB;QAC5B,OAAO,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;CACF,CAAC","sourcesContent":["import {Config} from '../../config';\nimport {VgEncodeEntry} from '../../vega.schema';\nimport {getMarkConfig} from '../common';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nfunction encodeEntry(model: UnitModel, fixedShape?: 'circle' | 'square') {\n const {config, width, height} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'include', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.nonPosition('size', model),\n ...shapeMixins(model, config, fixedShape),\n };\n}\n\nexport function shapeMixins(model: UnitModel, config: Config, fixedShape?: 'circle' | 'square'): VgEncodeEntry {\n if (fixedShape) {\n return {shape: {value: fixedShape}};\n }\n return mixins.nonPosition('shape', model, {defaultValue: getMarkConfig('shape', model.markDef, config) as string});\n}\n\nexport const point: MarkCompiler = {\n vgMark: 'symbol',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model);\n }\n};\n\nexport const circle: MarkCompiler = {\n vgMark: 'symbol',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model, 'circle');\n }\n};\n\nexport const square: MarkCompiler = {\n vgMark: 'symbol',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model, 'square');\n }\n};\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/rect.d.ts b/build/src/compile/mark/rect.d.ts new file mode 100644 index 0000000000..f112c90fad --- /dev/null +++ b/build/src/compile/mark/rect.d.ts @@ -0,0 +1,6 @@ +import { VgEncodeEntry } from '../../vega.schema'; +import { UnitModel } from '../unit'; +import { MarkCompiler } from './base'; +export declare const rect: MarkCompiler; +export declare function x(model: UnitModel): VgEncodeEntry; +export declare function y(model: UnitModel): VgEncodeEntry; diff --git a/build/src/compile/mark/rect.js b/build/src/compile/mark/rect.js new file mode 100644 index 0000000000..21cc33f057 --- /dev/null +++ b/build/src/compile/mark/rect.js @@ -0,0 +1,58 @@ +import * as tslib_1 from "tslib"; +import { X, Y } from '../../channel'; +import { isFieldDef } from '../../fielddef'; +import * as log from '../../log'; +import { RECT } from '../../mark'; +import { hasDiscreteDomain, ScaleType } from '../../scale'; +import * as mixins from './mixins'; +export var rect = { + vgMark: 'rect', + encodeEntry: function (model) { + return tslib_1.__assign({}, mixins.baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), x(model), y(model)); + } +}; +export function x(model) { + var xDef = model.encoding.x; + var x2Def = model.encoding.x2; + var xScale = model.getScaleComponent(X); + var xScaleType = xScale ? xScale.get('type') : undefined; + if (isFieldDef(xDef) && xDef.bin && !x2Def) { + return mixins.binnedPosition(xDef, 'x', model.scaleName('x'), 0, xScale.get('reverse')); + } + else if (isFieldDef(xDef) && xScale && hasDiscreteDomain(xScaleType)) { + /* istanbul ignore else */ + if (xScaleType === ScaleType.BAND) { + return mixins.bandPosition(xDef, 'x', model); + } + else { + // We don't support rect mark with point/ordinal scale + throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, xScaleType)); + } + } + else { // continuous scale or no scale + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMax'), mixins.pointPosition2(model, 'zeroOrMin', 'x2')); + } +} +export function y(model) { + var yDef = model.encoding.y; + var y2Def = model.encoding.y2; + var yScale = model.getScaleComponent(Y); + var yScaleType = yScale ? yScale.get('type') : undefined; + if (isFieldDef(yDef) && yDef.bin && !y2Def) { + return mixins.binnedPosition(yDef, 'y', model.scaleName('y'), 0, yScale.get('reverse')); + } + else if (isFieldDef(yDef) && yScale && hasDiscreteDomain(yScaleType)) { + /* istanbul ignore else */ + if (yScaleType === ScaleType.BAND) { + return mixins.bandPosition(yDef, 'y', model); + } + else { + // We don't support rect mark with point/ordinal scale + throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, yScaleType)); + } + } + else { // continuous scale or no scale + return tslib_1.__assign({}, mixins.pointPosition('y', model, 'zeroOrMax'), mixins.pointPosition2(model, 'zeroOrMin', 'y2')); + } +} +//# sourceMappingURL=rect.js.map \ No newline at end of file diff --git a/build/src/compile/mark/rect.js.map b/build/src/compile/mark/rect.js.map new file mode 100644 index 0000000000..a0b9dda955 --- /dev/null +++ b/build/src/compile/mark/rect.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rect.js","sourceRoot":"","sources":["../../../../src/compile/mark/rect.ts"],"names":[],"mappings":"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","sourcesContent":["import {X, Y} from '../../channel';\nimport {isFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {RECT} from '../../mark';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {VgEncodeEntry} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\n\nexport const rect: MarkCompiler = {\n vgMark: 'rect',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...x(model),\n ...y(model),\n };\n }\n};\n\nexport function x(model: UnitModel): VgEncodeEntry {\n const xDef = model.encoding.x;\n const x2Def = model.encoding.x2;\n const xScale = model.getScaleComponent(X);\n const xScaleType = xScale ? xScale.get('type') : undefined;\n\n if (isFieldDef(xDef) && xDef.bin && !x2Def) {\n return mixins.binnedPosition(xDef, 'x', model.scaleName('x'), 0, xScale.get('reverse'));\n } else if (isFieldDef(xDef) && xScale && hasDiscreteDomain(xScaleType)) {\n /* istanbul ignore else */\n if (xScaleType === ScaleType.BAND) {\n return mixins.bandPosition(xDef, 'x', model);\n } else {\n // We don't support rect mark with point/ordinal scale\n throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, xScaleType));\n }\n } else { // continuous scale or no scale\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMax'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'x2')\n };\n }\n}\n\nexport function y(model: UnitModel): VgEncodeEntry {\n const yDef = model.encoding.y;\n const y2Def = model.encoding.y2;\n const yScale = model.getScaleComponent(Y);\n const yScaleType = yScale ? yScale.get('type') : undefined;\n\n if (isFieldDef(yDef) && yDef.bin && !y2Def) {\n return mixins.binnedPosition(yDef, 'y', model.scaleName('y'), 0, yScale.get('reverse'));\n } else if (isFieldDef(yDef) && yScale && hasDiscreteDomain(yScaleType)) {\n /* istanbul ignore else */\n if (yScaleType === ScaleType.BAND) {\n return mixins.bandPosition(yDef, 'y', model);\n } else {\n // We don't support rect mark with point/ordinal scale\n throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, yScaleType));\n }\n } else { // continuous scale or no scale\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMax'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'y2')\n };\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/rule.d.ts b/build/src/compile/mark/rule.d.ts new file mode 100644 index 0000000000..4b4078e38f --- /dev/null +++ b/build/src/compile/mark/rule.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const rule: MarkCompiler; diff --git a/build/src/compile/mark/rule.js b/build/src/compile/mark/rule.js new file mode 100644 index 0000000000..811fa22efc --- /dev/null +++ b/build/src/compile/mark/rule.js @@ -0,0 +1,19 @@ +import * as tslib_1 from "tslib"; +import * as mixins from './mixins'; +import * as ref from './valueref'; +export var rule = { + vgMark: 'rule', + encodeEntry: function (model) { + var _config = model.config, markDef = model.markDef, width = model.width, height = model.height; + var orient = markDef.orient; + if (!model.encoding.x && !model.encoding.y && !model.encoding.latitude && !model.encoding.longitude) { + // Show nothing if we have none of x, y, lat, and long. + return {}; + } + return tslib_1.__assign({}, mixins.baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), mixins.pointPosition('x', model, orient === 'horizontal' ? 'zeroOrMin' : ref.mid(width)), mixins.pointPosition('y', model, orient === 'vertical' ? 'zeroOrMin' : ref.mid(height)), (orient !== 'vertical' ? mixins.pointPosition2(model, 'zeroOrMax', 'x2') : {}), (orient !== 'horizontal' ? mixins.pointPosition2(model, 'zeroOrMax', 'y2') : {}), mixins.nonPosition('size', model, { + vgChannel: 'strokeWidth', + defaultValue: markDef.size + })); + } +}; +//# sourceMappingURL=rule.js.map \ No newline at end of file diff --git a/build/src/compile/mark/rule.js.map b/build/src/compile/mark/rule.js.map new file mode 100644 index 0000000000..bcfa58fc6d --- /dev/null +++ b/build/src/compile/mark/rule.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rule.js","sourceRoot":"","sources":["../../../../src/compile/mark/rule.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,IAAM,IAAI,GAAiB;IAChC,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,UAAC,KAAgB;QACrB,IAAA,sBAAe,EAAE,uBAAO,EAAE,mBAAK,EAAE,qBAAM,CAAU;QACxD,IAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAE9B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE;YACnG,uDAAuD;YACvD,OAAO,EAAE,CAAC;SACX;QAED,4BACK,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAC,CAAC,EACjE,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EACxF,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAGvF,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAG9E,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAEhF,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE;YACnC,SAAS,EAAE,aAAa;YACxB,YAAY,EAAE,OAAO,CAAC,IAAI;SAC3B,CAAC,EACF;IACJ,CAAC;CACF,CAAC","sourcesContent":["import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\nexport const rule: MarkCompiler = {\n vgMark: 'rule',\n encodeEntry: (model: UnitModel) => {\n const {config: _config, markDef, width, height} = model;\n const orient = markDef.orient;\n\n if (!model.encoding.x && !model.encoding.y && !model.encoding.latitude && !model.encoding.longitude) {\n // Show nothing if we have none of x, y, lat, and long.\n return {};\n }\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, orient === 'horizontal' ? 'zeroOrMin' : ref.mid(width)),\n ...mixins.pointPosition('y', model, orient === 'vertical' ? 'zeroOrMin' : ref.mid(height)),\n\n // include x2 for horizontal or line segment rule\n ...(orient !== 'vertical' ? mixins.pointPosition2(model, 'zeroOrMax', 'x2') : {}),\n\n // include y2 for vertical or line segment rule\n ...(orient !== 'horizontal' ? mixins.pointPosition2(model, 'zeroOrMax', 'y2') : {}),\n\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth', // VL's rule size is strokeWidth\n defaultValue: markDef.size\n })\n };\n }\n};\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/text.d.ts b/build/src/compile/mark/text.d.ts new file mode 100644 index 0000000000..3f8145da15 --- /dev/null +++ b/build/src/compile/mark/text.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const text: MarkCompiler; diff --git a/build/src/compile/mark/text.js b/build/src/compile/mark/text.js new file mode 100644 index 0000000000..ea2c0731b1 --- /dev/null +++ b/build/src/compile/mark/text.js @@ -0,0 +1,21 @@ +import * as tslib_1 from "tslib"; +import { getMarkConfig } from '../common'; +import * as mixins from './mixins'; +import * as ref from './valueref'; +export var text = { + vgMark: 'text', + encodeEntry: function (model) { + var config = model.config, encoding = model.encoding, width = model.width, height = model.height, markDef = model.markDef; + return tslib_1.__assign({}, mixins.baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), mixins.pointPosition('x', model, ref.mid(width)), mixins.pointPosition('y', model, ref.mid(height)), mixins.text(model), mixins.nonPosition('size', model, tslib_1.__assign({}, (markDef.size ? { defaultValue: markDef.size } : {}), { vgChannel: 'fontSize' // VL's text size is fontSize + })), mixins.valueIfDefined('align', align(model.markDef, encoding, config))); + } +}; +function align(markDef, encoding, config) { + var a = markDef.align || getMarkConfig('align', markDef, config); + if (a === undefined) { + return 'center'; + } + // If there is a config, Vega-parser will process this already. + return undefined; +} +//# sourceMappingURL=text.js.map \ No newline at end of file diff --git a/build/src/compile/mark/text.js.map b/build/src/compile/mark/text.js.map new file mode 100644 index 0000000000..fcc30d5ca6 --- /dev/null +++ b/build/src/compile/mark/text.js.map @@ -0,0 +1 @@ +{"version":3,"file":"text.js","sourceRoot":"","sources":["../../../../src/compile/mark/text.ts"],"names":[],"mappings":";AAGA,OAAO,EAAC,aAAa,EAAC,MAAM,WAAW,CAAC;AAGxC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAGlC,MAAM,CAAC,IAAM,IAAI,GAAiB;IAChC,MAAM,EAAE,MAAM;IAEd,WAAW,EAAE,UAAC,KAAgB;QACrB,IAAA,qBAAM,EAAE,yBAAQ,EAAE,mBAAK,EAAE,qBAAM,EAAE,uBAAO,CAAU;QAEzD,4BACK,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAC,CAAC,EACjE,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAChD,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EACjD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAClB,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,uBAC9B,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,YAAY,EAAE,OAAO,CAAC,IAAI,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IACrD,SAAS,EAAE,UAAU,CAAE,6BAA6B;YACpD,EACC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,EACzE;IACJ,CAAC;CACF,CAAC;AACF,eAAe,OAAgB,EAAE,QAA0B,EAAE,MAAc;IACzE,IAAM,CAAC,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACnE,IAAI,CAAC,KAAK,SAAS,EAAE;QACnB,OAAO,QAAQ,CAAC;KACjB;IACD,+DAA+D;IAC/D,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import {Config} from '../../config';\nimport {Encoding} from '../../encoding';\nimport {MarkDef} from '../../mark';\nimport {getMarkConfig} from '../common';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nexport const text: MarkCompiler = {\n vgMark: 'text',\n\n encodeEntry: (model: UnitModel) => {\n const {config, encoding, width, height, markDef} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.text(model),\n ...mixins.nonPosition('size', model, {\n ...(markDef.size ? {defaultValue: markDef.size} : {}),\n vgChannel: 'fontSize' // VL's text size is fontSize\n }),\n ...mixins.valueIfDefined('align', align(model.markDef, encoding, config))\n };\n }\n};\nfunction align(markDef: MarkDef, encoding: Encoding, config: Config) {\n const a = markDef.align || getMarkConfig('align', markDef, config);\n if (a === undefined) {\n return 'center';\n }\n // If there is a config, Vega-parser will process this already.\n return undefined;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/tick.d.ts b/build/src/compile/mark/tick.d.ts new file mode 100644 index 0000000000..9e01bb786c --- /dev/null +++ b/build/src/compile/mark/tick.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const tick: MarkCompiler; diff --git a/build/src/compile/mark/tick.js b/build/src/compile/mark/tick.js new file mode 100644 index 0000000000..63d3865697 --- /dev/null +++ b/build/src/compile/mark/tick.js @@ -0,0 +1,41 @@ +import * as tslib_1 from "tslib"; +import { isVgRangeStep } from '../../vega.schema'; +import * as mixins from './mixins'; +import * as ref from './valueref'; +export var tick = { + vgMark: 'rect', + encodeEntry: function (model) { + var _a; + var config = model.config, markDef = model.markDef, width = model.width, height = model.height; + var orient = markDef.orient; + var vgSizeChannel = orient === 'horizontal' ? 'width' : 'height'; + var vgThicknessChannel = orient === 'horizontal' ? 'height' : 'width'; + return tslib_1.__assign({}, mixins.baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), mixins.pointPosition('x', model, ref.mid(width), 'xc'), mixins.pointPosition('y', model, ref.mid(height), 'yc'), mixins.nonPosition('size', model, { + defaultValue: defaultSize(model), + vgChannel: vgSizeChannel + }), (_a = {}, _a[vgThicknessChannel] = { value: markDef.thickness || config.tick.thickness }, _a)); + } +}; +function defaultSize(model) { + var config = model.config, markDef = model.markDef; + var orient = markDef.orient; + var scale = model.getScaleComponent(orient === 'horizontal' ? 'x' : 'y'); + if (markDef.size !== undefined) { + return markDef.size; + } + else if (config.tick.bandSize !== undefined) { + return config.tick.bandSize; + } + else { + var scaleRange = scale ? scale.get('range') : undefined; + var rangeStep = scaleRange && isVgRangeStep(scaleRange) ? + scaleRange.step : + config.scale.rangeStep; + if (typeof rangeStep !== 'number') { + // FIXME consolidate this log + throw new Error('Function does not handle non-numeric rangeStep'); + } + return rangeStep / 1.5; + } +} +//# sourceMappingURL=tick.js.map \ No newline at end of file diff --git a/build/src/compile/mark/tick.js.map b/build/src/compile/mark/tick.js.map new file mode 100644 index 0000000000..ad90423eab --- /dev/null +++ b/build/src/compile/mark/tick.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tick.js","sourceRoot":"","sources":["../../../../src/compile/mark/tick.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAGhD,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAGlC,MAAM,CAAC,IAAM,IAAI,GAAiB;IAChC,MAAM,EAAE,MAAM;IAEd,WAAW,EAAE,UAAC,KAAgB;;QACrB,IAAA,qBAAM,EAAE,uBAAO,EAAE,mBAAK,EAAE,qBAAM,CAAU;QAC/C,IAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAE9B,IAAM,aAAa,GAAG,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;QACnE,IAAM,kBAAkB,GAAG,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;QAExE,4BACK,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAC,CAAC,EAEjE,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,EACtD,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAGvD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE;YACnC,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC;YAChC,SAAS,EAAE,aAAa;SACzB,CAAC,eACD,kBAAkB,IAAG,EAAC,KAAK,EAAE,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,EAAC,OACzE;IACJ,CAAC;CACF,CAAC;AAEF,qBAAqB,KAAgB;IAC5B,IAAA,qBAAM,EAAE,uBAAO,CAAU;IAChC,IAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,IAAM,KAAK,GAAG,KAAK,CAAC,iBAAiB,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAE3E,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE;QAC9B,OAAO,OAAO,CAAC,IAAI,CAAC;KACrB;SAAM,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;QAC7C,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;KAC7B;SAAM;QACL,IAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1D,IAAM,SAAS,GAAG,UAAU,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;YACzD,UAAU,CAAC,IAAI,CAAC,CAAC;YACjB,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;QACzB,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE;YACjC,6BAA6B;YAC7B,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;SACnE;QACD,OAAO,SAAS,GAAG,GAAG,CAAC;KACxB;AACH,CAAC","sourcesContent":["import {isVgRangeStep} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nexport const tick: MarkCompiler = {\n vgMark: 'rect',\n\n encodeEntry: (model: UnitModel) => {\n const {config, markDef, width, height} = model;\n const orient = markDef.orient;\n\n const vgSizeChannel = orient === 'horizontal' ? 'width' : 'height';\n const vgThicknessChannel = orient === 'horizontal' ? 'height' : 'width';\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n\n ...mixins.pointPosition('x', model, ref.mid(width), 'xc'),\n ...mixins.pointPosition('y', model, ref.mid(height), 'yc'),\n\n // size / thickness => width / height\n ...mixins.nonPosition('size', model, {\n defaultValue: defaultSize(model),\n vgChannel: vgSizeChannel\n }),\n [vgThicknessChannel]: {value: markDef.thickness || config.tick.thickness},\n };\n }\n};\n\nfunction defaultSize(model: UnitModel): number {\n const {config, markDef} = model;\n const orient = markDef.orient;\n const scale = model.getScaleComponent(orient === 'horizontal' ? 'x' : 'y');\n\n if (markDef.size !== undefined) {\n return markDef.size;\n } else if (config.tick.bandSize !== undefined) {\n return config.tick.bandSize;\n } else {\n const scaleRange = scale ? scale.get('range') : undefined;\n const rangeStep = scaleRange && isVgRangeStep(scaleRange) ?\n scaleRange.step :\n config.scale.rangeStep;\n if (typeof rangeStep !== 'number') {\n // FIXME consolidate this log\n throw new Error('Function does not handle non-numeric rangeStep');\n }\n return rangeStep / 1.5;\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/mark/valueref.d.ts b/build/src/compile/mark/valueref.d.ts new file mode 100644 index 0000000000..7661e8919e --- /dev/null +++ b/build/src/compile/mark/valueref.d.ts @@ -0,0 +1,32 @@ +import { Channel } from '../../channel'; +import { Config } from '../../config'; +import { ChannelDef, ChannelDefWithCondition, FieldDef, FieldRefOption, TextFieldDef } from '../../fielddef'; +import { Mark, MarkDef } from '../../mark'; +import { StackProperties } from '../../stack'; +import { VgSignalRef, VgValueRef } from '../../vega.schema'; +import { ScaleComponent } from '../scale/component'; +/** + * @return Vega ValueRef for normal x- or y-position without projection + */ +export declare function position(channel: 'x' | 'y', channelDef: ChannelDef, scaleName: string, scale: ScaleComponent, stack: StackProperties, defaultRef: VgValueRef | (() => VgValueRef)): VgValueRef; +/** + * @return Vega ValueRef for normal x2- or y2-position without projection + */ +export declare function position2(channel: 'x2' | 'y2', aFieldDef: ChannelDef, a2fieldDef: ChannelDef, scaleName: string, scale: ScaleComponent, stack: StackProperties, defaultRef: VgValueRef | (() => VgValueRef)): VgValueRef; +export declare function getOffset(channel: 'x' | 'y' | 'x2' | 'y2', markDef: MarkDef): any; +/** + * Value Ref for binned fields + */ +export declare function bin(fieldDef: FieldDef, scaleName: string, side: 'start' | 'end', offset?: number): VgValueRef; +export declare function fieldRef(fieldDef: FieldDef, scaleName: string, opt: FieldRefOption, mixins?: { + offset?: number | VgValueRef; + band?: number | boolean; +}): VgValueRef; +export declare function bandRef(scaleName: string, band?: number | boolean): VgValueRef; +/** + * @returns {VgValueRef} Value Ref for xc / yc or mid point for other channels. + */ +export declare function midPoint(channel: Channel, channelDef: ChannelDef, scaleName: string, scale: ScaleComponent, stack: StackProperties, defaultRef: VgValueRef | (() => VgValueRef)): VgValueRef; +export declare function text(textDef: ChannelDefWithCondition>, config: Config): VgValueRef; +export declare function mid(sizeRef: VgSignalRef): VgValueRef; +export declare function getDefaultRef(defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax', channel: 'x' | 'y', scaleName: string, scale: ScaleComponent, mark: Mark): () => VgValueRef; diff --git a/build/src/compile/mark/valueref.js b/build/src/compile/mark/valueref.js new file mode 100644 index 0000000000..7a5f6dd466 --- /dev/null +++ b/build/src/compile/mark/valueref.js @@ -0,0 +1,190 @@ +import * as tslib_1 from "tslib"; +/** + * Utility files for producing Vega ValueRef for marks + */ +import { isArray, isFunction, isString } from 'vega-util'; +import { X, Y } from '../../channel'; +import { isFieldDef, isValueDef, vgField, } from '../../fielddef'; +import * as log from '../../log'; +import { hasDiscreteDomain, ScaleType } from '../../scale'; +import { QUANTITATIVE } from '../../type'; +import { contains, some } from '../../util'; +import { binRequiresRange, formatSignalRef } from '../common'; +// TODO: we need to find a way to refactor these so that scaleName is a part of scale +// but that's complicated. For now, this is a huge step moving forward. +/** + * @return Vega ValueRef for normal x- or y-position without projection + */ +export function position(channel, channelDef, scaleName, scale, stack, defaultRef) { + if (isFieldDef(channelDef) && stack && channel === stack.fieldChannel) { + // x or y use stack_end so that stacked line's point mark use stack_end too. + return fieldRef(channelDef, scaleName, { suffix: 'end' }); + } + return midPoint(channel, channelDef, scaleName, scale, stack, defaultRef); +} +/** + * @return Vega ValueRef for normal x2- or y2-position without projection + */ +export function position2(channel, aFieldDef, a2fieldDef, scaleName, scale, stack, defaultRef) { + if (isFieldDef(aFieldDef) && stack && + // If fieldChannel is X and channel is X2 (or Y and Y2) + channel.charAt(0) === stack.fieldChannel.charAt(0)) { + return fieldRef(aFieldDef, scaleName, { suffix: 'start' }); + } + return midPoint(channel, a2fieldDef, scaleName, scale, stack, defaultRef); +} +export function getOffset(channel, markDef) { + var offsetChannel = channel + 'Offset'; + // TODO: in the future read from encoding channel too + var markDefOffsetValue = markDef[offsetChannel]; + if (markDefOffsetValue) { + return markDefOffsetValue; + } + return undefined; +} +/** + * Value Ref for binned fields + */ +export function bin(fieldDef, scaleName, side, offset) { + var binSuffix = side === 'start' ? undefined : 'end'; + return fieldRef(fieldDef, scaleName, { binSuffix: binSuffix }, offset ? { offset: offset } : {}); +} +export function fieldRef(fieldDef, scaleName, opt, mixins) { + var ref = tslib_1.__assign({}, (scaleName ? { scale: scaleName } : {}), { field: vgField(fieldDef, opt) }); + if (mixins) { + return tslib_1.__assign({}, ref, mixins); + } + return ref; +} +export function bandRef(scaleName, band) { + if (band === void 0) { band = true; } + return { + scale: scaleName, + band: band + }; +} +/** + * Signal that returns the middle of a bin. Should only be used with x and y. + */ +function binMidSignal(fieldDef, scaleName) { + return { + signal: "(" + + ("scale(\"" + scaleName + "\", " + vgField(fieldDef, { expr: 'datum' }) + ")") + + " + " + + ("scale(\"" + scaleName + "\", " + vgField(fieldDef, { binSuffix: 'end', expr: 'datum' }) + ")") + + ")/2" + }; +} +/** + * @returns {VgValueRef} Value Ref for xc / yc or mid point for other channels. + */ +export function midPoint(channel, channelDef, scaleName, scale, stack, defaultRef) { + // TODO: datum support + if (channelDef) { + /* istanbul ignore else */ + if (isFieldDef(channelDef)) { + if (channelDef.bin) { + // Use middle only for x an y to place marks in the center between start and end of the bin range. + // We do not use the mid point for other channels (e.g. size) so that properties of legends and marks match. + if (contains([X, Y], channel) && channelDef.type === QUANTITATIVE) { + if (stack && stack.impute) { + // For stack, we computed bin_mid so we can impute. + return fieldRef(channelDef, scaleName, { binSuffix: 'mid' }); + } + // For non-stack, we can just calculate bin mid on the fly using signal. + return binMidSignal(channelDef, scaleName); + } + return fieldRef(channelDef, scaleName, binRequiresRange(channelDef, channel) ? { binSuffix: 'range' } : {}); + } + if (scale) { + var scaleType = scale.get('type'); + if (hasDiscreteDomain(scaleType)) { + if (scaleType === 'band') { + // For band, to get mid point, need to offset by half of the band + return fieldRef(channelDef, scaleName, { binSuffix: 'range' }, { band: 0.5 }); + } + return fieldRef(channelDef, scaleName, { binSuffix: 'range' }); + } + } + return fieldRef(channelDef, scaleName, {}); // no need for bin suffix + } + else if (isValueDef(channelDef)) { + var value = channelDef.value; + if (contains(['x', 'x2'], channel) && value === 'width') { + return { field: { group: 'width' } }; + } + else if (contains(['y', 'y2'], channel) && value === 'height') { + return { field: { group: 'height' } }; + } + return { value: value }; + } + // If channelDef is neither field def or value def, it's a condition-only def. + // In such case, we will use default ref. + } + return isFunction(defaultRef) ? defaultRef() : defaultRef; +} +export function text(textDef, config) { + // text + if (textDef) { + if (isFieldDef(textDef)) { + return formatSignalRef(textDef, textDef.format, 'datum', config); + } + else if (isValueDef(textDef)) { + return { value: textDef.value }; + } + } + return undefined; +} +export function mid(sizeRef) { + return tslib_1.__assign({}, sizeRef, { mult: 0.5 }); +} +/** + * Whether the scale definitely includes zero in the domain + */ +function domainDefinitelyIncludeZero(scale) { + if (scale.get('zero') !== false) { + return true; + } + var domains = scale.domains; + if (isArray(domains)) { + return some(domains, function (d) { return isArray(d) && d.length === 2 && d[0] <= 0 && d[1] >= 0; }); + } + return false; +} +export function getDefaultRef(defaultRef, channel, scaleName, scale, mark) { + return function () { + if (isString(defaultRef)) { + if (scaleName) { + var scaleType = scale.get('type'); + if (contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scaleType)) { + // Log scales cannot have zero. + // Zero in time scale is arbitrary, and does not affect ratio. + // (Time is an interval level of measurement, not ratio). + // See https://en.wikipedia.org/wiki/Level_of_measurement for more info. + if (mark === 'bar' || mark === 'area') { + log.warn(log.message.nonZeroScaleUsedWithLengthMark(mark, channel, { scaleType: scaleType })); + } + } + else { + if (domainDefinitelyIncludeZero(scale)) { + return { + scale: scaleName, + value: 0 + }; + } + if (mark === 'bar' || mark === 'area') { + log.warn(log.message.nonZeroScaleUsedWithLengthMark(mark, channel, { zeroFalse: scale.explicit.zero === false })); + } + } + } + if (defaultRef === 'zeroOrMin') { + return channel === 'x' ? { value: 0 } : { field: { group: 'height' } }; + } + else { // zeroOrMax + return channel === 'x' ? { field: { group: 'width' } } : { value: 0 }; + } + } + return defaultRef; + }; +} +//# sourceMappingURL=valueref.js.map \ No newline at end of file diff --git a/build/src/compile/mark/valueref.js.map b/build/src/compile/mark/valueref.js.map new file mode 100644 index 0000000000..38b1256871 --- /dev/null +++ b/build/src/compile/mark/valueref.js.map @@ -0,0 +1 @@ +{"version":3,"file":"valueref.js","sourceRoot":"","sources":["../../../../src/compile/mark/valueref.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Utility files for producing Vega ValueRef for marks\n */\nimport {isArray, isFunction, isString} from 'vega-util';\n\nimport {Channel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {\n ChannelDef,\n ChannelDefWithCondition,\n FieldDef,\n FieldRefOption,\n isFieldDef,\n isValueDef,\n TextFieldDef,\n vgField,\n} from '../../fielddef';\nimport * as log from '../../log';\nimport {Mark, MarkDef} from '../../mark';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {StackProperties} from '../../stack';\nimport {QUANTITATIVE} from '../../type';\nimport {contains, some} from '../../util';\nimport {VgSignalRef, VgValueRef} from '../../vega.schema';\nimport {binRequiresRange, formatSignalRef} from '../common';\nimport {ScaleComponent} from '../scale/component';\n\n\n// TODO: we need to find a way to refactor these so that scaleName is a part of scale\n// but that's complicated. For now, this is a huge step moving forward.\n\n/**\n * @return Vega ValueRef for normal x- or y-position without projection\n */\nexport function position(channel: 'x' | 'y', channelDef: ChannelDef, scaleName: string, scale: ScaleComponent,\n stack: StackProperties, defaultRef: VgValueRef | (() => VgValueRef)): VgValueRef {\n if (isFieldDef(channelDef) && stack && channel === stack.fieldChannel) {\n // x or y use stack_end so that stacked line's point mark use stack_end too.\n return fieldRef(channelDef, scaleName, {suffix: 'end'});\n }\n return midPoint(channel, channelDef, scaleName, scale, stack, defaultRef);\n}\n\n/**\n * @return Vega ValueRef for normal x2- or y2-position without projection\n */\nexport function position2(channel: 'x2' | 'y2', aFieldDef: ChannelDef, a2fieldDef: ChannelDef, scaleName: string, scale: ScaleComponent,\n stack: StackProperties, defaultRef: VgValueRef | (() => VgValueRef)): VgValueRef {\n if (isFieldDef(aFieldDef) && stack &&\n // If fieldChannel is X and channel is X2 (or Y and Y2)\n channel.charAt(0) === stack.fieldChannel.charAt(0)\n ) {\n return fieldRef(aFieldDef, scaleName, {suffix: 'start'});\n }\n return midPoint(channel, a2fieldDef, scaleName, scale, stack, defaultRef);\n}\n\n\n\nexport function getOffset(channel: 'x' | 'y' | 'x2' | 'y2', markDef: MarkDef) {\n const offsetChannel = channel + 'Offset';\n // TODO: in the future read from encoding channel too\n\n const markDefOffsetValue = markDef[offsetChannel];\n if (markDefOffsetValue) {\n return markDefOffsetValue;\n }\n\n return undefined;\n}\n\n/**\n * Value Ref for binned fields\n */\nexport function bin(fieldDef: FieldDef, scaleName: string, side: 'start' | 'end', offset?: number) {\n const binSuffix = side === 'start' ? undefined : 'end';\n return fieldRef(fieldDef, scaleName, {binSuffix}, offset ? {offset} : {});\n}\n\nexport function fieldRef(\n fieldDef: FieldDef, scaleName: string, opt: FieldRefOption,\n mixins?: {offset?: number | VgValueRef, band?: number|boolean}\n ): VgValueRef {\n\n const ref: VgValueRef = {\n ...(scaleName ? {scale: scaleName} : {}),\n field: vgField(fieldDef, opt),\n };\n\n if (mixins) {\n return {\n ...ref,\n ...mixins\n };\n }\n return ref;\n}\n\nexport function bandRef(scaleName: string, band: number|boolean = true): VgValueRef {\n return {\n scale: scaleName,\n band: band\n };\n}\n\n/**\n * Signal that returns the middle of a bin. Should only be used with x and y.\n */\nfunction binMidSignal(fieldDef: FieldDef, scaleName: string) {\n return {\n signal: `(` +\n `scale(\"${scaleName}\", ${vgField(fieldDef, {expr: 'datum'})})` +\n ` + ` +\n `scale(\"${scaleName}\", ${vgField(fieldDef, {binSuffix: 'end', expr: 'datum'})})`+\n `)/2`\n };\n}\n\n/**\n * @returns {VgValueRef} Value Ref for xc / yc or mid point for other channels.\n */\nexport function midPoint(\n channel: Channel,\n channelDef: ChannelDef,\n scaleName: string,\n scale: ScaleComponent,\n stack: StackProperties,\n defaultRef: VgValueRef | (() => VgValueRef)\n): VgValueRef {\n // TODO: datum support\n\n if (channelDef) {\n /* istanbul ignore else */\n\n if (isFieldDef(channelDef)) {\n if (channelDef.bin) {\n // Use middle only for x an y to place marks in the center between start and end of the bin range.\n // We do not use the mid point for other channels (e.g. size) so that properties of legends and marks match.\n if (contains([X, Y], channel) && channelDef.type === QUANTITATIVE) {\n if (stack && stack.impute) {\n // For stack, we computed bin_mid so we can impute.\n return fieldRef(channelDef, scaleName, {binSuffix: 'mid'});\n }\n // For non-stack, we can just calculate bin mid on the fly using signal.\n return binMidSignal(channelDef, scaleName);\n }\n return fieldRef(channelDef, scaleName, binRequiresRange(channelDef, channel) ? {binSuffix: 'range'} : {});\n }\n\n if (scale) {\n const scaleType = scale.get('type');\n if (hasDiscreteDomain(scaleType)) {\n if (scaleType === 'band') {\n // For band, to get mid point, need to offset by half of the band\n return fieldRef(channelDef, scaleName, {binSuffix: 'range'}, {band: 0.5});\n }\n return fieldRef(channelDef, scaleName, {binSuffix: 'range'});\n }\n }\n return fieldRef(channelDef, scaleName, {}); // no need for bin suffix\n } else if (isValueDef(channelDef)) {\n const value = channelDef.value;\n\n if (contains(['x', 'x2'], channel) && value === 'width') {\n return {field: {group: 'width'}};\n } else if (contains(['y', 'y2'], channel) && value === 'height') {\n return {field: {group: 'height'}};\n }\n\n return {value};\n }\n\n // If channelDef is neither field def or value def, it's a condition-only def.\n // In such case, we will use default ref.\n }\n\n return isFunction(defaultRef) ? defaultRef() : defaultRef;\n}\n\nexport function text(textDef: ChannelDefWithCondition>, config: Config): VgValueRef {\n // text\n if (textDef) {\n if (isFieldDef(textDef)) {\n return formatSignalRef(textDef, textDef.format, 'datum', config);\n } else if (isValueDef(textDef)) {\n return {value: textDef.value};\n }\n }\n return undefined;\n}\n\nexport function mid(sizeRef: VgSignalRef): VgValueRef {\n return {...sizeRef, mult: 0.5};\n}\n\n/**\n * Whether the scale definitely includes zero in the domain\n */\nfunction domainDefinitelyIncludeZero(scale: ScaleComponent) {\n if (scale.get('zero') !== false) {\n return true;\n }\n const domains = scale.domains;\n if (isArray(domains)) {\n return some(domains, (d) => isArray(d) && d.length === 2 && d[0] <=0 && d[1] >= 0);\n }\n return false;\n}\n\nexport function getDefaultRef(\n defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax',\n channel: 'x' | 'y', scaleName: string, scale: ScaleComponent, mark: Mark\n) {\n return () => {\n if (isString(defaultRef)) {\n if (scaleName) {\n const scaleType = scale.get('type');\n if (contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scaleType)) {\n // Log scales cannot have zero.\n // Zero in time scale is arbitrary, and does not affect ratio.\n // (Time is an interval level of measurement, not ratio).\n // See https://en.wikipedia.org/wiki/Level_of_measurement for more info.\n if (mark === 'bar' || mark === 'area') {\n log.warn(log.message.nonZeroScaleUsedWithLengthMark(mark, channel, {scaleType}));\n }\n } else {\n if (domainDefinitelyIncludeZero(scale)) {\n return {\n scale: scaleName,\n value: 0\n };\n }\n if (mark === 'bar' || mark === 'area') {\n log.warn(log.message.nonZeroScaleUsedWithLengthMark(\n mark, channel, {zeroFalse: scale.explicit.zero === false}\n ));\n }\n }\n }\n\n if (defaultRef === 'zeroOrMin') {\n return channel === 'x' ? {value: 0} : {field: {group: 'height'}};\n } else { // zeroOrMax\n return channel === 'x' ? {field: {group: 'width'}} : {value: 0};\n }\n }\n return defaultRef;\n };\n}\n\n"]} \ No newline at end of file diff --git a/build/src/compile/model.d.ts b/build/src/compile/model.d.ts new file mode 100644 index 0000000000..4c727d544f --- /dev/null +++ b/build/src/compile/model.d.ts @@ -0,0 +1,170 @@ +import { Channel, ScaleChannel, SingleDefChannel } from '../channel'; +import { Config } from '../config'; +import { Data, DataSourceType } from '../data'; +import { FieldDef, FieldRefOption } from '../fielddef'; +import { Resolve } from '../resolve'; +import { BaseSpec } from '../spec'; +import { TitleParams } from '../title'; +import { GenericCompositionLayout } from '../toplevelprops'; +import { Transform } from '../transform'; +import { Dict } from '../util'; +import { VgAxis, VgData, VgEncodeEntry, VgLayout, VgLegend, VgMarkGroup, VgProjection, VgSignal, VgSignalRef, VgTitle } from '../vega.schema'; +import { AxisComponentIndex } from './axis/component'; +import { ConcatModel } from './concat'; +import { DataComponent } from './data'; +import { FacetModel } from './facet'; +import { LayoutHeaderComponent } from './header/index'; +import { LayerModel } from './layer'; +import { LayoutSizeComponent, LayoutSizeIndex } from './layoutsize/component'; +import { LegendComponentIndex } from './legend/component'; +import { ProjectionComponent } from './projection/component'; +import { RepeatModel } from './repeat'; +import { RepeaterValue } from './repeater'; +import { ScaleComponent, ScaleComponentIndex } from './scale/component'; +import { SelectionComponent } from './selection/selection'; +import { UnitModel } from './unit'; +/** + * Composable Components that are intermediate results of the parsing phase of the + * compilations. The components represents parts of the specification in a form that + * can be easily merged (during parsing for composite specs). + * In addition, these components are easily transformed into Vega specifications + * during the "assemble" phase, which is the last phase of the compilation step. + */ +export interface Component { + data: DataComponent; + layoutSize: LayoutSizeComponent; + layoutHeaders: { + row?: LayoutHeaderComponent; + column?: LayoutHeaderComponent; + }; + mark: VgMarkGroup[]; + scales: ScaleComponentIndex; + projection: ProjectionComponent; + selection: Dict; + /** Dictionary mapping channel to VgAxis definition */ + axes: AxisComponentIndex; + /** Dictionary mapping channel to VgLegend definition */ + legends: LegendComponentIndex; + resolve: Resolve; +} +export interface NameMapInterface { + rename(oldname: string, newName: string): void; + has(name: string): boolean; + get(name: string): string; +} +export declare class NameMap implements NameMapInterface { + private nameMap; + constructor(); + rename(oldName: string, newName: string): void; + has(name: string): boolean; + get(name: string): string; +} +export declare function isUnitModel(model: Model): model is UnitModel; +export declare function isFacetModel(model: Model): model is FacetModel; +export declare function isRepeatModel(model: Model): model is RepeatModel; +export declare function isConcatModel(model: Model): model is ConcatModel; +export declare function isLayerModel(model: Model): model is LayerModel; +export declare abstract class Model { + abstract readonly type: 'unit' | 'facet' | 'layer' | 'concat' | 'repeat'; + readonly parent: Model; + readonly name: string; + readonly title: TitleParams; + readonly description: string; + readonly data: Data; + readonly transforms: Transform[]; + readonly layout: GenericCompositionLayout; + /** Name map for scales, which can be renamed by a model's parent. */ + protected scaleNameMap: NameMapInterface; + /** Name map for projections, which can be renamed by a model's parent. */ + protected projectionNameMap: NameMapInterface; + /** Name map for size, which can be renamed by a model's parent. */ + protected layoutSizeNameMap: NameMapInterface; + readonly repeater: RepeaterValue; + readonly config: Config; + readonly component: Component; + abstract readonly children: Model[]; + constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, repeater: RepeaterValue, resolve: Resolve); + readonly width: VgSignalRef; + readonly height: VgSignalRef; + protected initSize(size: LayoutSizeIndex): void; + parse(): void; + abstract parseData(): void; + abstract parseSelection(): void; + parseScale(): void; + parseProjection(): void; + abstract parseLayoutSize(): void; + /** + * Rename top-level spec's size to be just width / height, ignoring model name. + * This essentially merges the top-level spec's width/height signals with the width/height signals + * to help us reduce redundant signals declaration. + */ + private renameTopLevelLayoutSize; + abstract parseMarkGroup(): void; + abstract parseAxisAndHeader(): void; + parseLegend(): void; + abstract assembleSelectionTopLevelSignals(signals: any[]): any[]; + abstract assembleSelectionSignals(): any[]; + abstract assembleSelectionData(data: VgData[]): VgData[]; + assembleGroupStyle(): string; + assembleLayoutSize(): VgEncodeEntry; + assembleLayout(): VgLayout; + protected assembleDefaultLayout(): VgLayout; + abstract assembleLayoutSignals(): VgSignal[]; + assembleHeaderMarks(): VgMarkGroup[]; + abstract assembleMarks(): VgMarkGroup[]; + assembleAxes(): VgAxis[]; + assembleLegends(): VgLegend[]; + assembleProjections(): VgProjection[]; + assembleTitle(): VgTitle; + /** + * Assemble the mark group for this model. We accept optional `signals` so that we can include concat top-level signals with the top-level model's local signals. + */ + assembleGroup(signals?: VgSignal[]): any; + hasDescendantWithFieldOnChannel(channel: Channel): boolean; + getName(text: string): string; + /** + * Request a data source name for the given data source type and mark that data source as required. This method should be called in parse, so that all used data source can be correctly instantiated in assembleData(). + */ + requestDataName(name: DataSourceType): string; + getSizeSignalRef(sizeType: 'width' | 'height'): VgSignalRef; + /** + * Lookup the name of the datasource for an output node. You probably want to call this in assemble. + */ + lookupDataSource(name: string): string; + getSizeName(oldSizeName: string): string; + renameLayoutSize(oldName: string, newName: string): void; + renameScale(oldName: string, newName: string): void; + renameProjection(oldName: string, newName: string): void; + /** + * @return scale name for a given channel after the scale has been parsed and named. + */ + scaleName(originalScaleName: Channel | string, parse?: boolean): string; + /** + * @return projection name after the projection has been parsed and named. + */ + projectionName(parse?: boolean): string; + /** + * Corrects the data references in marks after assemble. + */ + correctDataNames: (mark: any) => any; + /** + * Traverse a model's hierarchy to get the scale component for a particular channel. + */ + getScaleComponent(channel: ScaleChannel): ScaleComponent; + /** + * Traverse a model's hierarchy to get a particular selection component. + */ + getSelectionComponent(variableName: string, origName: string): SelectionComponent; +} +/** Abstract class for UnitModel and FacetModel. Both of which can contain fieldDefs as a part of its own specification. */ +export declare abstract class ModelWithField extends Model { + abstract fieldDef(channel: SingleDefChannel): FieldDef; + /** Get "field" reference for vega */ + vgField(channel: SingleDefChannel, opt?: FieldRefOption): string; + protected abstract getMapping(): { + [key in Channel]?: any; + }; + reduceFieldDef(f: (acc: U, fd: FieldDef, c: Channel) => U, init: T, t?: any): any; + forEachFieldDef(f: (fd: FieldDef, c: Channel) => void, t?: any): void; + abstract channelHasField(channel: Channel): boolean; +} diff --git a/build/src/compile/model.js b/build/src/compile/model.js new file mode 100644 index 0000000000..0729d64e77 --- /dev/null +++ b/build/src/compile/model.js @@ -0,0 +1,459 @@ +import * as tslib_1 from "tslib"; +import { isNumber, isString } from 'vega-util'; +import { isChannel, isScaleChannel } from '../channel'; +import { forEach, reduce } from '../encoding'; +import { getFieldDef, vgField } from '../fielddef'; +import * as log from '../log'; +import { hasDiscreteDomain } from '../scale'; +import { isFacetSpec, isLayerSpec, isUnitSpec } from '../spec'; +import { extractTitleConfig } from '../title'; +import { extractCompositionLayout } from '../toplevelprops'; +import { normalizeTransform } from '../transform'; +import { contains, keys, varName } from '../util'; +import { isVgRangeStep } from '../vega.schema'; +import { assembleAxes } from './axis/assemble'; +import { getHeaderGroups, getTitleGroup, HEADER_CHANNELS } from './header/index'; +import { sizeExpr } from './layoutsize/assemble'; +import { assembleLegends } from './legend/assemble'; +import { parseLegend } from './legend/parse'; +import { assembleProjections } from './projection/assemble'; +import { parseProjection } from './projection/parse'; +import { assembleScales } from './scale/assemble'; +import { assembleDomain, getFieldFromDomain } from './scale/domain'; +import { parseScale } from './scale/parse'; +import { Split } from './split'; +var NameMap = /** @class */ (function () { + function NameMap() { + this.nameMap = {}; + } + NameMap.prototype.rename = function (oldName, newName) { + this.nameMap[oldName] = newName; + }; + NameMap.prototype.has = function (name) { + return this.nameMap[name] !== undefined; + }; + NameMap.prototype.get = function (name) { + // If the name appears in the _nameMap, we need to read its new name. + // We have to loop over the dict just in case the new name also gets renamed. + while (this.nameMap[name] && name !== this.nameMap[name]) { + name = this.nameMap[name]; + } + return name; + }; + return NameMap; +}()); +export { NameMap }; +/* + We use type guards instead of `instanceof` as `instanceof` makes + different parts of the compiler depend on the actual implementation of + the model classes, which in turn depend on different parts of the compiler. + Thus, `instanceof` leads to circular dependency problems. + + On the other hand, type guards only make different parts of the compiler + depend on the type of the model classes, but not the actual implementation. +*/ +export function isUnitModel(model) { + return model && model.type === 'unit'; +} +export function isFacetModel(model) { + return model && model.type === 'facet'; +} +export function isRepeatModel(model) { + return model && model.type === 'repeat'; +} +export function isConcatModel(model) { + return model && model.type === 'concat'; +} +export function isLayerModel(model) { + return model && model.type === 'layer'; +} +var Model = /** @class */ (function () { + function Model(spec, parent, parentGivenName, config, repeater, resolve) { + var _this = this; + this.children = []; + /** + * Corrects the data references in marks after assemble. + */ + this.correctDataNames = function (mark) { + // TODO: make this correct + // for normal data references + if (mark.from && mark.from.data) { + mark.from.data = _this.lookupDataSource(mark.from.data); + } + // for access to facet data + if (mark.from && mark.from.facet && mark.from.facet.data) { + mark.from.facet.data = _this.lookupDataSource(mark.from.facet.data); + } + return mark; + }; + this.parent = parent; + this.config = config; + this.repeater = repeater; + // If name is not provided, always use parent's givenName to avoid name conflicts. + this.name = spec.name || parentGivenName; + this.title = isString(spec.title) ? { text: spec.title } : spec.title; + // Shared name maps + this.scaleNameMap = parent ? parent.scaleNameMap : new NameMap(); + this.projectionNameMap = parent ? parent.projectionNameMap : new NameMap(); + this.layoutSizeNameMap = parent ? parent.layoutSizeNameMap : new NameMap(); + this.data = spec.data; + this.description = spec.description; + this.transforms = normalizeTransform(spec.transform || []); + this.layout = isUnitSpec(spec) || isLayerSpec(spec) ? undefined : extractCompositionLayout(spec); + this.component = { + data: { + sources: parent ? parent.component.data.sources : {}, + outputNodes: parent ? parent.component.data.outputNodes : {}, + outputNodeRefCounts: parent ? parent.component.data.outputNodeRefCounts : {}, + // data is faceted if the spec is a facet spec or the parent has faceted data and no data is defined + isFaceted: isFacetSpec(spec) || (parent && parent.component.data.isFaceted && !spec.data) + }, + layoutSize: new Split(), + layoutHeaders: { row: {}, column: {} }, + mark: null, + resolve: tslib_1.__assign({ scale: {}, axis: {}, legend: {} }, (resolve || {})), + selection: null, + scales: null, + projection: null, + axes: {}, + legends: {}, + }; + } + Object.defineProperty(Model.prototype, "width", { + get: function () { + return this.getSizeSignalRef('width'); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Model.prototype, "height", { + get: function () { + return this.getSizeSignalRef('height'); + }, + enumerable: true, + configurable: true + }); + Model.prototype.initSize = function (size) { + var width = size.width, height = size.height; + if (width) { + this.component.layoutSize.set('width', width, true); + } + if (height) { + this.component.layoutSize.set('height', height, true); + } + }; + Model.prototype.parse = function () { + this.parseScale(); + this.parseLayoutSize(); // depends on scale + this.renameTopLevelLayoutSize(); + this.parseSelection(); + this.parseProjection(); + this.parseData(); // (pathorder) depends on markDef; selection filters depend on parsed selections; depends on projection because some transforms require the finalized projection name. + this.parseAxisAndHeader(); // depends on scale and layout size + this.parseLegend(); // depends on scale, markDef + this.parseMarkGroup(); // depends on data name, scale, layout size, axisGroup, and children's scale, axis, legend and mark. + }; + Model.prototype.parseScale = function () { + parseScale(this); + }; + Model.prototype.parseProjection = function () { + parseProjection(this); + }; + /** + * Rename top-level spec's size to be just width / height, ignoring model name. + * This essentially merges the top-level spec's width/height signals with the width/height signals + * to help us reduce redundant signals declaration. + */ + Model.prototype.renameTopLevelLayoutSize = function () { + if (this.getName('width') !== 'width') { + this.renameLayoutSize(this.getName('width'), 'width'); + } + if (this.getName('height') !== 'height') { + this.renameLayoutSize(this.getName('height'), 'height'); + } + }; + Model.prototype.parseLegend = function () { + parseLegend(this); + }; + Model.prototype.assembleGroupStyle = function () { + if (this.type === 'unit' || this.type === 'layer') { + return 'cell'; + } + return undefined; + }; + Model.prototype.assembleLayoutSize = function () { + if (this.type === 'unit' || this.type === 'layer') { + return { + width: this.getSizeSignalRef('width'), + height: this.getSizeSignalRef('height') + }; + } + return undefined; + }; + Model.prototype.assembleLayout = function () { + if (!this.layout) { + return undefined; + } + var _a = this.layout, align = _a.align, bounds = _a.bounds, center = _a.center, _b = _a.spacing, spacing = _b === void 0 ? {} : _b; + return tslib_1.__assign({ padding: isNumber(spacing) ? spacing : { + row: spacing.row || 10, + column: spacing.column || 10 + } }, this.assembleDefaultLayout(), (align ? { align: align } : {}), (bounds ? { bounds: bounds } : {}), (center ? { center: center } : {})); + }; + Model.prototype.assembleDefaultLayout = function () { + return {}; + }; + Model.prototype.assembleHeaderMarks = function () { + var layoutHeaders = this.component.layoutHeaders; + var headerMarks = []; + for (var _i = 0, HEADER_CHANNELS_1 = HEADER_CHANNELS; _i < HEADER_CHANNELS_1.length; _i++) { + var channel = HEADER_CHANNELS_1[_i]; + if (layoutHeaders[channel].title) { + headerMarks.push(getTitleGroup(this, channel)); + } + } + for (var _a = 0, HEADER_CHANNELS_2 = HEADER_CHANNELS; _a < HEADER_CHANNELS_2.length; _a++) { + var channel = HEADER_CHANNELS_2[_a]; + headerMarks = headerMarks.concat(getHeaderGroups(this, channel)); + } + return headerMarks; + }; + Model.prototype.assembleAxes = function () { + return assembleAxes(this.component.axes, this.config); + }; + Model.prototype.assembleLegends = function () { + return assembleLegends(this); + }; + Model.prototype.assembleProjections = function () { + return assembleProjections(this); + }; + Model.prototype.assembleTitle = function () { + var title = tslib_1.__assign({}, extractTitleConfig(this.config.title).nonMark, this.title); + if (title.text) { + if (!contains(['unit', 'layer'], this.type)) { + // As described in https://github.com/vega/vega-lite/issues/2875: + // Due to vega/vega#960 (comment), we only support title's anchor for unit and layered spec for now. + if (title.anchor && title.anchor !== 'start') { + log.warn(log.message.cannotSetTitleAnchor(this.type)); + } + title.anchor = 'start'; + } + return keys(title).length > 0 ? title : undefined; + } + return undefined; + }; + /** + * Assemble the mark group for this model. We accept optional `signals` so that we can include concat top-level signals with the top-level model's local signals. + */ + Model.prototype.assembleGroup = function (signals) { + if (signals === void 0) { signals = []; } + var group = {}; + signals = signals.concat(this.assembleSelectionSignals()); + if (signals.length > 0) { + group.signals = signals; + } + var layout = this.assembleLayout(); + if (layout) { + group.layout = layout; + } + group.marks = [].concat(this.assembleHeaderMarks(), this.assembleMarks()); + // Only include scales if this spec is top-level or if parent is facet. + // (Otherwise, it will be merged with upper-level's scope.) + var scales = (!this.parent || isFacetModel(this.parent)) ? assembleScales(this) : []; + if (scales.length > 0) { + group.scales = scales; + } + var axes = this.assembleAxes(); + if (axes.length > 0) { + group.axes = axes; + } + var legends = this.assembleLegends(); + if (legends.length > 0) { + group.legends = legends; + } + return group; + }; + Model.prototype.hasDescendantWithFieldOnChannel = function (channel) { + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + if (isUnitModel(child)) { + if (child.channelHasField(channel)) { + return true; + } + } + else { + if (child.hasDescendantWithFieldOnChannel(channel)) { + return true; + } + } + } + return false; + }; + Model.prototype.getName = function (text) { + return varName((this.name ? this.name + '_' : '') + text); + }; + /** + * Request a data source name for the given data source type and mark that data source as required. This method should be called in parse, so that all used data source can be correctly instantiated in assembleData(). + */ + Model.prototype.requestDataName = function (name) { + var fullName = this.getName(name); + // Increase ref count. This is critical because otherwise we won't create a data source. + // We also increase the ref counts on OutputNode.getSource() calls. + var refCounts = this.component.data.outputNodeRefCounts; + refCounts[fullName] = (refCounts[fullName] || 0) + 1; + return fullName; + }; + Model.prototype.getSizeSignalRef = function (sizeType) { + if (isFacetModel(this.parent)) { + var channel = sizeType === 'width' ? 'x' : 'y'; + var scaleComponent = this.component.scales[channel]; + if (scaleComponent && !scaleComponent.merged) { // independent scale + var type = scaleComponent.get('type'); + var range = scaleComponent.get('range'); + if (hasDiscreteDomain(type) && isVgRangeStep(range)) { + var scaleName = scaleComponent.get('name'); + var domain = assembleDomain(this, channel); + var field = getFieldFromDomain(domain); + if (field) { + var fieldRef = vgField({ aggregate: 'distinct', field: field }, { expr: 'datum' }); + return { + signal: sizeExpr(scaleName, scaleComponent, fieldRef) + }; + } + else { + log.warn('Unknown field for ${channel}. Cannot calculate view size.'); + return null; + } + } + } + } + return { + signal: this.layoutSizeNameMap.get(this.getName(sizeType)) + }; + }; + /** + * Lookup the name of the datasource for an output node. You probably want to call this in assemble. + */ + Model.prototype.lookupDataSource = function (name) { + var node = this.component.data.outputNodes[name]; + if (!node) { + // Name not found in map so let's just return what we got. + // This can happen if we already have the correct name. + return name; + } + return node.getSource(); + }; + Model.prototype.getSizeName = function (oldSizeName) { + return this.layoutSizeNameMap.get(oldSizeName); + }; + Model.prototype.renameLayoutSize = function (oldName, newName) { + this.layoutSizeNameMap.rename(oldName, newName); + }; + Model.prototype.renameScale = function (oldName, newName) { + this.scaleNameMap.rename(oldName, newName); + }; + Model.prototype.renameProjection = function (oldName, newName) { + this.projectionNameMap.rename(oldName, newName); + }; + /** + * @return scale name for a given channel after the scale has been parsed and named. + */ + Model.prototype.scaleName = function (originalScaleName, parse) { + if (parse) { + // During the parse phase always return a value + // No need to refer to rename map because a scale can't be renamed + // before it has the original name. + return this.getName(originalScaleName); + } + // If there is a scale for the channel, it should either + // be in the scale component or exist in the name map + if ( + // If there is a scale for the channel, there should be a local scale component for it + (isChannel(originalScaleName) && isScaleChannel(originalScaleName) && this.component.scales[originalScaleName]) || + // in the scale name map (the scale get merged by its parent) + this.scaleNameMap.has(this.getName(originalScaleName))) { + return this.scaleNameMap.get(this.getName(originalScaleName)); + } + return undefined; + }; + /** + * @return projection name after the projection has been parsed and named. + */ + Model.prototype.projectionName = function (parse) { + if (parse) { + // During the parse phase always return a value + // No need to refer to rename map because a projection can't be renamed + // before it has the original name. + return this.getName('projection'); + } + if ((this.component.projection && !this.component.projection.merged) || this.projectionNameMap.has(this.getName('projection'))) { + return this.projectionNameMap.get(this.getName('projection')); + } + return undefined; + }; + /** + * Traverse a model's hierarchy to get the scale component for a particular channel. + */ + Model.prototype.getScaleComponent = function (channel) { + /* istanbul ignore next: This is warning for debugging test */ + if (!this.component.scales) { + throw new Error('getScaleComponent cannot be called before parseScale(). Make sure you have called parseScale or use parseUnitModelWithScale().'); + } + var localScaleComponent = this.component.scales[channel]; + if (localScaleComponent && !localScaleComponent.merged) { + return localScaleComponent; + } + return (this.parent ? this.parent.getScaleComponent(channel) : undefined); + }; + /** + * Traverse a model's hierarchy to get a particular selection component. + */ + Model.prototype.getSelectionComponent = function (variableName, origName) { + var sel = this.component.selection[variableName]; + if (!sel && this.parent) { + sel = this.parent.getSelectionComponent(variableName, origName); + } + if (!sel) { + throw new Error(log.message.selectionNotFound(origName)); + } + return sel; + }; + return Model; +}()); +export { Model }; +/** Abstract class for UnitModel and FacetModel. Both of which can contain fieldDefs as a part of its own specification. */ +var ModelWithField = /** @class */ (function (_super) { + tslib_1.__extends(ModelWithField, _super); + function ModelWithField() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** Get "field" reference for vega */ + ModelWithField.prototype.vgField = function (channel, opt) { + if (opt === void 0) { opt = {}; } + var fieldDef = this.fieldDef(channel); + if (!fieldDef) { + return undefined; + } + return vgField(fieldDef, opt); + }; + ModelWithField.prototype.reduceFieldDef = function (f, init, t) { + return reduce(this.getMapping(), function (acc, cd, c) { + var fieldDef = getFieldDef(cd); + if (fieldDef) { + return f(acc, fieldDef, c); + } + return acc; + }, init, t); + }; + ModelWithField.prototype.forEachFieldDef = function (f, t) { + forEach(this.getMapping(), function (cd, c) { + var fieldDef = getFieldDef(cd); + if (fieldDef) { + f(fieldDef, c); + } + }, t); + }; + return ModelWithField; +}(Model)); +export { ModelWithField }; +//# sourceMappingURL=model.js.map \ No newline at end of file diff --git a/build/src/compile/model.js.map b/build/src/compile/model.js.map new file mode 100644 index 0000000000..0031e83d30 --- /dev/null +++ b/build/src/compile/model.js.map @@ -0,0 +1 @@ +{"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/compile/model.ts"],"names":[],"mappings":"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","sourcesContent":["import {isNumber, isString} from 'vega-util';\nimport {Channel, isChannel, isScaleChannel, ScaleChannel, SingleDefChannel} from '../channel';\nimport {Config} from '../config';\nimport {Data, DataSourceType} from '../data';\nimport {forEach, reduce} from '../encoding';\nimport {ChannelDef, FieldDef, FieldRefOption, getFieldDef, vgField} from '../fielddef';\nimport * as log from '../log';\nimport {Resolve} from '../resolve';\nimport {hasDiscreteDomain} from '../scale';\nimport {BaseSpec, isFacetSpec, isLayerSpec, isUnitSpec} from '../spec';\nimport {extractTitleConfig, TitleParams} from '../title';\nimport {extractCompositionLayout, GenericCompositionLayout} from '../toplevelprops';\nimport {normalizeTransform, Transform} from '../transform';\nimport {contains, Dict, keys, varName} from '../util';\nimport {isVgRangeStep, VgAxis, VgData, VgEncodeEntry, VgLayout, VgLegend, VgMarkGroup, VgProjection, VgSignal, VgSignalRef, VgTitle} from '../vega.schema';\nimport {assembleAxes} from './axis/assemble';\nimport {AxisComponentIndex} from './axis/component';\nimport {ConcatModel} from './concat';\nimport {DataComponent} from './data';\nimport {FacetModel} from './facet';\nimport {getHeaderGroups, getTitleGroup, HEADER_CHANNELS, LayoutHeaderComponent} from './header/index';\nimport {LayerModel} from './layer';\nimport {sizeExpr} from './layoutsize/assemble';\nimport {LayoutSizeComponent, LayoutSizeIndex} from './layoutsize/component';\nimport {assembleLegends} from './legend/assemble';\nimport {LegendComponentIndex} from './legend/component';\nimport {parseLegend} from './legend/parse';\nimport {assembleProjections} from './projection/assemble';\nimport {ProjectionComponent} from './projection/component';\nimport {parseProjection} from './projection/parse';\nimport {RepeatModel} from './repeat';\nimport {RepeaterValue} from './repeater';\nimport {assembleScales} from './scale/assemble';\nimport {ScaleComponent, ScaleComponentIndex} from './scale/component';\nimport {assembleDomain, getFieldFromDomain} from './scale/domain';\nimport {parseScale} from './scale/parse';\nimport {SelectionComponent} from './selection/selection';\nimport {Split} from './split';\nimport {UnitModel} from './unit';\n\n/**\n * Composable Components that are intermediate results of the parsing phase of the\n * compilations. The components represents parts of the specification in a form that\n * can be easily merged (during parsing for composite specs).\n * In addition, these components are easily transformed into Vega specifications\n * during the \"assemble\" phase, which is the last phase of the compilation step.\n */\nexport interface Component {\n data: DataComponent;\n\n layoutSize: LayoutSizeComponent;\n\n layoutHeaders: {\n row?: LayoutHeaderComponent,\n column?: LayoutHeaderComponent\n };\n\n mark: VgMarkGroup[];\n scales: ScaleComponentIndex;\n projection: ProjectionComponent;\n selection: Dict;\n\n /** Dictionary mapping channel to VgAxis definition */\n axes: AxisComponentIndex;\n\n /** Dictionary mapping channel to VgLegend definition */\n legends: LegendComponentIndex;\n\n resolve: Resolve;\n}\n\nexport interface NameMapInterface {\n rename(oldname: string, newName: string): void;\n has(name: string): boolean;\n get(name: string): string;\n}\n\nexport class NameMap implements NameMapInterface {\n private nameMap: Dict;\n\n constructor() {\n this.nameMap = {};\n }\n\n public rename(oldName: string, newName: string) {\n this.nameMap[oldName] = newName;\n }\n\n\n public has(name: string): boolean {\n return this.nameMap[name] !== undefined;\n }\n\n public get(name: string): string {\n // If the name appears in the _nameMap, we need to read its new name.\n // We have to loop over the dict just in case the new name also gets renamed.\n while (this.nameMap[name] && name !== this.nameMap[name]) {\n name = this.nameMap[name];\n }\n\n return name;\n }\n}\n\n/*\n We use type guards instead of `instanceof` as `instanceof` makes\n different parts of the compiler depend on the actual implementation of\n the model classes, which in turn depend on different parts of the compiler.\n Thus, `instanceof` leads to circular dependency problems.\n\n On the other hand, type guards only make different parts of the compiler\n depend on the type of the model classes, but not the actual implementation.\n*/\n\nexport function isUnitModel(model: Model): model is UnitModel {\n return model && model.type === 'unit';\n}\n\nexport function isFacetModel(model: Model): model is FacetModel {\n return model && model.type === 'facet';\n}\n\nexport function isRepeatModel(model: Model): model is RepeatModel {\n return model && model.type === 'repeat';\n}\n\nexport function isConcatModel(model: Model): model is ConcatModel {\n return model && model.type === 'concat';\n}\n\nexport function isLayerModel(model: Model): model is LayerModel {\n return model && model.type === 'layer';\n}\n\nexport abstract class Model {\n public abstract readonly type: 'unit' | 'facet' | 'layer' | 'concat' | 'repeat';\n public readonly parent: Model;\n public readonly name: string;\n\n public readonly title: TitleParams;\n public readonly description: string;\n\n public readonly data: Data;\n public readonly transforms: Transform[];\n public readonly layout: GenericCompositionLayout;\n\n /** Name map for scales, which can be renamed by a model's parent. */\n protected scaleNameMap: NameMapInterface;\n\n /** Name map for projections, which can be renamed by a model's parent. */\n protected projectionNameMap: NameMapInterface;\n\n /** Name map for size, which can be renamed by a model's parent. */\n protected layoutSizeNameMap: NameMapInterface;\n\n public readonly repeater: RepeaterValue;\n\n public readonly config: Config;\n\n public readonly component: Component;\n\n public abstract readonly children: Model[] = [];\n\n constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, repeater: RepeaterValue, resolve: Resolve) {\n this.parent = parent;\n this.config = config;\n this.repeater = repeater;\n\n // If name is not provided, always use parent's givenName to avoid name conflicts.\n this.name = spec.name || parentGivenName;\n this.title = isString(spec.title) ? {text: spec.title} : spec.title;\n\n // Shared name maps\n this.scaleNameMap = parent ? parent.scaleNameMap : new NameMap();\n this.projectionNameMap = parent ? parent.projectionNameMap : new NameMap();\n this.layoutSizeNameMap = parent ? parent.layoutSizeNameMap : new NameMap();\n\n this.data = spec.data;\n\n this.description = spec.description;\n this.transforms = normalizeTransform(spec.transform || []);\n this.layout = isUnitSpec(spec) || isLayerSpec(spec) ? undefined : extractCompositionLayout(spec);\n\n this.component = {\n data: {\n sources: parent ? parent.component.data.sources : {},\n outputNodes: parent ? parent.component.data.outputNodes : {},\n outputNodeRefCounts: parent ? parent.component.data.outputNodeRefCounts : {},\n // data is faceted if the spec is a facet spec or the parent has faceted data and no data is defined\n isFaceted: isFacetSpec(spec) || (parent && parent.component.data.isFaceted && !spec.data)\n },\n layoutSize: new Split(),\n layoutHeaders:{row: {}, column: {}},\n mark: null,\n resolve: {\n scale: {}, axis: {}, legend: {},\n ...(resolve || {})\n },\n selection: null,\n scales: null,\n projection: null,\n axes: {},\n legends: {},\n };\n }\n\n public get width(): VgSignalRef {\n return this.getSizeSignalRef('width');\n }\n\n\n public get height(): VgSignalRef {\n return this.getSizeSignalRef('height');\n }\n\n protected initSize(size: LayoutSizeIndex) {\n const {width, height} = size;\n if (width) {\n this.component.layoutSize.set('width', width, true);\n }\n\n if (height) {\n this.component.layoutSize.set('height', height, true);\n }\n }\n\n public parse() {\n this.parseScale();\n\n this.parseLayoutSize(); // depends on scale\n this.renameTopLevelLayoutSize();\n\n this.parseSelection();\n this.parseProjection();\n this.parseData(); // (pathorder) depends on markDef; selection filters depend on parsed selections; depends on projection because some transforms require the finalized projection name.\n this.parseAxisAndHeader(); // depends on scale and layout size\n this.parseLegend(); // depends on scale, markDef\n this.parseMarkGroup(); // depends on data name, scale, layout size, axisGroup, and children's scale, axis, legend and mark.\n }\n\n public abstract parseData(): void;\n\n public abstract parseSelection(): void;\n\n\n public parseScale() {\n parseScale(this);\n }\n\n public parseProjection() {\n parseProjection(this);\n }\n\n public abstract parseLayoutSize(): void;\n\n /**\n * Rename top-level spec's size to be just width / height, ignoring model name.\n * This essentially merges the top-level spec's width/height signals with the width/height signals\n * to help us reduce redundant signals declaration.\n */\n private renameTopLevelLayoutSize() {\n if (this.getName('width') !== 'width') {\n this.renameLayoutSize(this.getName('width'), 'width');\n }\n if (this.getName('height') !== 'height') {\n this.renameLayoutSize(this.getName('height'), 'height');\n }\n }\n\n public abstract parseMarkGroup(): void;\n\n public abstract parseAxisAndHeader(): void;\n\n public parseLegend() {\n parseLegend(this);\n }\n\n public abstract assembleSelectionTopLevelSignals(signals: any[]): any[];\n public abstract assembleSelectionSignals(): any[];\n\n public abstract assembleSelectionData(data: VgData[]): VgData[];\n\n public assembleGroupStyle(): string {\n if (this.type === 'unit' || this.type === 'layer') {\n return 'cell';\n }\n return undefined;\n }\n\n public assembleLayoutSize(): VgEncodeEntry {\n if (this.type === 'unit' || this.type === 'layer') {\n return {\n width: this.getSizeSignalRef('width'),\n height: this.getSizeSignalRef('height')\n };\n }\n return undefined;\n }\n\n public assembleLayout(): VgLayout {\n if (!this.layout) {\n return undefined;\n }\n\n const {align, bounds, center, spacing = {}} = this.layout;\n\n return {\n padding: isNumber(spacing) ? spacing : {\n row: spacing.row || 10,\n column: spacing.column || 10\n },\n ...this.assembleDefaultLayout(),\n ...(align ? {align} : {}),\n ...(bounds ? {bounds} : {}),\n ...(center ? {center} : {})\n };\n }\n\n protected assembleDefaultLayout(): VgLayout {\n return {};\n }\n\n public abstract assembleLayoutSignals(): VgSignal[];\n\n public assembleHeaderMarks(): VgMarkGroup[] {\n const {layoutHeaders} = this.component;\n let headerMarks = [];\n\n for (const channel of HEADER_CHANNELS) {\n if (layoutHeaders[channel].title) {\n headerMarks.push(getTitleGroup(this, channel));\n }\n }\n\n for (const channel of HEADER_CHANNELS) {\n headerMarks = headerMarks.concat(getHeaderGroups(this, channel));\n }\n return headerMarks;\n }\n\n public abstract assembleMarks(): VgMarkGroup[]; // TODO: VgMarkGroup[]\n\n public assembleAxes(): VgAxis[] {\n return assembleAxes(this.component.axes, this.config);\n }\n\n public assembleLegends(): VgLegend[] {\n return assembleLegends(this);\n }\n\n public assembleProjections(): VgProjection[] {\n return assembleProjections(this);\n }\n\n public assembleTitle(): VgTitle {\n const title: VgTitle = {\n ...extractTitleConfig(this.config.title).nonMark,\n ...this.title\n };\n\n if (title.text) {\n if (!contains(['unit', 'layer'], this.type)) {\n // As described in https://github.com/vega/vega-lite/issues/2875:\n // Due to vega/vega#960 (comment), we only support title's anchor for unit and layered spec for now.\n\n if (title.anchor && title.anchor !== 'start') {\n log.warn(log.message.cannotSetTitleAnchor(this.type));\n }\n title.anchor = 'start';\n }\n\n return keys(title).length > 0 ? title : undefined;\n }\n return undefined;\n }\n\n /**\n * Assemble the mark group for this model. We accept optional `signals` so that we can include concat top-level signals with the top-level model's local signals.\n */\n public assembleGroup(signals: VgSignal[] = []) {\n const group: VgMarkGroup = {};\n\n signals = signals.concat(this.assembleSelectionSignals());\n\n if (signals.length > 0) {\n group.signals = signals;\n }\n\n const layout = this.assembleLayout();\n if (layout) {\n group.layout = layout;\n }\n\n group.marks = [].concat(\n this.assembleHeaderMarks(),\n this.assembleMarks()\n );\n\n // Only include scales if this spec is top-level or if parent is facet.\n // (Otherwise, it will be merged with upper-level's scope.)\n const scales = (!this.parent || isFacetModel(this.parent)) ? assembleScales(this) : [];\n if (scales.length > 0) {\n group.scales = scales;\n }\n\n const axes = this.assembleAxes();\n if (axes.length > 0) {\n group.axes = axes;\n }\n\n const legends = this.assembleLegends();\n if (legends.length > 0) {\n group.legends = legends;\n }\n\n return group;\n }\n\n public hasDescendantWithFieldOnChannel(channel: Channel) {\n for (const child of this.children) {\n if (isUnitModel(child)) {\n if (child.channelHasField(channel)) {\n return true;\n }\n } else {\n if (child.hasDescendantWithFieldOnChannel(channel)) {\n return true;\n }\n }\n }\n return false;\n }\n\n public getName(text: string) {\n return varName((this.name ? this.name + '_' : '') + text);\n }\n\n /**\n * Request a data source name for the given data source type and mark that data source as required. This method should be called in parse, so that all used data source can be correctly instantiated in assembleData().\n */\n public requestDataName(name: DataSourceType) {\n const fullName = this.getName(name);\n\n // Increase ref count. This is critical because otherwise we won't create a data source.\n // We also increase the ref counts on OutputNode.getSource() calls.\n const refCounts = this.component.data.outputNodeRefCounts;\n refCounts[fullName] = (refCounts[fullName] || 0) + 1;\n\n return fullName;\n }\n\n public getSizeSignalRef(sizeType: 'width' | 'height'): VgSignalRef {\n if (isFacetModel(this.parent)) {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const scaleComponent = this.component.scales[channel];\n\n if (scaleComponent && !scaleComponent.merged) { // independent scale\n const type = scaleComponent.get('type');\n const range = scaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const scaleName = scaleComponent.get('name');\n const domain = assembleDomain(this, channel);\n const field = getFieldFromDomain(domain);\n if (field) {\n const fieldRef = vgField({aggregate: 'distinct', field}, {expr: 'datum'});\n return {\n signal: sizeExpr(scaleName, scaleComponent, fieldRef)\n };\n } else {\n log.warn('Unknown field for ${channel}. Cannot calculate view size.');\n return null;\n }\n\n }\n }\n }\n\n return {\n signal: this.layoutSizeNameMap.get(this.getName(sizeType))\n };\n }\n\n /**\n * Lookup the name of the datasource for an output node. You probably want to call this in assemble.\n */\n public lookupDataSource(name: string) {\n const node = this.component.data.outputNodes[name];\n\n if (!node) {\n // Name not found in map so let's just return what we got.\n // This can happen if we already have the correct name.\n return name;\n }\n\n return node.getSource();\n }\n\n public getSizeName(oldSizeName: string): string {\n return this.layoutSizeNameMap.get(oldSizeName);\n }\n\n public renameLayoutSize(oldName: string, newName: string) {\n this.layoutSizeNameMap.rename(oldName, newName);\n }\n\n public renameScale(oldName: string, newName: string) {\n this.scaleNameMap.rename(oldName, newName);\n }\n\n public renameProjection(oldName: string, newName: string) {\n this.projectionNameMap.rename(oldName, newName);\n }\n\n /**\n * @return scale name for a given channel after the scale has been parsed and named.\n */\n public scaleName(originalScaleName: Channel | string, parse?: boolean): string {\n if (parse) {\n // During the parse phase always return a value\n // No need to refer to rename map because a scale can't be renamed\n // before it has the original name.\n return this.getName(originalScaleName);\n }\n\n // If there is a scale for the channel, it should either\n // be in the scale component or exist in the name map\n if (\n // If there is a scale for the channel, there should be a local scale component for it\n (isChannel(originalScaleName) && isScaleChannel(originalScaleName) && this.component.scales[originalScaleName]) ||\n // in the scale name map (the scale get merged by its parent)\n this.scaleNameMap.has(this.getName(originalScaleName))\n ) {\n return this.scaleNameMap.get(this.getName(originalScaleName));\n }\n return undefined;\n }\n\n /**\n * @return projection name after the projection has been parsed and named.\n */\n public projectionName(parse?: boolean): string {\n if (parse) {\n // During the parse phase always return a value\n // No need to refer to rename map because a projection can't be renamed\n // before it has the original name.\n return this.getName('projection');\n }\n\n if ((this.component.projection && !this.component.projection.merged) || this.projectionNameMap.has(this.getName('projection'))) {\n return this.projectionNameMap.get(this.getName('projection'));\n }\n return undefined;\n }\n\n /**\n * Corrects the data references in marks after assemble.\n */\n public correctDataNames = (mark: VgMarkGroup) => {\n // TODO: make this correct\n\n // for normal data references\n if (mark.from && mark.from.data) {\n mark.from.data = this.lookupDataSource(mark.from.data);\n }\n\n // for access to facet data\n if (mark.from && mark.from.facet && mark.from.facet.data) {\n mark.from.facet.data = this.lookupDataSource(mark.from.facet.data);\n }\n\n return mark;\n }\n\n /**\n * Traverse a model's hierarchy to get the scale component for a particular channel.\n */\n public getScaleComponent(channel: ScaleChannel): ScaleComponent {\n /* istanbul ignore next: This is warning for debugging test */\n if (!this.component.scales) {\n throw new Error('getScaleComponent cannot be called before parseScale(). Make sure you have called parseScale or use parseUnitModelWithScale().');\n }\n\n const localScaleComponent = this.component.scales[channel];\n if (localScaleComponent && !localScaleComponent.merged) {\n return localScaleComponent;\n }\n return (this.parent ? this.parent.getScaleComponent(channel) : undefined);\n }\n\n /**\n * Traverse a model's hierarchy to get a particular selection component.\n */\n public getSelectionComponent(variableName: string, origName: string): SelectionComponent {\n let sel = this.component.selection[variableName];\n if (!sel && this.parent) {\n sel = this.parent.getSelectionComponent(variableName, origName);\n }\n if (!sel) {\n throw new Error(log.message.selectionNotFound(origName));\n }\n return sel;\n }\n}\n\n/** Abstract class for UnitModel and FacetModel. Both of which can contain fieldDefs as a part of its own specification. */\nexport abstract class ModelWithField extends Model {\n public abstract fieldDef(channel: SingleDefChannel): FieldDef;\n\n /** Get \"field\" reference for vega */\n public vgField(channel: SingleDefChannel, opt: FieldRefOption = {}) {\n const fieldDef = this.fieldDef(channel);\n\n if (!fieldDef) {\n return undefined;\n }\n\n return vgField(fieldDef, opt);\n }\n\n protected abstract getMapping(): {[key in Channel]?: any};\n\n public reduceFieldDef(f: (acc: U, fd: FieldDef, c: Channel) => U, init: T, t?: any) {\n return reduce(this.getMapping(), (acc:U , cd: ChannelDef, c: Channel) => {\n const fieldDef = getFieldDef(cd);\n if (fieldDef) {\n return f(acc, fieldDef, c);\n }\n return acc;\n }, init, t);\n }\n\n public forEachFieldDef(f: (fd: FieldDef, c: Channel) => void, t?: any) {\n forEach(this.getMapping(), (cd: ChannelDef, c: Channel) => {\n const fieldDef = getFieldDef(cd);\n if (fieldDef) {\n f(fieldDef, c);\n }\n }, t);\n }\n public abstract channelHasField(channel: Channel): boolean;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/projection/assemble.d.ts b/build/src/compile/projection/assemble.d.ts new file mode 100644 index 0000000000..6e21546091 --- /dev/null +++ b/build/src/compile/projection/assemble.d.ts @@ -0,0 +1,5 @@ +import { VgProjection } from '../../vega.schema'; +import { Model } from '../model'; +export declare function assembleProjections(model: Model): VgProjection[]; +export declare function assembleProjectionsForModelAndChildren(model: Model): VgProjection[]; +export declare function assembleProjectionForModel(model: Model): VgProjection[]; diff --git a/build/src/compile/projection/assemble.js b/build/src/compile/projection/assemble.js new file mode 100644 index 0000000000..b4c09aa4af --- /dev/null +++ b/build/src/compile/projection/assemble.js @@ -0,0 +1,44 @@ +import * as tslib_1 from "tslib"; +import { contains } from '../../util'; +import { isVgSignalRef } from '../../vega.schema'; +import { isConcatModel, isLayerModel, isRepeatModel } from '../model'; +export function assembleProjections(model) { + if (isLayerModel(model) || isConcatModel(model) || isRepeatModel(model)) { + return assembleProjectionsForModelAndChildren(model); + } + else { + return assembleProjectionForModel(model); + } +} +export function assembleProjectionsForModelAndChildren(model) { + return model.children.reduce(function (projections, child) { + return projections.concat(child.assembleProjections()); + }, assembleProjectionForModel(model)); +} +export function assembleProjectionForModel(model) { + var component = model.component.projection; + if (!component || component.merged) { + return []; + } + var projection = component.combine(); + var name = projection.name, rest = tslib_1.__rest(projection, ["name"]); // we need to extract name so that it is always present in the output and pass TS type validation + var size = { + signal: "[" + component.size.map(function (ref) { return ref.signal; }).join(', ') + "]" + }; + var fit = component.data.reduce(function (sources, data) { + var source = isVgSignalRef(data) ? data.signal : "data('" + model.lookupDataSource(data) + "')"; + if (!contains(sources, source)) { + // build a unique list of sources + sources.push(source); + } + return sources; + }, []); + if (fit.length <= 0) { + throw new Error("Projection's fit didn't find any data sources"); + } + return [tslib_1.__assign({ name: name, + size: size, fit: { + signal: fit.length > 1 ? "[" + fit.join(', ') + "]" : fit[0] + } }, rest)]; +} +//# sourceMappingURL=assemble.js.map \ No newline at end of file diff --git a/build/src/compile/projection/assemble.js.map b/build/src/compile/projection/assemble.js.map new file mode 100644 index 0000000000..0457cb4242 --- /dev/null +++ b/build/src/compile/projection/assemble.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../../../src/compile/projection/assemble.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,EAAC,aAAa,EAA4B,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAC,aAAa,EAAE,YAAY,EAAE,aAAa,EAAQ,MAAM,UAAU,CAAC;AAE3E,MAAM,8BAA8B,KAAY;IAC9C,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE;QACvE,OAAO,sCAAsC,CAAC,KAAK,CAAC,CAAC;KACtD;SAAM;QACL,OAAO,0BAA0B,CAAC,KAAK,CAAC,CAAC;KAC1C;AACH,CAAC;AAED,MAAM,iDAAiD,KAAY;IACjE,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAC,WAAW,EAAE,KAAK;QAC9C,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC,CAAC;IACzD,CAAC,EAAE,0BAA0B,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,qCAAqC,KAAY;IACrD,IAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC;IAC7C,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,EAAE;QAClC,OAAO,EAAE,CAAC;KACX;IAED,IAAM,UAAU,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;IAChC,IAAA,sBAAI,EAAE,2CAAO,CAAe,CAAE,iGAAiG;IAEtI,IAAM,IAAI,GAAgB;QACxB,MAAM,EAAE,MAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,UAAC,GAAG,IAAK,OAAA,GAAG,CAAC,MAAM,EAAV,CAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAG;KAClE,CAAC;IAEF,IAAM,GAAG,GAAa,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,UAAC,OAAO,EAAE,IAAI;QACxD,IAAM,MAAM,GAAW,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAS,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAI,CAAC;QACrG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE;YAC9B,iCAAiC;YACjC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SACtB;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE;QACnB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;KAClE;IAED,OAAO,oBACL,IAAI,MAAA;YACJ,IAAI,MAAA,EACJ,GAAG,EAAE;gBACH,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;aACxD,IACE,IAAI,EACP,CAAC;AACL,CAAC","sourcesContent":["import {contains} from '../../util';\nimport {isVgSignalRef, VgProjection, VgSignalRef} from '../../vega.schema';\nimport {isConcatModel, isLayerModel, isRepeatModel, Model} from '../model';\n\nexport function assembleProjections(model: Model): VgProjection[] {\n if (isLayerModel(model) || isConcatModel(model) || isRepeatModel(model)) {\n return assembleProjectionsForModelAndChildren(model);\n } else {\n return assembleProjectionForModel(model);\n }\n}\n\nexport function assembleProjectionsForModelAndChildren(model: Model): VgProjection[] {\n return model.children.reduce((projections, child) => {\n return projections.concat(child.assembleProjections());\n }, assembleProjectionForModel(model));\n}\n\nexport function assembleProjectionForModel(model: Model): VgProjection[] {\n const component = model.component.projection;\n if (!component || component.merged) {\n return [];\n }\n\n const projection = component.combine();\n const {name, ...rest} = projection; // we need to extract name so that it is always present in the output and pass TS type validation\n\n const size: VgSignalRef = {\n signal: `[${component.size.map((ref) => ref.signal).join(', ')}]`\n };\n\n const fit: string[] = component.data.reduce((sources, data) => {\n const source: string = isVgSignalRef(data) ? data.signal : `data('${model.lookupDataSource(data)}')`;\n if (!contains(sources, source)) {\n // build a unique list of sources\n sources.push(source);\n }\n return sources;\n }, []);\n\n if (fit.length <= 0) {\n throw new Error(\"Projection's fit didn't find any data sources\");\n }\n\n return [{\n name,\n size,\n fit: {\n signal: fit.length > 1 ? `[${fit.join(', ')}]` : fit[0]\n },\n ...rest\n }];\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/projection/component.d.ts b/build/src/compile/projection/component.d.ts new file mode 100644 index 0000000000..ceae86e04b --- /dev/null +++ b/build/src/compile/projection/component.d.ts @@ -0,0 +1,10 @@ +import { Projection } from '../../projection'; +import { VgProjection, VgSignalRef } from '../../vega.schema'; +import { Split } from '../split'; +export declare class ProjectionComponent extends Split { + specifiedProjection: Projection; + size: VgSignalRef[]; + data: (string | VgSignalRef)[]; + merged: boolean; + constructor(name: string, specifiedProjection: Projection, size: VgSignalRef[], data: (string | VgSignalRef)[]); +} diff --git a/build/src/compile/projection/component.js b/build/src/compile/projection/component.js new file mode 100644 index 0000000000..7ae5510519 --- /dev/null +++ b/build/src/compile/projection/component.js @@ -0,0 +1,18 @@ +import * as tslib_1 from "tslib"; +import { Split } from '../split'; +var ProjectionComponent = /** @class */ (function (_super) { + tslib_1.__extends(ProjectionComponent, _super); + function ProjectionComponent(name, specifiedProjection, size, data) { + var _this = _super.call(this, tslib_1.__assign({}, specifiedProjection), // all explicit properties of projection + { name: name } // name as initial implicit property + ) || this; + _this.specifiedProjection = specifiedProjection; + _this.size = size; + _this.data = data; + _this.merged = false; + return _this; + } + return ProjectionComponent; +}(Split)); +export { ProjectionComponent }; +//# sourceMappingURL=component.js.map \ No newline at end of file diff --git a/build/src/compile/projection/component.js.map b/build/src/compile/projection/component.js.map new file mode 100644 index 0000000000..de57d64452 --- /dev/null +++ b/build/src/compile/projection/component.js.map @@ -0,0 +1 @@ +{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../src/compile/projection/component.ts"],"names":[],"mappings":";AAEA,OAAO,EAAC,KAAK,EAAC,MAAM,UAAU,CAAC;AAE/B;IAAyC,+CAAmB;IAG1D,6BAAY,IAAY,EAAS,mBAA+B,EAAS,IAAmB,EAAS,IAA8B;QAAnI,YACE,uCACM,mBAAmB,GAAI,wCAAwC;QACnE,EAAC,IAAI,MAAA,EAAC,CAAE,oCAAoC;SAC7C,SACF;QALgC,yBAAmB,GAAnB,mBAAmB,CAAY;QAAS,UAAI,GAAJ,IAAI,CAAe;QAAS,UAAI,GAAJ,IAAI,CAA0B;QAF5H,YAAM,GAAG,KAAK,CAAC;;IAOtB,CAAC;IACH,0BAAC;AAAD,CAAC,AATD,CAAyC,KAAK,GAS7C","sourcesContent":["import {Projection} from '../../projection';\nimport {VgProjection, VgSignalRef} from '../../vega.schema';\nimport {Split} from '../split';\n\nexport class ProjectionComponent extends Split {\n public merged = false;\n\n constructor(name: string, public specifiedProjection: Projection, public size: VgSignalRef[], public data: (string | VgSignalRef)[]) {\n super(\n {...specifiedProjection}, // all explicit properties of projection\n {name} // name as initial implicit property\n );\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/projection/parse.d.ts b/build/src/compile/projection/parse.d.ts new file mode 100644 index 0000000000..587464fa0d --- /dev/null +++ b/build/src/compile/projection/parse.d.ts @@ -0,0 +1,2 @@ +import { Model } from '../model'; +export declare function parseProjection(model: Model): void; diff --git a/build/src/compile/projection/parse.js b/build/src/compile/projection/parse.js new file mode 100644 index 0000000000..1484c35a36 --- /dev/null +++ b/build/src/compile/projection/parse.js @@ -0,0 +1,118 @@ +import * as tslib_1 from "tslib"; +import { LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2, SHAPE } from '../../channel'; +import { MAIN } from '../../data'; +import { PROJECTION_PROPERTIES } from '../../projection'; +import { GEOJSON } from '../../type'; +import { duplicate, every, stringify } from '../../util'; +import { isUnitModel } from '../model'; +import { ProjectionComponent } from './component'; +export function parseProjection(model) { + if (isUnitModel(model)) { + model.component.projection = parseUnitProjection(model); + } + else { + // because parse happens from leaves up (unit specs before layer spec), + // we can be sure that the above if statement has already occurred + // and therefore we have access to child.component.projection + // for each of model's children + model.component.projection = parseNonUnitProjections(model); + } +} +function parseUnitProjection(model) { + var specifiedProjection = model.specifiedProjection, config = model.config, hasProjection = model.hasProjection; + if (hasProjection) { + var data_1 = []; + [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach(function (posssiblePair) { + if (model.channelHasField(posssiblePair[0]) || model.channelHasField(posssiblePair[1])) { + data_1.push({ + signal: model.getName("geojson_" + data_1.length) + }); + } + }); + if (model.channelHasField(SHAPE) && model.fieldDef(SHAPE).type === GEOJSON) { + data_1.push({ + signal: model.getName("geojson_" + data_1.length) + }); + } + if (data_1.length === 0) { + // main source is geojson, so we can just use that + data_1.push(model.requestDataName(MAIN)); + } + return new ProjectionComponent(model.projectionName(true), tslib_1.__assign({}, (config.projection || {}), (specifiedProjection || {})), [model.getSizeSignalRef('width'), model.getSizeSignalRef('height')], data_1); + } + return undefined; +} +function mergeIfNoConflict(first, second) { + var allPropertiesShared = every(PROJECTION_PROPERTIES, function (prop) { + // neither has the poperty + if (!first.explicit.hasOwnProperty(prop) && + !second.explicit.hasOwnProperty(prop)) { + return true; + } + // both have property and an equal value for property + if (first.explicit.hasOwnProperty(prop) && + second.explicit.hasOwnProperty(prop) && + // some properties might be signals or objects and require hashing for comparison + stringify(first.get(prop)) === stringify(second.get(prop))) { + return true; + } + return false; + }); + var size = stringify(first.size) === stringify(second.size); + if (size) { + if (allPropertiesShared) { + return first; + } + else if (stringify(first.explicit) === stringify({})) { + return second; + } + else if (stringify(second.explicit) === stringify({})) { + return first; + } + } + // if all properties don't match, let each unit spec have its own projection + return null; +} +function parseNonUnitProjections(model) { + if (model.children.length === 0) { + return undefined; + } + var nonUnitProjection; + var mergable = every(model.children, function (child) { + parseProjection(child); + var projection = child.component.projection; + if (!projection) { + // child layer does not use a projection + return true; + } + else if (!nonUnitProjection) { + // cached 'projection' is null, cache this one + nonUnitProjection = projection; + return true; + } + else { + var merge = mergeIfNoConflict(nonUnitProjection, projection); + if (merge) { + nonUnitProjection = merge; + } + return !!merge; + } + }); + // it cached one and all other children share the same projection, + if (nonUnitProjection && mergable) { + // so we can elevate it to the layer level + var name_1 = model.projectionName(true); + var modelProjection_1 = new ProjectionComponent(name_1, nonUnitProjection.specifiedProjection, nonUnitProjection.size, duplicate(nonUnitProjection.data)); + // rename and assign all others as merged + model.children.forEach(function (child) { + if (child.component.projection) { + modelProjection_1.data = modelProjection_1.data.concat(child.component.projection.data); + child.renameProjection(child.component.projection.get('name'), name_1); + child.component.projection.merged = true; + } + }); + return modelProjection_1; + } + return undefined; +} +//# sourceMappingURL=parse.js.map \ No newline at end of file diff --git a/build/src/compile/projection/parse.js.map b/build/src/compile/projection/parse.js.map new file mode 100644 index 0000000000..6acd128e89 --- /dev/null +++ b/build/src/compile/projection/parse.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../src/compile/projection/parse.ts"],"names":[],"mappings":"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","sourcesContent":["import {LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2, SHAPE} from '../../channel';\nimport {MAIN} from '../../data';\nimport {PROJECTION_PROPERTIES} from '../../projection';\nimport {GEOJSON} from '../../type';\nimport {duplicate, every, stringify} from '../../util';\nimport {VgSignalRef} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {UnitModel} from '../unit';\nimport {ProjectionComponent} from './component';\n\nexport function parseProjection(model: Model) {\n if (isUnitModel(model)) {\n model.component.projection = parseUnitProjection(model);\n } else {\n // because parse happens from leaves up (unit specs before layer spec),\n // we can be sure that the above if statement has already occurred\n // and therefore we have access to child.component.projection\n // for each of model's children\n model.component.projection = parseNonUnitProjections(model);\n }\n}\n\nfunction parseUnitProjection(model: UnitModel): ProjectionComponent {\n const {specifiedProjection, config, hasProjection} = model;\n\n if (hasProjection) {\n const data: (VgSignalRef | string)[] = [];\n\n [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach((posssiblePair) => {\n if (model.channelHasField(posssiblePair[0]) || model.channelHasField(posssiblePair[1])) {\n data.push({\n signal: model.getName(`geojson_${data.length}`)\n });\n }\n });\n\n if (model.channelHasField(SHAPE) && model.fieldDef(SHAPE).type === GEOJSON) {\n data.push({\n signal: model.getName(`geojson_${data.length}`)\n });\n }\n\n if (data.length === 0) {\n // main source is geojson, so we can just use that\n data.push(model.requestDataName(MAIN));\n }\n\n return new ProjectionComponent(model.projectionName(true), {\n ...(config.projection || {}),\n ...(specifiedProjection || {}),\n }, [model.getSizeSignalRef('width'), model.getSizeSignalRef('height')], data);\n }\n\n return undefined;\n}\n\n\nfunction mergeIfNoConflict(first: ProjectionComponent, second: ProjectionComponent): ProjectionComponent {\n const allPropertiesShared = every(PROJECTION_PROPERTIES, (prop) => {\n // neither has the poperty\n if (!first.explicit.hasOwnProperty(prop) &&\n !second.explicit.hasOwnProperty(prop)) {\n return true;\n }\n // both have property and an equal value for property\n if (first.explicit.hasOwnProperty(prop) &&\n second.explicit.hasOwnProperty(prop) &&\n // some properties might be signals or objects and require hashing for comparison\n stringify(first.get(prop)) === stringify(second.get(prop))) {\n return true;\n }\n return false;\n });\n\n const size = stringify(first.size) === stringify(second.size);\n if (size) {\n if (allPropertiesShared) {\n return first;\n } else if (stringify(first.explicit) === stringify({})) {\n return second;\n } else if (stringify(second.explicit) === stringify({})) {\n return first;\n }\n }\n\n // if all properties don't match, let each unit spec have its own projection\n return null;\n}\n\nfunction parseNonUnitProjections(model: Model): ProjectionComponent {\n if (model.children.length === 0) {\n return undefined;\n }\n\n let nonUnitProjection: ProjectionComponent;\n const mergable = every(model.children, (child) => {\n parseProjection(child);\n const projection = child.component.projection;\n if (!projection) {\n // child layer does not use a projection\n return true;\n } else if (!nonUnitProjection) {\n // cached 'projection' is null, cache this one\n nonUnitProjection = projection;\n return true;\n } else {\n const merge = mergeIfNoConflict(nonUnitProjection, projection);\n if (merge) {\n nonUnitProjection = merge;\n }\n return !!merge;\n }\n });\n\n // it cached one and all other children share the same projection,\n if (nonUnitProjection && mergable) {\n // so we can elevate it to the layer level\n const name = model.projectionName(true);\n const modelProjection = new ProjectionComponent(\n name,\n nonUnitProjection.specifiedProjection,\n nonUnitProjection.size,\n duplicate(nonUnitProjection.data)\n );\n\n // rename and assign all others as merged\n model.children.forEach((child) => {\n if (child.component.projection) {\n modelProjection.data = modelProjection.data.concat(child.component.projection.data);\n child.renameProjection(child.component.projection.get('name'), name);\n child.component.projection.merged = true;\n }\n });\n\n return modelProjection;\n }\n\n return undefined;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/repeat.d.ts b/build/src/compile/repeat.d.ts new file mode 100644 index 0000000000..1e37751fef --- /dev/null +++ b/build/src/compile/repeat.d.ts @@ -0,0 +1,16 @@ +import { Config } from '../config'; +import { Repeat } from '../repeat'; +import { NormalizedRepeatSpec } from '../spec'; +import { VgLayout } from '../vega.schema'; +import { BaseConcatModel } from './baseconcat'; +import { Model } from './model'; +import { RepeaterValue } from './repeater'; +export declare class RepeatModel extends BaseConcatModel { + readonly type: 'repeat'; + readonly repeat: Repeat; + readonly children: Model[]; + constructor(spec: NormalizedRepeatSpec, parent: Model, parentGivenName: string, repeatValues: RepeaterValue, config: Config); + private _initChildren; + parseLayoutSize(): void; + protected assembleDefaultLayout(): VgLayout; +} diff --git a/build/src/compile/repeat.js b/build/src/compile/repeat.js new file mode 100644 index 0000000000..1cb960b99e --- /dev/null +++ b/build/src/compile/repeat.js @@ -0,0 +1,50 @@ +import * as tslib_1 from "tslib"; +import * as log from '../log'; +import { BaseConcatModel } from './baseconcat'; +import { buildModel } from './buildmodel'; +import { parseRepeatLayoutSize } from './layoutsize/parse'; +var RepeatModel = /** @class */ (function (_super) { + tslib_1.__extends(RepeatModel, _super); + function RepeatModel(spec, parent, parentGivenName, repeatValues, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, repeatValues, spec.resolve) || this; + _this.type = 'repeat'; + if (spec.resolve && spec.resolve.axis && (spec.resolve.axis.x === 'shared' || spec.resolve.axis.y === 'shared')) { + log.warn(log.message.REPEAT_CANNOT_SHARE_AXIS); + } + _this.repeat = spec.repeat; + _this.children = _this._initChildren(spec, _this.repeat, repeatValues, config); + return _this; + } + RepeatModel.prototype._initChildren = function (spec, repeat, repeater, config) { + var children = []; + var row = repeat.row || [repeater ? repeater.row : null]; + var column = repeat.column || [repeater ? repeater.column : null]; + // cross product + for (var _i = 0, row_1 = row; _i < row_1.length; _i++) { + var rowField = row_1[_i]; + for (var _a = 0, column_1 = column; _a < column_1.length; _a++) { + var columnField = column_1[_a]; + var name_1 = (rowField ? '_' + rowField : '') + (columnField ? '_' + columnField : ''); + var childRepeat = { + row: rowField, + column: columnField + }; + children.push(buildModel(spec.spec, this, this.getName('child' + name_1), undefined, childRepeat, config, false)); + } + } + return children; + }; + RepeatModel.prototype.parseLayoutSize = function () { + parseRepeatLayoutSize(this); + }; + RepeatModel.prototype.assembleDefaultLayout = function () { + return { + columns: this.repeat && this.repeat.column ? this.repeat.column.length : 1, + bounds: 'full', + align: 'all' + }; + }; + return RepeatModel; +}(BaseConcatModel)); +export { RepeatModel }; +//# sourceMappingURL=repeat.js.map \ No newline at end of file diff --git a/build/src/compile/repeat.js.map b/build/src/compile/repeat.js.map new file mode 100644 index 0000000000..962d14d7d2 --- /dev/null +++ b/build/src/compile/repeat.js.map @@ -0,0 +1 @@ +{"version":3,"file":"repeat.js","sourceRoot":"","sources":["../../../src/compile/repeat.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,GAAG,MAAM,QAAQ,CAAC;AAI9B,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAIzD;IAAiC,uCAAe;IAM9C,qBAAY,IAA0B,EAAE,MAAa,EAAE,eAAuB,EAAE,YAA2B,EAAE,MAAc;QAA3H,YACE,kBAAM,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,SAQzE;QAde,UAAI,GAAa,QAAQ,CAAC;QAQxC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,QAAQ,CAAC,EAAE;YAC/G,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;SAChD;QAED,KAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,KAAI,CAAC,QAAQ,GAAG,KAAI,CAAC,aAAa,CAAC,IAAI,EAAE,KAAI,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;;IAC9E,CAAC;IAEO,mCAAa,GAArB,UAAsB,IAA0B,EAAE,MAAc,EAAE,QAAuB,EAAE,MAAc;QACvG,IAAM,QAAQ,GAAY,EAAE,CAAC;QAC7B,IAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEpE,gBAAgB;QAChB,KAAuB,UAAG,EAAH,WAAG,EAAH,iBAAG,EAAH,IAAG,EAAE;YAAvB,IAAM,QAAQ,YAAA;YACjB,KAA0B,UAAM,EAAN,iBAAM,EAAN,oBAAM,EAAN,IAAM,EAAE;gBAA7B,IAAM,WAAW,eAAA;gBACpB,IAAM,MAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAEvF,IAAM,WAAW,GAAG;oBAClB,GAAG,EAAE,QAAQ;oBACb,MAAM,EAAE,WAAW;iBACpB,CAAC;gBAEF,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,MAAI,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;aACjH;SACF;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEM,qCAAe,GAAtB;QACE,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAES,2CAAqB,GAA/B;QACE,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC1E,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,KAAK;SACb,CAAC;IACJ,CAAC;IACH,kBAAC;AAAD,CAAC,AAlDD,CAAiC,eAAe,GAkD/C","sourcesContent":["\nimport {Config} from '../config';\nimport * as log from '../log';\nimport {Repeat} from '../repeat';\nimport {NormalizedRepeatSpec} from '../spec';\nimport {VgLayout} from '../vega.schema';\nimport {BaseConcatModel} from './baseconcat';\nimport {buildModel} from './buildmodel';\nimport {parseRepeatLayoutSize} from './layoutsize/parse';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\n\nexport class RepeatModel extends BaseConcatModel {\n public readonly type: 'repeat' = 'repeat';\n public readonly repeat: Repeat;\n\n public readonly children: Model[];\n\n constructor(spec: NormalizedRepeatSpec, parent: Model, parentGivenName: string, repeatValues: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, repeatValues, spec.resolve);\n\n if (spec.resolve && spec.resolve.axis && (spec.resolve.axis.x === 'shared' || spec.resolve.axis.y === 'shared')) {\n log.warn(log.message.REPEAT_CANNOT_SHARE_AXIS);\n }\n\n this.repeat = spec.repeat;\n this.children = this._initChildren(spec, this.repeat, repeatValues, config);\n }\n\n private _initChildren(spec: NormalizedRepeatSpec, repeat: Repeat, repeater: RepeaterValue, config: Config): Model[] {\n const children: Model[] = [];\n const row = repeat.row || [repeater ? repeater.row : null];\n const column = repeat.column || [repeater ? repeater.column : null];\n\n // cross product\n for (const rowField of row) {\n for (const columnField of column) {\n const name = (rowField ? '_' + rowField : '') + (columnField ? '_' + columnField : '');\n\n const childRepeat = {\n row: rowField,\n column: columnField\n };\n\n children.push(buildModel(spec.spec, this, this.getName('child' + name), undefined, childRepeat, config, false));\n }\n }\n\n return children;\n }\n\n public parseLayoutSize() {\n parseRepeatLayoutSize(this);\n }\n\n protected assembleDefaultLayout(): VgLayout {\n return {\n columns: this.repeat && this.repeat.column ? this.repeat.column.length : 1,\n bounds: 'full',\n align: 'all'\n };\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/repeater.d.ts b/build/src/compile/repeater.d.ts new file mode 100644 index 0000000000..9541e6b9ad --- /dev/null +++ b/build/src/compile/repeater.d.ts @@ -0,0 +1,9 @@ +import { Encoding } from '../encoding'; +import { FacetMapping } from '../facet'; +import { Field } from '../fielddef'; +export declare type RepeaterValue = { + row?: string; + column?: string; +}; +export declare function replaceRepeaterInFacet(facet: FacetMapping, repeater: RepeaterValue): FacetMapping; +export declare function replaceRepeaterInEncoding(encoding: Encoding, repeater: RepeaterValue): Encoding; diff --git a/build/src/compile/repeater.js b/build/src/compile/repeater.js new file mode 100644 index 0000000000..11d679a0cc --- /dev/null +++ b/build/src/compile/repeater.js @@ -0,0 +1,88 @@ +import * as tslib_1 from "tslib"; +import { isArray } from 'vega-util'; +import { hasConditionalFieldDef, isConditionalDef, isFieldDef, isRepeatRef } from '../fielddef'; +import * as log from '../log'; +import { isSortField } from '../sort'; +export function replaceRepeaterInFacet(facet, repeater) { + return replaceRepeater(facet, repeater); +} +export function replaceRepeaterInEncoding(encoding, repeater) { + return replaceRepeater(encoding, repeater); +} +/** + * Replaces repeated value and returns if the repeated value is valid. + */ +function replaceRepeat(o, repeater) { + if (isRepeatRef(o.field)) { + if (o.field.repeat in repeater) { + // any needed to calm down ts compiler + return tslib_1.__assign({}, o, { field: repeater[o.field.repeat] }); + } + else { + log.warn(log.message.noSuchRepeatedValue(o.field.repeat)); + return undefined; + } + } + return o; +} +/** + * Replace repeater values in a field def with the concrete field name. + */ +function replaceRepeaterInFieldDef(fieldDef, repeater) { + fieldDef = replaceRepeat(fieldDef, repeater); + if (fieldDef === undefined) { + // the field def should be ignored + return undefined; + } + if (fieldDef.sort && isSortField(fieldDef.sort)) { + var sort = replaceRepeat(fieldDef.sort, repeater); + fieldDef = tslib_1.__assign({}, fieldDef, (sort ? { sort: sort } : {})); + } + return fieldDef; +} +function replaceRepeaterInChannelDef(channelDef, repeater) { + if (isFieldDef(channelDef)) { + var fd = replaceRepeaterInFieldDef(channelDef, repeater); + if (fd) { + return fd; + } + else if (isConditionalDef(channelDef)) { + return { condition: channelDef.condition }; + } + } + else { + if (hasConditionalFieldDef(channelDef)) { + var fd = replaceRepeaterInFieldDef(channelDef.condition, repeater); + if (fd) { + return tslib_1.__assign({}, channelDef, { condition: fd }); + } + else { + var condition = channelDef.condition, channelDefWithoutCondition = tslib_1.__rest(channelDef, ["condition"]); + return channelDefWithoutCondition; + } + } + return channelDef; + } + return undefined; +} +function replaceRepeater(mapping, repeater) { + var out = {}; + for (var channel in mapping) { + if (mapping.hasOwnProperty(channel)) { + var channelDef = mapping[channel]; + if (isArray(channelDef)) { + // array cannot have condition + out[channel] = channelDef.map(function (cd) { return replaceRepeaterInChannelDef(cd, repeater); }) + .filter(function (cd) { return cd; }); + } + else { + var cd = replaceRepeaterInChannelDef(channelDef, repeater); + if (cd) { + out[channel] = cd; + } + } + } + } + return out; +} +//# sourceMappingURL=repeater.js.map \ No newline at end of file diff --git a/build/src/compile/repeater.js.map b/build/src/compile/repeater.js.map new file mode 100644 index 0000000000..b89de1fb54 --- /dev/null +++ b/build/src/compile/repeater.js.map @@ -0,0 +1 @@ +{"version":3,"file":"repeater.js","sourceRoot":"","sources":["../../../src/compile/repeater.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAGlC,OAAO,EAAQ,sBAAsB,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAW,MAAM,aAAa,CAAC;AAE/G,OAAO,KAAK,GAAG,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAC,WAAW,EAAC,MAAM,SAAS,CAAC;AAOpC,MAAM,iCAAiC,KAA0B,EAAE,QAAuB;IACxF,OAAO,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAyB,CAAC;AAClE,CAAC;AAED,MAAM,oCAAoC,QAAyB,EAAE,QAAuB;IAC1F,OAAO,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAqB,CAAC;AACjE,CAAC;AAED;;GAEG;AACH,uBAAkD,CAAI,EAAE,QAAuB;IAC7E,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;QACxB,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,QAAQ,EAAE;YAC9B,sCAAsC;YACtC,4BAAW,CAAQ,IAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAE;SACvD;aAAM;YACL,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAC1D,OAAO,SAAS,CAAC;SAClB;KACF;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;GAEG;AACH,mCAAmC,QAA8B,EAAE,QAAuB;IACxF,QAAQ,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAE7C,IAAI,QAAQ,KAAK,SAAS,EAAE;QAC1B,kCAAkC;QAClC,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,QAAQ,CAAC,IAAI,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;QAC/C,IAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpD,QAAQ,wBACH,QAAQ,EACR,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,IAAI,MAAA,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CACxB,CAAC;KACH;IAED,OAAO,QAAiC,CAAC;AAC3C,CAAC;AAED,qCAAqC,UAA6B,EAAE,QAAuB;IACzF,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE;QAC1B,IAAM,EAAE,GAAG,yBAAyB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC3D,IAAI,EAAE,EAAE;YACN,OAAO,EAAE,CAAC;SACX;aAAM,IAAI,gBAAgB,CAAC,UAAU,CAAC,EAAE;YACvC,OAAO,EAAC,SAAS,EAAE,UAAU,CAAC,SAAS,EAAC,CAAC;SAC1C;KACF;SAAM;QACL,IAAI,sBAAsB,CAAC,UAAU,CAAC,EAAE;YACtC,IAAM,EAAE,GAAG,yBAAyB,CAAC,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACrE,IAAI,EAAE,EAAE;gBACN,OAAO,qBACF,UAAU,IACb,SAAS,EAAE,EAAE,GACQ,CAAC;aACzB;iBAAM;gBACE,IAAA,gCAAS,EAAE,sEAA6B,CAAe;gBAC9D,OAAO,0BAAgD,CAAC;aACzD;SACF;QACD,OAAO,UAAsB,CAAC;KAC/B;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAID,yBAAyB,OAA+B,EAAE,QAAuB;IAC/E,IAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,IAAM,OAAO,IAAI,OAAO,EAAE;QAC7B,IAAI,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE;YACnC,IAAM,UAAU,GAA4C,OAAO,CAAC,OAAO,CAAC,CAAC;YAE7E,IAAI,OAAO,CAAC,UAAU,CAAC,EAAE;gBACvB,8BAA8B;gBAC9B,GAAG,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,UAAA,EAAE,IAAI,OAAA,2BAA2B,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAzC,CAAyC,CAAC;qBAC3E,MAAM,CAAC,UAAA,EAAE,IAAI,OAAA,EAAE,EAAF,CAAE,CAAC,CAAC;aACrB;iBAAM;gBACL,IAAM,EAAE,GAAG,2BAA2B,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;gBAC7D,IAAI,EAAE,EAAE;oBACN,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;iBACnB;aACF;SACF;KACF;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import {isArray} from 'vega-util';\nimport {Encoding} from '../encoding';\nimport {FacetMapping} from '../facet';\nimport {Field, hasConditionalFieldDef, isConditionalDef, isFieldDef, isRepeatRef, ValueDef} from '../fielddef';\nimport {ChannelDef, ScaleFieldDef} from '../fielddef';\nimport * as log from '../log';\nimport {isSortField} from '../sort';\n\nexport type RepeaterValue = {\n row?: string,\n column?: string\n};\n\nexport function replaceRepeaterInFacet(facet: FacetMapping, repeater: RepeaterValue): FacetMapping {\n return replaceRepeater(facet, repeater) as FacetMapping;\n}\n\nexport function replaceRepeaterInEncoding(encoding: Encoding, repeater: RepeaterValue): Encoding {\n return replaceRepeater(encoding, repeater) as Encoding;\n}\n\n/**\n * Replaces repeated value and returns if the repeated value is valid.\n */\nfunction replaceRepeat(o: T, repeater: RepeaterValue): T {\n if (isRepeatRef(o.field)) {\n if (o.field.repeat in repeater) {\n // any needed to calm down ts compiler\n return {...o as any, field: repeater[o.field.repeat]};\n } else {\n log.warn(log.message.noSuchRepeatedValue(o.field.repeat));\n return undefined;\n }\n }\n return o;\n}\n\n/**\n * Replace repeater values in a field def with the concrete field name.\n */\nfunction replaceRepeaterInFieldDef(fieldDef: ScaleFieldDef, repeater: RepeaterValue): ScaleFieldDef {\n fieldDef = replaceRepeat(fieldDef, repeater);\n\n if (fieldDef === undefined) {\n // the field def should be ignored\n return undefined;\n }\n\n if (fieldDef.sort && isSortField(fieldDef.sort)) {\n const sort = replaceRepeat(fieldDef.sort, repeater);\n fieldDef = {\n ...fieldDef,\n ...(sort ? {sort} : {})\n };\n }\n\n return fieldDef as ScaleFieldDef;\n}\n\nfunction replaceRepeaterInChannelDef(channelDef: ChannelDef, repeater: RepeaterValue): ChannelDef {\n if (isFieldDef(channelDef)) {\n const fd = replaceRepeaterInFieldDef(channelDef, repeater);\n if (fd) {\n return fd;\n } else if (isConditionalDef(channelDef)) {\n return {condition: channelDef.condition};\n }\n } else {\n if (hasConditionalFieldDef(channelDef)) {\n const fd = replaceRepeaterInFieldDef(channelDef.condition, repeater);\n if (fd) {\n return {\n ...channelDef,\n condition: fd\n } as ChannelDef;\n } else {\n const {condition, ...channelDefWithoutCondition} = channelDef;\n return channelDefWithoutCondition as ChannelDef;\n }\n }\n return channelDef as ValueDef;\n }\n return undefined;\n}\n\ntype EncodingOrFacet = Encoding | FacetMapping;\n\nfunction replaceRepeater(mapping: EncodingOrFacet, repeater: RepeaterValue): EncodingOrFacet {\n const out: EncodingOrFacet = {};\n for (const channel in mapping) {\n if (mapping.hasOwnProperty(channel)) {\n const channelDef: ChannelDef | ChannelDef[] = mapping[channel];\n\n if (isArray(channelDef)) {\n // array cannot have condition\n out[channel] = channelDef.map(cd => replaceRepeaterInChannelDef(cd, repeater))\n .filter(cd => cd);\n } else {\n const cd = replaceRepeaterInChannelDef(channelDef, repeater);\n if (cd) {\n out[channel] = cd;\n }\n }\n }\n }\n return out;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/resolve.d.ts b/build/src/compile/resolve.d.ts new file mode 100644 index 0000000000..1438c6e3a8 --- /dev/null +++ b/build/src/compile/resolve.d.ts @@ -0,0 +1,5 @@ +import { ScaleChannel } from '../channel'; +import { Resolve, ResolveMode } from '../resolve'; +import { Model } from './model'; +export declare function defaultScaleResolve(channel: ScaleChannel, model: Model): ResolveMode; +export declare function parseGuideResolve(resolve: Resolve, channel: ScaleChannel): ResolveMode; diff --git a/build/src/compile/resolve.js b/build/src/compile/resolve.js new file mode 100644 index 0000000000..db9fd40105 --- /dev/null +++ b/build/src/compile/resolve.js @@ -0,0 +1,26 @@ +import { POSITION_SCALE_CHANNELS } from '../channel'; +import * as log from '../log'; +import { contains } from '../util'; +import { isConcatModel, isFacetModel, isLayerModel, isRepeatModel } from './model'; +export function defaultScaleResolve(channel, model) { + if (isLayerModel(model) || isFacetModel(model)) { + return 'shared'; + } + else if (isConcatModel(model) || isRepeatModel(model)) { + return contains(POSITION_SCALE_CHANNELS, channel) ? 'independent' : 'shared'; + } + /* istanbul ignore next: should never reach here. */ + throw new Error('invalid model type for resolve'); +} +export function parseGuideResolve(resolve, channel) { + var channelScaleResolve = resolve.scale[channel]; + var guide = contains(POSITION_SCALE_CHANNELS, channel) ? 'axis' : 'legend'; + if (channelScaleResolve === 'independent') { + if (resolve[guide][channel] === 'shared') { + log.warn(log.message.independentScaleMeansIndependentGuide(channel)); + } + return 'independent'; + } + return resolve[guide][channel] || 'shared'; +} +//# sourceMappingURL=resolve.js.map \ No newline at end of file diff --git a/build/src/compile/resolve.js.map b/build/src/compile/resolve.js.map new file mode 100644 index 0000000000..80d1da20ab --- /dev/null +++ b/build/src/compile/resolve.js.map @@ -0,0 +1 @@ +{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/compile/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,uBAAuB,EAAe,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,GAAG,MAAM,QAAQ,CAAC;AAE9B,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AACjC,OAAO,EAAC,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAQ,MAAM,SAAS,CAAC;AAExF,MAAM,8BAA8B,OAAqB,EAAE,KAAY;IACrE,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE;QAC9C,OAAO,QAAQ,CAAC;KACjB;SAAM,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE;QACvD,OAAO,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC;KAC9E;IACD,oDAAoD;IACpD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,4BAA4B,OAAgB,EAAE,OAAqB;IACvE,IAAM,mBAAmB,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnD,IAAM,KAAK,GAAG,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;IAE7E,IAAI,mBAAmB,KAAK,aAAa,EAAE;QACzC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,EAAE;YACxC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,qCAAqC,CAAC,OAAO,CAAC,CAAC,CAAC;SACtE;QACD,OAAO,aAAa,CAAC;KACtB;IAED,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC;AAC7C,CAAC","sourcesContent":["import {POSITION_SCALE_CHANNELS, ScaleChannel} from '../channel';\nimport * as log from '../log';\nimport {Resolve, ResolveMode} from '../resolve';\nimport {contains} from '../util';\nimport {isConcatModel, isFacetModel, isLayerModel, isRepeatModel, Model} from './model';\n\nexport function defaultScaleResolve(channel: ScaleChannel, model: Model): ResolveMode {\n if (isLayerModel(model) || isFacetModel(model)) {\n return 'shared';\n } else if (isConcatModel(model) || isRepeatModel(model)) {\n return contains(POSITION_SCALE_CHANNELS, channel) ? 'independent' : 'shared';\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('invalid model type for resolve');\n}\n\nexport function parseGuideResolve(resolve: Resolve, channel: ScaleChannel): ResolveMode {\n const channelScaleResolve = resolve.scale[channel];\n const guide = contains(POSITION_SCALE_CHANNELS, channel) ? 'axis' : 'legend';\n\n if (channelScaleResolve === 'independent') {\n if (resolve[guide][channel] === 'shared') {\n log.warn(log.message.independentScaleMeansIndependentGuide(channel));\n }\n return 'independent';\n }\n\n return resolve[guide][channel] || 'shared';\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/scale/assemble.d.ts b/build/src/compile/scale/assemble.d.ts new file mode 100644 index 0000000000..4ed232b58c --- /dev/null +++ b/build/src/compile/scale/assemble.d.ts @@ -0,0 +1,6 @@ +import { Channel } from '../../channel'; +import { VgRange, VgScale } from '../../vega.schema'; +import { Model } from '../model'; +export declare function assembleScales(model: Model): VgScale[]; +export declare function assembleScalesForModel(model: Model): VgScale[]; +export declare function assembleScaleRange(scaleRange: VgRange, scaleName: string, model: Model, channel: Channel): VgRange; diff --git a/build/src/compile/scale/assemble.js b/build/src/compile/scale/assemble.js new file mode 100644 index 0000000000..f915ddac97 --- /dev/null +++ b/build/src/compile/scale/assemble.js @@ -0,0 +1,69 @@ +import * as tslib_1 from "tslib"; +import { isArray } from 'vega-util'; +import { keys } from '../../util'; +import { isVgRangeStep, isVgSignalRef } from '../../vega.schema'; +import { isConcatModel, isLayerModel, isRepeatModel } from '../model'; +import { isRawSelectionDomain, selectionScaleDomain } from '../selection/selection'; +import { assembleDomain } from './domain'; +export function assembleScales(model) { + if (isLayerModel(model) || isConcatModel(model) || isRepeatModel(model)) { + // For concat / layer / repeat, include scales of children too + return model.children.reduce(function (scales, child) { + return scales.concat(assembleScales(child)); + }, assembleScalesForModel(model)); + } + else { + // For facet, child scales would not be included in the parent's scope. + // For unit, there is no child. + return assembleScalesForModel(model); + } +} +export function assembleScalesForModel(model) { + return keys(model.component.scales).reduce(function (scales, channel) { + var scaleComponent = model.component.scales[channel]; + if (scaleComponent.merged) { + // Skipped merged scales + return scales; + } + var scale = scaleComponent.combine(); + // need to separate const and non const object destruction + var domainRaw = scale.domainRaw, range = scale.range; + var name = scale.name, type = scale.type, _d = scale.domainRaw, _r = scale.range, otherScaleProps = tslib_1.__rest(scale, ["name", "type", "domainRaw", "range"]); + range = assembleScaleRange(range, name, model, channel); + // As scale parsing occurs before selection parsing, a temporary signal + // is used for domainRaw. Here, we detect if this temporary signal + // is set, and replace it with the correct domainRaw signal. + // For more information, see isRawSelectionDomain in selection.ts. + if (domainRaw && isRawSelectionDomain(domainRaw)) { + domainRaw = selectionScaleDomain(model, domainRaw); + } + scales.push(tslib_1.__assign({ name: name, + type: type, domain: assembleDomain(model, channel) }, (domainRaw ? { domainRaw: domainRaw } : {}), { range: range }, otherScaleProps)); + return scales; + }, []); +} +export function assembleScaleRange(scaleRange, scaleName, model, channel) { + // add signals to x/y range + if (channel === 'x' || channel === 'y') { + if (isVgRangeStep(scaleRange)) { + // For x/y range step, use a signal created in layout assemble instead of a constant range step. + return { + step: { signal: scaleName + '_step' } + }; + } + else if (isArray(scaleRange) && scaleRange.length === 2) { + var r0 = scaleRange[0]; + var r1 = scaleRange[1]; + if (r0 === 0 && isVgSignalRef(r1)) { + // Replace width signal just in case it is renamed. + return [0, { signal: model.getSizeName(r1.signal) }]; + } + else if (isVgSignalRef(r0) && r1 === 0) { + // Replace height signal just in case it is renamed. + return [{ signal: model.getSizeName(r0.signal) }, 0]; + } + } + } + return scaleRange; +} +//# sourceMappingURL=assemble.js.map \ No newline at end of file diff --git a/build/src/compile/scale/assemble.js.map b/build/src/compile/scale/assemble.js.map new file mode 100644 index 0000000000..1786b8c42e --- /dev/null +++ b/build/src/compile/scale/assemble.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../../../src/compile/scale/assemble.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAElC,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAC;AAChC,OAAO,EAAC,aAAa,EAAE,aAAa,EAAmB,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAC,aAAa,EAAE,YAAY,EAAE,aAAa,EAAQ,MAAM,UAAU,CAAC;AAC3E,OAAO,EAAC,oBAAoB,EAAE,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAExC,MAAM,yBAAyB,KAAY;IACzC,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE;QACvE,8DAA8D;QAC9D,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAC,MAAM,EAAE,KAAK;YACzC,OAAO,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9C,CAAC,EAAE,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC;KACnC;SAAM;QACL,uEAAuE;QACvE,+BAA+B;QAC/B,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC;KACtC;AACH,CAAC;AAED,MAAM,iCAAiC,KAAY;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,UAAC,MAAiB,EAAE,OAAqB;QAClF,IAAM,cAAc,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvD,IAAI,cAAc,CAAC,MAAM,EAAE;YACzB,wBAAwB;YACxB,OAAO,MAAM,CAAC;SACf;QAED,IAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,CAAC;QAEvC,0DAA0D;QACrD,IAAA,2BAAS,EAAE,mBAAK,CAAU;QACxB,IAAA,iBAAI,EAAE,iBAAI,EAAE,oBAAa,EAAE,gBAAS,EAAE,+EAAkB,CAAU;QAEzE,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAExD,uEAAuE;QACvE,kEAAkE;QAClE,4DAA4D;QAC5D,kEAAkE;QAClE,IAAI,SAAS,IAAI,oBAAoB,CAAC,SAAS,CAAC,EAAE;YAChD,SAAS,GAAG,oBAAoB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;SACpD;QAGD,MAAM,CAAC,IAAI,oBACT,IAAI,MAAA;YACJ,IAAI,MAAA,EACJ,MAAM,EAAE,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,IACnC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAC,SAAS,WAAA,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IACjC,KAAK,EAAE,KAAK,IACT,eAAe,EAClB,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,EAAe,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,6BAA6B,UAAmB,EAAE,SAAiB,EAAE,KAAY,EAAE,OAAgB;IACvG,2BAA2B;IAC3B,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,GAAG,EAAE;QACtC,IAAI,aAAa,CAAC,UAAU,CAAC,EAAE;YAC7B,gGAAgG;YAChG,OAAO;gBACL,IAAI,EAAE,EAAC,MAAM,EAAE,SAAS,GAAG,OAAO,EAAC;aACpC,CAAC;SACH;aAAM,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;YACzD,IAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YACzB,IAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YACzB,IAAI,EAAE,KAAK,CAAC,IAAI,aAAa,CAAC,EAAE,CAAC,EAAE;gBACjC,mDAAmD;gBACnD,OAAO,CAAC,CAAC,EAAE,EAAC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,EAAC,CAAC,CAAC;aACpD;iBAAM,IAAI,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;gBACxC,oDAAoD;gBACpD,OAAO,CAAC,EAAC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,EAAC,EAAE,CAAC,CAAC,CAAC;aACpD;SACF;KACF;IACD,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["import {isArray} from 'vega-util';\nimport {Channel, ScaleChannel} from '../../channel';\nimport {keys} from '../../util';\nimport {isVgRangeStep, isVgSignalRef, VgRange, VgScale} from '../../vega.schema';\nimport {isConcatModel, isLayerModel, isRepeatModel, Model} from '../model';\nimport {isRawSelectionDomain, selectionScaleDomain} from '../selection/selection';\nimport {assembleDomain} from './domain';\n\nexport function assembleScales(model: Model): VgScale[] {\n if (isLayerModel(model) || isConcatModel(model) || isRepeatModel(model)) {\n // For concat / layer / repeat, include scales of children too\n return model.children.reduce((scales, child) => {\n return scales.concat(assembleScales(child));\n }, assembleScalesForModel(model));\n } else {\n // For facet, child scales would not be included in the parent's scope.\n // For unit, there is no child.\n return assembleScalesForModel(model);\n }\n}\n\nexport function assembleScalesForModel(model: Model): VgScale[] {\n return keys(model.component.scales).reduce((scales: VgScale[], channel: ScaleChannel) => {\n const scaleComponent = model.component.scales[channel];\n if (scaleComponent.merged) {\n // Skipped merged scales\n return scales;\n }\n\n const scale = scaleComponent.combine();\n\n // need to separate const and non const object destruction\n let {domainRaw, range} = scale;\n const {name, type, domainRaw: _d, range: _r, ...otherScaleProps} = scale;\n\n range = assembleScaleRange(range, name, model, channel);\n\n // As scale parsing occurs before selection parsing, a temporary signal\n // is used for domainRaw. Here, we detect if this temporary signal\n // is set, and replace it with the correct domainRaw signal.\n // For more information, see isRawSelectionDomain in selection.ts.\n if (domainRaw && isRawSelectionDomain(domainRaw)) {\n domainRaw = selectionScaleDomain(model, domainRaw);\n }\n\n\n scales.push({\n name,\n type,\n domain: assembleDomain(model, channel),\n ...(domainRaw ? {domainRaw} : {}),\n range: range,\n ...otherScaleProps\n });\n\n return scales;\n }, [] as VgScale[]);\n}\n\nexport function assembleScaleRange(scaleRange: VgRange, scaleName: string, model: Model, channel: Channel) {\n // add signals to x/y range\n if (channel === 'x' || channel === 'y') {\n if (isVgRangeStep(scaleRange)) {\n // For x/y range step, use a signal created in layout assemble instead of a constant range step.\n return {\n step: {signal: scaleName + '_step'}\n };\n } else if (isArray(scaleRange) && scaleRange.length === 2) {\n const r0 = scaleRange[0];\n const r1 = scaleRange[1];\n if (r0 === 0 && isVgSignalRef(r1)) {\n // Replace width signal just in case it is renamed.\n return [0, {signal: model.getSizeName(r1.signal)}];\n } else if (isVgSignalRef(r0) && r1 === 0) {\n // Replace height signal just in case it is renamed.\n return [{signal: model.getSizeName(r0.signal)}, 0];\n }\n }\n }\n return scaleRange;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/scale/component.d.ts b/build/src/compile/scale/component.d.ts new file mode 100644 index 0000000000..75569d644f --- /dev/null +++ b/build/src/compile/scale/component.d.ts @@ -0,0 +1,21 @@ +import { ScaleChannel } from '../../channel'; +import { Scale, ScaleType } from '../../scale'; +import { Omit } from '../../util'; +import { VgNonUnionDomain, VgScale } from '../../vega.schema'; +import { Explicit, Split } from '../split'; +/** + * All VgDomain property except domain. + * (We exclude domain as we have a special "domains" array that allow us merge them all at once in assemble.) + */ +export declare type ScaleComponentProps = Omit; +export declare class ScaleComponent extends Split { + merged: boolean; + domains: VgNonUnionDomain[]; + constructor(name: string, typeWithExplicit: Explicit); +} +export declare type ScaleComponentIndex = { + [P in ScaleChannel]?: ScaleComponent; +}; +export declare type ScaleIndex = { + [P in ScaleChannel]?: Scale; +}; diff --git a/build/src/compile/scale/component.js b/build/src/compile/scale/component.js new file mode 100644 index 0000000000..a7c783550c --- /dev/null +++ b/build/src/compile/scale/component.js @@ -0,0 +1,17 @@ +import * as tslib_1 from "tslib"; +import { Split } from '../split'; +var ScaleComponent = /** @class */ (function (_super) { + tslib_1.__extends(ScaleComponent, _super); + function ScaleComponent(name, typeWithExplicit) { + var _this = _super.call(this, {}, // no initial explicit property + { name: name } // name as initial implicit property + ) || this; + _this.merged = false; + _this.domains = []; + _this.setWithExplicit('type', typeWithExplicit); + return _this; + } + return ScaleComponent; +}(Split)); +export { ScaleComponent }; +//# sourceMappingURL=component.js.map \ No newline at end of file diff --git a/build/src/compile/scale/component.js.map b/build/src/compile/scale/component.js.map new file mode 100644 index 0000000000..25e45713a4 --- /dev/null +++ b/build/src/compile/scale/component.js.map @@ -0,0 +1 @@ +{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../src/compile/scale/component.ts"],"names":[],"mappings":";AAIA,OAAO,EAAW,KAAK,EAAC,MAAM,UAAU,CAAC;AASzC;IAAoC,0CAA0B;IAK5D,wBAAY,IAAY,EAAE,gBAAqC;QAA/D,YACE,kBACE,EAAE,EAAM,+BAA+B;QACvC,EAAC,IAAI,MAAA,EAAC,CAAE,oCAAoC;SAC7C,SAEF;QAVM,YAAM,GAAG,KAAK,CAAC;QAEf,aAAO,GAAuB,EAAE,CAAC;QAOtC,KAAI,CAAC,eAAe,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;;IACjD,CAAC;IACH,qBAAC;AAAD,CAAC,AAZD,CAAoC,KAAK,GAYxC","sourcesContent":["import {ScaleChannel} from '../../channel';\nimport {Scale, ScaleType} from '../../scale';\nimport {Omit} from '../../util';\nimport {VgNonUnionDomain, VgScale} from '../../vega.schema';\nimport {Explicit, Split} from '../split';\n\n/**\n * All VgDomain property except domain.\n * (We exclude domain as we have a special \"domains\" array that allow us merge them all at once in assemble.)\n */\n// TODO: also exclude domainRaw and property implement the right scaleComponent for selection domain\nexport type ScaleComponentProps = Omit;\n\nexport class ScaleComponent extends Split {\n public merged = false;\n\n public domains: VgNonUnionDomain[] = [];\n\n constructor(name: string, typeWithExplicit: Explicit) {\n super(\n {}, // no initial explicit property\n {name} // name as initial implicit property\n );\n this.setWithExplicit('type', typeWithExplicit);\n }\n}\n\n// Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\nexport type ScaleComponentIndex = {[P in ScaleChannel]?: ScaleComponent};\n\nexport type ScaleIndex = {[P in ScaleChannel]?: Scale};\n"]} \ No newline at end of file diff --git a/build/src/compile/scale/domain.d.ts b/build/src/compile/scale/domain.d.ts new file mode 100644 index 0000000000..17722e6666 --- /dev/null +++ b/build/src/compile/scale/domain.d.ts @@ -0,0 +1,32 @@ +import { ScaleChannel } from '../../channel'; +import { FieldDef } from '../../fielddef'; +import { ScaleType } from '../../scale'; +import { EncodingSortField } from '../../sort'; +import { VgDomain, VgNonUnionDomain } from '../../vega.schema'; +import { Model } from '../model'; +import { UnitModel } from '../unit'; +export declare function parseScaleDomain(model: Model): void; +export declare function parseDomainForChannel(model: UnitModel, channel: ScaleChannel): VgNonUnionDomain[]; +export declare function domainSort(model: UnitModel, channel: ScaleChannel, scaleType: ScaleType): true | EncodingSortField; +/** + * Determine if a scale can use unaggregated domain. + * @return {Boolean} Returns true if all of the following conditons applies: + * 1. `scale.domain` is `unaggregated` + * 2. Aggregation function is not `count` or `sum` + * 3. The scale is quantitative or time scale. + */ +export declare function canUseUnaggregatedDomain(fieldDef: FieldDef, scaleType: ScaleType): { + valid: boolean; + reason?: string; +}; +/** + * Converts an array of domains to a single Vega scale domain. + */ +export declare function mergeDomains(domains: VgNonUnionDomain[]): VgDomain; +/** + * Return a field if a scale single field. + * Return `undefined` otherwise. + * + */ +export declare function getFieldFromDomain(domain: VgDomain): string; +export declare function assembleDomain(model: Model, channel: ScaleChannel): VgDomain; diff --git a/build/src/compile/scale/domain.js b/build/src/compile/scale/domain.js new file mode 100644 index 0000000000..818701f310 --- /dev/null +++ b/build/src/compile/scale/domain.js @@ -0,0 +1,427 @@ +import * as tslib_1 from "tslib"; +import { isString } from 'vega-util'; +import { SHARED_DOMAIN_OP_INDEX } from '../../aggregate'; +import { binToString, isBinParams } from '../../bin'; +import { isScaleChannel } from '../../channel'; +import { MAIN, RAW } from '../../data'; +import { valueExpr, vgField } from '../../fielddef'; +import * as log from '../../log'; +import { hasDiscreteDomain, isBinScale, isSelectionDomain } from '../../scale'; +import { isSortArray, isSortField } from '../../sort'; +import * as util from '../../util'; +import { isDataRefDomain, isDataRefUnionedDomain, isFieldRefUnionDomain } from '../../vega.schema'; +import { binRequiresRange } from '../common'; +import { sortArrayIndexField } from '../data/calculate'; +import { FACET_SCALE_PREFIX } from '../data/optimize'; +import { isFacetModel, isUnitModel } from '../model'; +import { SELECTION_DOMAIN } from '../selection/selection'; +export function parseScaleDomain(model) { + if (isUnitModel(model)) { + parseUnitScaleDomain(model); + } + else { + parseNonUnitScaleDomain(model); + } +} +function parseUnitScaleDomain(model) { + var scales = model.specifiedScales; + var localScaleComponents = model.component.scales; + util.keys(localScaleComponents).forEach(function (channel) { + var specifiedScale = scales[channel]; + var specifiedDomain = specifiedScale ? specifiedScale.domain : undefined; + var domains = parseDomainForChannel(model, channel); + var localScaleCmpt = localScaleComponents[channel]; + localScaleCmpt.domains = domains; + if (isSelectionDomain(specifiedDomain)) { + // As scale parsing occurs before selection parsing, we use a temporary + // signal here and append the scale.domain definition. This is replaced + // with the correct domainRaw signal during scale assembly. + // For more information, see isRawSelectionDomain in selection.ts. + // FIXME: replace this with a special property in the scaleComponent + localScaleCmpt.set('domainRaw', { + signal: SELECTION_DOMAIN + util.hash(specifiedDomain) + }, true); + } + if (model.component.data.isFaceted) { + // get resolve from closest facet parent as this decides whether we need to refer to cloned subtree or not + var facetParent = model; + while (!isFacetModel(facetParent) && facetParent.parent) { + facetParent = facetParent.parent; + } + var resolve = facetParent.component.resolve.scale[channel]; + if (resolve === 'shared') { + for (var _i = 0, domains_1 = domains; _i < domains_1.length; _i++) { + var domain = domains_1[_i]; + // Replace the scale domain with data output from a cloned subtree after the facet. + if (isDataRefDomain(domain)) { + // use data from cloned subtree (which is the same as data but with a prefix added once) + domain.data = FACET_SCALE_PREFIX + domain.data.replace(FACET_SCALE_PREFIX, ''); + } + } + } + } + }); +} +function parseNonUnitScaleDomain(model) { + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + parseScaleDomain(child); + } + var localScaleComponents = model.component.scales; + util.keys(localScaleComponents).forEach(function (channel) { + var domains; + var domainRaw = null; + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + var childComponent = child.component.scales[channel]; + if (childComponent) { + if (domains === undefined) { + domains = childComponent.domains; + } + else { + domains = domains.concat(childComponent.domains); + } + var dr = childComponent.get('domainRaw'); + if (domainRaw && dr && domainRaw.signal !== dr.signal) { + log.warn('The same selection must be used to override scale domains in a layered view.'); + } + domainRaw = dr; + } + } + localScaleComponents[channel].domains = domains; + if (domainRaw) { + localScaleComponents[channel].set('domainRaw', domainRaw, true); + } + }); +} +/** + * Remove unaggregated domain if it is not applicable + * Add unaggregated domain if domain is not specified and config.scale.useUnaggregatedDomain is true. + */ +function normalizeUnaggregatedDomain(domain, fieldDef, scaleType, scaleConfig) { + if (domain === 'unaggregated') { + var _a = canUseUnaggregatedDomain(fieldDef, scaleType), valid = _a.valid, reason = _a.reason; + if (!valid) { + log.warn(reason); + return undefined; + } + } + else if (domain === undefined && scaleConfig.useUnaggregatedDomain) { + // Apply config if domain is not specified. + var valid = canUseUnaggregatedDomain(fieldDef, scaleType).valid; + if (valid) { + return 'unaggregated'; + } + } + return domain; +} +export function parseDomainForChannel(model, channel) { + var scaleType = model.getScaleComponent(channel).get('type'); + var domain = normalizeUnaggregatedDomain(model.scaleDomain(channel), model.fieldDef(channel), scaleType, model.config.scale); + if (domain !== model.scaleDomain(channel)) { + model.specifiedScales[channel] = tslib_1.__assign({}, model.specifiedScales[channel], { domain: domain }); + } + // If channel is either X or Y then union them with X2 & Y2 if they exist + if (channel === 'x' && model.channelHasField('x2')) { + if (model.channelHasField('x')) { + return parseSingleChannelDomain(scaleType, domain, model, 'x').concat(parseSingleChannelDomain(scaleType, domain, model, 'x2')); + } + else { + return parseSingleChannelDomain(scaleType, domain, model, 'x2'); + } + } + else if (channel === 'y' && model.channelHasField('y2')) { + if (model.channelHasField('y')) { + return parseSingleChannelDomain(scaleType, domain, model, 'y').concat(parseSingleChannelDomain(scaleType, domain, model, 'y2')); + } + else { + return parseSingleChannelDomain(scaleType, domain, model, 'y2'); + } + } + return parseSingleChannelDomain(scaleType, domain, model, channel); +} +function mapDomainToDataSignal(domain, type, timeUnit) { + return domain.map(function (v) { + var data = valueExpr(v, { timeUnit: timeUnit, type: type }); + return { signal: "{data: " + data + "}" }; + }); +} +function parseSingleChannelDomain(scaleType, domain, model, channel) { + var fieldDef = model.fieldDef(channel); + if (domain && domain !== 'unaggregated' && !isSelectionDomain(domain)) { // explicit value + var type = fieldDef.type, timeUnit = fieldDef.timeUnit; + if (type === 'temporal' || timeUnit) { + return mapDomainToDataSignal(domain, type, timeUnit); + } + return [domain]; + } + var stack = model.stack; + if (stack && channel === stack.fieldChannel) { + if (stack.offset === 'normalize') { + return [[0, 1]]; + } + var data = model.requestDataName(MAIN); + return [{ + data: data, + field: model.vgField(channel, { suffix: 'start' }) + }, { + data: data, + field: model.vgField(channel, { suffix: 'end' }) + }]; + } + var sort = isScaleChannel(channel) ? domainSort(model, channel, scaleType) : undefined; + if (domain === 'unaggregated') { + var data = model.requestDataName(MAIN); + var field = fieldDef.field; + return [{ + data: data, + field: vgField({ field: field, aggregate: 'min' }) + }, { + data: data, + field: vgField({ field: field, aggregate: 'max' }) + }]; + } + else if (fieldDef.bin) { // bin + if (isBinScale(scaleType)) { + var signal = model.getName(binToString(fieldDef.bin) + "_" + fieldDef.field + "_bins"); + return [{ signal: "sequence(" + signal + ".start, " + signal + ".stop + " + signal + ".step, " + signal + ".step)" }]; + } + if (hasDiscreteDomain(scaleType)) { + // ordinal bin scale takes domain from bin_range, ordered by bin start + // This is useful for both axis-based scale (x/y) and legend-based scale (other channels). + return [{ + // If sort by aggregation of a specified sort field, we need to use RAW table, + // so we can aggregate values for the scale independently from the main aggregation. + data: util.isBoolean(sort) ? model.requestDataName(MAIN) : model.requestDataName(RAW), + // Use range if we added it and the scale does not support computing a range as a signal. + field: model.vgField(channel, binRequiresRange(fieldDef, channel) ? { binSuffix: 'range' } : {}), + // we have to use a sort object if sort = true to make the sort correct by bin start + sort: sort === true || !isSortField(sort) ? { + field: model.vgField(channel, {}), + op: 'min' // min or max doesn't matter since we sort by the start of the bin range + } : sort + }]; + } + else { // continuous scales + if (channel === 'x' || channel === 'y') { + if (isBinParams(fieldDef.bin) && fieldDef.bin.extent) { + return [fieldDef.bin.extent]; + } + // X/Y position have to include start and end for non-ordinal scale + var data = model.requestDataName(MAIN); + return [{ + data: data, + field: model.vgField(channel, {}) + }, { + data: data, + field: model.vgField(channel, { binSuffix: 'end' }) + }]; + } + else { + // TODO: use bin_mid + return [{ + data: model.requestDataName(MAIN), + field: model.vgField(channel, {}) + }]; + } + } + } + else if (sort) { + return [{ + // If sort by aggregation of a specified sort field, we need to use RAW table, + // so we can aggregate values for the scale independently from the main aggregation. + data: util.isBoolean(sort) ? model.requestDataName(MAIN) : model.requestDataName(RAW), + field: model.vgField(channel), + sort: sort + }]; + } + else { + return [{ + data: model.requestDataName(MAIN), + field: model.vgField(channel) + }]; + } +} +export function domainSort(model, channel, scaleType) { + if (!hasDiscreteDomain(scaleType)) { + return undefined; + } + var fieldDef = model.fieldDef(channel); + var sort = fieldDef.sort; + // if the sort is specified with array, use the derived sort index field + if (isSortArray(sort)) { + return { + op: 'min', + field: sortArrayIndexField(fieldDef, channel), + order: 'ascending' + }; + } + // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale) + if (isSortField(sort)) { + // flatten nested fields + return tslib_1.__assign({}, sort, (sort.field ? { field: util.replacePathInField(sort.field) } : {})); + } + if (sort === 'descending') { + return { + op: 'min', + field: model.vgField(channel), + order: 'descending' + }; + } + if (util.contains(['ascending', undefined /* default =ascending*/], sort)) { + return true; + } + // sort == null + return undefined; +} +/** + * Determine if a scale can use unaggregated domain. + * @return {Boolean} Returns true if all of the following conditons applies: + * 1. `scale.domain` is `unaggregated` + * 2. Aggregation function is not `count` or `sum` + * 3. The scale is quantitative or time scale. + */ +export function canUseUnaggregatedDomain(fieldDef, scaleType) { + if (!fieldDef.aggregate) { + return { + valid: false, + reason: log.message.unaggregateDomainHasNoEffectForRawField(fieldDef) + }; + } + if (!SHARED_DOMAIN_OP_INDEX[fieldDef.aggregate]) { + return { + valid: false, + reason: log.message.unaggregateDomainWithNonSharedDomainOp(fieldDef.aggregate) + }; + } + if (fieldDef.type === 'quantitative') { + if (scaleType === 'log') { + return { + valid: false, + reason: log.message.unaggregatedDomainWithLogScale(fieldDef) + }; + } + } + return { valid: true }; +} +/** + * Converts an array of domains to a single Vega scale domain. + */ +export function mergeDomains(domains) { + var uniqueDomains = util.unique(domains.map(function (domain) { + // ignore sort property when computing the unique domains + if (isDataRefDomain(domain)) { + var _s = domain.sort, domainWithoutSort = tslib_1.__rest(domain, ["sort"]); + return domainWithoutSort; + } + return domain; + }), util.hash); + var sorts = util.unique(domains.map(function (d) { + if (isDataRefDomain(d)) { + var s = d.sort; + if (s !== undefined && !util.isBoolean(s)) { + if (s.op === 'count') { + // let's make sure that if op is count, we don't use a field + delete s.field; + } + if (s.order === 'ascending') { + // drop order: ascending as it is the default + delete s.order; + } + } + return s; + } + return undefined; + }).filter(function (s) { return s !== undefined; }), util.hash); + if (uniqueDomains.length === 1) { + var domain = domains[0]; + if (isDataRefDomain(domain) && sorts.length > 0) { + var sort_1 = sorts[0]; + if (sorts.length > 1) { + log.warn(log.message.MORE_THAN_ONE_SORT); + sort_1 = true; + } + return tslib_1.__assign({}, domain, { sort: sort_1 }); + } + return domain; + } + // only keep simple sort properties that work with unioned domains + var simpleSorts = util.unique(sorts.map(function (s) { + if (s === true) { + return s; + } + if (s.op === 'count') { + return s; + } + log.warn(log.message.domainSortDropped(s)); + return true; + }), util.hash); + var sort = undefined; + if (simpleSorts.length === 1) { + sort = simpleSorts[0]; + } + else if (simpleSorts.length > 1) { + log.warn(log.message.MORE_THAN_ONE_SORT); + sort = true; + } + var allData = util.unique(domains.map(function (d) { + if (isDataRefDomain(d)) { + return d.data; + } + return null; + }), function (x) { return x; }); + if (allData.length === 1 && allData[0] !== null) { + // create a union domain of different fields with a single data source + var domain = tslib_1.__assign({ data: allData[0], fields: uniqueDomains.map(function (d) { return d.field; }) }, (sort ? { sort: sort } : {})); + return domain; + } + return tslib_1.__assign({ fields: uniqueDomains }, (sort ? { sort: sort } : {})); +} +/** + * Return a field if a scale single field. + * Return `undefined` otherwise. + * + */ +export function getFieldFromDomain(domain) { + if (isDataRefDomain(domain) && isString(domain.field)) { + return domain.field; + } + else if (isDataRefUnionedDomain(domain)) { + var field = void 0; + for (var _i = 0, _a = domain.fields; _i < _a.length; _i++) { + var nonUnionDomain = _a[_i]; + if (isDataRefDomain(nonUnionDomain) && isString(nonUnionDomain.field)) { + if (!field) { + field = nonUnionDomain.field; + } + else if (field !== nonUnionDomain.field) { + log.warn('Detected faceted independent scales that union domain of multiple fields from different data sources. We will use the first field. The result view size may be incorrect.'); + return field; + } + } + } + log.warn('Detected faceted independent scales that union domain of identical fields from different source detected. We will assume that this is the same field from a different fork of the same data source. However, if this is not case, the result view size maybe incorrect.'); + return field; + } + else if (isFieldRefUnionDomain(domain)) { + log.warn('Detected faceted independent scales that union domain of multiple fields from the same data source. We will use the first field. The result view size may be incorrect.'); + var field = domain.fields[0]; + return isString(field) ? field : undefined; + } + return undefined; +} +export function assembleDomain(model, channel) { + var scaleComponent = model.component.scales[channel]; + var domains = scaleComponent.domains.map(function (domain) { + // Correct references to data as the original domain's data was determined + // in parseScale, which happens before parseData. Thus the original data + // reference can be incorrect. + if (isDataRefDomain(domain)) { + domain.data = model.lookupDataSource(domain.data); + } + return domain; + }); + // domains is an array that has to be merged into a single vega domain + return mergeDomains(domains); +} +//# sourceMappingURL=domain.js.map \ No newline at end of file diff --git a/build/src/compile/scale/domain.js.map b/build/src/compile/scale/domain.js.map new file mode 100644 index 0000000000..ba868159ec --- /dev/null +++ b/build/src/compile/scale/domain.js.map @@ -0,0 +1 @@ +{"version":3,"file":"domain.js","sourceRoot":"","sources":["../../../../src/compile/scale/domain.ts"],"names":[],"mappings":"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","sourcesContent":["import {isString} from 'vega-util';\nimport {SHARED_DOMAIN_OP_INDEX} from '../../aggregate';\nimport {binToString, isBinParams} from '../../bin';\nimport {isScaleChannel, ScaleChannel} from '../../channel';\nimport {MAIN, RAW} from '../../data';\nimport {DateTime} from '../../datetime';\nimport {FieldDef, ScaleFieldDef, valueExpr, vgField} from '../../fielddef';\nimport * as log from '../../log';\nimport {Domain, hasDiscreteDomain, isBinScale, isSelectionDomain, ScaleConfig, ScaleType} from '../../scale';\nimport {EncodingSortField, isSortArray, isSortField} from '../../sort';\nimport {TimeUnit} from '../../timeunit';\nimport {Type} from '../../type';\nimport * as util from '../../util';\nimport {isDataRefDomain, isDataRefUnionedDomain, isFieldRefUnionDomain, VgDataRef, VgDomain, VgFieldRefUnionDomain, VgNonUnionDomain, VgSortField, VgUnionSortField} from '../../vega.schema';\nimport {binRequiresRange} from '../common';\nimport {sortArrayIndexField} from '../data/calculate';\nimport {FACET_SCALE_PREFIX} from '../data/optimize';\nimport {isFacetModel, isUnitModel, Model} from '../model';\nimport {SELECTION_DOMAIN} from '../selection/selection';\nimport {UnitModel} from '../unit';\nimport {ScaleComponentIndex} from './component';\n\n\nexport function parseScaleDomain(model: Model) {\n if (isUnitModel(model)) {\n parseUnitScaleDomain(model);\n } else {\n parseNonUnitScaleDomain(model);\n }\n}\n\nfunction parseUnitScaleDomain(model: UnitModel) {\n const scales = model.specifiedScales;\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n util.keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n const specifiedScale = scales[channel];\n const specifiedDomain = specifiedScale ? specifiedScale.domain : undefined;\n\n const domains = parseDomainForChannel(model, channel);\n const localScaleCmpt = localScaleComponents[channel];\n localScaleCmpt.domains = domains;\n\n if (isSelectionDomain(specifiedDomain)) {\n // As scale parsing occurs before selection parsing, we use a temporary\n // signal here and append the scale.domain definition. This is replaced\n // with the correct domainRaw signal during scale assembly.\n // For more information, see isRawSelectionDomain in selection.ts.\n\n // FIXME: replace this with a special property in the scaleComponent\n localScaleCmpt.set('domainRaw', {\n signal: SELECTION_DOMAIN + util.hash(specifiedDomain)\n }, true);\n }\n\n if (model.component.data.isFaceted) {\n // get resolve from closest facet parent as this decides whether we need to refer to cloned subtree or not\n let facetParent: Model = model;\n while (!isFacetModel(facetParent) && facetParent.parent) {\n facetParent = facetParent.parent;\n }\n\n const resolve = facetParent.component.resolve.scale[channel];\n\n if (resolve === 'shared') {\n for (const domain of domains) {\n // Replace the scale domain with data output from a cloned subtree after the facet.\n if (isDataRefDomain(domain)) {\n // use data from cloned subtree (which is the same as data but with a prefix added once)\n domain.data = FACET_SCALE_PREFIX + domain.data.replace(FACET_SCALE_PREFIX, '');\n }\n }\n }\n }\n });\n}\n\nfunction parseNonUnitScaleDomain(model: Model) {\n for (const child of model.children) {\n parseScaleDomain(child);\n }\n\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n util.keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n let domains: VgNonUnionDomain[];\n let domainRaw = null;\n\n for (const child of model.children) {\n const childComponent = child.component.scales[channel];\n if (childComponent) {\n if (domains === undefined) {\n domains = childComponent.domains;\n } else {\n domains = domains.concat(childComponent.domains);\n }\n\n const dr = childComponent.get('domainRaw');\n if (domainRaw && dr && domainRaw.signal !== dr.signal) {\n log.warn('The same selection must be used to override scale domains in a layered view.');\n }\n domainRaw = dr;\n }\n }\n\n localScaleComponents[channel].domains = domains;\n\n if (domainRaw) {\n localScaleComponents[channel].set('domainRaw', domainRaw, true);\n }\n });\n}\n\n\n/**\n * Remove unaggregated domain if it is not applicable\n * Add unaggregated domain if domain is not specified and config.scale.useUnaggregatedDomain is true.\n */\nfunction normalizeUnaggregatedDomain(domain: Domain, fieldDef: FieldDef, scaleType: ScaleType, scaleConfig: ScaleConfig) {\n if (domain === 'unaggregated') {\n const {valid, reason} = canUseUnaggregatedDomain(fieldDef, scaleType);\n if(!valid) {\n log.warn(reason);\n return undefined;\n }\n } else if (domain === undefined && scaleConfig.useUnaggregatedDomain) {\n // Apply config if domain is not specified.\n const {valid} = canUseUnaggregatedDomain(fieldDef, scaleType);\n if (valid) {\n return 'unaggregated';\n }\n }\n\n return domain;\n}\n\nexport function parseDomainForChannel(model: UnitModel, channel: ScaleChannel): VgNonUnionDomain[] {\n const scaleType = model.getScaleComponent(channel).get('type');\n\n const domain = normalizeUnaggregatedDomain(model.scaleDomain(channel), model.fieldDef(channel), scaleType, model.config.scale);\n if (domain !== model.scaleDomain(channel)) {\n model.specifiedScales[channel] = {\n ...model.specifiedScales[channel],\n domain\n };\n }\n\n // If channel is either X or Y then union them with X2 & Y2 if they exist\n if (channel === 'x' && model.channelHasField('x2')) {\n if (model.channelHasField('x')) {\n return parseSingleChannelDomain(scaleType, domain, model, 'x').concat(parseSingleChannelDomain(scaleType, domain, model, 'x2'));\n } else {\n return parseSingleChannelDomain(scaleType, domain, model, 'x2');\n }\n } else if (channel === 'y' && model.channelHasField('y2')) {\n if (model.channelHasField('y')) {\n return parseSingleChannelDomain(scaleType, domain, model, 'y').concat(parseSingleChannelDomain(scaleType, domain, model, 'y2'));\n } else {\n return parseSingleChannelDomain(scaleType, domain, model, 'y2');\n }\n }\n return parseSingleChannelDomain(scaleType, domain, model, channel);\n}\n\nfunction mapDomainToDataSignal(domain: T[], type: Type, timeUnit: TimeUnit) {\n return domain.map(v => {\n const data = valueExpr(v, {timeUnit, type});\n return {signal: `{data: ${data}}`};\n });\n}\n\nfunction parseSingleChannelDomain(scaleType: ScaleType, domain: Domain, model: UnitModel, channel: ScaleChannel | 'x2' | 'y2'): VgNonUnionDomain[] {\n const fieldDef = model.fieldDef(channel);\n\n if (domain && domain !== 'unaggregated' && !isSelectionDomain(domain)) { // explicit value\n const {type, timeUnit} = fieldDef;\n if (type === 'temporal' || timeUnit) {\n return mapDomainToDataSignal(domain, type, timeUnit);\n }\n\n return [domain];\n }\n\n const stack = model.stack;\n if (stack && channel === stack.fieldChannel) {\n if(stack.offset === 'normalize') {\n return [[0, 1]];\n }\n\n const data = model.requestDataName(MAIN);\n return [{\n data,\n field: model.vgField(channel, {suffix: 'start'})\n }, {\n data,\n field: model.vgField(channel, {suffix: 'end'})\n }];\n }\n\n const sort = isScaleChannel(channel) ? domainSort(model, channel, scaleType) : undefined;\n\n if (domain === 'unaggregated') {\n const data = model.requestDataName(MAIN);\n const {field} = fieldDef;\n return [{\n data,\n field: vgField({field, aggregate: 'min'})\n }, {\n data,\n field: vgField({field, aggregate: 'max'})\n }];\n } else if (fieldDef.bin) { // bin\n if (isBinScale(scaleType)) {\n const signal = model.getName(`${binToString(fieldDef.bin)}_${fieldDef.field}_bins`);\n return [{signal: `sequence(${signal}.start, ${signal}.stop + ${signal}.step, ${signal}.step)`}];\n }\n\n if (hasDiscreteDomain(scaleType)) {\n // ordinal bin scale takes domain from bin_range, ordered by bin start\n // This is useful for both axis-based scale (x/y) and legend-based scale (other channels).\n return [{\n // If sort by aggregation of a specified sort field, we need to use RAW table,\n // so we can aggregate values for the scale independently from the main aggregation.\n data: util.isBoolean(sort) ? model.requestDataName(MAIN) : model.requestDataName(RAW),\n // Use range if we added it and the scale does not support computing a range as a signal.\n field: model.vgField(channel, binRequiresRange(fieldDef, channel) ? {binSuffix: 'range'} : {}),\n // we have to use a sort object if sort = true to make the sort correct by bin start\n sort: sort === true || !isSortField(sort) ? {\n field: model.vgField(channel, {}),\n op: 'min' // min or max doesn't matter since we sort by the start of the bin range\n } : sort\n }];\n } else { // continuous scales\n if (channel === 'x' || channel === 'y') {\n if (isBinParams(fieldDef.bin) && fieldDef.bin.extent) {\n return [fieldDef.bin.extent];\n }\n // X/Y position have to include start and end for non-ordinal scale\n const data = model.requestDataName(MAIN);\n return [{\n data,\n field: model.vgField(channel, {})\n }, {\n data,\n field: model.vgField(channel, {binSuffix: 'end'})\n }];\n } else {\n // TODO: use bin_mid\n return [{\n data: model.requestDataName(MAIN),\n field: model.vgField(channel, {})\n }];\n }\n }\n } else if (sort) {\n return [{\n // If sort by aggregation of a specified sort field, we need to use RAW table,\n // so we can aggregate values for the scale independently from the main aggregation.\n data: util.isBoolean(sort) ? model.requestDataName(MAIN) : model.requestDataName(RAW),\n field: model.vgField(channel),\n sort: sort\n }];\n } else {\n return [{\n data: model.requestDataName(MAIN),\n field: model.vgField(channel)\n }];\n }\n}\n\n\nexport function domainSort(model: UnitModel, channel: ScaleChannel, scaleType: ScaleType): true | EncodingSortField {\n if (!hasDiscreteDomain(scaleType)) {\n return undefined;\n }\n\n const fieldDef: ScaleFieldDef = model.fieldDef(channel);\n const sort = fieldDef.sort;\n\n // if the sort is specified with array, use the derived sort index field\n if (isSortArray(sort)) {\n return {\n op: 'min',\n field: sortArrayIndexField(fieldDef, channel),\n order: 'ascending'\n };\n }\n\n // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale)\n if (isSortField(sort)) {\n // flatten nested fields\n return {\n ...sort,\n ...(sort.field ? {field: util.replacePathInField(sort.field)} : {})\n };\n }\n\n if (sort === 'descending') {\n return {\n op: 'min',\n field: model.vgField(channel),\n order: 'descending'\n };\n }\n\n if (util.contains(['ascending', undefined /* default =ascending*/], sort)) {\n return true;\n }\n\n // sort == null\n return undefined;\n}\n\n\n\n/**\n * Determine if a scale can use unaggregated domain.\n * @return {Boolean} Returns true if all of the following conditons applies:\n * 1. `scale.domain` is `unaggregated`\n * 2. Aggregation function is not `count` or `sum`\n * 3. The scale is quantitative or time scale.\n */\nexport function canUseUnaggregatedDomain(fieldDef: FieldDef, scaleType: ScaleType): {valid: boolean, reason?: string} {\n if (!fieldDef.aggregate) {\n return {\n valid: false,\n reason: log.message.unaggregateDomainHasNoEffectForRawField(fieldDef)\n };\n }\n\n if (!SHARED_DOMAIN_OP_INDEX[fieldDef.aggregate]) {\n return {\n valid: false,\n reason: log.message.unaggregateDomainWithNonSharedDomainOp(fieldDef.aggregate)\n };\n }\n\n if (fieldDef.type === 'quantitative') {\n if (scaleType === 'log') {\n return {\n valid: false,\n reason: log.message.unaggregatedDomainWithLogScale(fieldDef)\n };\n }\n }\n\n return {valid: true};\n}\n\n/**\n * Converts an array of domains to a single Vega scale domain.\n */\nexport function mergeDomains(domains: VgNonUnionDomain[]): VgDomain {\n const uniqueDomains = util.unique(domains.map(domain => {\n // ignore sort property when computing the unique domains\n if (isDataRefDomain(domain)) {\n const {sort: _s, ...domainWithoutSort} = domain;\n return domainWithoutSort;\n }\n return domain;\n }), util.hash);\n\n const sorts: VgSortField[] = util.unique(domains.map(d => {\n if (isDataRefDomain(d)) {\n const s = d.sort;\n if (s !== undefined && !util.isBoolean(s)) {\n if (s.op === 'count') {\n // let's make sure that if op is count, we don't use a field\n delete s.field;\n }\n if (s.order === 'ascending') {\n // drop order: ascending as it is the default\n delete s.order;\n }\n }\n return s;\n }\n return undefined;\n }).filter(s => s !== undefined), util.hash);\n\n if (uniqueDomains.length === 1) {\n const domain = domains[0];\n if (isDataRefDomain(domain) && sorts.length > 0) {\n let sort = sorts[0];\n if (sorts.length > 1) {\n log.warn(log.message.MORE_THAN_ONE_SORT);\n sort = true;\n }\n return {\n ...domain,\n sort\n };\n }\n return domain;\n }\n\n // only keep simple sort properties that work with unioned domains\n const simpleSorts = util.unique(sorts.map(s => {\n if (s === true) {\n return s;\n }\n if (s.op === 'count') {\n return s;\n }\n log.warn(log.message.domainSortDropped(s));\n return true;\n }), util.hash) as VgUnionSortField[];\n\n let sort: VgUnionSortField = undefined;\n\n if (simpleSorts.length === 1) {\n sort = simpleSorts[0];\n } else if (simpleSorts.length > 1) {\n log.warn(log.message.MORE_THAN_ONE_SORT);\n sort = true;\n }\n\n const allData = util.unique(domains.map(d => {\n if (isDataRefDomain(d)) {\n return d.data;\n }\n return null;\n }), x => x);\n\n if (allData.length === 1 && allData[0] !== null) {\n // create a union domain of different fields with a single data source\n const domain: VgFieldRefUnionDomain = {\n data: allData[0],\n fields: uniqueDomains.map(d => (d as VgDataRef).field),\n ...(sort ? {sort} : {})\n };\n\n return domain;\n }\n\n return {fields: uniqueDomains, ...(sort ? {sort} : {})};\n}\n\n/**\n * Return a field if a scale single field.\n * Return `undefined` otherwise.\n *\n */\nexport function getFieldFromDomain(domain: VgDomain): string {\n if (isDataRefDomain(domain) && isString(domain.field)) {\n return domain.field;\n } else if (isDataRefUnionedDomain(domain)) {\n let field;\n for (const nonUnionDomain of domain.fields) {\n if (isDataRefDomain(nonUnionDomain) && isString(nonUnionDomain.field)) {\n if (!field) {\n field = nonUnionDomain.field;\n } else if (field !== nonUnionDomain.field) {\n log.warn('Detected faceted independent scales that union domain of multiple fields from different data sources. We will use the first field. The result view size may be incorrect.');\n return field;\n }\n }\n }\n log.warn('Detected faceted independent scales that union domain of identical fields from different source detected. We will assume that this is the same field from a different fork of the same data source. However, if this is not case, the result view size maybe incorrect.');\n return field;\n } else if (isFieldRefUnionDomain(domain)) {\n log.warn('Detected faceted independent scales that union domain of multiple fields from the same data source. We will use the first field. The result view size may be incorrect.');\n const field = domain.fields[0];\n return isString(field) ? field : undefined;\n }\n\n return undefined;\n}\n\nexport function assembleDomain(model: Model, channel: ScaleChannel) {\n const scaleComponent = model.component.scales[channel];\n const domains = scaleComponent.domains.map(domain => {\n // Correct references to data as the original domain's data was determined\n // in parseScale, which happens before parseData. Thus the original data\n // reference can be incorrect.\n\n if (isDataRefDomain(domain)) {\n domain.data = model.lookupDataSource(domain.data);\n }\n return domain;\n });\n\n // domains is an array that has to be merged into a single vega domain\n return mergeDomains(domains);\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/scale/parse.d.ts b/build/src/compile/scale/parse.d.ts new file mode 100644 index 0000000000..3a1c753b06 --- /dev/null +++ b/build/src/compile/scale/parse.d.ts @@ -0,0 +1,3 @@ +import { Model } from '../model'; +export declare function parseScale(model: Model): void; +export declare function parseScaleCore(model: Model): void; diff --git a/build/src/compile/scale/parse.js b/build/src/compile/scale/parse.js new file mode 100644 index 0000000000..e5edbe3ddf --- /dev/null +++ b/build/src/compile/scale/parse.js @@ -0,0 +1,125 @@ +import { SCALE_CHANNELS, SHAPE, X, Y } from '../../channel'; +import { getFieldDef, hasConditionalFieldDef, isFieldDef } from '../../fielddef'; +import { GEOSHAPE } from '../../mark'; +import { NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES, scaleCompatible, scaleTypePrecedence, } from '../../scale'; +import { GEOJSON } from '../../type'; +import { keys } from '../../util'; +import { isUnitModel } from '../model'; +import { defaultScaleResolve } from '../resolve'; +import { mergeValuesWithExplicit, tieBreakByComparing } from '../split'; +import { ScaleComponent } from './component'; +import { parseScaleDomain } from './domain'; +import { parseScaleProperty } from './properties'; +import { parseScaleRange } from './range'; +import { scaleType } from './type'; +export function parseScale(model) { + parseScaleCore(model); + parseScaleDomain(model); + for (var _i = 0, NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES_1 = NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES; _i < NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES_1.length; _i++) { + var prop = NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES_1[_i]; + parseScaleProperty(model, prop); + } + // range depends on zero + parseScaleRange(model); +} +export function parseScaleCore(model) { + if (isUnitModel(model)) { + model.component.scales = parseUnitScaleCore(model); + } + else { + model.component.scales = parseNonUnitScaleCore(model); + } +} +/** + * Parse scales for all channels of a model. + */ +function parseUnitScaleCore(model) { + var encoding = model.encoding, config = model.config, mark = model.mark; + return SCALE_CHANNELS.reduce(function (scaleComponents, channel) { + var fieldDef; + var specifiedScale = undefined; + var channelDef = encoding[channel]; + // Don't generate scale for shape of geoshape + if (isFieldDef(channelDef) && mark === GEOSHAPE && + channel === SHAPE && channelDef.type === GEOJSON) { + return scaleComponents; + } + if (isFieldDef(channelDef)) { + fieldDef = channelDef; + specifiedScale = channelDef.scale; + } + else if (hasConditionalFieldDef(channelDef)) { + fieldDef = channelDef.condition; + specifiedScale = channelDef.condition['scale']; // We use ['scale'] since we know that channel here has scale for sure + } + else if (channel === X) { + fieldDef = getFieldDef(encoding.x2); + } + else if (channel === Y) { + fieldDef = getFieldDef(encoding.y2); + } + if (fieldDef && specifiedScale !== null && specifiedScale !== false) { + specifiedScale = specifiedScale || {}; + var specifiedScaleType = specifiedScale.type; + var sType = scaleType(specifiedScale.type, channel, fieldDef, mark, config.scale); + scaleComponents[channel] = new ScaleComponent(model.scaleName(channel + '', true), { value: sType, explicit: specifiedScaleType === sType }); + } + return scaleComponents; + }, {}); +} +var scaleTypeTieBreaker = tieBreakByComparing(function (st1, st2) { return (scaleTypePrecedence(st1) - scaleTypePrecedence(st2)); }); +function parseNonUnitScaleCore(model) { + var scaleComponents = model.component.scales = {}; + var scaleTypeWithExplicitIndex = {}; + var resolve = model.component.resolve; + var _loop_1 = function (child) { + parseScaleCore(child); + // Instead of always merging right away -- check if it is compatible to merge first! + keys(child.component.scales).forEach(function (channel) { + // if resolve is undefined, set default first + resolve.scale[channel] = resolve.scale[channel] || defaultScaleResolve(channel, model); + if (resolve.scale[channel] === 'shared') { + var explicitScaleType = scaleTypeWithExplicitIndex[channel]; + var childScaleType = child.component.scales[channel].getWithExplicit('type'); + if (explicitScaleType) { + if (scaleCompatible(explicitScaleType.value, childScaleType.value)) { + // merge scale component if type are compatible + scaleTypeWithExplicitIndex[channel] = mergeValuesWithExplicit(explicitScaleType, childScaleType, 'type', 'scale', scaleTypeTieBreaker); + } + else { + // Otherwise, update conflicting channel to be independent + resolve.scale[channel] = 'independent'; + // Remove from the index so they don't get merged + delete scaleTypeWithExplicitIndex[channel]; + } + } + else { + scaleTypeWithExplicitIndex[channel] = childScaleType; + } + } + }); + }; + // Parse each child scale and determine if a particular channel can be merged. + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + _loop_1(child); + } + // Merge each channel listed in the index + keys(scaleTypeWithExplicitIndex).forEach(function (channel) { + // Create new merged scale component + var name = model.scaleName(channel, true); + var typeWithExplicit = scaleTypeWithExplicitIndex[channel]; + scaleComponents[channel] = new ScaleComponent(name, typeWithExplicit); + // rename each child and mark them as merged + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + var childScale = child.component.scales[channel]; + if (childScale) { + child.renameScale(childScale.get('name'), name); + childScale.merged = true; + } + } + }); + return scaleComponents; +} +//# sourceMappingURL=parse.js.map \ No newline at end of file diff --git a/build/src/compile/scale/parse.js.map b/build/src/compile/scale/parse.js.map new file mode 100644 index 0000000000..6385ab7d15 --- /dev/null +++ b/build/src/compile/scale/parse.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../src/compile/scale/parse.ts"],"names":[],"mappings":"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","sourcesContent":["import {SCALE_CHANNELS, ScaleChannel, SHAPE, X, Y} from '../../channel';\nimport {FieldDef, getFieldDef, hasConditionalFieldDef, isFieldDef} from '../../fielddef';\nimport {GEOSHAPE} from '../../mark';\nimport {\n NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES,\n Scale,\n scaleCompatible,\n ScaleType,\n scaleTypePrecedence,\n} from '../../scale';\nimport {GEOJSON} from '../../type';\nimport {keys} from '../../util';\nimport {VgScale} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {defaultScaleResolve} from '../resolve';\nimport {Explicit, mergeValuesWithExplicit, tieBreakByComparing} from '../split';\nimport {UnitModel} from '../unit';\nimport {ScaleComponent, ScaleComponentIndex} from './component';\nimport {parseScaleDomain} from './domain';\nimport {parseScaleProperty} from './properties';\nimport {parseScaleRange} from './range';\nimport {scaleType} from './type';\n\nexport function parseScale(model: Model) {\n parseScaleCore(model);\n parseScaleDomain(model);\n for (const prop of NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES) {\n parseScaleProperty(model, prop);\n }\n // range depends on zero\n parseScaleRange(model);\n}\n\nexport function parseScaleCore(model: Model) {\n if (isUnitModel(model)) {\n model.component.scales = parseUnitScaleCore(model);\n } else {\n model.component.scales = parseNonUnitScaleCore(model);\n }\n}\n\n/**\n * Parse scales for all channels of a model.\n */\nfunction parseUnitScaleCore(model: UnitModel): ScaleComponentIndex {\n const {encoding, config, mark} = model;\n\n return SCALE_CHANNELS.reduce((scaleComponents: ScaleComponentIndex, channel: ScaleChannel) => {\n let fieldDef: FieldDef;\n let specifiedScale: Scale | null = undefined;\n\n const channelDef = encoding[channel];\n\n // Don't generate scale for shape of geoshape\n if (\n isFieldDef(channelDef) && mark === GEOSHAPE &&\n channel === SHAPE && channelDef.type === GEOJSON\n ) {\n return scaleComponents;\n }\n\n if (isFieldDef(channelDef)) {\n fieldDef = channelDef;\n specifiedScale = channelDef.scale;\n } else if (hasConditionalFieldDef(channelDef)) {\n fieldDef = channelDef.condition;\n specifiedScale = channelDef.condition['scale']; // We use ['scale'] since we know that channel here has scale for sure\n } else if (channel === X) {\n fieldDef = getFieldDef(encoding.x2);\n } else if (channel === Y) {\n fieldDef = getFieldDef(encoding.y2);\n }\n\n if (fieldDef && specifiedScale !== null && specifiedScale !== false) {\n specifiedScale = specifiedScale || {};\n const specifiedScaleType = specifiedScale.type;\n const sType = scaleType(specifiedScale.type, channel, fieldDef, mark, config.scale);\n scaleComponents[channel] = new ScaleComponent(\n model.scaleName(channel + '', true),\n {value: sType, explicit: specifiedScaleType === sType}\n );\n }\n return scaleComponents;\n }, {});\n}\n\nconst scaleTypeTieBreaker = tieBreakByComparing(\n (st1: ScaleType, st2: ScaleType) => (scaleTypePrecedence(st1) - scaleTypePrecedence(st2))\n);\n\n\nfunction parseNonUnitScaleCore(model: Model) {\n const scaleComponents: ScaleComponentIndex = model.component.scales = {};\n\n const scaleTypeWithExplicitIndex: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleChannel]?: Explicit\n } = {};\n const resolve = model.component.resolve;\n\n // Parse each child scale and determine if a particular channel can be merged.\n for (const child of model.children) {\n parseScaleCore(child);\n\n // Instead of always merging right away -- check if it is compatible to merge first!\n keys(child.component.scales).forEach((channel: ScaleChannel) => {\n // if resolve is undefined, set default first\n resolve.scale[channel] = resolve.scale[channel] || defaultScaleResolve(channel, model);\n\n if (resolve.scale[channel] === 'shared') {\n const explicitScaleType = scaleTypeWithExplicitIndex[channel];\n const childScaleType = child.component.scales[channel].getWithExplicit('type');\n\n if (explicitScaleType) {\n if (scaleCompatible(explicitScaleType.value, childScaleType.value)) {\n // merge scale component if type are compatible\n scaleTypeWithExplicitIndex[channel] = mergeValuesWithExplicit(\n explicitScaleType, childScaleType, 'type', 'scale', scaleTypeTieBreaker\n );\n } else {\n // Otherwise, update conflicting channel to be independent\n resolve.scale[channel] = 'independent';\n // Remove from the index so they don't get merged\n delete scaleTypeWithExplicitIndex[channel];\n }\n } else {\n scaleTypeWithExplicitIndex[channel] = childScaleType;\n }\n }\n });\n }\n\n // Merge each channel listed in the index\n keys(scaleTypeWithExplicitIndex).forEach((channel: ScaleChannel) => {\n // Create new merged scale component\n const name = model.scaleName(channel, true);\n const typeWithExplicit = scaleTypeWithExplicitIndex[channel];\n scaleComponents[channel] = new ScaleComponent(name, typeWithExplicit);\n\n // rename each child and mark them as merged\n for (const child of model.children) {\n const childScale = child.component.scales[channel];\n if (childScale) {\n child.renameScale(childScale.get('name'), name);\n childScale.merged = true;\n }\n }\n });\n\n return scaleComponents;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/scale/properties.d.ts b/build/src/compile/scale/properties.d.ts new file mode 100644 index 0000000000..13684a573b --- /dev/null +++ b/build/src/compile/scale/properties.d.ts @@ -0,0 +1,17 @@ +import { Channel } from '../../channel'; +import { Config } from '../../config'; +import { FieldDef, ScaleFieldDef } from '../../fielddef'; +import { BarConfig, MarkDef } from '../../mark'; +import { Domain, NiceTime, Scale, ScaleConfig, ScaleType } from '../../scale'; +import { Sort } from '../../sort'; +import { Model } from '../model'; +import { ScaleComponentProps } from './component'; +export declare function parseScaleProperty(model: Model, property: keyof (Scale | ScaleComponentProps)): void; +export declare function getDefaultValue(property: keyof Scale, channel: Channel, fieldDef: ScaleFieldDef, scaleType: ScaleType, scalePadding: number, scalePaddingInner: number, specifiedDomain: Scale['domain'], markDef: MarkDef, config: Config): any; +export declare function parseNonUnitScaleProperty(model: Model, property: keyof (Scale | ScaleComponentProps)): void; +export declare function nice(scaleType: ScaleType, channel: Channel, fieldDef: FieldDef): boolean | NiceTime; +export declare function padding(channel: Channel, scaleType: ScaleType, scaleConfig: ScaleConfig, fieldDef: FieldDef, markDef: MarkDef, barConfig: BarConfig): number; +export declare function paddingInner(paddingValue: number, channel: Channel, scaleConfig: ScaleConfig): number; +export declare function paddingOuter(paddingValue: number, channel: Channel, scaleType: ScaleType, paddingInnerValue: number, scaleConfig: ScaleConfig): number; +export declare function reverse(scaleType: ScaleType, sort: Sort): boolean; +export declare function zero(channel: Channel, fieldDef: FieldDef, specifiedScale: Domain, markDef: MarkDef): boolean; diff --git a/build/src/compile/scale/properties.js b/build/src/compile/scale/properties.js new file mode 100644 index 0000000000..7abc9a9f2d --- /dev/null +++ b/build/src/compile/scale/properties.js @@ -0,0 +1,203 @@ +import { X, Y } from '../../channel'; +import * as log from '../../log'; +import { channelScalePropertyIncompatability, hasContinuousDomain, isContinuousToContinuous, ScaleType, scaleTypeSupportProperty } from '../../scale'; +import * as util from '../../util'; +import { contains, keys } from '../../util'; +import { isUnitModel } from '../model'; +import { mergeValuesWithExplicit, tieBreakByComparing } from '../split'; +import { parseScaleRange } from './range'; +export function parseScaleProperty(model, property) { + if (isUnitModel(model)) { + parseUnitScaleProperty(model, property); + } + else { + parseNonUnitScaleProperty(model, property); + } +} +function parseUnitScaleProperty(model, property) { + var localScaleComponents = model.component.scales; + keys(localScaleComponents).forEach(function (channel) { + var specifiedScale = model.specifiedScales[channel]; + var localScaleCmpt = localScaleComponents[channel]; + var mergedScaleCmpt = model.getScaleComponent(channel); + var fieldDef = model.fieldDef(channel); + var config = model.config; + var specifiedValue = specifiedScale[property]; + var sType = mergedScaleCmpt.get('type'); + var supportedByScaleType = scaleTypeSupportProperty(sType, property); + var channelIncompatability = channelScalePropertyIncompatability(channel, property); + if (specifiedValue !== undefined) { + // If there is a specified value, check if it is compatible with scale type and channel + if (!supportedByScaleType) { + log.warn(log.message.scalePropertyNotWorkWithScaleType(sType, property, channel)); + } + else if (channelIncompatability) { // channel + log.warn(channelIncompatability); + } + } + if (supportedByScaleType && channelIncompatability === undefined) { + if (specifiedValue !== undefined) { + // copyKeyFromObject ensure type safety + localScaleCmpt.copyKeyFromObject(property, specifiedScale); + } + else { + var value = getDefaultValue(property, channel, fieldDef, mergedScaleCmpt.get('type'), mergedScaleCmpt.get('padding'), mergedScaleCmpt.get('paddingInner'), specifiedScale.domain, model.markDef, config); + if (value !== undefined) { + localScaleCmpt.set(property, value, false); + } + } + } + }); +} +// Note: This method is used in Voyager. +export function getDefaultValue(property, channel, fieldDef, scaleType, scalePadding, scalePaddingInner, specifiedDomain, markDef, config) { + var scaleConfig = config.scale; + // If we have default rule-base, determine default value first + switch (property) { + case 'nice': + return nice(scaleType, channel, fieldDef); + case 'padding': + return padding(channel, scaleType, scaleConfig, fieldDef, markDef, config.bar); + case 'paddingInner': + return paddingInner(scalePadding, channel, scaleConfig); + case 'paddingOuter': + return paddingOuter(scalePadding, channel, scaleType, scalePaddingInner, scaleConfig); + case 'reverse': + return reverse(scaleType, fieldDef.sort); + case 'zero': + return zero(channel, fieldDef, specifiedDomain, markDef); + } + // Otherwise, use scale config + return scaleConfig[property]; +} +export function parseNonUnitScaleProperty(model, property) { + var localScaleComponents = model.component.scales; + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + if (property === 'range') { + parseScaleRange(child); + } + else { + parseScaleProperty(child, property); + } + } + keys(localScaleComponents).forEach(function (channel) { + var valueWithExplicit; + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + var childComponent = child.component.scales[channel]; + if (childComponent) { + var childValueWithExplicit = childComponent.getWithExplicit(property); + valueWithExplicit = mergeValuesWithExplicit(valueWithExplicit, childValueWithExplicit, property, 'scale', tieBreakByComparing(function (v1, v2) { + switch (property) { + case 'range': + // For range step, prefer larger step + if (v1.step && v2.step) { + return v1.step - v2.step; + } + return 0; + // TODO: precedence rule for other properties + } + return 0; + })); + } + } + localScaleComponents[channel].setWithExplicit(property, valueWithExplicit); + }); +} +export function nice(scaleType, channel, fieldDef) { + if (fieldDef.bin || util.contains([ScaleType.TIME, ScaleType.UTC], scaleType)) { + return undefined; + } + return util.contains([X, Y], channel); // return true for quantitative X/Y unless binned +} +export function padding(channel, scaleType, scaleConfig, fieldDef, markDef, barConfig) { + if (util.contains([X, Y], channel)) { + if (isContinuousToContinuous(scaleType)) { + if (scaleConfig.continuousPadding !== undefined) { + return scaleConfig.continuousPadding; + } + var type = markDef.type, orient = markDef.orient; + if (type === 'bar' && !fieldDef.bin) { + if ((orient === 'vertical' && channel === 'x') || + (orient === 'horizontal' && channel === 'y')) { + return barConfig.continuousBandSize; + } + } + } + if (scaleType === ScaleType.POINT) { + return scaleConfig.pointPadding; + } + } + return undefined; +} +export function paddingInner(paddingValue, channel, scaleConfig) { + if (paddingValue !== undefined) { + // If user has already manually specified "padding", no need to add default paddingInner. + return undefined; + } + if (util.contains([X, Y], channel)) { + // Padding is only set for X and Y by default. + // Basically it doesn't make sense to add padding for color and size. + // paddingOuter would only be called if it's a band scale, just return the default for bandScale. + return scaleConfig.bandPaddingInner; + } + return undefined; +} +export function paddingOuter(paddingValue, channel, scaleType, paddingInnerValue, scaleConfig) { + if (paddingValue !== undefined) { + // If user has already manually specified "padding", no need to add default paddingOuter. + return undefined; + } + if (util.contains([X, Y], channel)) { + // Padding is only set for X and Y by default. + // Basically it doesn't make sense to add padding for color and size. + if (scaleType === ScaleType.BAND) { + if (scaleConfig.bandPaddingOuter !== undefined) { + return scaleConfig.bandPaddingOuter; + } + /* By default, paddingOuter is paddingInner / 2. The reason is that + size (width/height) = step * (cardinality - paddingInner + 2 * paddingOuter). + and we want the width/height to be integer by default. + Note that step (by default) and cardinality are integers.) */ + return paddingInnerValue / 2; + } + } + return undefined; +} +export function reverse(scaleType, sort) { + if (hasContinuousDomain(scaleType) && sort === 'descending') { + // For continuous domain scales, Vega does not support domain sort. + // Thus, we reverse range instead if sort is descending + return true; + } + return undefined; +} +export function zero(channel, fieldDef, specifiedScale, markDef) { + // If users explicitly provide a domain range, we should not augment zero as that will be unexpected. + var hasCustomDomain = !!specifiedScale && specifiedScale !== 'unaggregated'; + if (hasCustomDomain) { + return false; + } + // If there is no custom domain, return true only for the following cases: + // 1) using quantitative field with size + // While this can be either ratio or interval fields, our assumption is that + // ratio are more common. + if (channel === 'size' && fieldDef.type === 'quantitative') { + return true; + } + // 2) non-binned, quantitative x-scale or y-scale + // (For binning, we should not include zero by default because binning are calculated without zero.) + if (!fieldDef.bin && util.contains([X, Y], channel)) { + var orient = markDef.orient, type = markDef.type; + if (contains(['bar', 'area', 'line', 'trail'], type)) { + if ((orient === 'horizontal' && channel === 'y') || + (orient === 'vertical' && channel === 'x')) { + return false; + } + } + return true; + } + return false; +} +//# sourceMappingURL=properties.js.map \ No newline at end of file diff --git a/build/src/compile/scale/properties.js.map b/build/src/compile/scale/properties.js.map new file mode 100644 index 0000000000..4d8477aa17 --- /dev/null +++ b/build/src/compile/scale/properties.js.map @@ -0,0 +1 @@ +{"version":3,"file":"properties.js","sourceRoot":"","sources":["../../../../src/compile/scale/properties.ts"],"names":[],"mappings":"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","sourcesContent":["import {Channel, ScaleChannel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {FieldDef, ScaleFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {BarConfig, MarkDef} from '../../mark';\nimport {channelScalePropertyIncompatability, Domain, hasContinuousDomain, isContinuousToContinuous, NiceTime, Scale, ScaleConfig, ScaleType, scaleTypeSupportProperty} from '../../scale';\nimport {Sort} from '../../sort';\nimport * as util from '../../util';\nimport {contains, keys} from '../../util';\nimport {VgScale} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {Explicit, mergeValuesWithExplicit, tieBreakByComparing} from '../split';\nimport {UnitModel} from '../unit';\nimport {ScaleComponentIndex, ScaleComponentProps} from './component';\nimport {parseScaleRange} from './range';\n\nexport function parseScaleProperty(model: Model, property: keyof (Scale | ScaleComponentProps)) {\n if (isUnitModel(model)) {\n parseUnitScaleProperty(model, property);\n } else {\n parseNonUnitScaleProperty(model, property);\n }\n}\n\nfunction parseUnitScaleProperty(model: UnitModel, property: keyof (Scale | ScaleComponentProps)) {\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n const specifiedScale = model.specifiedScales[channel];\n const localScaleCmpt = localScaleComponents[channel];\n const mergedScaleCmpt = model.getScaleComponent(channel);\n const fieldDef = model.fieldDef(channel);\n const config = model.config;\n\n const specifiedValue = specifiedScale[property];\n const sType = mergedScaleCmpt.get('type');\n\n const supportedByScaleType = scaleTypeSupportProperty(sType, property);\n const channelIncompatability = channelScalePropertyIncompatability(channel, property);\n\n if (specifiedValue !== undefined) {\n // If there is a specified value, check if it is compatible with scale type and channel\n if (!supportedByScaleType) {\n log.warn(log.message.scalePropertyNotWorkWithScaleType(sType, property, channel));\n } else if (channelIncompatability) { // channel\n log.warn(channelIncompatability);\n }\n }\n if (supportedByScaleType && channelIncompatability === undefined) {\n if (specifiedValue !== undefined) {\n // copyKeyFromObject ensure type safety\n localScaleCmpt.copyKeyFromObject(property, specifiedScale);\n } else {\n const value = getDefaultValue(\n property, channel, fieldDef,\n mergedScaleCmpt.get('type'),\n mergedScaleCmpt.get('padding'),\n mergedScaleCmpt.get('paddingInner'),\n specifiedScale.domain,\n model.markDef, config\n );\n if (value !== undefined) {\n localScaleCmpt.set(property, value, false);\n }\n }\n }\n });\n}\n\n// Note: This method is used in Voyager.\nexport function getDefaultValue(\n property: keyof Scale, channel: Channel, fieldDef: ScaleFieldDef,\n scaleType: ScaleType, scalePadding: number, scalePaddingInner: number,\n specifiedDomain: Scale['domain'], markDef: MarkDef, config: Config) {\n const scaleConfig = config.scale;\n\n // If we have default rule-base, determine default value first\n switch (property) {\n case 'nice':\n return nice(scaleType, channel, fieldDef);\n case 'padding':\n return padding(channel, scaleType, scaleConfig, fieldDef, markDef, config.bar);\n case 'paddingInner':\n return paddingInner(scalePadding, channel, scaleConfig);\n case 'paddingOuter':\n return paddingOuter(scalePadding, channel, scaleType, scalePaddingInner, scaleConfig);\n case 'reverse':\n return reverse(scaleType, fieldDef.sort);\n case 'zero':\n return zero(channel, fieldDef, specifiedDomain, markDef);\n }\n // Otherwise, use scale config\n return scaleConfig[property];\n}\n\nexport function parseNonUnitScaleProperty(model: Model, property: keyof (Scale | ScaleComponentProps)) {\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n for (const child of model.children) {\n if (property === 'range') {\n parseScaleRange(child);\n } else {\n parseScaleProperty(child, property);\n }\n }\n\n keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n let valueWithExplicit: Explicit;\n\n for (const child of model.children) {\n const childComponent = child.component.scales[channel];\n if (childComponent) {\n const childValueWithExplicit = childComponent.getWithExplicit(property);\n valueWithExplicit = mergeValuesWithExplicit(\n valueWithExplicit, childValueWithExplicit,\n property,\n 'scale',\n tieBreakByComparing((v1, v2) => {\n switch (property) {\n case 'range':\n // For range step, prefer larger step\n if (v1.step && v2.step) {\n return v1.step - v2.step;\n }\n return 0;\n // TODO: precedence rule for other properties\n }\n return 0;\n })\n );\n }\n }\n localScaleComponents[channel].setWithExplicit(property, valueWithExplicit);\n });\n}\n\nexport function nice(scaleType: ScaleType, channel: Channel, fieldDef: FieldDef): boolean | NiceTime {\n if (fieldDef.bin || util.contains([ScaleType.TIME, ScaleType.UTC], scaleType)) {\n return undefined;\n }\n return util.contains([X, Y], channel); // return true for quantitative X/Y unless binned\n}\n\nexport function padding(channel: Channel, scaleType: ScaleType, scaleConfig: ScaleConfig, fieldDef: FieldDef, markDef: MarkDef, barConfig: BarConfig) {\n if (util.contains([X, Y], channel)) {\n if (isContinuousToContinuous(scaleType)) {\n if (scaleConfig.continuousPadding !== undefined) {\n return scaleConfig.continuousPadding;\n }\n\n const {type, orient} = markDef;\n if (type === 'bar' && !fieldDef.bin) {\n if (\n (orient === 'vertical' && channel === 'x') ||\n (orient === 'horizontal' && channel === 'y')\n ) {\n return barConfig.continuousBandSize;\n }\n }\n }\n\n if (scaleType === ScaleType.POINT) {\n return scaleConfig.pointPadding;\n }\n }\n return undefined;\n}\n\nexport function paddingInner(paddingValue: number, channel: Channel, scaleConfig: ScaleConfig) {\n if (paddingValue !== undefined) {\n // If user has already manually specified \"padding\", no need to add default paddingInner.\n return undefined;\n }\n\n if (util.contains([X, Y], channel)) {\n // Padding is only set for X and Y by default.\n // Basically it doesn't make sense to add padding for color and size.\n\n // paddingOuter would only be called if it's a band scale, just return the default for bandScale.\n return scaleConfig.bandPaddingInner;\n }\n return undefined;\n}\n\nexport function paddingOuter(paddingValue: number, channel: Channel, scaleType: ScaleType, paddingInnerValue: number, scaleConfig: ScaleConfig) {\n if (paddingValue !== undefined) {\n // If user has already manually specified \"padding\", no need to add default paddingOuter.\n return undefined;\n }\n\n if (util.contains([X, Y], channel)) {\n // Padding is only set for X and Y by default.\n // Basically it doesn't make sense to add padding for color and size.\n if (scaleType === ScaleType.BAND) {\n if (scaleConfig.bandPaddingOuter !== undefined) {\n return scaleConfig.bandPaddingOuter;\n }\n /* By default, paddingOuter is paddingInner / 2. The reason is that\n size (width/height) = step * (cardinality - paddingInner + 2 * paddingOuter).\n and we want the width/height to be integer by default.\n Note that step (by default) and cardinality are integers.) */\n return paddingInnerValue / 2;\n }\n }\n return undefined;\n}\n\nexport function reverse(scaleType: ScaleType, sort: Sort) {\n if (hasContinuousDomain(scaleType) && sort === 'descending') {\n // For continuous domain scales, Vega does not support domain sort.\n // Thus, we reverse range instead if sort is descending\n return true;\n }\n return undefined;\n}\n\nexport function zero(channel: Channel, fieldDef: FieldDef, specifiedScale: Domain, markDef: MarkDef) {\n\n // If users explicitly provide a domain range, we should not augment zero as that will be unexpected.\n const hasCustomDomain = !!specifiedScale && specifiedScale !== 'unaggregated';\n if (hasCustomDomain) {\n return false;\n }\n\n // If there is no custom domain, return true only for the following cases:\n\n // 1) using quantitative field with size\n // While this can be either ratio or interval fields, our assumption is that\n // ratio are more common.\n if (channel === 'size' && fieldDef.type === 'quantitative') {\n return true;\n }\n\n // 2) non-binned, quantitative x-scale or y-scale\n // (For binning, we should not include zero by default because binning are calculated without zero.)\n if (!fieldDef.bin && util.contains([X, Y], channel)) {\n const {orient, type} = markDef;\n if (contains(['bar', 'area', 'line', 'trail'], type)) {\n if (\n (orient === 'horizontal' && channel === 'y') ||\n (orient === 'vertical' && channel === 'x')\n ) {\n return false;\n }\n }\n\n return true;\n }\n return false;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/scale/range.d.ts b/build/src/compile/scale/range.d.ts new file mode 100644 index 0000000000..6f9c7c20d5 --- /dev/null +++ b/build/src/compile/scale/range.d.ts @@ -0,0 +1,22 @@ +import { Channel } from '../../channel'; +import { Config } from '../../config'; +import { Mark } from '../../mark'; +import { Range, Scale, ScaleType, Scheme } from '../../scale'; +import { Type } from '../../type'; +import { VgRange } from '../../vega.schema'; +import { Model } from '../model'; +import { Explicit } from '../split'; +export declare type RangeMixins = { + range: Range; +} | { + rangeStep: number; +} | { + scheme: Scheme; +}; +export declare const RANGE_PROPERTIES: (keyof Scale)[]; +export declare function parseScaleRange(model: Model): void; +/** + * Return mixins that includes one of the range properties (range, rangeStep, scheme). + */ +export declare function parseRangeForChannel(channel: Channel, scaleType: ScaleType, type: Type, specifiedScale: Scale, config: Config, zero: boolean, mark: Mark, sizeSpecified: boolean, sizeSignal: string, xyRangeSteps: number[]): Explicit; +export declare function defaultRange(channel: Channel, scaleType: ScaleType, type: Type, config: Config, zero: boolean, mark: Mark, sizeSignal: string, xyRangeSteps: number[], noRangeStep: boolean): VgRange; diff --git a/build/src/compile/scale/range.js b/build/src/compile/scale/range.js new file mode 100644 index 0000000000..1751336e83 --- /dev/null +++ b/build/src/compile/scale/range.js @@ -0,0 +1,229 @@ +import { isNumber } from 'vega-util'; +import { COLOR, FILL, OPACITY, SCALE_CHANNELS, SHAPE, SIZE, STROKE, X, Y } from '../../channel'; +import * as log from '../../log'; +import { channelScalePropertyIncompatability, isExtendedScheme, scaleTypeSupportProperty, } from '../../scale'; +import { hasContinuousDomain } from '../../scale'; +import * as util from '../../util'; +import { isVgRangeStep } from '../../vega.schema'; +import { isUnitModel } from '../model'; +import { makeExplicit, makeImplicit } from '../split'; +import { parseNonUnitScaleProperty } from './properties'; +export var RANGE_PROPERTIES = ['range', 'rangeStep', 'scheme']; +export function parseScaleRange(model) { + if (isUnitModel(model)) { + parseUnitScaleRange(model); + } + else { + parseNonUnitScaleProperty(model, 'range'); + } +} +function parseUnitScaleRange(model) { + var localScaleComponents = model.component.scales; + // use SCALE_CHANNELS instead of scales[channel] to ensure that x, y come first! + SCALE_CHANNELS.forEach(function (channel) { + var localScaleCmpt = localScaleComponents[channel]; + if (!localScaleCmpt) { + return; + } + var mergedScaleCmpt = model.getScaleComponent(channel); + var specifiedScale = model.specifiedScales[channel]; + var fieldDef = model.fieldDef(channel); + // Read if there is a specified width/height + var sizeType = channel === 'x' ? 'width' : channel === 'y' ? 'height' : undefined; + var sizeSpecified = sizeType ? !!model.component.layoutSize.get(sizeType) : undefined; + var scaleType = mergedScaleCmpt.get('type'); + // if autosize is fit, size cannot be data driven + var rangeStep = util.contains(['point', 'band'], scaleType) || !!specifiedScale.rangeStep; + if (sizeType && model.fit && !sizeSpecified && rangeStep) { + log.warn(log.message.CANNOT_FIX_RANGE_STEP_WITH_FIT); + sizeSpecified = true; + } + var xyRangeSteps = getXYRangeStep(model); + var rangeWithExplicit = parseRangeForChannel(channel, scaleType, fieldDef.type, specifiedScale, model.config, localScaleCmpt.get('zero'), model.mark, sizeSpecified, model.getName(sizeType), xyRangeSteps); + localScaleCmpt.setWithExplicit('range', rangeWithExplicit); + }); +} +function getXYRangeStep(model) { + var xyRangeSteps = []; + var xScale = model.getScaleComponent('x'); + var xRange = xScale && xScale.get('range'); + if (xRange && isVgRangeStep(xRange) && isNumber(xRange.step)) { + xyRangeSteps.push(xRange.step); + } + var yScale = model.getScaleComponent('y'); + var yRange = yScale && yScale.get('range'); + if (yRange && isVgRangeStep(yRange) && isNumber(yRange.step)) { + xyRangeSteps.push(yRange.step); + } + return xyRangeSteps; +} +/** + * Return mixins that includes one of the range properties (range, rangeStep, scheme). + */ +export function parseRangeForChannel(channel, scaleType, type, specifiedScale, config, zero, mark, sizeSpecified, sizeSignal, xyRangeSteps) { + var noRangeStep = sizeSpecified || specifiedScale.rangeStep === null; + // Check if any of the range properties is specified. + // If so, check if it is compatible and make sure that we only output one of the properties + for (var _i = 0, RANGE_PROPERTIES_1 = RANGE_PROPERTIES; _i < RANGE_PROPERTIES_1.length; _i++) { + var property = RANGE_PROPERTIES_1[_i]; + if (specifiedScale[property] !== undefined) { + var supportedByScaleType = scaleTypeSupportProperty(scaleType, property); + var channelIncompatability = channelScalePropertyIncompatability(channel, property); + if (!supportedByScaleType) { + log.warn(log.message.scalePropertyNotWorkWithScaleType(scaleType, property, channel)); + } + else if (channelIncompatability) { // channel + log.warn(channelIncompatability); + } + else { + switch (property) { + case 'range': + return makeExplicit(specifiedScale[property]); + case 'scheme': + return makeExplicit(parseScheme(specifiedScale[property])); + case 'rangeStep': + var rangeStep = specifiedScale[property]; + if (rangeStep !== null) { + if (!sizeSpecified) { + return makeExplicit({ step: rangeStep }); + } + else { + // If top-level size is specified, we ignore specified rangeStep. + log.warn(log.message.rangeStepDropped(channel)); + } + } + } + } + } + } + return makeImplicit(defaultRange(channel, scaleType, type, config, zero, mark, sizeSignal, xyRangeSteps, noRangeStep)); +} +function parseScheme(scheme) { + if (isExtendedScheme(scheme)) { + var r = { scheme: scheme.name }; + if (scheme.count) { + r.count = scheme.count; + } + if (scheme.extent) { + r.extent = scheme.extent; + } + return r; + } + return { scheme: scheme }; +} +export function defaultRange(channel, scaleType, type, config, zero, mark, sizeSignal, xyRangeSteps, noRangeStep) { + switch (channel) { + case X: + case Y: + if (util.contains(['point', 'band'], scaleType) && !noRangeStep) { + if (channel === X && mark === 'text') { + if (config.scale.textXRangeStep) { + return { step: config.scale.textXRangeStep }; + } + } + else { + if (config.scale.rangeStep) { + return { step: config.scale.rangeStep }; + } + } + } + // If range step is null, use zero to width or height. + // Note that these range signals are temporary + // as they can be merged and renamed. + // (We do not have the right size signal here since parseLayoutSize() happens after parseScale().) + // We will later replace these temporary names with + // the final name in assembleScaleRange() + if (channel === Y && hasContinuousDomain(scaleType)) { + // For y continuous scale, we have to start from the height as the bottom part has the max value. + return [{ signal: sizeSignal }, 0]; + } + else { + return [0, { signal: sizeSignal }]; + } + case SIZE: + // TODO: support custom rangeMin, rangeMax + var rangeMin = sizeRangeMin(mark, zero, config); + var rangeMax = sizeRangeMax(mark, xyRangeSteps, config); + return [rangeMin, rangeMax]; + case SHAPE: + return 'symbol'; + case COLOR: + case FILL: + case STROKE: + if (scaleType === 'ordinal') { + // Only nominal data uses ordinal scale by default + return type === 'nominal' ? 'category' : 'ordinal'; + } + return mark === 'rect' || mark === 'geoshape' ? 'heatmap' : 'ramp'; + case OPACITY: + // TODO: support custom rangeMin, rangeMax + return [config.scale.minOpacity, config.scale.maxOpacity]; + } + /* istanbul ignore next: should never reach here */ + throw new Error("Scale range undefined for channel " + channel); +} +function sizeRangeMin(mark, zero, config) { + if (zero) { + return 0; + } + switch (mark) { + case 'bar': + case 'tick': + return config.scale.minBandSize; + case 'line': + case 'trail': + case 'rule': + return config.scale.minStrokeWidth; + case 'text': + return config.scale.minFontSize; + case 'point': + case 'square': + case 'circle': + return config.scale.minSize; + } + /* istanbul ignore next: should never reach here */ + // sizeRangeMin not implemented for the mark + throw new Error(log.message.incompatibleChannel('size', mark)); +} +function sizeRangeMax(mark, xyRangeSteps, config) { + var scaleConfig = config.scale; + switch (mark) { + case 'bar': + case 'tick': + if (config.scale.maxBandSize !== undefined) { + return config.scale.maxBandSize; + } + return minXYRangeStep(xyRangeSteps, config.scale) - 1; + case 'line': + case 'trail': + case 'rule': + return config.scale.maxStrokeWidth; + case 'text': + return config.scale.maxFontSize; + case 'point': + case 'square': + case 'circle': + if (config.scale.maxSize) { + return config.scale.maxSize; + } + // FIXME this case totally should be refactored + var pointStep = minXYRangeStep(xyRangeSteps, scaleConfig); + return (pointStep - 2) * (pointStep - 2); + } + /* istanbul ignore next: should never reach here */ + // sizeRangeMax not implemented for the mark + throw new Error(log.message.incompatibleChannel('size', mark)); +} +/** + * @returns {number} Range step of x or y or minimum between the two if both are ordinal scale. + */ +function minXYRangeStep(xyRangeSteps, scaleConfig) { + if (xyRangeSteps.length > 0) { + return Math.min.apply(null, xyRangeSteps); + } + if (scaleConfig.rangeStep) { + return scaleConfig.rangeStep; + } + return 21; // FIXME: re-evaluate the default value here. +} +//# sourceMappingURL=range.js.map \ No newline at end of file diff --git a/build/src/compile/scale/range.js.map b/build/src/compile/scale/range.js.map new file mode 100644 index 0000000000..57089b7f7b --- /dev/null +++ b/build/src/compile/scale/range.js.map @@ -0,0 +1 @@ +{"version":3,"file":"range.js","sourceRoot":"","sources":["../../../../src/compile/scale/range.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAC;AAEnC,OAAO,EAAU,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAgB,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAC,MAAM,eAAe,CAAC;AAErH,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AAEjC,OAAO,EACL,mCAAmC,EACnC,gBAAgB,EAKhB,wBAAwB,GAEzB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,mBAAmB,EAAC,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,OAAO,EAAC,aAAa,EAAoB,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAC,WAAW,EAAQ,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAW,YAAY,EAAE,YAAY,EAAC,MAAM,UAAU,CAAC;AAG9D,OAAO,EAAC,yBAAyB,EAAC,MAAM,cAAc,CAAC;AAKvD,MAAM,CAAC,IAAM,gBAAgB,GAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;AAGlF,MAAM,0BAA0B,KAAY;IAC1C,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE;QACtB,mBAAmB,CAAC,KAAK,CAAC,CAAC;KAC5B;SAAM;QACL,yBAAyB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;KAC3C;AACH,CAAC;AAED,6BAA6B,KAAgB;IAC3C,IAAM,oBAAoB,GAAwB,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC;IAEzE,gFAAgF;IAChF,cAAc,CAAC,OAAO,CAAC,UAAC,OAAqB;QAC3C,IAAM,cAAc,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,cAAc,EAAE;YACnB,OAAO;SACR;QACD,IAAM,eAAe,GAAG,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAGzD,IAAM,cAAc,GAAG,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QACtD,IAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAEzC,4CAA4C;QAC5C,IAAM,QAAQ,GAAG,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QACpF,IAAI,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEtF,IAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE9C,iDAAiD;QACjD,IAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC;QAC5F,IAAI,QAAQ,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,aAAa,IAAI,SAAS,EAAE;YACxD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;YACrD,aAAa,GAAG,IAAI,CAAC;SACtB;QAED,IAAM,YAAY,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QAE3C,IAAM,iBAAiB,GAAG,oBAAoB,CAC5C,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,MAAM,EAC/D,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,YAAY,CAC7F,CAAC;QAEF,cAAc,CAAC,eAAe,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,wBAAwB,KAAgB;IACtC,IAAM,YAAY,GAAa,EAAE,CAAC;IAElC,IAAM,MAAM,GAAG,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAM,MAAM,GAAG,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAI,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QAC5D,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;KAChC;IAED,IAAM,MAAM,GAAG,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAM,MAAM,GAAG,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAI,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QAC5D,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;KAChC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,+BACF,OAAgB,EAAE,SAAoB,EAAE,IAAU,EAAE,cAAqB,EAAE,MAAc,EACzF,IAAa,EAAE,IAAU,EAAE,aAAsB,EAAE,UAAkB,EAAE,YAAsB;IAG/F,IAAM,WAAW,GAAG,aAAa,IAAI,cAAc,CAAC,SAAS,KAAK,IAAI,CAAC;IAEvE,qDAAqD;IACrD,2FAA2F;IAC3F,KAAuB,UAAgB,EAAhB,qCAAgB,EAAhB,8BAAgB,EAAhB,IAAgB,EAAE;QAApC,IAAM,QAAQ,yBAAA;QACjB,IAAI,cAAc,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE;YAC1C,IAAM,oBAAoB,GAAG,wBAAwB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC3E,IAAM,sBAAsB,GAAG,mCAAmC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACtF,IAAI,CAAC,oBAAoB,EAAE;gBACzB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,iCAAiC,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;aACvF;iBAAM,IAAI,sBAAsB,EAAE,EAAE,UAAU;gBAC7C,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;aAClC;iBAAM;gBACL,QAAQ,QAAQ,EAAE;oBAChB,KAAK,OAAO;wBACV,OAAO,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAChD,KAAK,QAAQ;wBACX,OAAO,YAAY,CAAC,WAAW,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBAC7D,KAAK,WAAW;wBACd,IAAM,SAAS,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;wBAC3C,IAAI,SAAS,KAAK,IAAI,EAAE;4BACtB,IAAI,CAAC,aAAa,EAAE;gCAClB,OAAO,YAAY,CAAC,EAAC,IAAI,EAAE,SAAS,EAAC,CAAC,CAAC;6BACxC;iCAAM;gCACL,iEAAiE;gCACjE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;6BACjD;yBACF;iBACJ;aACF;SACF;KACF;IACD,OAAO,YAAY,CACjB,YAAY,CACV,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAChC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,CAClD,CACF,CAAC;AACJ,CAAC;AAED,qBAAqB,MAAc;IACjC,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE;QAC5B,IAAM,CAAC,GAAa,EAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,KAAK,EAAE;YAChB,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;SACxB;QACD,IAAI,MAAM,CAAC,MAAM,EAAE;YACjB,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;SAC1B;QACD,OAAO,CAAC,CAAC;KACV;IACD,OAAO,EAAC,MAAM,EAAE,MAAM,EAAC,CAAC;AAC1B,CAAC;AAED,MAAM,uBACJ,OAAgB,EAAE,SAAoB,EAAE,IAAU,EAAE,MAAc,EAAE,IAAa,EAAE,IAAU,EAC7F,UAAkB,EAAE,YAAsB,EAAE,WAAoB;IAEhE,QAAQ,OAAO,EAAE;QACf,KAAK,CAAC,CAAC;QACP,KAAK,CAAC;YACJ,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE;gBAC/D,IAAI,OAAO,KAAK,CAAC,IAAI,IAAI,KAAK,MAAM,EAAE;oBACpC,IAAI,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE;wBAC/B,OAAO,EAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,EAAC,CAAC;qBAC5C;iBACF;qBAAM;oBACL,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE;wBAC1B,OAAO,EAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,EAAC,CAAC;qBACvC;iBACF;aACF;YAED,sDAAsD;YACtD,8CAA8C;YAC9C,qCAAqC;YACrC,kGAAkG;YAClG,mDAAmD;YACnD,yCAAyC;YAEzC,IAAI,OAAO,KAAK,CAAC,IAAI,mBAAmB,CAAC,SAAS,CAAC,EAAE;gBACnD,iGAAiG;gBACjG,OAAO,CAAC,EAAC,MAAM,EAAE,UAAU,EAAC,EAAE,CAAC,CAAC,CAAC;aAClC;iBAAM;gBACL,OAAO,CAAC,CAAC,EAAE,EAAC,MAAM,EAAE,UAAU,EAAC,CAAC,CAAC;aAClC;QACH,KAAK,IAAI;YACP,0CAA0C;YAC1C,IAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAClD,IAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;YAC1D,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC9B,KAAK,KAAK;YACR,OAAO,QAAQ,CAAC;QAClB,KAAK,KAAK,CAAC;QACX,KAAK,IAAI,CAAC;QACV,KAAK,MAAM;YACT,IAAI,SAAS,KAAK,SAAS,EAAE;gBAC3B,kDAAkD;gBAClD,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;aACpD;YACD,OAAO,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;QACrE,KAAK,OAAO;YACV,0CAA0C;YAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;KAC7D;IACD,mDAAmD;IACnD,MAAM,IAAI,KAAK,CAAC,uCAAqC,OAAS,CAAC,CAAC;AAClE,CAAC;AAED,sBAAsB,IAAU,EAAE,IAAa,EAAE,MAAc;IAC7D,IAAI,IAAI,EAAE;QACR,OAAO,CAAC,CAAC;KACV;IACD,QAAQ,IAAI,EAAE;QACZ,KAAK,KAAK,CAAC;QACX,KAAK,MAAM;YACT,OAAO,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC;QAClC,KAAK,MAAM,CAAC;QACZ,KAAK,OAAO,CAAC;QACb,KAAK,MAAM;YACT,OAAO,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC;QACrC,KAAK,MAAM;YACT,OAAO,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC;QAClC,KAAK,OAAO,CAAC;QACb,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;KAC/B;IACD,mDAAmD;IACnD,4CAA4C;IAC5C,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,sBAAsB,IAAU,EAAE,YAAsB,EAAE,MAAc;IACtE,IAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;IACjC,QAAQ,IAAI,EAAE;QACZ,KAAK,KAAK,CAAC;QACX,KAAK,MAAM;YACT,IAAI,MAAM,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE;gBAC1C,OAAO,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC;aACjC;YACD,OAAO,cAAc,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxD,KAAK,MAAM,CAAC;QACZ,KAAK,OAAO,CAAC;QACb,KAAK,MAAM;YACT,OAAO,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC;QACrC,KAAK,MAAM;YACT,OAAO,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC;QAClC,KAAK,OAAO,CAAC;QACb,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ;YACX,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;gBACxB,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;aAC7B;YAED,+CAA+C;YAC/C,IAAM,SAAS,GAAG,cAAc,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;YAC5D,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;KAC5C;IACD,mDAAmD;IACnD,4CAA4C;IAC5C,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AACjE,CAAC;AAED;;GAEG;AACH,wBAAwB,YAAsB,EAAE,WAAwB;IACtE,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;KAC3C;IACD,IAAI,WAAW,CAAC,SAAS,EAAE;QACzB,OAAO,WAAW,CAAC,SAAS,CAAC;KAC9B;IACD,OAAO,EAAE,CAAC,CAAC,6CAA6C;AAC1D,CAAC","sourcesContent":["import {isNumber} from 'vega-util';\n\nimport {Channel, COLOR, FILL, OPACITY, SCALE_CHANNELS, ScaleChannel, SHAPE, SIZE, STROKE, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport * as log from '../../log';\nimport {Mark} from '../../mark';\nimport {\n channelScalePropertyIncompatability,\n isExtendedScheme,\n Range,\n Scale,\n ScaleConfig,\n ScaleType,\n scaleTypeSupportProperty,\n Scheme,\n} from '../../scale';\nimport {hasContinuousDomain} from '../../scale';\nimport {Type} from '../../type';\nimport * as util from '../../util';\nimport {isVgRangeStep, VgRange, VgScheme} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {Explicit, makeExplicit, makeImplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {ScaleComponentIndex} from './component';\nimport {parseNonUnitScaleProperty} from './properties';\n\n\nexport type RangeMixins = {range: Range} | {rangeStep: number} | {scheme: Scheme};\n\nexport const RANGE_PROPERTIES: (keyof Scale)[] = ['range', 'rangeStep', 'scheme'];\n\n\nexport function parseScaleRange(model: Model) {\n if (isUnitModel(model)) {\n parseUnitScaleRange(model);\n } else {\n parseNonUnitScaleProperty(model, 'range');\n }\n}\n\nfunction parseUnitScaleRange(model: UnitModel) {\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n // use SCALE_CHANNELS instead of scales[channel] to ensure that x, y come first!\n SCALE_CHANNELS.forEach((channel: ScaleChannel) => {\n const localScaleCmpt = localScaleComponents[channel];\n if (!localScaleCmpt) {\n return;\n }\n const mergedScaleCmpt = model.getScaleComponent(channel);\n\n\n const specifiedScale = model.specifiedScales[channel];\n const fieldDef = model.fieldDef(channel);\n\n // Read if there is a specified width/height\n const sizeType = channel === 'x' ? 'width' : channel === 'y' ? 'height' : undefined;\n let sizeSpecified = sizeType ? !!model.component.layoutSize.get(sizeType) : undefined;\n\n const scaleType = mergedScaleCmpt.get('type');\n\n // if autosize is fit, size cannot be data driven\n const rangeStep = util.contains(['point', 'band'], scaleType) || !!specifiedScale.rangeStep;\n if (sizeType && model.fit && !sizeSpecified && rangeStep) {\n log.warn(log.message.CANNOT_FIX_RANGE_STEP_WITH_FIT);\n sizeSpecified = true;\n }\n\n const xyRangeSteps = getXYRangeStep(model);\n\n const rangeWithExplicit = parseRangeForChannel(\n channel, scaleType, fieldDef.type, specifiedScale, model.config,\n localScaleCmpt.get('zero'), model.mark, sizeSpecified, model.getName(sizeType), xyRangeSteps\n );\n\n localScaleCmpt.setWithExplicit('range', rangeWithExplicit);\n });\n}\n\nfunction getXYRangeStep(model: UnitModel) {\n const xyRangeSteps: number[] = [];\n\n const xScale = model.getScaleComponent('x');\n const xRange = xScale && xScale.get('range');\n if (xRange && isVgRangeStep(xRange) && isNumber(xRange.step)) {\n xyRangeSteps.push(xRange.step);\n }\n\n const yScale = model.getScaleComponent('y');\n const yRange = yScale && yScale.get('range');\n if (yRange && isVgRangeStep(yRange) && isNumber(yRange.step)) {\n xyRangeSteps.push(yRange.step);\n }\n\n return xyRangeSteps;\n}\n\n/**\n * Return mixins that includes one of the range properties (range, rangeStep, scheme).\n */\nexport function parseRangeForChannel(\n channel: Channel, scaleType: ScaleType, type: Type, specifiedScale: Scale, config: Config,\n zero: boolean, mark: Mark, sizeSpecified: boolean, sizeSignal: string, xyRangeSteps: number[]\n ): Explicit {\n\n const noRangeStep = sizeSpecified || specifiedScale.rangeStep === null;\n\n // Check if any of the range properties is specified.\n // If so, check if it is compatible and make sure that we only output one of the properties\n for (const property of RANGE_PROPERTIES) {\n if (specifiedScale[property] !== undefined) {\n const supportedByScaleType = scaleTypeSupportProperty(scaleType, property);\n const channelIncompatability = channelScalePropertyIncompatability(channel, property);\n if (!supportedByScaleType) {\n log.warn(log.message.scalePropertyNotWorkWithScaleType(scaleType, property, channel));\n } else if (channelIncompatability) { // channel\n log.warn(channelIncompatability);\n } else {\n switch (property) {\n case 'range':\n return makeExplicit(specifiedScale[property]);\n case 'scheme':\n return makeExplicit(parseScheme(specifiedScale[property]));\n case 'rangeStep':\n const rangeStep = specifiedScale[property];\n if (rangeStep !== null) {\n if (!sizeSpecified) {\n return makeExplicit({step: rangeStep});\n } else {\n // If top-level size is specified, we ignore specified rangeStep.\n log.warn(log.message.rangeStepDropped(channel));\n }\n }\n }\n }\n }\n }\n return makeImplicit(\n defaultRange(\n channel, scaleType, type, config,\n zero, mark, sizeSignal, xyRangeSteps, noRangeStep\n )\n );\n}\n\nfunction parseScheme(scheme: Scheme) {\n if (isExtendedScheme(scheme)) {\n const r: VgScheme = {scheme: scheme.name};\n if (scheme.count) {\n r.count = scheme.count;\n }\n if (scheme.extent) {\n r.extent = scheme.extent;\n }\n return r;\n }\n return {scheme: scheme};\n}\n\nexport function defaultRange(\n channel: Channel, scaleType: ScaleType, type: Type, config: Config, zero: boolean, mark: Mark,\n sizeSignal: string, xyRangeSteps: number[], noRangeStep: boolean\n): VgRange {\n switch (channel) {\n case X:\n case Y:\n if (util.contains(['point', 'band'], scaleType) && !noRangeStep) {\n if (channel === X && mark === 'text') {\n if (config.scale.textXRangeStep) {\n return {step: config.scale.textXRangeStep};\n }\n } else {\n if (config.scale.rangeStep) {\n return {step: config.scale.rangeStep};\n }\n }\n }\n\n // If range step is null, use zero to width or height.\n // Note that these range signals are temporary\n // as they can be merged and renamed.\n // (We do not have the right size signal here since parseLayoutSize() happens after parseScale().)\n // We will later replace these temporary names with\n // the final name in assembleScaleRange()\n\n if (channel === Y && hasContinuousDomain(scaleType)) {\n // For y continuous scale, we have to start from the height as the bottom part has the max value.\n return [{signal: sizeSignal}, 0];\n } else {\n return [0, {signal: sizeSignal}];\n }\n case SIZE:\n // TODO: support custom rangeMin, rangeMax\n const rangeMin = sizeRangeMin(mark, zero, config);\n const rangeMax = sizeRangeMax(mark, xyRangeSteps, config);\n return [rangeMin, rangeMax];\n case SHAPE:\n return 'symbol';\n case COLOR:\n case FILL:\n case STROKE:\n if (scaleType === 'ordinal') {\n // Only nominal data uses ordinal scale by default\n return type === 'nominal' ? 'category' : 'ordinal';\n }\n return mark === 'rect' || mark === 'geoshape' ? 'heatmap' : 'ramp';\n case OPACITY:\n // TODO: support custom rangeMin, rangeMax\n return [config.scale.minOpacity, config.scale.maxOpacity];\n }\n /* istanbul ignore next: should never reach here */\n throw new Error(`Scale range undefined for channel ${channel}`);\n}\n\nfunction sizeRangeMin(mark: Mark, zero: boolean, config: Config) {\n if (zero) {\n return 0;\n }\n switch (mark) {\n case 'bar':\n case 'tick':\n return config.scale.minBandSize;\n case 'line':\n case 'trail':\n case 'rule':\n return config.scale.minStrokeWidth;\n case 'text':\n return config.scale.minFontSize;\n case 'point':\n case 'square':\n case 'circle':\n return config.scale.minSize;\n }\n /* istanbul ignore next: should never reach here */\n // sizeRangeMin not implemented for the mark\n throw new Error(log.message.incompatibleChannel('size', mark));\n}\n\nfunction sizeRangeMax(mark: Mark, xyRangeSteps: number[], config: Config) {\n const scaleConfig = config.scale;\n switch (mark) {\n case 'bar':\n case 'tick':\n if (config.scale.maxBandSize !== undefined) {\n return config.scale.maxBandSize;\n }\n return minXYRangeStep(xyRangeSteps, config.scale) - 1;\n case 'line':\n case 'trail':\n case 'rule':\n return config.scale.maxStrokeWidth;\n case 'text':\n return config.scale.maxFontSize;\n case 'point':\n case 'square':\n case 'circle':\n if (config.scale.maxSize) {\n return config.scale.maxSize;\n }\n\n // FIXME this case totally should be refactored\n const pointStep = minXYRangeStep(xyRangeSteps, scaleConfig);\n return (pointStep - 2) * (pointStep - 2);\n }\n /* istanbul ignore next: should never reach here */\n // sizeRangeMax not implemented for the mark\n throw new Error(log.message.incompatibleChannel('size', mark));\n}\n\n/**\n * @returns {number} Range step of x or y or minimum between the two if both are ordinal scale.\n */\nfunction minXYRangeStep(xyRangeSteps: number[], scaleConfig: ScaleConfig): number {\n if (xyRangeSteps.length > 0) {\n return Math.min.apply(null, xyRangeSteps);\n }\n if (scaleConfig.rangeStep) {\n return scaleConfig.rangeStep;\n }\n return 21; // FIXME: re-evaluate the default value here.\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/scale/type.d.ts b/build/src/compile/scale/type.d.ts new file mode 100644 index 0000000000..b6e317d975 --- /dev/null +++ b/build/src/compile/scale/type.d.ts @@ -0,0 +1,10 @@ +import { Channel } from '../../channel'; +import { FieldDef } from '../../fielddef'; +import { Mark } from '../../mark'; +import { ScaleConfig, ScaleType } from '../../scale'; +export declare type RangeType = 'continuous' | 'discrete' | 'flexible' | undefined; +/** + * Determine if there is a specified scale type and if it is appropriate, + * or determine default type if type is unspecified or inappropriate. + */ +export declare function scaleType(specifiedType: ScaleType, channel: Channel, fieldDef: FieldDef, mark: Mark, scaleConfig: ScaleConfig): ScaleType; diff --git a/build/src/compile/scale/type.js b/build/src/compile/scale/type.js new file mode 100644 index 0000000000..8a8a1e8e85 --- /dev/null +++ b/build/src/compile/scale/type.js @@ -0,0 +1,95 @@ +import { isColorChannel, isScaleChannel, rangeType } from '../../channel'; +import * as log from '../../log'; +import { channelSupportScaleType, scaleTypeSupportDataType } from '../../scale'; +import * as util from '../../util'; +/** + * Determine if there is a specified scale type and if it is appropriate, + * or determine default type if type is unspecified or inappropriate. + */ +// NOTE: CompassQL uses this method. +export function scaleType(specifiedType, channel, fieldDef, mark, scaleConfig) { + var defaultScaleType = defaultType(channel, fieldDef, mark, scaleConfig); + if (!isScaleChannel(channel)) { + // There is no scale for these channels + return null; + } + if (specifiedType !== undefined) { + // Check if explicitly specified scale type is supported by the channel + if (!channelSupportScaleType(channel, specifiedType)) { + log.warn(log.message.scaleTypeNotWorkWithChannel(channel, specifiedType, defaultScaleType)); + return defaultScaleType; + } + // Check if explicitly specified scale type is supported by the data type + if (!scaleTypeSupportDataType(specifiedType, fieldDef.type, fieldDef.bin)) { + log.warn(log.message.scaleTypeNotWorkWithFieldDef(specifiedType, defaultScaleType)); + return defaultScaleType; + } + return specifiedType; + } + return defaultScaleType; +} +/** + * Determine appropriate default scale type. + */ +// NOTE: Voyager uses this method. +function defaultType(channel, fieldDef, mark, scaleConfig) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + if (isColorChannel(channel) || rangeType(channel) === 'discrete') { + if (channel === 'shape' && fieldDef.type === 'ordinal') { + log.warn(log.message.discreteChannelCannotEncode(channel, 'ordinal')); + } + return 'ordinal'; + } + if (util.contains(['x', 'y'], channel)) { + if (util.contains(['rect', 'bar', 'rule'], mark)) { + // The rect/bar mark should fit into a band. + // For rule, using band scale to make rule align with axis ticks better https://github.com/vega/vega-lite/issues/3429 + return 'band'; + } + if (mark === 'bar') { + return 'band'; + } + } + // Otherwise, use ordinal point scale so we can easily get center positions of the marks. + return 'point'; + case 'temporal': + if (isColorChannel(channel)) { + return 'sequential'; + } + else if (rangeType(channel) === 'discrete') { + log.warn(log.message.discreteChannelCannotEncode(channel, 'temporal')); + // TODO: consider using quantize (equivalent to binning) once we have it + return 'ordinal'; + } + return 'time'; + case 'quantitative': + if (isColorChannel(channel)) { + if (fieldDef.bin) { + return 'bin-ordinal'; + } + // Use `sequential` as the default color scale for continuous data + // since it supports both array range and scheme range. + return 'sequential'; + } + else if (rangeType(channel) === 'discrete') { + log.warn(log.message.discreteChannelCannotEncode(channel, 'quantitative')); + // TODO: consider using quantize (equivalent to binning) once we have it + return 'ordinal'; + } + // x and y use a linear scale because selections don't work with bin scales. + // Binned scales apply discretization but pan/zoom apply transformations to a [min, max] extent domain. + if (fieldDef.bin && channel !== 'x' && channel !== 'y') { + return 'bin-linear'; + } + return 'linear'; + case 'latitude': + case 'longitude': + case 'geojson': + return undefined; + } + /* istanbul ignore next: should never reach this */ + throw new Error(log.message.invalidFieldType(fieldDef.type)); +} +//# sourceMappingURL=type.js.map \ No newline at end of file diff --git a/build/src/compile/scale/type.js.map b/build/src/compile/scale/type.js.map new file mode 100644 index 0000000000..f8cb2baf7a --- /dev/null +++ b/build/src/compile/scale/type.js.map @@ -0,0 +1 @@ +{"version":3,"file":"type.js","sourceRoot":"","sources":["../../../../src/compile/scale/type.ts"],"names":[],"mappings":"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","sourcesContent":["import {Channel, isColorChannel, isScaleChannel, rangeType} from '../../channel';\nimport {FieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {Mark} from '../../mark';\nimport {channelSupportScaleType, ScaleConfig, ScaleType, scaleTypeSupportDataType} from '../../scale';\nimport * as util from '../../util';\n\nexport type RangeType = 'continuous' | 'discrete' | 'flexible' | undefined;\n\n/**\n * Determine if there is a specified scale type and if it is appropriate,\n * or determine default type if type is unspecified or inappropriate.\n */\n// NOTE: CompassQL uses this method.\nexport function scaleType(\n specifiedType: ScaleType, channel: Channel, fieldDef: FieldDef,\n mark: Mark, scaleConfig: ScaleConfig\n): ScaleType {\n\n const defaultScaleType = defaultType(channel, fieldDef, mark, scaleConfig);\n\n if (!isScaleChannel(channel)) {\n // There is no scale for these channels\n return null;\n }\n if (specifiedType !== undefined) {\n // Check if explicitly specified scale type is supported by the channel\n if (!channelSupportScaleType(channel, specifiedType)) {\n log.warn(log.message.scaleTypeNotWorkWithChannel(channel, specifiedType, defaultScaleType));\n return defaultScaleType;\n }\n\n // Check if explicitly specified scale type is supported by the data type\n if (!scaleTypeSupportDataType(specifiedType, fieldDef.type, fieldDef.bin)) {\n log.warn(log.message.scaleTypeNotWorkWithFieldDef(specifiedType, defaultScaleType));\n return defaultScaleType;\n }\n\n return specifiedType;\n }\n\n return defaultScaleType;\n}\n\n/**\n * Determine appropriate default scale type.\n */\n// NOTE: Voyager uses this method.\nfunction defaultType(\n channel: Channel, fieldDef: FieldDef, mark: Mark, scaleConfig: ScaleConfig\n): ScaleType {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n if (isColorChannel(channel)|| rangeType(channel) === 'discrete') {\n if (channel === 'shape' && fieldDef.type === 'ordinal') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'ordinal'));\n }\n return 'ordinal';\n }\n\n if (util.contains(['x', 'y'], channel)) {\n if (util.contains(['rect', 'bar', 'rule'], mark)) {\n // The rect/bar mark should fit into a band.\n // For rule, using band scale to make rule align with axis ticks better https://github.com/vega/vega-lite/issues/3429\n return 'band';\n }\n if (mark === 'bar') {\n return 'band';\n }\n }\n // Otherwise, use ordinal point scale so we can easily get center positions of the marks.\n return 'point';\n\n case 'temporal':\n if (isColorChannel(channel)) {\n return 'sequential';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'temporal'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n return 'time';\n\n case 'quantitative':\n if (isColorChannel(channel)) {\n if (fieldDef.bin) {\n return 'bin-ordinal';\n }\n // Use `sequential` as the default color scale for continuous data\n // since it supports both array range and scheme range.\n return 'sequential';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'quantitative'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n\n // x and y use a linear scale because selections don't work with bin scales.\n // Binned scales apply discretization but pan/zoom apply transformations to a [min, max] extent domain.\n if (fieldDef.bin && channel !== 'x' && channel !== 'y') {\n return 'bin-linear';\n }\n return 'linear';\n\n case 'latitude':\n case 'longitude':\n case 'geojson':\n return undefined;\n }\n\n /* istanbul ignore next: should never reach this */\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/interval.d.ts b/build/src/compile/selection/interval.d.ts new file mode 100644 index 0000000000..291c4dc4b5 --- /dev/null +++ b/build/src/compile/selection/interval.d.ts @@ -0,0 +1,5 @@ +import { SelectionCompiler } from './selection'; +export declare const BRUSH = "_brush"; +export declare const SCALE_TRIGGER = "_scale_trigger"; +declare const interval: SelectionCompiler; +export default interval; diff --git a/build/src/compile/selection/interval.js b/build/src/compile/selection/interval.js new file mode 100644 index 0000000000..ca53893509 --- /dev/null +++ b/build/src/compile/selection/interval.js @@ -0,0 +1,184 @@ +import * as tslib_1 from "tslib"; +import { stringValue } from 'vega-util'; +import { X, Y } from '../../channel'; +import { warn } from '../../log'; +import { hasContinuousDomain, isBinScale } from '../../scale'; +import { keys } from '../../util'; +import { channelSignalName, positionalProjections, STORE, TUPLE, unitName, } from './selection'; +import scales from './transforms/scales'; +export var BRUSH = '_brush'; +export var SCALE_TRIGGER = '_scale_trigger'; +var interval = { + predicate: 'vlInterval', + scaleDomain: 'vlIntervalDomain', + signals: function (model, selCmpt) { + var name = selCmpt.name; + var hasScales = scales.has(selCmpt); + var signals = []; + var intervals = []; + var tupleTriggers = []; + var scaleTriggers = []; + if (selCmpt.translate && !hasScales) { + var filterExpr_1 = "!event.item || event.item.mark.name !== " + stringValue(name + BRUSH); + events(selCmpt, function (_, evt) { + var filters = evt.between[0].filter || (evt.between[0].filter = []); + if (filters.indexOf(filterExpr_1) < 0) { + filters.push(filterExpr_1); + } + }); + } + selCmpt.project.forEach(function (p) { + var channel = p.channel; + if (channel !== X && channel !== Y) { + warn('Interval selections only support x and y encoding channels.'); + return; + } + var cs = channelSignals(model, selCmpt, channel); + var dname = channelSignalName(selCmpt, channel, 'data'); + var vname = channelSignalName(selCmpt, channel, 'visual'); + var scaleStr = stringValue(model.scaleName(channel)); + var scaleType = model.getScaleComponent(channel).get('type'); + var toNum = hasContinuousDomain(scaleType) ? '+' : ''; + signals.push.apply(signals, cs); + tupleTriggers.push(dname); + intervals.push("{encoding: " + stringValue(channel) + ", " + + ("field: " + stringValue(p.field) + ", extent: " + dname + "}")); + scaleTriggers.push({ + scaleName: model.scaleName(channel), + expr: "(!isArray(" + dname + ") || " + + ("(" + toNum + "invert(" + scaleStr + ", " + vname + ")[0] === " + toNum + dname + "[0] && ") + + (toNum + "invert(" + scaleStr + ", " + vname + ")[1] === " + toNum + dname + "[1]))") + }); + }); + // Proxy scale reactions to ensure that an infinite loop doesn't occur + // when an interval selection filter touches the scale. + if (!hasScales) { + signals.push({ + name: name + SCALE_TRIGGER, + update: scaleTriggers.map(function (t) { return t.expr; }).join(' && ') + + (" ? " + (name + SCALE_TRIGGER) + " : {}") + }); + } + // Only add an interval to the store if it has valid data extents. Data extents + // are set to null if pixel extents are equal to account for intervals over + // ordinal/nominal domains which, when inverted, will still produce a valid datum. + return signals.concat({ + name: name + TUPLE, + on: [{ + events: tupleTriggers.map(function (t) { return ({ signal: t }); }), + update: tupleTriggers.join(' && ') + + (" ? {unit: " + unitName(model) + ", intervals: [" + intervals.join(', ') + "]} : null") + }] + }); + }, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'true' : "{unit: " + unitName(model) + "}"); + }, + marks: function (model, selCmpt, marks) { + var name = selCmpt.name; + var _a = positionalProjections(selCmpt), xi = _a.xi, yi = _a.yi; + var store = "data(" + stringValue(selCmpt.name + STORE) + ")"; + // Do not add a brush if we're binding to scales. + if (scales.has(selCmpt)) { + return marks; + } + var update = { + x: xi !== null ? { signal: name + "_x[0]" } : { value: 0 }, + y: yi !== null ? { signal: name + "_y[0]" } : { value: 0 }, + x2: xi !== null ? { signal: name + "_x[1]" } : { field: { group: 'width' } }, + y2: yi !== null ? { signal: name + "_y[1]" } : { field: { group: 'height' } } + }; + // If the selection is resolved to global, only a single interval is in + // the store. Wrap brush mark's encodings with a production rule to test + // this based on the `unit` property. Hide the brush mark if it corresponds + // to a unit different from the one in the store. + if (selCmpt.resolve === 'global') { + for (var _i = 0, _b = keys(update); _i < _b.length; _i++) { + var key = _b[_i]; + update[key] = [tslib_1.__assign({ test: store + ".length && " + store + "[0].unit === " + unitName(model) }, update[key]), { value: 0 }]; + } + } + // Two brush marks ensure that fill colors and other aesthetic choices do + // not interefere with the core marks, but that the brushed region can still + // be interacted with (e.g., dragging it around). + var _c = selCmpt.mark, fill = _c.fill, fillOpacity = _c.fillOpacity, stroke = tslib_1.__rest(_c, ["fill", "fillOpacity"]); + var vgStroke = keys(stroke).reduce(function (def, k) { + def[k] = [{ + test: [ + xi !== null && name + "_x[0] !== " + name + "_x[1]", + yi != null && name + "_y[0] !== " + name + "_y[1]", + ].filter(function (x) { return x; }).join(' && '), + value: stroke[k] + }, { value: null }]; + return def; + }, {}); + return [{ + name: name + BRUSH + '_bg', + type: 'rect', + clip: true, + encode: { + enter: { + fill: { value: fill }, + fillOpacity: { value: fillOpacity } + }, + update: update + } + }].concat(marks, { + name: name + BRUSH, + type: 'rect', + clip: true, + encode: { + enter: { + fill: { value: 'transparent' } + }, + update: tslib_1.__assign({}, update, vgStroke) + } + }); + } +}; +export default interval; +/** + * Returns the visual and data signals for an interval selection. + */ +function channelSignals(model, selCmpt, channel) { + var vname = channelSignalName(selCmpt, channel, 'visual'); + var dname = channelSignalName(selCmpt, channel, 'data'); + var hasScales = scales.has(selCmpt); + var scaleName = model.scaleName(channel); + var scaleStr = stringValue(scaleName); + var scale = model.getScaleComponent(channel); + var scaleType = scale ? scale.get('type') : undefined; + var size = model.getSizeSignalRef(channel === X ? 'width' : 'height').signal; + var coord = channel + "(unit)"; + var on = events(selCmpt, function (def, evt) { + return def.concat({ events: evt.between[0], update: "[" + coord + ", " + coord + "]" }, // Brush Start + { events: evt, update: "[" + vname + "[0], clamp(" + coord + ", 0, " + size + ")]" } // Brush End + ); + }); + // React to pan/zooms of continuous scales. Non-continuous scales + // (bin-linear, band, point) cannot be pan/zoomed and any other changes + // to their domains (e.g., filtering) should clear the brushes. + on.push({ + events: { signal: selCmpt.name + SCALE_TRIGGER }, + update: hasContinuousDomain(scaleType) && !isBinScale(scaleType) ? + "[scale(" + scaleStr + ", " + dname + "[0]), scale(" + scaleStr + ", " + dname + "[1])]" : "[0, 0]" + }); + return hasScales ? [{ name: dname, on: [] }] : [{ + name: vname, value: [], on: on + }, { + name: dname, + on: [{ events: { signal: vname }, update: vname + "[0] === " + vname + "[1] ? null : invert(" + scaleStr + ", " + vname + ")" }] + }]; +} +function events(selCmpt, cb) { + return selCmpt.events.reduce(function (on, evt) { + if (!evt.between) { + warn(evt + " is not an ordered event stream for interval selections"); + return on; + } + return cb(on, evt); + }, []); +} +//# sourceMappingURL=interval.js.map \ No newline at end of file diff --git a/build/src/compile/selection/interval.js.map b/build/src/compile/selection/interval.js.map new file mode 100644 index 0000000000..a5e2178e2a --- /dev/null +++ b/build/src/compile/selection/interval.js.map @@ -0,0 +1 @@ +{"version":3,"file":"interval.js","sourceRoot":"","sources":["../../../../src/compile/selection/interval.ts"],"names":[],"mappings":"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","sourcesContent":["import {stringValue} from 'vega-util';\nimport {X, Y} from '../../channel';\nimport {warn} from '../../log';\nimport {hasContinuousDomain, isBinScale} from '../../scale';\nimport {keys} from '../../util';\nimport {VgEventStream} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {\n channelSignalName,\n positionalProjections,\n SelectionCompiler,\n SelectionComponent,\n STORE,\n TUPLE,\n unitName,\n} from './selection';\nimport scales from './transforms/scales';\n\nexport const BRUSH = '_brush';\nexport const SCALE_TRIGGER = '_scale_trigger';\n\nconst interval:SelectionCompiler = {\n predicate: 'vlInterval',\n scaleDomain: 'vlIntervalDomain',\n\n signals: function(model, selCmpt) {\n const name = selCmpt.name;\n const hasScales = scales.has(selCmpt);\n const signals: any[] = [];\n const intervals: any[] = [];\n const tupleTriggers: string[] = [];\n const scaleTriggers: any[] = [];\n\n if (selCmpt.translate && !hasScales) {\n const filterExpr = `!event.item || event.item.mark.name !== ${stringValue(name + BRUSH)}`;\n events(selCmpt, function(_: any[], evt: VgEventStream) {\n const filters = evt.between[0].filter || (evt.between[0].filter = []);\n if (filters.indexOf(filterExpr) < 0) {\n filters.push(filterExpr);\n }\n });\n }\n\n selCmpt.project.forEach(function(p) {\n const channel = p.channel;\n if (channel !== X && channel !== Y) {\n warn('Interval selections only support x and y encoding channels.');\n return;\n }\n\n const cs = channelSignals(model, selCmpt, channel);\n const dname = channelSignalName(selCmpt, channel, 'data');\n const vname = channelSignalName(selCmpt, channel, 'visual');\n const scaleStr = stringValue(model.scaleName(channel));\n const scaleType = model.getScaleComponent(channel).get('type');\n const toNum = hasContinuousDomain(scaleType) ? '+' : '';\n\n signals.push.apply(signals, cs);\n tupleTriggers.push(dname);\n intervals.push(`{encoding: ${stringValue(channel)}, ` +\n `field: ${stringValue(p.field)}, extent: ${dname}}`);\n\n scaleTriggers.push({\n scaleName: model.scaleName(channel),\n expr: `(!isArray(${dname}) || ` +\n `(${toNum}invert(${scaleStr}, ${vname})[0] === ${toNum}${dname}[0] && ` +\n `${toNum}invert(${scaleStr}, ${vname})[1] === ${toNum}${dname}[1]))`\n });\n });\n\n // Proxy scale reactions to ensure that an infinite loop doesn't occur\n // when an interval selection filter touches the scale.\n if (!hasScales) {\n signals.push({\n name: name + SCALE_TRIGGER,\n update: scaleTriggers.map((t) => t.expr).join(' && ') +\n ` ? ${name + SCALE_TRIGGER} : {}`\n });\n }\n\n // Only add an interval to the store if it has valid data extents. Data extents\n // are set to null if pixel extents are equal to account for intervals over\n // ordinal/nominal domains which, when inverted, will still produce a valid datum.\n return signals.concat({\n name: name + TUPLE,\n on: [{\n events: tupleTriggers.map((t) => ({signal: t})),\n update: tupleTriggers.join(' && ') +\n ` ? {unit: ${unitName(model)}, intervals: [${intervals.join(', ')}]} : null`\n }]\n });\n },\n\n modifyExpr: function(model, selCmpt) {\n const tpl = selCmpt.name + TUPLE;\n return tpl + ', ' +\n (selCmpt.resolve === 'global' ? 'true' : `{unit: ${unitName(model)}}`);\n },\n\n marks: function(model, selCmpt, marks) {\n const name = selCmpt.name;\n const {xi, yi} = positionalProjections(selCmpt);\n const store = `data(${stringValue(selCmpt.name + STORE)})`;\n\n // Do not add a brush if we're binding to scales.\n if (scales.has(selCmpt)) {\n return marks;\n }\n\n const update: any = {\n x: xi !== null ? {signal: `${name}_x[0]`} : {value: 0},\n y: yi !== null ? {signal: `${name}_y[0]`} : {value: 0},\n x2: xi !== null ? {signal: `${name}_x[1]`} : {field: {group: 'width'}},\n y2: yi !== null ? {signal: `${name}_y[1]`} : {field: {group: 'height'}}\n };\n\n // If the selection is resolved to global, only a single interval is in\n // the store. Wrap brush mark's encodings with a production rule to test\n // this based on the `unit` property. Hide the brush mark if it corresponds\n // to a unit different from the one in the store.\n if (selCmpt.resolve === 'global') {\n for (const key of keys(update)) {\n update[key] = [{\n test: `${store}.length && ${store}[0].unit === ${unitName(model)}`,\n ...update[key]\n }, {value: 0}];\n }\n }\n\n // Two brush marks ensure that fill colors and other aesthetic choices do\n // not interefere with the core marks, but that the brushed region can still\n // be interacted with (e.g., dragging it around).\n const {fill, fillOpacity, ...stroke} = selCmpt.mark;\n const vgStroke = keys(stroke).reduce((def, k) => {\n def[k] = [{\n test: [\n xi !== null && `${name}_x[0] !== ${name}_x[1]`,\n yi != null && `${name}_y[0] !== ${name}_y[1]`,\n ].filter(x => x).join(' && '),\n value: stroke[k]\n }, {value: null}];\n return def;\n }, {});\n\n return [{\n name: name + BRUSH + '_bg',\n type: 'rect',\n clip: true,\n encode: {\n enter: {\n fill: {value: fill},\n fillOpacity: {value: fillOpacity}\n },\n update: update\n }\n } as any].concat(marks, {\n name: name + BRUSH,\n type: 'rect',\n clip: true,\n encode: {\n enter: {\n fill: {value: 'transparent'}\n },\n update: {...update, ...vgStroke}\n }\n });\n }\n};\nexport default interval;\n\n/**\n * Returns the visual and data signals for an interval selection.\n */\nfunction channelSignals(model: UnitModel, selCmpt: SelectionComponent, channel: 'x'|'y'): any {\n const vname = channelSignalName(selCmpt, channel, 'visual');\n const dname = channelSignalName(selCmpt, channel, 'data');\n const hasScales = scales.has(selCmpt);\n const scaleName = model.scaleName(channel);\n const scaleStr = stringValue(scaleName);\n const scale = model.getScaleComponent(channel);\n const scaleType = scale ? scale.get('type') : undefined;\n const size = model.getSizeSignalRef(channel === X ? 'width' : 'height').signal;\n const coord = `${channel}(unit)`;\n\n const on = events(selCmpt, function(def: any[], evt: VgEventStream) {\n return def.concat(\n {events: evt.between[0], update: `[${coord}, ${coord}]`}, // Brush Start\n {events: evt, update: `[${vname}[0], clamp(${coord}, 0, ${size})]`} // Brush End\n );\n });\n\n // React to pan/zooms of continuous scales. Non-continuous scales\n // (bin-linear, band, point) cannot be pan/zoomed and any other changes\n // to their domains (e.g., filtering) should clear the brushes.\n on.push({\n events: {signal: selCmpt.name + SCALE_TRIGGER},\n update: hasContinuousDomain(scaleType) && !isBinScale(scaleType) ?\n `[scale(${scaleStr}, ${dname}[0]), scale(${scaleStr}, ${dname}[1])]` : `[0, 0]`\n });\n\n return hasScales ? [{name: dname, on: []}] : [{\n name: vname, value: [], on: on\n }, {\n name: dname,\n on: [{events: {signal: vname}, update: `${vname}[0] === ${vname}[1] ? null : invert(${scaleStr}, ${vname})`}]\n }];\n}\n\nfunction events(selCmpt: SelectionComponent, cb: Function) {\n return selCmpt.events.reduce(function(on: any[], evt: VgEventStream) {\n if (!evt.between) {\n warn(`${evt} is not an ordered event stream for interval selections`);\n return on;\n }\n return cb(on, evt);\n }, []);\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/multi.d.ts b/build/src/compile/selection/multi.d.ts new file mode 100644 index 0000000000..d504dacddc --- /dev/null +++ b/build/src/compile/selection/multi.d.ts @@ -0,0 +1,13 @@ +import { UnitModel } from '../unit'; +import { SelectionCompiler, SelectionComponent } from './selection'; +export declare function signals(model: UnitModel, selCmpt: SelectionComponent): { + name: string; + value: {}; + on: { + events: any; + update: string; + force: boolean; + }[]; +}[]; +declare const multi: SelectionCompiler; +export default multi; diff --git a/build/src/compile/selection/multi.js b/build/src/compile/selection/multi.js new file mode 100644 index 0000000000..bc4ac1320f --- /dev/null +++ b/build/src/compile/selection/multi.js @@ -0,0 +1,53 @@ +import { stringValue } from 'vega-util'; +import { accessPathWithDatum } from '../../util'; +import { TUPLE, unitName } from './selection'; +import nearest from './transforms/nearest'; +export function signals(model, selCmpt) { + var proj = selCmpt.project; + var datum = nearest.has(selCmpt) ? + '(item().isVoronoi ? datum.datum : datum)' : 'datum'; + var bins = []; + var encodings = proj.map(function (p) { return stringValue(p.channel); }).filter(function (e) { return e; }).join(', '); + var fields = proj.map(function (p) { return stringValue(p.field); }).join(', '); + var values = proj.map(function (p) { + var channel = p.channel; + var fieldDef = model.fieldDef(channel); + // Binned fields should capture extents, for a range test against the raw field. + return (fieldDef && fieldDef.bin) ? (bins.push(p.field), + "[" + accessPathWithDatum(model.vgField(channel, {}), datum) + ", " + + (accessPathWithDatum(model.vgField(channel, { binSuffix: 'end' }), datum) + "]")) : + "" + accessPathWithDatum(p.field, datum); + }).join(', '); + // Only add a discrete selection to the store if a datum is present _and_ + // the interaction isn't occurring on a group mark. This guards against + // polluting interactive state with invalid values in faceted displays + // as the group marks are also data-driven. We force the update to account + // for constant null states but varying toggles (e.g., shift-click in + // whitespace followed by a click in whitespace; the store should only + // be cleared on the second click). + return [{ + name: selCmpt.name + TUPLE, + value: {}, + on: [{ + events: selCmpt.events, + update: "datum && item().mark.marktype !== 'group' ? " + + ("{unit: " + unitName(model) + ", encodings: [" + encodings + "], ") + + ("fields: [" + fields + "], values: [" + values + "]") + + (bins.length ? ', ' + bins.map(function (b) { return stringValue('bin_' + b) + ": 1"; }).join(', ') : '') + + '} : null', + force: true + }] + }]; +} +var multi = { + predicate: 'vlMulti', + scaleDomain: 'vlMultiDomain', + signals: signals, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'null' : "{unit: " + unitName(model) + "}"); + } +}; +export default multi; +//# sourceMappingURL=multi.js.map \ No newline at end of file diff --git a/build/src/compile/selection/multi.js.map b/build/src/compile/selection/multi.js.map new file mode 100644 index 0000000000..4756070fe3 --- /dev/null +++ b/build/src/compile/selection/multi.js.map @@ -0,0 +1 @@ +{"version":3,"file":"multi.js","sourceRoot":"","sources":["../../../../src/compile/selection/multi.ts"],"names":[],"mappings":"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","sourcesContent":["import {stringValue} from 'vega-util';\n\nimport {accessPathWithDatum} from '../../util';\nimport {UnitModel} from '../unit';\nimport {SelectionCompiler, SelectionComponent, TUPLE, unitName} from './selection';\nimport nearest from './transforms/nearest';\n\nexport function signals(model: UnitModel, selCmpt: SelectionComponent) {\n const proj = selCmpt.project;\n const datum = nearest.has(selCmpt) ?\n '(item().isVoronoi ? datum.datum : datum)' : 'datum';\n const bins: string[] = [];\n const encodings = proj.map((p) => stringValue(p.channel)).filter((e) => e).join(', ');\n const fields = proj.map((p) => stringValue(p.field)).join(', ');\n const values = proj.map((p) => {\n const channel = p.channel;\n const fieldDef = model.fieldDef(channel);\n // Binned fields should capture extents, for a range test against the raw field.\n return (fieldDef && fieldDef.bin) ? (bins.push(p.field),\n `[${accessPathWithDatum(model.vgField(channel, {}), datum)}, ` +\n `${accessPathWithDatum(model.vgField(channel, {binSuffix: 'end'}), datum)}]`) :\n `${accessPathWithDatum(p.field, datum)}`;\n }).join(', ');\n\n // Only add a discrete selection to the store if a datum is present _and_\n // the interaction isn't occurring on a group mark. This guards against\n // polluting interactive state with invalid values in faceted displays\n // as the group marks are also data-driven. We force the update to account\n // for constant null states but varying toggles (e.g., shift-click in\n // whitespace followed by a click in whitespace; the store should only\n // be cleared on the second click).\n return [{\n name: selCmpt.name + TUPLE,\n value: {},\n on: [{\n events: selCmpt.events,\n update: `datum && item().mark.marktype !== 'group' ? ` +\n `{unit: ${unitName(model)}, encodings: [${encodings}], ` +\n `fields: [${fields}], values: [${values}]` +\n (bins.length ? ', ' + bins.map((b) => `${stringValue('bin_' + b)}: 1`).join(', ') : '') +\n '} : null',\n force: true\n }]\n }];\n}\n\nconst multi:SelectionCompiler = {\n predicate: 'vlMulti',\n scaleDomain: 'vlMultiDomain',\n\n signals: signals,\n\n modifyExpr: function(model, selCmpt) {\n const tpl = selCmpt.name + TUPLE;\n return tpl + ', ' +\n (selCmpt.resolve === 'global' ? 'null' : `{unit: ${unitName(model)}}`);\n }\n};\n\nexport default multi;\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/selection.d.ts b/build/src/compile/selection/selection.d.ts new file mode 100644 index 0000000000..8cd4167e1d --- /dev/null +++ b/build/src/compile/selection/selection.d.ts @@ -0,0 +1,65 @@ +import { Channel, ScaleChannel } from '../../channel'; +import { LogicalOperand } from '../../logical'; +import { BrushConfig, SelectionDef, SelectionResolution, SelectionType } from '../../selection'; +import { Dict } from '../../util'; +import { VgBinding, VgData, VgEventStream, VgSignalRef } from '../../vega.schema'; +import { DataFlowNode } from '../data/dataflow'; +import { TimeUnitNode } from '../data/timeunit'; +import { LayerModel } from '../layer'; +import { Model } from '../model'; +import { UnitModel } from '../unit'; +import { SelectionComponent } from './selection'; +export declare const STORE = "_store"; +export declare const TUPLE = "_tuple"; +export declare const MODIFY = "_modify"; +export declare const SELECTION_DOMAIN = "_selection_domain_"; +export interface SelectionComponent { + name: string; + type: SelectionType; + events: VgEventStream; + bind?: 'scales' | VgBinding | { + [key: string]: VgBinding; + }; + resolve: SelectionResolution; + empty: 'all' | 'none'; + mark?: BrushConfig; + _signalNames: {}; + project?: ProjectComponent[]; + fields?: any; + timeUnit?: TimeUnitNode; + scales?: Channel[]; + toggle?: any; + translate?: any; + zoom?: any; + nearest?: any; +} +export interface ProjectComponent { + field?: string; + channel?: ScaleChannel; +} +export interface SelectionCompiler { + signals: (model: UnitModel, selCmpt: SelectionComponent) => any[]; + topLevelSignals?: (model: Model, selCmpt: SelectionComponent, signals: any[]) => any[]; + modifyExpr: (model: UnitModel, selCmpt: SelectionComponent) => string; + marks?: (model: UnitModel, selCmpt: SelectionComponent, marks: any[]) => any[]; + predicate: string; + scaleDomain: string; +} +export declare function parseUnitSelection(model: UnitModel, selDefs: Dict): Dict; +export declare function assembleUnitSelectionSignals(model: UnitModel, signals: any[]): any[]; +export declare function assembleTopLevelSignals(model: UnitModel, signals: any[]): any[]; +export declare function assembleUnitSelectionData(model: UnitModel, data: VgData[]): VgData[]; +export declare function assembleUnitSelectionMarks(model: UnitModel, marks: any[]): any[]; +export declare function assembleLayerSelectionMarks(model: LayerModel, marks: any[]): any[]; +export declare function selectionPredicate(model: Model, selections: LogicalOperand, dfnode?: DataFlowNode): string; +export declare function isRawSelectionDomain(domainRaw: VgSignalRef): boolean; +export declare function selectionScaleDomain(model: Model, domainRaw: VgSignalRef): VgSignalRef; +export declare function unitName(model: Model): string; +export declare function requiresSelectionId(model: Model): boolean; +export declare function channelSignalName(selCmpt: SelectionComponent, channel: Channel, range: 'visual' | 'data'): any; +export declare function positionalProjections(selCmpt: SelectionComponent): { + x: ProjectComponent; + xi: number; + y: ProjectComponent; + yi: number; +}; diff --git a/build/src/compile/selection/selection.js b/build/src/compile/selection/selection.js new file mode 100644 index 0000000000..9a18ae70eb --- /dev/null +++ b/build/src/compile/selection/selection.js @@ -0,0 +1,283 @@ +import * as tslib_1 from "tslib"; +import { selector as parseSelector } from 'vega-event-selector'; +import { isString, stringValue } from 'vega-util'; +import { X, Y } from '../../channel'; +import { warn } from '../../log'; +import { SELECTION_ID } from '../../selection'; +import { accessPathWithDatum, logicalExpr, varName } from '../../util'; +import { isFacetModel, isUnitModel } from '../model'; +import intervalCompiler from './interval'; +import multiCompiler from './multi'; +import singleCompiler from './single'; +import { forEachTransform } from './transforms/transforms'; +export var STORE = '_store'; +export var TUPLE = '_tuple'; +export var MODIFY = '_modify'; +export var SELECTION_DOMAIN = '_selection_domain_'; +export function parseUnitSelection(model, selDefs) { + var selCmpts = {}; + var selectionConfig = model.config.selection; + var _loop_1 = function (name_1) { + if (!selDefs.hasOwnProperty(name_1)) { + return "continue"; + } + var selDef = selDefs[name_1]; + var cfg = selectionConfig[selDef.type]; + // Set default values from config if a property hasn't been specified, + // or if it is true. E.g., "translate": true should use the default + // event handlers for translate. However, true may be a valid value for + // a property (e.g., "nearest": true). + for (var key in cfg) { + // A selection should contain either `encodings` or `fields`, only use + // default values for these two values if neither of them is specified. + if ((key === 'encodings' && selDef.fields) || (key === 'fields' && selDef.encodings)) { + continue; + } + if (key === 'mark') { + selDef[key] = tslib_1.__assign({}, cfg[key], selDef[key]); + } + if (selDef[key] === undefined || selDef[key] === true) { + selDef[key] = cfg[key] || selDef[key]; + } + } + name_1 = varName(name_1); + var selCmpt = selCmpts[name_1] = tslib_1.__assign({}, selDef, { name: name_1, events: isString(selDef.on) ? parseSelector(selDef.on, 'scope') : selDef.on }); + forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.parse) { + txCompiler.parse(model, selDef, selCmpt); + } + }); + }; + for (var name_1 in selDefs) { + _loop_1(name_1); + } + return selCmpts; +} +export function assembleUnitSelectionSignals(model, signals) { + forEachSelection(model, function (selCmpt, selCompiler) { + var name = selCmpt.name; + var modifyExpr = selCompiler.modifyExpr(model, selCmpt); + signals.push.apply(signals, selCompiler.signals(model, selCmpt)); + forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.signals) { + signals = txCompiler.signals(model, selCmpt, signals); + } + if (txCompiler.modifyExpr) { + modifyExpr = txCompiler.modifyExpr(model, selCmpt, modifyExpr); + } + }); + signals.push({ + name: name + MODIFY, + on: [{ + events: { signal: name + TUPLE }, + update: "modify(" + stringValue(selCmpt.name + STORE) + ", " + modifyExpr + ")" + }] + }); + }); + var facetModel = getFacetModel(model); + if (signals.length && facetModel) { + var name_2 = stringValue(facetModel.getName('cell')); + signals.unshift({ + name: 'facet', + value: {}, + on: [{ + events: parseSelector('mousemove', 'scope'), + update: "isTuple(facet) ? facet : group(" + name_2 + ").datum" + }] + }); + } + return signals; +} +export function assembleTopLevelSignals(model, signals) { + var needsUnit = false; + forEachSelection(model, function (selCmpt, selCompiler) { + if (selCompiler.topLevelSignals) { + signals = selCompiler.topLevelSignals(model, selCmpt, signals); + } + forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.topLevelSignals) { + signals = txCompiler.topLevelSignals(model, selCmpt, signals); + } + }); + needsUnit = true; + }); + if (needsUnit) { + var hasUnit = signals.filter(function (s) { return s.name === 'unit'; }); + if (!(hasUnit.length)) { + signals.unshift({ + name: 'unit', + value: {}, + on: [{ events: 'mousemove', update: 'isTuple(group()) ? group() : unit' }] + }); + } + } + return signals; +} +export function assembleUnitSelectionData(model, data) { + forEachSelection(model, function (selCmpt) { + var contains = data.filter(function (d) { return d.name === selCmpt.name + STORE; }); + if (!contains.length) { + data.push({ name: selCmpt.name + STORE }); + } + }); + return data; +} +export function assembleUnitSelectionMarks(model, marks) { + forEachSelection(model, function (selCmpt, selCompiler) { + marks = selCompiler.marks ? selCompiler.marks(model, selCmpt, marks) : marks; + forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.marks) { + marks = txCompiler.marks(model, selCmpt, marks); + } + }); + }); + return marks; +} +export function assembleLayerSelectionMarks(model, marks) { + model.children.forEach(function (child) { + if (isUnitModel(child)) { + marks = assembleUnitSelectionMarks(child, marks); + } + }); + return marks; +} +export function selectionPredicate(model, selections, dfnode) { + var stores = []; + function expr(name) { + var vname = varName(name); + var selCmpt = model.getSelectionComponent(vname, name); + var store = stringValue(vname + STORE); + if (selCmpt.timeUnit) { + var child = dfnode || model.component.data.raw; + var tunode = selCmpt.timeUnit.clone(); + if (child.parent) { + tunode.insertAsParentOf(child); + } + else { + child.parent = tunode; + } + } + if (selCmpt.empty !== 'none') { + stores.push(store); + } + return compiler(selCmpt.type).predicate + ("(" + store + ", datum") + + (selCmpt.resolve === 'global' ? ')' : ", " + stringValue(selCmpt.resolve) + ")"); + } + var predicateStr = logicalExpr(selections, expr); + return (stores.length + ? '!(' + stores.map(function (s) { return "length(data(" + s + "))"; }).join(' || ') + ') || ' + : '') + ("(" + predicateStr + ")"); +} +// Selections are parsed _after_ scales. If a scale domain is set to +// use a selection, the SELECTION_DOMAIN constant is used as the +// domainRaw.signal during scale.parse and then replaced with the necessary +// selection expression function during scale.assemble. To not pollute the +// type signatures to account for this setup, the selection domain definition +// is coerced to a string and appended to SELECTION_DOMAIN. +export function isRawSelectionDomain(domainRaw) { + return domainRaw.signal.indexOf(SELECTION_DOMAIN) >= 0; +} +export function selectionScaleDomain(model, domainRaw) { + var selDomain = JSON.parse(domainRaw.signal.replace(SELECTION_DOMAIN, '')); + var name = varName(selDomain.selection); + var selCmpt = model.component.selection && model.component.selection[name]; + if (selCmpt) { + warn('Use "bind": "scales" to setup a binding for scales and selections within the same view.'); + } + else { + selCmpt = model.getSelectionComponent(name, selDomain.selection); + if (!selDomain.encoding && !selDomain.field) { + selDomain.field = selCmpt.project[0].field; + if (selCmpt.project.length > 1) { + warn('A "field" or "encoding" must be specified when using a selection as a scale domain. ' + + ("Using \"field\": " + stringValue(selDomain.field) + ".")); + } + } + return { + signal: compiler(selCmpt.type).scaleDomain + + ("(" + stringValue(name + STORE) + ", " + stringValue(selDomain.encoding || null) + ", ") + + stringValue(selDomain.field || null) + + (selCmpt.resolve === 'global' ? ')' : ", " + stringValue(selCmpt.resolve) + ")") + }; + } + return { signal: 'null' }; +} +// Utility functions +function forEachSelection(model, cb) { + var selections = model.component.selection; + for (var name_3 in selections) { + if (selections.hasOwnProperty(name_3)) { + var sel = selections[name_3]; + cb(sel, compiler(sel.type)); + } + } +} +function compiler(type) { + switch (type) { + case 'single': + return singleCompiler; + case 'multi': + return multiCompiler; + case 'interval': + return intervalCompiler; + } + return null; +} +function getFacetModel(model) { + var parent = model.parent; + while (parent) { + if (isFacetModel(parent)) { + break; + } + parent = parent.parent; + } + return parent; +} +export function unitName(model) { + var name = stringValue(model.name); + var facet = getFacetModel(model); + if (facet) { + name += (facet.facet.row ? " + '_' + (" + accessPathWithDatum(facet.vgField('row'), 'facet') + ")" : '') + + (facet.facet.column ? " + '_' + (" + accessPathWithDatum(facet.vgField('column'), 'facet') + ")" : ''); + } + return name; +} +export function requiresSelectionId(model) { + var identifier = false; + forEachSelection(model, function (selCmpt) { + identifier = identifier || selCmpt.project.some(function (proj) { return proj.field === SELECTION_ID; }); + }); + return identifier; +} +export function channelSignalName(selCmpt, channel, range) { + var sgNames = selCmpt._signalNames || (selCmpt._signalNames = {}); + if (sgNames[channel] && sgNames[channel][range]) { + return sgNames[channel][range]; + } + sgNames[channel] = sgNames[channel] || {}; + var basename = varName(selCmpt.name + '_' + (range === 'visual' ? channel : selCmpt.fields[channel])); + var name = basename; + var counter = 1; + while (sgNames[name]) { + name = basename + "_" + counter++; + } + return (sgNames[name] = sgNames[channel][range] = name); +} +export function positionalProjections(selCmpt) { + var x = null; + var xi = null; + var y = null; + var yi = null; + selCmpt.project.forEach(function (p, i) { + if (p.channel === X) { + x = p; + xi = i; + } + else if (p.channel === Y) { + y = p; + yi = i; + } + }); + return { x: x, xi: xi, y: y, yi: yi }; +} +//# sourceMappingURL=selection.js.map \ No newline at end of file diff --git a/build/src/compile/selection/selection.js.map b/build/src/compile/selection/selection.js.map new file mode 100644 index 0000000000..759f64100c --- /dev/null +++ b/build/src/compile/selection/selection.js.map @@ -0,0 +1 @@ +{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../../src/compile/selection/selection.ts"],"names":[],"mappings":"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","sourcesContent":["import {selector as parseSelector} from 'vega-event-selector';\nimport {isString, stringValue} from 'vega-util';\nimport {Channel, ScaleChannel, X, Y} from '../../channel';\nimport {warn} from '../../log';\nimport {LogicalOperand} from '../../logical';\nimport {BrushConfig, SELECTION_ID, SelectionDef, SelectionResolution, SelectionType} from '../../selection';\nimport {accessPathWithDatum, Dict, logicalExpr, varName} from '../../util';\nimport {VgBinding, VgData, VgEventStream, VgSignalRef} from '../../vega.schema';\nimport {DataFlowNode} from '../data/dataflow';\nimport {TimeUnitNode} from '../data/timeunit';\nimport {FacetModel} from '../facet';\nimport {LayerModel} from '../layer';\nimport {isFacetModel, isUnitModel, Model} from '../model';\nimport {UnitModel} from '../unit';\nimport intervalCompiler from './interval';\nimport multiCompiler from './multi';\nimport {SelectionComponent} from './selection';\nimport singleCompiler from './single';\nimport {forEachTransform} from './transforms/transforms';\n\n\nexport const STORE = '_store';\nexport const TUPLE = '_tuple';\nexport const MODIFY = '_modify';\nexport const SELECTION_DOMAIN = '_selection_domain_';\n\nexport interface SelectionComponent {\n name: string;\n type: SelectionType;\n events: VgEventStream;\n // predicate?: string;\n bind?: 'scales' | VgBinding | {[key: string]: VgBinding};\n resolve: SelectionResolution;\n empty: 'all' | 'none';\n mark?: BrushConfig;\n\n _signalNames: {};\n\n // Transforms\n project?: ProjectComponent[];\n fields?: any;\n timeUnit?: TimeUnitNode;\n scales?: Channel[];\n toggle?: any;\n translate?: any;\n zoom?: any;\n nearest?: any;\n}\n\nexport interface ProjectComponent {\n field?: string;\n channel?: ScaleChannel;\n}\n\nexport interface SelectionCompiler {\n signals: (model: UnitModel, selCmpt: SelectionComponent) => any[];\n topLevelSignals?: (model: Model, selCmpt: SelectionComponent, signals: any[]) => any[];\n modifyExpr: (model: UnitModel, selCmpt: SelectionComponent) => string;\n marks?: (model: UnitModel, selCmpt:SelectionComponent, marks: any[]) => any[];\n predicate: string; // Vega expr string to determine inclusion in selection.\n scaleDomain: string; // Vega expr string to materialize a scale domain.\n}\n\nexport function parseUnitSelection(model: UnitModel, selDefs: Dict) {\n const selCmpts: Dict = {};\n const selectionConfig = model.config.selection;\n\n for (let name in selDefs) {\n if (!selDefs.hasOwnProperty(name)) {\n continue;\n }\n\n const selDef = selDefs[name];\n const cfg = selectionConfig[selDef.type];\n\n // Set default values from config if a property hasn't been specified,\n // or if it is true. E.g., \"translate\": true should use the default\n // event handlers for translate. However, true may be a valid value for\n // a property (e.g., \"nearest\": true).\n for (const key in cfg) {\n // A selection should contain either `encodings` or `fields`, only use\n // default values for these two values if neither of them is specified.\n if ((key === 'encodings' && selDef.fields) || (key === 'fields' && selDef.encodings)) {\n continue;\n }\n\n if (key === 'mark') {\n selDef[key] = {...cfg[key], ...selDef[key]};\n }\n\n if (selDef[key] === undefined || selDef[key] === true) {\n selDef[key] = cfg[key] || selDef[key];\n }\n }\n\n name = varName(name);\n const selCmpt = selCmpts[name] = {\n ...selDef,\n name: name,\n events: isString(selDef.on) ? parseSelector(selDef.on, 'scope') : selDef.on,\n } as SelectionComponent;\n\n forEachTransform(selCmpt, txCompiler => {\n if (txCompiler.parse) {\n txCompiler.parse(model, selDef, selCmpt);\n }\n });\n }\n\n return selCmpts;\n}\n\nexport function assembleUnitSelectionSignals(model: UnitModel, signals: any[]) {\n forEachSelection(model, (selCmpt, selCompiler) => {\n const name = selCmpt.name;\n let modifyExpr = selCompiler.modifyExpr(model, selCmpt);\n\n signals.push.apply(signals, selCompiler.signals(model, selCmpt));\n\n forEachTransform(selCmpt, txCompiler => {\n if (txCompiler.signals) {\n signals = txCompiler.signals(model, selCmpt, signals);\n }\n if (txCompiler.modifyExpr) {\n modifyExpr = txCompiler.modifyExpr(model, selCmpt, modifyExpr);\n }\n });\n\n signals.push({\n name: name + MODIFY,\n on: [{\n events: {signal: name + TUPLE},\n update: `modify(${stringValue(selCmpt.name + STORE)}, ${modifyExpr})`\n }]\n });\n });\n\n const facetModel = getFacetModel(model);\n if (signals.length && facetModel) {\n const name = stringValue(facetModel.getName('cell'));\n signals.unshift({\n name: 'facet',\n value: {},\n on: [{\n events: parseSelector('mousemove', 'scope'),\n update: `isTuple(facet) ? facet : group(${name}).datum`\n }]\n });\n }\n\n return signals;\n}\n\nexport function assembleTopLevelSignals(model: UnitModel, signals: any[]) {\n let needsUnit = false;\n forEachSelection(model, (selCmpt, selCompiler) => {\n if (selCompiler.topLevelSignals) {\n signals = selCompiler.topLevelSignals(model, selCmpt, signals);\n }\n\n forEachTransform(selCmpt, txCompiler => {\n if (txCompiler.topLevelSignals) {\n signals = txCompiler.topLevelSignals(model, selCmpt, signals);\n }\n });\n\n needsUnit = true;\n });\n\n if (needsUnit) {\n const hasUnit = signals.filter((s) => s.name === 'unit');\n if (!(hasUnit.length)) {\n signals.unshift({\n name: 'unit',\n value: {},\n on: [{events: 'mousemove', update: 'isTuple(group()) ? group() : unit'}]\n });\n }\n }\n\n return signals;\n}\n\nexport function assembleUnitSelectionData(model: UnitModel, data: VgData[]): VgData[] {\n forEachSelection(model, selCmpt => {\n const contains = data.filter((d) => d.name === selCmpt.name + STORE);\n if (!contains.length) {\n data.push({name: selCmpt.name + STORE});\n }\n });\n\n return data;\n}\n\nexport function assembleUnitSelectionMarks(model: UnitModel, marks: any[]): any[] {\n forEachSelection(model, (selCmpt, selCompiler) => {\n marks = selCompiler.marks ? selCompiler.marks(model, selCmpt, marks) : marks;\n forEachTransform(selCmpt, (txCompiler) => {\n if (txCompiler.marks) {\n marks = txCompiler.marks(model, selCmpt, marks);\n }\n });\n });\n\n return marks;\n}\n\nexport function assembleLayerSelectionMarks(model: LayerModel, marks: any[]): any[] {\n model.children.forEach(child => {\n if (isUnitModel(child)) {\n marks = assembleUnitSelectionMarks(child, marks);\n }\n });\n\n return marks;\n}\n\nexport function selectionPredicate(model: Model, selections: LogicalOperand, dfnode?: DataFlowNode): string {\n const stores: string[] = [];\n function expr(name: string): string {\n const vname = varName(name);\n const selCmpt = model.getSelectionComponent(vname, name);\n const store = stringValue(vname + STORE);\n\n if (selCmpt.timeUnit) {\n const child = dfnode || model.component.data.raw;\n const tunode = selCmpt.timeUnit.clone();\n if (child.parent) {\n tunode.insertAsParentOf(child);\n } else {\n child.parent = tunode;\n }\n }\n\n if (selCmpt.empty !== 'none') {\n stores.push(store);\n }\n\n return compiler(selCmpt.type).predicate + `(${store}, datum` +\n (selCmpt.resolve === 'global' ? ')' : `, ${stringValue(selCmpt.resolve)})`);\n }\n\n const predicateStr = logicalExpr(selections, expr);\n return (stores.length\n ? '!(' + stores.map((s) => `length(data(${s}))`).join(' || ') + ') || '\n : ''\n ) + `(${predicateStr})`;\n}\n\n// Selections are parsed _after_ scales. If a scale domain is set to\n// use a selection, the SELECTION_DOMAIN constant is used as the\n// domainRaw.signal during scale.parse and then replaced with the necessary\n// selection expression function during scale.assemble. To not pollute the\n// type signatures to account for this setup, the selection domain definition\n// is coerced to a string and appended to SELECTION_DOMAIN.\nexport function isRawSelectionDomain(domainRaw: VgSignalRef) {\n return domainRaw.signal.indexOf(SELECTION_DOMAIN) >= 0;\n}\nexport function selectionScaleDomain(model: Model, domainRaw: VgSignalRef): VgSignalRef {\n const selDomain = JSON.parse(domainRaw.signal.replace(SELECTION_DOMAIN, ''));\n const name = varName(selDomain.selection);\n\n let selCmpt = model.component.selection && model.component.selection[name];\n if (selCmpt) {\n warn('Use \"bind\": \"scales\" to setup a binding for scales and selections within the same view.');\n } else {\n selCmpt = model.getSelectionComponent(name, selDomain.selection);\n if (!selDomain.encoding && !selDomain.field) {\n selDomain.field = selCmpt.project[0].field;\n if (selCmpt.project.length > 1) {\n warn('A \"field\" or \"encoding\" must be specified when using a selection as a scale domain. ' +\n `Using \"field\": ${stringValue(selDomain.field)}.`);\n }\n }\n return {\n signal: compiler(selCmpt.type).scaleDomain +\n `(${stringValue(name + STORE)}, ${stringValue(selDomain.encoding || null)}, ` +\n stringValue(selDomain.field || null) +\n (selCmpt.resolve === 'global' ? ')' : `, ${stringValue(selCmpt.resolve)})`)\n };\n }\n\n return {signal: 'null'};\n}\n\n// Utility functions\n\nfunction forEachSelection(model: Model, cb: (selCmpt: SelectionComponent, selCompiler: SelectionCompiler) => void) {\n const selections = model.component.selection;\n for (const name in selections) {\n if (selections.hasOwnProperty(name)) {\n const sel = selections[name];\n cb(sel, compiler(sel.type));\n }\n }\n}\n\nfunction compiler(type: SelectionType): SelectionCompiler {\n switch (type) {\n case 'single':\n return singleCompiler;\n case 'multi':\n return multiCompiler;\n case 'interval':\n return intervalCompiler;\n }\n return null;\n}\n\nfunction getFacetModel(model: Model): FacetModel {\n let parent = model.parent;\n while (parent) {\n if (isFacetModel(parent)) {\n break;\n }\n parent = parent.parent;\n }\n\n return parent as FacetModel;\n}\n\nexport function unitName(model: Model) {\n let name = stringValue(model.name);\n const facet = getFacetModel(model);\n if (facet) {\n name += (facet.facet.row ? ` + '_' + (${accessPathWithDatum(facet.vgField('row'), 'facet')})` : '')\n + (facet.facet.column ? ` + '_' + (${accessPathWithDatum(facet.vgField('column'), 'facet')})` : '');\n }\n return name;\n}\n\nexport function requiresSelectionId(model: Model) {\n let identifier = false;\n forEachSelection(model, (selCmpt) => {\n identifier = identifier || selCmpt.project.some((proj) => proj.field === SELECTION_ID);\n });\n return identifier;\n}\n\nexport function channelSignalName(selCmpt: SelectionComponent, channel: Channel, range: 'visual' | 'data') {\n const sgNames = selCmpt._signalNames || (selCmpt._signalNames = {});\n if (sgNames[channel] && sgNames[channel][range]) {\n return sgNames[channel][range];\n }\n\n sgNames[channel] = sgNames[channel] || {};\n const basename = varName(selCmpt.name + '_' + (range === 'visual' ? channel : selCmpt.fields[channel]));\n let name = basename;\n let counter = 1;\n while (sgNames[name]) {\n name = `${basename}_${counter++}`;\n }\n\n return (sgNames[name] = sgNames[channel][range] = name);\n}\n\nexport function positionalProjections(selCmpt: SelectionComponent) {\n let x:ProjectComponent = null;\n let xi:number = null;\n let y:ProjectComponent = null;\n let yi: number = null;\n\n selCmpt.project.forEach((p, i) => {\n if (p.channel === X) {\n x = p;\n xi = i;\n } else if (p.channel === Y) {\n y = p;\n yi = i;\n }\n });\n return {x, xi, y, yi};\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/single.d.ts b/build/src/compile/selection/single.d.ts new file mode 100644 index 0000000000..5f9c718150 --- /dev/null +++ b/build/src/compile/selection/single.d.ts @@ -0,0 +1,3 @@ +import { SelectionCompiler } from './selection'; +declare const single: SelectionCompiler; +export default single; diff --git a/build/src/compile/selection/single.js b/build/src/compile/selection/single.js new file mode 100644 index 0000000000..b72adcb3e7 --- /dev/null +++ b/build/src/compile/selection/single.js @@ -0,0 +1,25 @@ +import { stringValue } from 'vega-util'; +import { signals as multiSignals } from './multi'; +import { STORE, TUPLE, unitName } from './selection'; +var single = { + predicate: 'vlSingle', + scaleDomain: 'vlSingleDomain', + signals: multiSignals, + topLevelSignals: function (model, selCmpt, signals) { + var hasSignal = signals.filter(function (s) { return s.name === selCmpt.name; }); + var data = "data(" + stringValue(selCmpt.name + STORE) + ")"; + var values = data + "[0].values"; + return hasSignal.length ? signals : signals.concat({ + name: selCmpt.name, + update: data + ".length && {" + + selCmpt.project.map(function (p, i) { return p.field + ": " + values + "[" + i + "]"; }).join(', ') + '}' + }); + }, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'true' : "{unit: " + unitName(model) + "}"); + } +}; +export default single; +//# sourceMappingURL=single.js.map \ No newline at end of file diff --git a/build/src/compile/selection/single.js.map b/build/src/compile/selection/single.js.map new file mode 100644 index 0000000000..c404fa726d --- /dev/null +++ b/build/src/compile/selection/single.js.map @@ -0,0 +1 @@ +{"version":3,"file":"single.js","sourceRoot":"","sources":["../../../../src/compile/selection/single.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,SAAS,CAAC;AAChD,OAAO,EAAoB,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAC;AAGtE,IAAM,MAAM,GAAqB;IAC/B,SAAS,EAAE,UAAU;IACrB,WAAW,EAAE,gBAAgB;IAE7B,OAAO,EAAE,YAAY;IAErB,eAAe,EAAE,UAAS,KAAK,EAAE,OAAO,EAAE,OAAO;QAC/C,IAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,EAAvB,CAAuB,CAAC,CAAC;QACjE,IAAM,IAAI,GAAG,UAAQ,WAAW,CAAC,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC,MAAG,CAAC;QAC1D,IAAM,MAAM,GAAM,IAAI,eAAY,CAAC;QACnC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;YACjD,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAK,IAAI,iBAAc;gBAC3B,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAC,CAAC,EAAE,CAAC,IAAK,OAAG,CAAC,CAAC,KAAK,UAAK,MAAM,SAAI,CAAC,MAAG,EAA7B,CAA6B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG;SAChF,CAAC,CAAC;IACL,CAAC;IAED,UAAU,EAAE,UAAS,KAAK,EAAE,OAAO;QACjC,IAAM,GAAG,GAAG,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC;QACjC,OAAO,GAAG,GAAG,IAAI;YACf,CAAC,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAU,QAAQ,CAAC,KAAK,CAAC,MAAG,CAAC,CAAC;IAC3E,CAAC;CACF,CAAC;AAEF,eAAe,MAAM,CAAC","sourcesContent":["import {stringValue} from 'vega-util';\n\nimport {signals as multiSignals} from './multi';\nimport {SelectionCompiler, STORE, TUPLE, unitName} from './selection';\n\n\nconst single:SelectionCompiler = {\n predicate: 'vlSingle',\n scaleDomain: 'vlSingleDomain',\n\n signals: multiSignals,\n\n topLevelSignals: function(model, selCmpt, signals) {\n const hasSignal = signals.filter((s) => s.name === selCmpt.name);\n const data = `data(${stringValue(selCmpt.name + STORE)})`;\n const values = `${data}[0].values`;\n return hasSignal.length ? signals : signals.concat({\n name: selCmpt.name,\n update: `${data}.length && {` +\n selCmpt.project.map((p, i) => `${p.field}: ${values}[${i}]`).join(', ') + '}'\n });\n },\n\n modifyExpr: function(model, selCmpt) {\n const tpl = selCmpt.name + TUPLE;\n return tpl + ', ' +\n (selCmpt.resolve === 'global' ? 'true' : `{unit: ${unitName(model)}}`);\n }\n};\n\nexport default single;\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/transforms/inputs.d.ts b/build/src/compile/selection/transforms/inputs.d.ts new file mode 100644 index 0000000000..373049cd38 --- /dev/null +++ b/build/src/compile/selection/transforms/inputs.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const inputBindings: TransformCompiler; +export default inputBindings; diff --git a/build/src/compile/selection/transforms/inputs.js b/build/src/compile/selection/transforms/inputs.js new file mode 100644 index 0000000000..b31b20151c --- /dev/null +++ b/build/src/compile/selection/transforms/inputs.js @@ -0,0 +1,48 @@ +import { stringValue } from 'vega-util'; +import { accessPathWithDatum, varName } from '../../../util'; +import { TUPLE } from '../selection'; +import nearest from './nearest'; +var inputBindings = { + has: function (selCmpt) { + return selCmpt.type === 'single' && selCmpt.resolve === 'global' && + selCmpt.bind && selCmpt.bind !== 'scales'; + }, + topLevelSignals: function (model, selCmpt, signals) { + var name = selCmpt.name; + var proj = selCmpt.project; + var bind = selCmpt.bind; + var datum = nearest.has(selCmpt) ? + '(item().isVoronoi ? datum.datum : datum)' : 'datum'; + proj.forEach(function (p) { + var sgname = varName(name + "_" + p.field); + var hasSignal = signals.filter(function (s) { return s.name === sgname; }); + if (!hasSignal.length) { + signals.unshift({ + name: sgname, + value: '', + on: [{ + events: selCmpt.events, + update: "datum && item().mark.marktype !== 'group' ? " + accessPathWithDatum(p.field, datum) + " : null" + }], + bind: bind[p.field] || bind[p.channel] || bind + }); + } + }); + return signals; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name; + var proj = selCmpt.project; + var signal = signals.filter(function (s) { return s.name === name + TUPLE; })[0]; + var fields = proj.map(function (p) { return stringValue(p.field); }).join(', '); + var values = proj.map(function (p) { return varName(name + "_" + p.field); }); + if (values.length) { + signal.update = values.join(' && ') + " ? {fields: [" + fields + "], values: [" + values.join(', ') + "]} : null"; + } + delete signal.value; + delete signal.on; + return signals; + } +}; +export default inputBindings; +//# sourceMappingURL=inputs.js.map \ No newline at end of file diff --git a/build/src/compile/selection/transforms/inputs.js.map b/build/src/compile/selection/transforms/inputs.js.map new file mode 100644 index 0000000000..525bd7be4b --- /dev/null +++ b/build/src/compile/selection/transforms/inputs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"inputs.js","sourceRoot":"","sources":["../../../../../src/compile/selection/transforms/inputs.ts"],"names":[],"mappings":"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","sourcesContent":["import {stringValue} from 'vega-util';\nimport {accessPathWithDatum, varName} from '../../../util';\nimport {TUPLE} from '../selection';\nimport nearest from './nearest';\nimport {TransformCompiler} from './transforms';\n\n\nconst inputBindings:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'single' && selCmpt.resolve === 'global' &&\n selCmpt.bind && selCmpt.bind !== 'scales';\n },\n\n topLevelSignals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const proj = selCmpt.project;\n const bind = selCmpt.bind;\n const datum = nearest.has(selCmpt) ?\n '(item().isVoronoi ? datum.datum : datum)' : 'datum';\n\n proj.forEach(function(p) {\n const sgname = varName(`${name}_${p.field}`);\n const hasSignal = signals.filter((s) => s.name === sgname);\n if (!hasSignal.length) {\n signals.unshift({\n name: sgname,\n value: '',\n on: [{\n events: selCmpt.events,\n update: `datum && item().mark.marktype !== 'group' ? ${accessPathWithDatum(p.field, datum)} : null`\n }],\n bind: bind[p.field] || bind[p.channel] || bind\n });\n }\n });\n\n return signals;\n },\n\n signals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const proj = selCmpt.project;\n const signal = signals.filter((s) => s.name === name + TUPLE)[0];\n const fields = proj.map((p) => stringValue(p.field)).join(', ');\n const values = proj.map((p) => varName(`${name}_${p.field}`));\n\n if (values.length) {\n signal.update = `${values.join(' && ')} ? {fields: [${fields}], values: [${values.join(', ')}]} : null`;\n }\n\n delete signal.value;\n delete signal.on;\n\n return signals;\n }\n};\n\nexport default inputBindings;\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/transforms/nearest.d.ts b/build/src/compile/selection/transforms/nearest.d.ts new file mode 100644 index 0000000000..f8969314eb --- /dev/null +++ b/build/src/compile/selection/transforms/nearest.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const nearest: TransformCompiler; +export default nearest; diff --git a/build/src/compile/selection/transforms/nearest.js b/build/src/compile/selection/transforms/nearest.js new file mode 100644 index 0000000000..804adc53e7 --- /dev/null +++ b/build/src/compile/selection/transforms/nearest.js @@ -0,0 +1,53 @@ +import * as log from '../../../log'; +import { isPathMark } from '../../../mark'; +import { positionalProjections } from '../selection'; +var VORONOI = 'voronoi'; +var nearest = { + has: function (selCmpt) { + return selCmpt.type !== 'interval' && selCmpt.nearest; + }, + marks: function (model, selCmpt, marks) { + var _a = positionalProjections(selCmpt), x = _a.x, y = _a.y; + var markType = model.mark; + if (isPathMark(markType)) { + log.warn(log.message.nearestNotSupportForContinuous(markType)); + return marks; + } + var cellDef = { + name: model.getName(VORONOI), + type: 'path', + from: { data: model.getName('marks') }, + encode: { + enter: { + fill: { value: 'transparent' }, + strokeWidth: { value: 0.35 }, + stroke: { value: 'transparent' }, + isVoronoi: { value: true } + } + }, + transform: [{ + type: 'voronoi', + x: { expr: (x || (!x && !y)) ? 'datum.datum.x || 0' : '0' }, + y: { expr: (y || (!x && !y)) ? 'datum.datum.y || 0' : '0' }, + size: [model.getSizeSignalRef('width'), model.getSizeSignalRef('height')] + }] + }; + var index = 0; + var exists = false; + marks.forEach(function (mark, i) { + var name = mark.name || ''; + if (name === model.component.mark[0].name) { + index = i; + } + else if (name.indexOf(VORONOI) >= 0) { + exists = true; + } + }); + if (!exists) { + marks.splice(index + 1, 0, cellDef); + } + return marks; + } +}; +export default nearest; +//# sourceMappingURL=nearest.js.map \ No newline at end of file diff --git a/build/src/compile/selection/transforms/nearest.js.map b/build/src/compile/selection/transforms/nearest.js.map new file mode 100644 index 0000000000..f7b051528d --- /dev/null +++ b/build/src/compile/selection/transforms/nearest.js.map @@ -0,0 +1 @@ +{"version":3,"file":"nearest.js","sourceRoot":"","sources":["../../../../../src/compile/selection/transforms/nearest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AACzC,OAAO,EAAC,qBAAqB,EAAC,MAAM,cAAc,CAAC;AAGnD,IAAM,OAAO,GAAG,SAAS,CAAC;AAE1B,IAAM,OAAO,GAAqB;IAChC,GAAG,EAAE,UAAS,OAAO;QACnB,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IACxD,CAAC;IAED,KAAK,EAAE,UAAS,KAAK,EAAE,OAAO,EAAE,KAAK;QAC7B,IAAA,mCAAuC,EAAtC,QAAC,EAAE,QAAC,CAAmC;QAC9C,IAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC;QAC5B,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE;YACxB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,8BAA8B,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC/D,OAAO,KAAK,CAAC;SACd;QAED,IAAM,OAAO,GAAG;YACd,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YAC5B,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,EAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAC;YACpC,MAAM,EAAE;gBACN,KAAK,EAAE;oBACL,IAAI,EAAE,EAAC,KAAK,EAAE,aAAa,EAAC;oBAC5B,WAAW,EAAE,EAAC,KAAK,EAAE,IAAI,EAAC;oBAC1B,MAAM,EAAE,EAAC,KAAK,EAAE,aAAa,EAAC;oBAC9B,SAAS,EAAE,EAAC,KAAK,EAAE,IAAI,EAAC;iBACzB;aACF;YACD,SAAS,EAAE,CAAC;oBACV,IAAI,EAAE,SAAS;oBACf,CAAC,EAAE,EAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAAG,EAAC;oBACzD,CAAC,EAAE,EAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAAG,EAAC;oBACzD,IAAI,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;iBAC1E,CAAC;SACH,CAAC;QAEF,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,KAAK,CAAC,OAAO,CAAC,UAAC,IAAI,EAAE,CAAC;YACpB,IAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;YAC7B,IAAI,IAAI,KAAK,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;gBACzC,KAAK,GAAG,CAAC,CAAC;aACX;iBAAM,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBACrC,MAAM,GAAG,IAAI,CAAC;aACf;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,EAAE;YACX,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;SACrC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC;AAEF,eAAe,OAAO,CAAC","sourcesContent":["import * as log from '../../../log';\nimport {isPathMark} from '../../../mark';\nimport {positionalProjections} from '../selection';\nimport {TransformCompiler} from './transforms';\n\nconst VORONOI = 'voronoi';\n\nconst nearest:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type !== 'interval' && selCmpt.nearest;\n },\n\n marks: function(model, selCmpt, marks) {\n const {x, y} = positionalProjections(selCmpt);\n const markType = model.mark;\n if (isPathMark(markType)) {\n log.warn(log.message.nearestNotSupportForContinuous(markType));\n return marks;\n }\n\n const cellDef = {\n name: model.getName(VORONOI),\n type: 'path',\n from: {data: model.getName('marks')},\n encode: {\n enter: {\n fill: {value: 'transparent'},\n strokeWidth: {value: 0.35},\n stroke: {value: 'transparent'},\n isVoronoi: {value: true}\n }\n },\n transform: [{\n type: 'voronoi',\n x: {expr: (x || (!x && !y)) ? 'datum.datum.x || 0' : '0'},\n y: {expr: (y || (!x && !y)) ? 'datum.datum.y || 0' : '0'},\n size: [model.getSizeSignalRef('width'), model.getSizeSignalRef('height')]\n }]\n };\n\n let index = 0;\n let exists = false;\n marks.forEach((mark, i) => {\n const name = mark.name || '';\n if (name === model.component.mark[0].name) {\n index = i;\n } else if (name.indexOf(VORONOI) >= 0) {\n exists = true;\n }\n });\n\n if (!exists) {\n marks.splice(index + 1, 0, cellDef);\n }\n\n return marks;\n }\n};\n\nexport default nearest;\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/transforms/project.d.ts b/build/src/compile/selection/transforms/project.d.ts new file mode 100644 index 0000000000..c42bdba3e3 --- /dev/null +++ b/build/src/compile/selection/transforms/project.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const project: TransformCompiler; +export default project; diff --git a/build/src/compile/selection/transforms/project.js b/build/src/compile/selection/transforms/project.js new file mode 100644 index 0000000000..d83eebdb4e --- /dev/null +++ b/build/src/compile/selection/transforms/project.js @@ -0,0 +1,52 @@ +import * as log from '../../../log'; +import { keys } from '../../../util'; +import { TimeUnitNode } from '../../data/timeunit'; +var project = { + has: function (selDef) { + var def = selDef; + return def.fields !== undefined || def.encodings !== undefined; + }, + parse: function (model, selDef, selCmpt) { + var channels = {}; + var timeUnits = {}; + // TODO: find a possible channel mapping for these fields. + (selDef.fields || []).forEach(function (field) { return channels[field] = null; }); + (selDef.encodings || []).forEach(function (channel) { + var fieldDef = model.fieldDef(channel); + if (fieldDef) { + if (fieldDef.timeUnit) { + var tuField = model.vgField(channel); + channels[tuField] = channel; + // Construct TimeUnitComponents which will be combined into a + // TimeUnitNode. This node may need to be inserted into the + // dataflow if the selection is used across views that do not + // have these time units defined. + timeUnits[tuField] = { + as: tuField, + field: fieldDef.field, + timeUnit: fieldDef.timeUnit + }; + } + else { + channels[fieldDef.field] = channel; + } + } + else { + log.warn(log.message.cannotProjectOnChannelWithoutField(channel)); + } + }); + var projection = selCmpt.project || (selCmpt.project = []); + for (var field in channels) { + if (channels.hasOwnProperty(field)) { + projection.push({ field: field, channel: channels[field] }); + } + } + var fields = selCmpt.fields || (selCmpt.fields = {}); + projection.filter(function (p) { return p.channel; }).forEach(function (p) { return fields[p.channel] = p.field; }); + if (keys(timeUnits).length) { + selCmpt.timeUnit = new TimeUnitNode(null, timeUnits); + } + } +}; +export default project; +//# sourceMappingURL=project.js.map \ No newline at end of file diff --git a/build/src/compile/selection/transforms/project.js.map b/build/src/compile/selection/transforms/project.js.map new file mode 100644 index 0000000000..a021f24fd2 --- /dev/null +++ b/build/src/compile/selection/transforms/project.js.map @@ -0,0 +1 @@ +{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../../../src/compile/selection/transforms/project.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAEpC,OAAO,EAAC,IAAI,EAAC,MAAM,eAAe,CAAC;AACnC,OAAO,EAAoB,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAIpE,IAAM,OAAO,GAAsB;IACjC,GAAG,EAAE,UAAS,MAAyC;QACrD,IAAM,GAAG,GAAG,MAAsB,CAAC;QACnC,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC;IACjE,CAAC;IAED,KAAK,EAAE,UAAS,KAAK,EAAE,MAAM,EAAE,OAAO;QACpC,IAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,IAAM,SAAS,GAAuC,EAAE,CAAC;QAEzD,0DAA0D;QAC1D,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAC,KAAK,IAAK,OAAA,QAAQ,CAAC,KAAK,CAAC,GAAG,IAAI,EAAtB,CAAsB,CAAC,CAAC;QAEjE,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAC,OAAyB;YACzD,IAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACzC,IAAI,QAAQ,EAAE;gBACZ,IAAI,QAAQ,CAAC,QAAQ,EAAE;oBACrB,IAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBACvC,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;oBAE5B,6DAA6D;oBAC7D,2DAA2D;oBAC3D,6DAA6D;oBAC7D,iCAAiC;oBACjC,SAAS,CAAC,OAAO,CAAC,GAAG;wBACnB,EAAE,EAAE,OAAO;wBACX,KAAK,EAAE,QAAQ,CAAC,KAAK;wBACrB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;qBAC5B,CAAC;iBACH;qBAAM;oBACL,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;iBACpC;aACF;iBAAM;gBACL,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,kCAAkC,CAAC,OAAO,CAAC,CAAC,CAAC;aACnE;QACH,CAAC,CAAC,CAAC;QAEH,IAAM,UAAU,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QAC7D,KAAK,IAAM,KAAK,IAAI,QAAQ,EAAE;YAC5B,IAAI,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE;gBAClC,UAAU,CAAC,IAAI,CAAC,EAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAC,CAAC,CAAC;aAC3D;SACF;QAED,IAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;QACvD,UAAU,CAAC,MAAM,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,OAAO,EAAT,CAAS,CAAC,CAAC,OAAO,CAAC,UAAC,CAAC,IAAK,OAAA,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAA3B,CAA2B,CAAC,CAAC;QAEhF,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE;YAC1B,OAAO,CAAC,QAAQ,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;SACtD;IACH,CAAC;CACF,CAAC;AAEF,eAAe,OAAO,CAAC","sourcesContent":["import {SingleDefChannel} from '../../../channel';\nimport * as log from '../../../log';\nimport {SelectionDef} from '../../../selection';\nimport {keys} from '../../../util';\nimport {TimeUnitComponent, TimeUnitNode} from '../../data/timeunit';\nimport {SelectionComponent} from '../selection';\nimport {TransformCompiler} from './transforms';\n\nconst project: TransformCompiler = {\n has: function(selDef: SelectionComponent | SelectionDef) {\n const def = selDef as SelectionDef;\n return def.fields !== undefined || def.encodings !== undefined;\n },\n\n parse: function(model, selDef, selCmpt) {\n const channels = {};\n const timeUnits: {[key: string]: TimeUnitComponent} = {};\n\n // TODO: find a possible channel mapping for these fields.\n (selDef.fields || []).forEach((field) => channels[field] = null);\n\n (selDef.encodings || []).forEach((channel: SingleDefChannel) => {\n const fieldDef = model.fieldDef(channel);\n if (fieldDef) {\n if (fieldDef.timeUnit) {\n const tuField = model.vgField(channel);\n channels[tuField] = channel;\n\n // Construct TimeUnitComponents which will be combined into a\n // TimeUnitNode. This node may need to be inserted into the\n // dataflow if the selection is used across views that do not\n // have these time units defined.\n timeUnits[tuField] = {\n as: tuField,\n field: fieldDef.field,\n timeUnit: fieldDef.timeUnit\n };\n } else {\n channels[fieldDef.field] = channel;\n }\n } else {\n log.warn(log.message.cannotProjectOnChannelWithoutField(channel));\n }\n });\n\n const projection = selCmpt.project || (selCmpt.project = []);\n for (const field in channels) {\n if (channels.hasOwnProperty(field)) {\n projection.push({field: field, channel: channels[field]});\n }\n }\n\n const fields = selCmpt.fields || (selCmpt.fields = {});\n projection.filter((p) => p.channel).forEach((p) => fields[p.channel] = p.field);\n\n if (keys(timeUnits).length) {\n selCmpt.timeUnit = new TimeUnitNode(null, timeUnits);\n }\n }\n};\n\nexport default project;\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/transforms/scales.d.ts b/build/src/compile/selection/transforms/scales.d.ts new file mode 100644 index 0000000000..d5f9f53c01 --- /dev/null +++ b/build/src/compile/selection/transforms/scales.d.ts @@ -0,0 +1,6 @@ +import { Channel } from '../../../channel'; +import { UnitModel } from '../../unit'; +import { TransformCompiler } from './transforms'; +declare const scaleBindings: TransformCompiler; +export default scaleBindings; +export declare function domain(model: UnitModel, channel: Channel): string; diff --git a/build/src/compile/selection/transforms/scales.js b/build/src/compile/selection/transforms/scales.js new file mode 100644 index 0000000000..5872b37eb6 --- /dev/null +++ b/build/src/compile/selection/transforms/scales.js @@ -0,0 +1,60 @@ +import { stringValue } from 'vega-util'; +import { X, Y } from '../../../channel'; +import * as log from '../../../log'; +import { hasContinuousDomain, isBinScale } from '../../../scale'; +import { channelSignalName } from '../selection'; +var scaleBindings = { + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.resolve === 'global' && + selCmpt.bind && selCmpt.bind === 'scales'; + }, + parse: function (model, selDef, selCmpt) { + var bound = selCmpt.scales = []; + selCmpt.project.forEach(function (p) { + var channel = p.channel; + var scale = model.getScaleComponent(channel); + var scaleType = scale ? scale.get('type') : undefined; + if (!scale || !hasContinuousDomain(scaleType) || isBinScale(scaleType)) { + log.warn(log.message.SCALE_BINDINGS_CONTINUOUS); + return; + } + scale.set('domainRaw', { signal: channelSignalName(selCmpt, channel, 'data') }, true); + bound.push(channel); + // Bind both x/y for diag plot of repeated views. + if (model.repeater && model.repeater.row === model.repeater.column) { + var scale2 = model.getScaleComponent(channel === X ? Y : X); + scale2.set('domainRaw', { signal: channelSignalName(selCmpt, channel, 'data') }, true); + } + }); + }, + topLevelSignals: function (model, selCmpt, signals) { + // Top-level signals are only needed when coordinating composed views. + if (!model.parent) { + return signals; + } + var channels = selCmpt.scales.filter(function (channel) { + return !(signals.filter(function (s) { return s.name === channelSignalName(selCmpt, channel, 'data'); }).length); + }); + return signals.concat(channels.map(function (channel) { + return { name: channelSignalName(selCmpt, channel, 'data') }; + })); + }, + signals: function (model, selCmpt, signals) { + // Nested signals need only push to top-level signals when within composed views. + if (model.parent) { + selCmpt.scales.forEach(function (channel) { + var signal = signals.filter(function (s) { return s.name === channelSignalName(selCmpt, channel, 'data'); })[0]; + signal.push = 'outer'; + delete signal.value; + delete signal.update; + }); + } + return signals; + } +}; +export default scaleBindings; +export function domain(model, channel) { + var scale = stringValue(model.scaleName(channel)); + return "domain(" + scale + ")"; +} +//# sourceMappingURL=scales.js.map \ No newline at end of file diff --git a/build/src/compile/selection/transforms/scales.js.map b/build/src/compile/selection/transforms/scales.js.map new file mode 100644 index 0000000000..82b1ad6013 --- /dev/null +++ b/build/src/compile/selection/transforms/scales.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scales.js","sourceRoot":"","sources":["../../../../../src/compile/selection/transforms/scales.ts"],"names":[],"mappings":"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","sourcesContent":["import {stringValue} from 'vega-util';\nimport {Channel, X, Y} from '../../../channel';\nimport * as log from '../../../log';\nimport {hasContinuousDomain, isBinScale} from '../../../scale';\nimport {UnitModel} from '../../unit';\nimport {channelSignalName} from '../selection';\nimport {TransformCompiler} from './transforms';\n\n\nconst scaleBindings:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.resolve === 'global' &&\n selCmpt.bind && selCmpt.bind === 'scales';\n },\n\n parse: function(model, selDef, selCmpt) {\n const bound: Channel[] = selCmpt.scales = [];\n\n selCmpt.project.forEach(function(p) {\n const channel = p.channel;\n const scale = model.getScaleComponent(channel);\n const scaleType = scale ? scale.get('type') : undefined;\n\n if (!scale || !hasContinuousDomain(scaleType) || isBinScale(scaleType)) {\n log.warn(log.message.SCALE_BINDINGS_CONTINUOUS);\n return;\n }\n\n scale.set('domainRaw', {signal: channelSignalName(selCmpt, channel, 'data')}, true);\n bound.push(channel);\n\n // Bind both x/y for diag plot of repeated views.\n if (model.repeater && model.repeater.row === model.repeater.column) {\n const scale2 = model.getScaleComponent(channel === X ? Y : X);\n scale2.set('domainRaw', {signal: channelSignalName(selCmpt, channel, 'data')}, true);\n }\n });\n },\n\n topLevelSignals: function(model, selCmpt, signals) {\n // Top-level signals are only needed when coordinating composed views.\n if (!model.parent) {\n return signals;\n }\n\n const channels = selCmpt.scales.filter((channel) => {\n return !(signals.filter(s => s.name === channelSignalName(selCmpt, channel, 'data')).length);\n });\n\n return signals.concat(channels.map((channel) => {\n return {name: channelSignalName(selCmpt, channel, 'data')};\n }));\n },\n\n signals: function(model, selCmpt, signals) {\n // Nested signals need only push to top-level signals when within composed views.\n if (model.parent) {\n selCmpt.scales.forEach(channel => {\n const signal = signals.filter(s => s.name === channelSignalName(selCmpt, channel, 'data'))[0];\n\n signal.push = 'outer';\n delete signal.value;\n delete signal.update;\n });\n }\n\n return signals;\n }\n};\n\nexport default scaleBindings;\n\nexport function domain(model: UnitModel, channel: Channel) {\n const scale = stringValue(model.scaleName(channel));\n return `domain(${scale})`;\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/transforms/toggle.d.ts b/build/src/compile/selection/transforms/toggle.d.ts new file mode 100644 index 0000000000..f6ef21b38d --- /dev/null +++ b/build/src/compile/selection/transforms/toggle.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const toggle: TransformCompiler; +export default toggle; diff --git a/build/src/compile/selection/transforms/toggle.js b/build/src/compile/selection/transforms/toggle.js new file mode 100644 index 0000000000..bc98062c7d --- /dev/null +++ b/build/src/compile/selection/transforms/toggle.js @@ -0,0 +1,25 @@ +import { TUPLE, unitName } from '../selection'; +var TOGGLE = '_toggle'; +var toggle = { + has: function (selCmpt) { + return selCmpt.type === 'multi' && selCmpt.toggle; + }, + signals: function (model, selCmpt, signals) { + return signals.concat({ + name: selCmpt.name + TOGGLE, + value: false, + on: [{ events: selCmpt.events, update: selCmpt.toggle }] + }); + }, + modifyExpr: function (model, selCmpt, expr) { + var tpl = selCmpt.name + TUPLE; + var signal = selCmpt.name + TOGGLE; + return signal + " ? null : " + tpl + ", " + + (selCmpt.resolve === 'global' ? + signal + " ? null : true, " : + signal + " ? null : {unit: " + unitName(model) + "}, ") + + (signal + " ? " + tpl + " : null"); + } +}; +export default toggle; +//# sourceMappingURL=toggle.js.map \ No newline at end of file diff --git a/build/src/compile/selection/transforms/toggle.js.map b/build/src/compile/selection/transforms/toggle.js.map new file mode 100644 index 0000000000..ae759247ed --- /dev/null +++ b/build/src/compile/selection/transforms/toggle.js.map @@ -0,0 +1 @@ +{"version":3,"file":"toggle.js","sourceRoot":"","sources":["../../../../../src/compile/selection/transforms/toggle.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,KAAK,EAAE,QAAQ,EAAC,MAAM,cAAc,CAAC;AAI7C,IAAM,MAAM,GAAG,SAAS,CAAC;AAEzB,IAAM,MAAM,GAAqB;IAC/B,GAAG,EAAE,UAAS,OAAO;QACnB,OAAO,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IACpD,CAAC;IAED,OAAO,EAAE,UAAS,KAAK,EAAE,OAAO,EAAE,OAAO;QACvC,OAAO,OAAO,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI,GAAG,MAAM;YAC3B,KAAK,EAAE,KAAK;YACZ,EAAE,EAAE,CAAC,EAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAC,CAAC;SACvD,CAAC,CAAC;IACL,CAAC;IAED,UAAU,EAAE,UAAS,KAAK,EAAE,OAAO,EAAE,IAAI;QACvC,IAAM,GAAG,GAAG,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC;QACjC,IAAM,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC;QAErC,OAAU,MAAM,kBAAa,GAAG,OAAI;YAClC,CAAC,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC;gBAC1B,MAAM,qBAAkB,CAAC,CAAC;gBAC1B,MAAM,yBAAoB,QAAQ,CAAC,KAAK,CAAC,QAAK,CAAC;aACjD,MAAM,WAAM,GAAG,YAAS,CAAA,CAAC;IAChC,CAAC;CACF,CAAC;AAEF,eAAe,MAAM,CAAC","sourcesContent":["\nimport {TUPLE, unitName} from '../selection';\nimport {TransformCompiler} from './transforms';\n\n\nconst TOGGLE = '_toggle';\n\nconst toggle:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'multi' && selCmpt.toggle;\n },\n\n signals: function(model, selCmpt, signals) {\n return signals.concat({\n name: selCmpt.name + TOGGLE,\n value: false,\n on: [{events: selCmpt.events, update: selCmpt.toggle}]\n });\n },\n\n modifyExpr: function(model, selCmpt, expr) {\n const tpl = selCmpt.name + TUPLE;\n const signal = selCmpt.name + TOGGLE;\n\n return `${signal} ? null : ${tpl}, ` +\n (selCmpt.resolve === 'global' ?\n `${signal} ? null : true, ` :\n `${signal} ? null : {unit: ${unitName(model)}}, `) +\n `${signal} ? ${tpl} : null`;\n }\n};\n\nexport default toggle;\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/transforms/transforms.d.ts b/build/src/compile/selection/transforms/transforms.d.ts new file mode 100644 index 0000000000..2bcebfc18a --- /dev/null +++ b/build/src/compile/selection/transforms/transforms.d.ts @@ -0,0 +1,14 @@ +import { SelectionDef } from '../../../selection'; +import { VgSignal } from '../../../vega.schema'; +import { Model } from '../../model'; +import { UnitModel } from '../../unit'; +import { SelectionComponent } from '../selection'; +export interface TransformCompiler { + has: (selCmpt: SelectionComponent | SelectionDef) => boolean; + parse?: (model: UnitModel, def: SelectionDef, selCmpt: SelectionComponent) => void; + signals?: (model: UnitModel, selCmpt: SelectionComponent, signals: VgSignal[]) => VgSignal[]; + topLevelSignals?: (model: Model, selCmpt: SelectionComponent, signals: VgSignal[]) => VgSignal[]; + modifyExpr?: (model: UnitModel, selCmpt: SelectionComponent, expr: string) => string; + marks?: (model: UnitModel, selCmpt: SelectionComponent, marks: any[]) => any[]; +} +export declare function forEachTransform(selCmpt: SelectionComponent, cb: (tx: TransformCompiler) => void): void; diff --git a/build/src/compile/selection/transforms/transforms.js b/build/src/compile/selection/transforms/transforms.js new file mode 100644 index 0000000000..4365aaca98 --- /dev/null +++ b/build/src/compile/selection/transforms/transforms.js @@ -0,0 +1,17 @@ +import inputs from './inputs'; +import nearest from './nearest'; +import project from './project'; +import scales from './scales'; +import toggle from './toggle'; +import translate from './translate'; +import zoom from './zoom'; +var compilers = { project: project, toggle: toggle, scales: scales, + translate: translate, zoom: zoom, inputs: inputs, nearest: nearest }; +export function forEachTransform(selCmpt, cb) { + for (var t in compilers) { + if (compilers[t].has(selCmpt)) { + cb(compilers[t]); + } + } +} +//# sourceMappingURL=transforms.js.map \ No newline at end of file diff --git a/build/src/compile/selection/transforms/transforms.js.map b/build/src/compile/selection/transforms/transforms.js.map new file mode 100644 index 0000000000..f0e2c81f7a --- /dev/null +++ b/build/src/compile/selection/transforms/transforms.js.map @@ -0,0 +1 @@ +{"version":3,"file":"transforms.js","sourceRoot":"","sources":["../../../../../src/compile/selection/transforms/transforms.ts"],"names":[],"mappings":"AAiBA,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,OAAO,MAAM,WAAW,CAAC;AAChC,OAAO,OAAO,MAAM,WAAW,CAAC;AAChC,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,SAAS,MAAM,aAAa,CAAC;AACpC,OAAO,IAAI,MAAM,QAAQ,CAAC;AAC1B,IAAM,SAAS,GAA4B,EAAC,OAAO,SAAA,EAAE,MAAM,QAAA,EAAE,MAAM,QAAA;IACjE,SAAS,WAAA,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,OAAO,SAAA,EAAC,CAAC;AAEpC,MAAM,2BAA2B,OAA2B,EAAE,EAAmC;IAC/F,KAAK,IAAM,CAAC,IAAI,SAAS,EAAE;QACzB,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YAC7B,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;SAClB;KACF;AACH,CAAC","sourcesContent":["import {SelectionDef} from '../../../selection';\nimport {Dict} from '../../../util';\nimport {VgSignal} from '../../../vega.schema';\nimport {Model} from '../../model';\nimport {UnitModel} from '../../unit';\nimport {SelectionComponent} from '../selection';\n\n\nexport interface TransformCompiler {\n has: (selCmpt: SelectionComponent | SelectionDef) => boolean;\n parse?: (model: UnitModel, def: SelectionDef, selCmpt: SelectionComponent) => void;\n signals?: (model: UnitModel, selCmpt: SelectionComponent, signals: VgSignal[]) => VgSignal[];\n topLevelSignals?: (model: Model, selCmpt: SelectionComponent, signals: VgSignal[]) => VgSignal[];\n modifyExpr?: (model: UnitModel, selCmpt: SelectionComponent, expr: string) => string;\n marks?: (model: UnitModel, selCmpt:SelectionComponent, marks: any[]) => any[];\n}\n\nimport inputs from './inputs';\nimport nearest from './nearest';\nimport project from './project';\nimport scales from './scales';\nimport toggle from './toggle';\nimport translate from './translate';\nimport zoom from './zoom';\nconst compilers: Dict = {project, toggle, scales,\n translate, zoom, inputs, nearest};\n\nexport function forEachTransform(selCmpt: SelectionComponent, cb: (tx: TransformCompiler) => void) {\n for (const t in compilers) {\n if (compilers[t].has(selCmpt)) {\n cb(compilers[t]);\n }\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/transforms/translate.d.ts b/build/src/compile/selection/transforms/translate.d.ts new file mode 100644 index 0000000000..10335d8543 --- /dev/null +++ b/build/src/compile/selection/transforms/translate.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const translate: TransformCompiler; +export default translate; diff --git a/build/src/compile/selection/transforms/translate.js b/build/src/compile/selection/transforms/translate.js new file mode 100644 index 0000000000..3c27d26fd1 --- /dev/null +++ b/build/src/compile/selection/transforms/translate.js @@ -0,0 +1,74 @@ +import { selector as parseSelector } from 'vega-event-selector'; +import { X, Y } from '../../../channel'; +import { BRUSH as INTERVAL_BRUSH } from '../interval'; +import { channelSignalName, positionalProjections } from '../selection'; +import scalesCompiler, { domain } from './scales'; +var ANCHOR = '_translate_anchor'; +var DELTA = '_translate_delta'; +var translate = { + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.translate; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name; + var hasScales = scalesCompiler.has(selCmpt); + var anchor = name + ANCHOR; + var _a = positionalProjections(selCmpt), x = _a.x, y = _a.y; + var events = parseSelector(selCmpt.translate, 'scope'); + if (!hasScales) { + events = events.map(function (e) { return (e.between[0].markname = name + INTERVAL_BRUSH, e); }); + } + signals.push({ + name: anchor, + value: {}, + on: [{ + events: events.map(function (e) { return e.between[0]; }), + update: '{x: x(unit), y: y(unit)' + + (x !== null ? ', extent_x: ' + (hasScales ? domain(model, X) : + "slice(" + channelSignalName(selCmpt, 'x', 'visual') + ")") : '') + + (y !== null ? ', extent_y: ' + (hasScales ? domain(model, Y) : + "slice(" + channelSignalName(selCmpt, 'y', 'visual') + ")") : '') + '}' + }] + }, { + name: name + DELTA, + value: {}, + on: [{ + events: events, + update: "{x: " + anchor + ".x - x(unit), y: " + anchor + ".y - y(unit)}" + }] + }); + if (x !== null) { + onDelta(model, selCmpt, X, 'width', signals); + } + if (y !== null) { + onDelta(model, selCmpt, Y, 'height', signals); + } + return signals; + } +}; +export default translate; +function onDelta(model, selCmpt, channel, size, signals) { + var name = selCmpt.name; + var hasScales = scalesCompiler.has(selCmpt); + var signal = signals.filter(function (s) { + return s.name === channelSignalName(selCmpt, channel, hasScales ? 'data' : 'visual'); + })[0]; + var anchor = name + ANCHOR; + var delta = name + DELTA; + var sizeSg = model.getSizeSignalRef(size).signal; + var scaleCmpt = model.getScaleComponent(channel); + var scaleType = scaleCmpt.get('type'); + var sign = hasScales && channel === X ? '-' : ''; // Invert delta when panning x-scales. + var extent = anchor + ".extent_" + channel; + var offset = "" + sign + delta + "." + channel + " / " + (hasScales ? "" + sizeSg : "span(" + extent + ")"); + var panFn = !hasScales ? 'panLinear' : + scaleType === 'log' ? 'panLog' : + scaleType === 'pow' ? 'panPow' : 'panLinear'; + var update = panFn + "(" + extent + ", " + offset + + (hasScales && scaleType === 'pow' ? ", " + (scaleCmpt.get('exponent') || 1) : '') + ')'; + signal.on.push({ + events: { signal: delta }, + update: hasScales ? update : "clampRange(" + update + ", 0, " + sizeSg + ")" + }); +} +//# sourceMappingURL=translate.js.map \ No newline at end of file diff --git a/build/src/compile/selection/transforms/translate.js.map b/build/src/compile/selection/transforms/translate.js.map new file mode 100644 index 0000000000..26c55df193 --- /dev/null +++ b/build/src/compile/selection/transforms/translate.js.map @@ -0,0 +1 @@ +{"version":3,"file":"translate.js","sourceRoot":"","sources":["../../../../../src/compile/selection/transforms/translate.ts"],"names":[],"mappings":"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","sourcesContent":["import {selector as parseSelector} from 'vega-event-selector';\n\nimport {ScaleChannel, X, Y} from '../../../channel';\nimport {VgSignal} from '../../../vega.schema';\nimport {BRUSH as INTERVAL_BRUSH} from '../interval';\nimport {channelSignalName, positionalProjections, SelectionComponent} from '../selection';\nimport {UnitModel} from './../../unit';\nimport scalesCompiler, {domain} from './scales';\nimport {TransformCompiler} from './transforms';\n\n\nconst ANCHOR = '_translate_anchor';\nconst DELTA = '_translate_delta';\n\nconst translate:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.translate;\n },\n\n signals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const anchor = name + ANCHOR;\n const {x, y} = positionalProjections(selCmpt);\n let events = parseSelector(selCmpt.translate, 'scope');\n\n if (!hasScales) {\n events = events.map((e) => (e.between[0].markname = name + INTERVAL_BRUSH, e));\n }\n\n signals.push({\n name: anchor,\n value: {},\n on: [{\n events: events.map((e) => e.between[0]),\n update: '{x: x(unit), y: y(unit)' +\n (x !== null ? ', extent_x: ' + (hasScales ? domain(model, X) :\n `slice(${channelSignalName(selCmpt, 'x', 'visual')})`) : '') +\n\n (y !== null ? ', extent_y: ' + (hasScales ? domain(model, Y) :\n `slice(${channelSignalName(selCmpt, 'y', 'visual')})`) : '') + '}'\n }]\n }, {\n name: name + DELTA,\n value: {},\n on: [{\n events: events,\n update: `{x: ${anchor}.x - x(unit), y: ${anchor}.y - y(unit)}`\n }]\n });\n\n if (x !== null) {\n onDelta(model, selCmpt, X, 'width', signals);\n }\n\n if (y !== null) {\n onDelta(model, selCmpt, Y, 'height', signals);\n }\n\n return signals;\n }\n};\n\nexport default translate;\n\nfunction onDelta(model: UnitModel, selCmpt: SelectionComponent, channel: ScaleChannel, size: 'width' | 'height', signals: VgSignal[]) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const signal = signals.filter(s => {\n return s.name === channelSignalName(selCmpt, channel, hasScales ? 'data' : 'visual');\n })[0];\n const anchor = name + ANCHOR;\n const delta = name + DELTA;\n const sizeSg = model.getSizeSignalRef(size).signal;\n const scaleCmpt = model.getScaleComponent(channel);\n const scaleType = scaleCmpt.get('type');\n const sign = hasScales && channel === X ? '-' : ''; // Invert delta when panning x-scales.\n const extent = `${anchor}.extent_${channel}`;\n const offset = `${sign}${delta}.${channel} / ` + (hasScales ? `${sizeSg}` : `span(${extent})`);\n const panFn = !hasScales ? 'panLinear' :\n scaleType === 'log' ? 'panLog' :\n scaleType === 'pow' ? 'panPow' : 'panLinear';\n const update = `${panFn}(${extent}, ${offset}` +\n (hasScales && scaleType === 'pow' ? `, ${scaleCmpt.get('exponent') || 1}` : '') + ')';\n\n signal.on.push({\n events: {signal: delta},\n update: hasScales ? update : `clampRange(${update}, 0, ${sizeSg})`\n });\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/selection/transforms/zoom.d.ts b/build/src/compile/selection/transforms/zoom.d.ts new file mode 100644 index 0000000000..1147a5bf64 --- /dev/null +++ b/build/src/compile/selection/transforms/zoom.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const zoom: TransformCompiler; +export default zoom; diff --git a/build/src/compile/selection/transforms/zoom.js b/build/src/compile/selection/transforms/zoom.js new file mode 100644 index 0000000000..a7bac568a7 --- /dev/null +++ b/build/src/compile/selection/transforms/zoom.js @@ -0,0 +1,74 @@ +import { selector as parseSelector } from 'vega-event-selector'; +import { stringValue } from 'vega-util'; +import { X, Y } from '../../../channel'; +import { BRUSH as INTERVAL_BRUSH } from '../interval'; +import { channelSignalName, positionalProjections } from '../selection'; +import { default as scalesCompiler, domain } from './scales'; +var ANCHOR = '_zoom_anchor'; +var DELTA = '_zoom_delta'; +var zoom = { + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.zoom; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name; + var hasScales = scalesCompiler.has(selCmpt); + var delta = name + DELTA; + var _a = positionalProjections(selCmpt), x = _a.x, y = _a.y; + var sx = stringValue(model.scaleName(X)); + var sy = stringValue(model.scaleName(Y)); + var events = parseSelector(selCmpt.zoom, 'scope'); + if (!hasScales) { + events = events.map(function (e) { return (e.markname = name + INTERVAL_BRUSH, e); }); + } + signals.push({ + name: name + ANCHOR, + on: [{ + events: events, + update: !hasScales ? "{x: x(unit), y: y(unit)}" : + '{' + [ + (sx ? "x: invert(" + sx + ", x(unit))" : ''), + (sy ? "y: invert(" + sy + ", y(unit))" : '') + ].filter(function (expr) { return !!expr; }).join(', ') + '}' + }] + }, { + name: delta, + on: [{ + events: events, + force: true, + update: 'pow(1.001, event.deltaY * pow(16, event.deltaMode))' + }] + }); + if (x !== null) { + onDelta(model, selCmpt, 'x', 'width', signals); + } + if (y !== null) { + onDelta(model, selCmpt, 'y', 'height', signals); + } + return signals; + } +}; +export default zoom; +function onDelta(model, selCmpt, channel, size, signals) { + var name = selCmpt.name; + var hasScales = scalesCompiler.has(selCmpt); + var signal = signals.filter(function (s) { + return s.name === channelSignalName(selCmpt, channel, hasScales ? 'data' : 'visual'); + })[0]; + var sizeSg = model.getSizeSignalRef(size).signal; + var scaleCmpt = model.getScaleComponent(channel); + var scaleType = scaleCmpt.get('type'); + var base = hasScales ? domain(model, channel) : signal.name; + var delta = name + DELTA; + var anchor = "" + name + ANCHOR + "." + channel; + var zoomFn = !hasScales ? 'zoomLinear' : + scaleType === 'log' ? 'zoomLog' : + scaleType === 'pow' ? 'zoomPow' : 'zoomLinear'; + var update = zoomFn + "(" + base + ", " + anchor + ", " + delta + + (hasScales && scaleType === 'pow' ? ", " + (scaleCmpt.get('exponent') || 1) : '') + ')'; + signal.on.push({ + events: { signal: delta }, + update: hasScales ? update : "clampRange(" + update + ", 0, " + sizeSg + ")" + }); +} +//# sourceMappingURL=zoom.js.map \ No newline at end of file diff --git a/build/src/compile/selection/transforms/zoom.js.map b/build/src/compile/selection/transforms/zoom.js.map new file mode 100644 index 0000000000..4f4df9c688 --- /dev/null +++ b/build/src/compile/selection/transforms/zoom.js.map @@ -0,0 +1 @@ +{"version":3,"file":"zoom.js","sourceRoot":"","sources":["../../../../../src/compile/selection/transforms/zoom.ts"],"names":[],"mappings":"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","sourcesContent":["import {selector as parseSelector} from 'vega-event-selector';\nimport {stringValue} from 'vega-util';\nimport {ScaleChannel, X, Y} from '../../../channel';\nimport {VgSignal} from '../../../vega.schema';\nimport {BRUSH as INTERVAL_BRUSH} from '../interval';\nimport {channelSignalName, positionalProjections, SelectionComponent} from '../selection';\nimport {UnitModel} from './../../unit';\nimport {default as scalesCompiler, domain} from './scales';\nimport {TransformCompiler} from './transforms';\n\n\nconst ANCHOR = '_zoom_anchor';\nconst DELTA = '_zoom_delta';\n\nconst zoom:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.zoom;\n },\n\n signals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const delta = name + DELTA;\n const {x, y} = positionalProjections(selCmpt);\n const sx = stringValue(model.scaleName(X));\n const sy = stringValue(model.scaleName(Y));\n let events = parseSelector(selCmpt.zoom, 'scope');\n\n if (!hasScales) {\n events = events.map((e) => (e.markname = name + INTERVAL_BRUSH, e));\n }\n\n signals.push({\n name: name + ANCHOR,\n on: [{\n events: events,\n update: !hasScales ? `{x: x(unit), y: y(unit)}` :\n '{' + [\n (sx ? `x: invert(${sx}, x(unit))` : ''),\n (sy ? `y: invert(${sy}, y(unit))` : '')\n ].filter((expr) => !!expr).join(', ') + '}'\n }]\n }, {\n name: delta,\n on: [{\n events: events,\n force: true,\n update: 'pow(1.001, event.deltaY * pow(16, event.deltaMode))'\n }]\n });\n\n if (x !== null) {\n onDelta(model, selCmpt, 'x', 'width', signals);\n }\n\n if (y !== null) {\n onDelta(model, selCmpt, 'y', 'height', signals);\n }\n\n return signals;\n }\n};\n\nexport default zoom;\n\nfunction onDelta(model: UnitModel, selCmpt: SelectionComponent, channel: ScaleChannel, size: 'width' | 'height', signals: VgSignal[]) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const signal = signals.filter(s => {\n return s.name === channelSignalName(selCmpt, channel, hasScales ? 'data' : 'visual');\n })[0];\n const sizeSg = model.getSizeSignalRef(size).signal;\n const scaleCmpt = model.getScaleComponent(channel);\n const scaleType = scaleCmpt.get('type');\n const base = hasScales ? domain(model, channel) : signal.name;\n const delta = name + DELTA;\n const anchor = `${name}${ANCHOR}.${channel}`;\n const zoomFn = !hasScales ? 'zoomLinear' :\n scaleType === 'log' ? 'zoomLog' :\n scaleType === 'pow' ? 'zoomPow' : 'zoomLinear';\n const update = `${zoomFn}(${base}, ${anchor}, ${delta}` +\n (hasScales && scaleType === 'pow' ? `, ${scaleCmpt.get('exponent') || 1}` : '') + ')';\n\n signal.on.push({\n events: {signal: delta},\n update: hasScales ? update : `clampRange(${update}, 0, ${sizeSg})`\n });\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/split.d.ts b/build/src/compile/split.d.ts new file mode 100644 index 0000000000..0586861945 --- /dev/null +++ b/build/src/compile/split.d.ts @@ -0,0 +1,33 @@ +/** + * Generic class for storing properties that are explicitly specified + * and implicitly determined by the compiler. + * This is important for scale/axis/legend merging as + * we want to prioritize properties that users explicitly specified. + */ +export declare class Split { + readonly explicit: Partial; + readonly implicit: Partial; + constructor(explicit?: Partial, implicit?: Partial); + clone(): Split; + combine(): Partial; + get(key: K): T[K]; + getWithExplicit(key: K): Explicit; + setWithExplicit(key: K, value: Explicit): void; + set(key: K, value: T[K], explicit: boolean): this; + copyKeyFromSplit(key: keyof T, s: Split): void; + copyKeyFromObject>(key: keyof T, s: S): void; + /** + * Merge split object into this split object. Properties from the other split + * overwrite properties from this split. + */ + copyAll(other: Split): void; +} +export interface Explicit { + explicit: boolean; + value: T; +} +export declare function makeExplicit(value: T): Explicit; +export declare function makeImplicit(value: T): Explicit; +export declare function tieBreakByComparing(compare: (v1: T, v2: T) => number): (v1: Explicit, v2: Explicit, property: keyof S, propertyOf: string | number | symbol) => Explicit; +export declare function defaultTieBreaker(v1: Explicit, v2: Explicit, property: keyof S, propertyOf: string | number | symbol): Explicit; +export declare function mergeValuesWithExplicit(v1: Explicit, v2: Explicit, property: keyof S, propertyOf: 'scale' | 'axis' | 'legend' | '', tieBreaker?: (v1: Explicit, v2: Explicit, property: keyof S, propertyOf: string) => Explicit): Explicit; diff --git a/build/src/compile/split.js b/build/src/compile/split.js new file mode 100644 index 0000000000..0b2f0a9d92 --- /dev/null +++ b/build/src/compile/split.js @@ -0,0 +1,128 @@ +import * as tslib_1 from "tslib"; +import * as log from '../log'; +import { duplicate, keys, stringify } from '../util'; +/** + * Generic class for storing properties that are explicitly specified + * and implicitly determined by the compiler. + * This is important for scale/axis/legend merging as + * we want to prioritize properties that users explicitly specified. + */ +var Split = /** @class */ (function () { + function Split(explicit, implicit) { + if (explicit === void 0) { explicit = {}; } + if (implicit === void 0) { implicit = {}; } + this.explicit = explicit; + this.implicit = implicit; + } + Split.prototype.clone = function () { + return new Split(duplicate(this.explicit), duplicate(this.implicit)); + }; + Split.prototype.combine = function () { + // FIXME remove "as any". + // Add "as any" to avoid an error "Spread types may only be created from object types". + return tslib_1.__assign({}, this.explicit, this.implicit); + }; + Split.prototype.get = function (key) { + // Explicit has higher precedence + return this.explicit[key] !== undefined ? this.explicit[key] : this.implicit[key]; + }; + Split.prototype.getWithExplicit = function (key) { + // Explicit has higher precedence + if (this.explicit[key] !== undefined) { + return { explicit: true, value: this.explicit[key] }; + } + else if (this.implicit[key] !== undefined) { + return { explicit: false, value: this.implicit[key] }; + } + return { explicit: false, value: undefined }; + }; + Split.prototype.setWithExplicit = function (key, value) { + if (value.value !== undefined) { + this.set(key, value.value, value.explicit); + } + }; + Split.prototype.set = function (key, value, explicit) { + delete this[explicit ? 'implicit' : 'explicit'][key]; + this[explicit ? 'explicit' : 'implicit'][key] = value; + return this; + }; + Split.prototype.copyKeyFromSplit = function (key, s) { + // Explicit has higher precedence + if (s.explicit[key] !== undefined) { + this.set(key, s.explicit[key], true); + } + else if (s.implicit[key] !== undefined) { + this.set(key, s.implicit[key], false); + } + }; + Split.prototype.copyKeyFromObject = function (key, s) { + // Explicit has higher precedence + if (s[key] !== undefined) { + this.set(key, s[key], true); + } + }; + /** + * Merge split object into this split object. Properties from the other split + * overwrite properties from this split. + */ + Split.prototype.copyAll = function (other) { + for (var _i = 0, _a = keys(other.combine()); _i < _a.length; _i++) { + var key = _a[_i]; + var val = other.getWithExplicit(key); + this.setWithExplicit(key, val); + } + }; + return Split; +}()); +export { Split }; +export function makeExplicit(value) { + return { + explicit: true, + value: value + }; +} +export function makeImplicit(value) { + return { + explicit: false, + value: value + }; +} +export function tieBreakByComparing(compare) { + return function (v1, v2, property, propertyOf) { + var diff = compare(v1.value, v2.value); + if (diff > 0) { + return v1; + } + else if (diff < 0) { + return v2; + } + return defaultTieBreaker(v1, v2, property, propertyOf); + }; +} +export function defaultTieBreaker(v1, v2, property, propertyOf) { + if (v1.explicit && v2.explicit) { + log.warn(log.message.mergeConflictingProperty(property, propertyOf, v1.value, v2.value)); + } + // If equal score, prefer v1. + return v1; +} +export function mergeValuesWithExplicit(v1, v2, property, propertyOf, tieBreaker) { + if (tieBreaker === void 0) { tieBreaker = defaultTieBreaker; } + if (v1 === undefined || v1.value === undefined) { + // For first run + return v2; + } + if (v1.explicit && !v2.explicit) { + return v1; + } + else if (v2.explicit && !v1.explicit) { + return v2; + } + else if (stringify(v1.value) === stringify(v2.value)) { + return v1; + } + else { + return tieBreaker(v1, v2, property, propertyOf); + } +} +//# sourceMappingURL=split.js.map \ No newline at end of file diff --git a/build/src/compile/split.js.map b/build/src/compile/split.js.map new file mode 100644 index 0000000000..c015e1cad2 --- /dev/null +++ b/build/src/compile/split.js.map @@ -0,0 +1 @@ +{"version":3,"file":"split.js","sourceRoot":"","sources":["../../../src/compile/split.ts"],"names":[],"mappings":"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","sourcesContent":["import * as log from '../log';\nimport {duplicate, keys, stringify} from '../util';\n\n\n/**\n * Generic class for storing properties that are explicitly specified\n * and implicitly determined by the compiler.\n * This is important for scale/axis/legend merging as\n * we want to prioritize properties that users explicitly specified.\n */\nexport class Split {\n constructor(\n public readonly explicit: Partial = {},\n public readonly implicit: Partial = {}\n ) {}\n\n public clone() {\n return new Split(duplicate(this.explicit), duplicate(this.implicit));\n }\n\n public combine(): Partial {\n // FIXME remove \"as any\".\n // Add \"as any\" to avoid an error \"Spread types may only be created from object types\".\n return {\n ...this.explicit as any, // Explicit properties comes first\n ...this.implicit as any\n };\n }\n\n public get(key: K): T[K] {\n // Explicit has higher precedence\n return this.explicit[key] !== undefined ? this.explicit[key] : this.implicit[key];\n }\n\n public getWithExplicit(key: K): Explicit {\n // Explicit has higher precedence\n if (this.explicit[key] !== undefined) {\n return {explicit: true, value: this.explicit[key]};\n } else if (this.implicit[key] !== undefined) {\n return {explicit: false, value: this.implicit[key]};\n }\n return {explicit: false, value: undefined};\n }\n\n public setWithExplicit(key: K, value: Explicit) {\n if (value.value !== undefined) {\n this.set(key, value.value, value.explicit);\n }\n }\n\n public set(key: K, value: T[K], explicit: boolean) {\n delete this[explicit ? 'implicit' : 'explicit'][key];\n this[explicit ? 'explicit' : 'implicit'][key] = value;\n return this;\n }\n\n public copyKeyFromSplit(key: keyof T, s: Split) {\n // Explicit has higher precedence\n if (s.explicit[key] !== undefined) {\n this.set(key, s.explicit[key], true);\n } else if (s.implicit[key] !== undefined) {\n this.set(key, s.implicit[key], false);\n }\n }\n public copyKeyFromObject>(key: keyof T, s: S) {\n // Explicit has higher precedence\n if (s[key] !== undefined) {\n this.set(key, s[key], true);\n }\n }\n\n /**\n * Merge split object into this split object. Properties from the other split\n * overwrite properties from this split.\n */\n public copyAll(other: Split) {\n for (const key of keys(other.combine())) {\n const val = other.getWithExplicit(key);\n this.setWithExplicit(key, val);\n }\n }\n}\n\nexport interface Explicit {\n explicit: boolean;\n value: T;\n}\n\n\nexport function makeExplicit(value: T): Explicit {\n return {\n explicit: true,\n value\n };\n}\n\nexport function makeImplicit(value: T): Explicit {\n return {\n explicit: false,\n value\n };\n}\n\nexport function tieBreakByComparing(compare: (v1: T, v2: T) => number) {\n return (v1: Explicit, v2: Explicit, property: keyof S | never, propertyOf: string | number | symbol): Explicit => {\n const diff = compare(v1.value, v2.value);\n if (diff > 0) {\n return v1;\n } else if (diff < 0) {\n return v2;\n }\n return defaultTieBreaker(v1, v2, property, propertyOf);\n };\n}\n\nexport function defaultTieBreaker(v1: Explicit, v2: Explicit, property: keyof S, propertyOf: string | number | symbol) {\n if (v1.explicit && v2.explicit) {\n log.warn(log.message.mergeConflictingProperty(property, propertyOf, v1.value, v2.value));\n }\n // If equal score, prefer v1.\n return v1;\n}\n\nexport function mergeValuesWithExplicit(\n v1: Explicit, v2: Explicit,\n property: keyof S,\n propertyOf: 'scale' | 'axis' | 'legend' | '',\n tieBreaker: (v1: Explicit, v2: Explicit, property: keyof S, propertyOf: string) => Explicit = defaultTieBreaker\n ) {\n if (v1 === undefined || v1.value === undefined) {\n // For first run\n return v2;\n }\n\n if (v1.explicit && !v2.explicit) {\n return v1;\n } else if (v2.explicit && !v1.explicit) {\n return v2;\n } else if (stringify(v1.value) === stringify(v2.value)) {\n return v1;\n } else {\n return tieBreaker(v1, v2, property, propertyOf);\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compile/unit.d.ts b/build/src/compile/unit.d.ts new file mode 100644 index 0000000000..cc7f9d80ae --- /dev/null +++ b/build/src/compile/unit.d.ts @@ -0,0 +1,65 @@ +import { Axis } from '../axis'; +import { Channel, ScaleChannel, SingleDefChannel } from '../channel'; +import { Config } from '../config'; +import * as vlEncoding from '../encoding'; +import { Encoding } from '../encoding'; +import { FieldDef } from '../fielddef'; +import { Legend } from '../legend'; +import { Mark, MarkDef } from '../mark'; +import { Projection } from '../projection'; +import { Domain } from '../scale'; +import { SelectionDef } from '../selection'; +import { LayoutSizeMixins, NormalizedUnitSpec } from '../spec'; +import { StackProperties } from '../stack'; +import { Dict } from '../util'; +import { VgData, VgEncodeEntry, VgLayout, VgSignal } from '../vega.schema'; +import { AxisIndex } from './axis/component'; +import { LegendIndex } from './legend/component'; +import { Model, ModelWithField } from './model'; +import { RepeaterValue } from './repeater'; +import { ScaleIndex } from './scale/component'; +/** + * Internal model of Vega-Lite specification for the compiler. + */ +export declare class UnitModel extends ModelWithField { + fit: boolean; + readonly type: 'unit'; + readonly markDef: MarkDef; + readonly encoding: Encoding; + readonly specifiedScales: ScaleIndex; + readonly stack: StackProperties; + protected specifiedAxes: AxisIndex; + protected specifiedLegends: LegendIndex; + specifiedProjection: Projection; + readonly selection: Dict; + children: Model[]; + constructor(spec: NormalizedUnitSpec, parent: Model, parentGivenName: string, parentGivenSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean); + readonly hasProjection: boolean; + /** + * Return specified Vega-lite scale domain for a particular channel + * @param channel + */ + scaleDomain(channel: ScaleChannel): Domain; + axis(channel: Channel): Axis; + legend(channel: Channel): Legend; + private initScales; + private initAxes; + private initLegend; + parseData(): void; + parseLayoutSize(): void; + parseSelection(): void; + parseMarkGroup(): void; + parseAxisAndHeader(): void; + assembleSelectionTopLevelSignals(signals: any[]): VgSignal[]; + assembleSelectionSignals(): VgSignal[]; + assembleSelectionData(data: VgData[]): VgData[]; + assembleLayout(): VgLayout; + assembleLayoutSignals(): VgSignal[]; + assembleMarks(): any[]; + assembleLayoutSize(): VgEncodeEntry; + protected getMapping(): vlEncoding.Encoding; + toSpec(excludeConfig?: any, excludeData?: any): any; + readonly mark: Mark; + channelHasField(channel: Channel): boolean; + fieldDef(channel: SingleDefChannel): FieldDef; +} diff --git a/build/src/compile/unit.js b/build/src/compile/unit.js new file mode 100644 index 0000000000..49eb21d622 --- /dev/null +++ b/build/src/compile/unit.js @@ -0,0 +1,209 @@ +import * as tslib_1 from "tslib"; +import { GEOPOSITION_CHANNELS, NONPOSITION_SCALE_CHANNELS, SCALE_CHANNELS, X, Y } from '../channel'; +import * as vlEncoding from '../encoding'; +import { normalizeEncoding } from '../encoding'; +import { getFieldDef, hasConditionalFieldDef, isFieldDef } from '../fielddef'; +import { GEOSHAPE, isMarkDef } from '../mark'; +import { stack } from '../stack'; +import { duplicate } from '../util'; +import { parseUnitAxis } from './axis/parse'; +import { parseData } from './data/parse'; +import { assembleLayoutSignals } from './layoutsize/assemble'; +import { parseUnitLayoutSize } from './layoutsize/parse'; +import { normalizeMarkDef } from './mark/init'; +import { parseMarkGroup } from './mark/mark'; +import { isLayerModel, ModelWithField } from './model'; +import { replaceRepeaterInEncoding } from './repeater'; +import { assembleTopLevelSignals, assembleUnitSelectionData, assembleUnitSelectionMarks, assembleUnitSelectionSignals, parseUnitSelection } from './selection/selection'; +/** + * Internal model of Vega-Lite specification for the compiler. + */ +var UnitModel = /** @class */ (function (_super) { + tslib_1.__extends(UnitModel, _super); + function UnitModel(spec, parent, parentGivenName, parentGivenSize, repeater, config, fit) { + if (parentGivenSize === void 0) { parentGivenSize = {}; } + var _this = _super.call(this, spec, parent, parentGivenName, config, repeater, undefined) || this; + _this.fit = fit; + _this.type = 'unit'; + _this.specifiedScales = {}; + _this.specifiedAxes = {}; + _this.specifiedLegends = {}; + _this.specifiedProjection = {}; + _this.selection = {}; + _this.children = []; + _this.initSize(tslib_1.__assign({}, parentGivenSize, (spec.width ? { width: spec.width } : {}), (spec.height ? { height: spec.height } : {}))); + var mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var encoding = _this.encoding = normalizeEncoding(replaceRepeaterInEncoding(spec.encoding || {}, repeater), mark); + _this.markDef = normalizeMarkDef(spec.mark, encoding, config); + // calculate stack properties + _this.stack = stack(mark, encoding, _this.config.stack); + _this.specifiedScales = _this.initScales(mark, encoding); + _this.specifiedAxes = _this.initAxes(encoding); + _this.specifiedLegends = _this.initLegend(encoding); + _this.specifiedProjection = spec.projection; + // Selections will be initialized upon parse. + _this.selection = spec.selection; + return _this; + } + Object.defineProperty(UnitModel.prototype, "hasProjection", { + get: function () { + var encoding = this.encoding; + var isGeoShapeMark = this.mark === GEOSHAPE; + var hasGeoPosition = encoding && GEOPOSITION_CHANNELS.some(function (channel) { return isFieldDef(encoding[channel]); }); + return isGeoShapeMark || hasGeoPosition; + }, + enumerable: true, + configurable: true + }); + /** + * Return specified Vega-lite scale domain for a particular channel + * @param channel + */ + UnitModel.prototype.scaleDomain = function (channel) { + var scale = this.specifiedScales[channel]; + return scale ? scale.domain : undefined; + }; + UnitModel.prototype.axis = function (channel) { + return this.specifiedAxes[channel]; + }; + UnitModel.prototype.legend = function (channel) { + return this.specifiedLegends[channel]; + }; + UnitModel.prototype.initScales = function (mark, encoding) { + return SCALE_CHANNELS.reduce(function (scales, channel) { + var fieldDef; + var specifiedScale; + var channelDef = encoding[channel]; + if (isFieldDef(channelDef)) { + fieldDef = channelDef; + specifiedScale = channelDef.scale; + } + else if (hasConditionalFieldDef(channelDef)) { + fieldDef = channelDef.condition; + specifiedScale = channelDef.condition['scale']; + } + else if (channel === 'x') { + fieldDef = getFieldDef(encoding.x2); + } + else if (channel === 'y') { + fieldDef = getFieldDef(encoding.y2); + } + if (fieldDef) { + scales[channel] = specifiedScale || {}; + } + return scales; + }, {}); + }; + UnitModel.prototype.initAxes = function (encoding) { + return [X, Y].reduce(function (_axis, channel) { + // Position Axis + // TODO: handle ConditionFieldDef + var channelDef = encoding[channel]; + if (isFieldDef(channelDef) || + (channel === X && isFieldDef(encoding.x2)) || + (channel === Y && isFieldDef(encoding.y2))) { + var axisSpec = isFieldDef(channelDef) ? channelDef.axis : null; + // We no longer support false in the schema, but we keep false here for backward compatibility. + if (axisSpec !== null && axisSpec !== false) { + _axis[channel] = tslib_1.__assign({}, axisSpec); + } + } + return _axis; + }, {}); + }; + UnitModel.prototype.initLegend = function (encoding) { + return NONPOSITION_SCALE_CHANNELS.reduce(function (_legend, channel) { + var channelDef = encoding[channel]; + if (channelDef) { + var legend = isFieldDef(channelDef) ? channelDef.legend : + (hasConditionalFieldDef(channelDef)) ? channelDef.condition['legend'] : null; + if (legend !== null && legend !== false) { + _legend[channel] = tslib_1.__assign({}, legend); + } + } + return _legend; + }, {}); + }; + UnitModel.prototype.parseData = function () { + this.component.data = parseData(this); + }; + UnitModel.prototype.parseLayoutSize = function () { + parseUnitLayoutSize(this); + }; + UnitModel.prototype.parseSelection = function () { + this.component.selection = parseUnitSelection(this, this.selection); + }; + UnitModel.prototype.parseMarkGroup = function () { + this.component.mark = parseMarkGroup(this); + }; + UnitModel.prototype.parseAxisAndHeader = function () { + this.component.axes = parseUnitAxis(this); + }; + UnitModel.prototype.assembleSelectionTopLevelSignals = function (signals) { + return assembleTopLevelSignals(this, signals); + }; + UnitModel.prototype.assembleSelectionSignals = function () { + return assembleUnitSelectionSignals(this, []); + }; + UnitModel.prototype.assembleSelectionData = function (data) { + return assembleUnitSelectionData(this, data); + }; + UnitModel.prototype.assembleLayout = function () { + return null; + }; + UnitModel.prototype.assembleLayoutSignals = function () { + return assembleLayoutSignals(this); + }; + UnitModel.prototype.assembleMarks = function () { + var marks = this.component.mark || []; + // If this unit is part of a layer, selections should augment + // all in concert rather than each unit individually. This + // ensures correct interleaving of clipping and brushed marks. + if (!this.parent || !isLayerModel(this.parent)) { + marks = assembleUnitSelectionMarks(this, marks); + } + return marks.map(this.correctDataNames); + }; + UnitModel.prototype.assembleLayoutSize = function () { + return { + width: this.getSizeSignalRef('width'), + height: this.getSizeSignalRef('height') + }; + }; + UnitModel.prototype.getMapping = function () { + return this.encoding; + }; + UnitModel.prototype.toSpec = function (excludeConfig, excludeData) { + var encoding = duplicate(this.encoding); + var spec; + spec = { + mark: this.markDef, + encoding: encoding + }; + if (!excludeConfig) { + spec.config = duplicate(this.config); + } + if (!excludeData) { + spec.data = duplicate(this.data); + } + // remove defaults + return spec; + }; + Object.defineProperty(UnitModel.prototype, "mark", { + get: function () { + return this.markDef.type; + }, + enumerable: true, + configurable: true + }); + UnitModel.prototype.channelHasField = function (channel) { + return vlEncoding.channelHasField(this.encoding, channel); + }; + UnitModel.prototype.fieldDef = function (channel) { + var channelDef = this.encoding[channel]; + return getFieldDef(channelDef); + }; + return UnitModel; +}(ModelWithField)); +export { UnitModel }; +//# sourceMappingURL=unit.js.map \ No newline at end of file diff --git a/build/src/compile/unit.js.map b/build/src/compile/unit.js.map new file mode 100644 index 0000000000..d0dbe0c18d --- /dev/null +++ b/build/src/compile/unit.js.map @@ -0,0 +1 @@ +{"version":3,"file":"unit.js","sourceRoot":"","sources":["../../../src/compile/unit.ts"],"names":[],"mappings":"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","sourcesContent":["import {Axis} from '../axis';\nimport {Channel, GEOPOSITION_CHANNELS, NONPOSITION_SCALE_CHANNELS, SCALE_CHANNELS, ScaleChannel, SingleDefChannel, X, Y} from '../channel';\nimport {Config} from '../config';\nimport * as vlEncoding from '../encoding';\nimport {Encoding, normalizeEncoding} from '../encoding';\nimport {ChannelDef, FieldDef, getFieldDef, hasConditionalFieldDef, isFieldDef} from '../fielddef';\nimport {Legend} from '../legend';\nimport {GEOSHAPE, isMarkDef, Mark, MarkDef} from '../mark';\nimport {Projection} from '../projection';\nimport {Domain, Scale} from '../scale';\nimport {SelectionDef} from '../selection';\nimport {LayoutSizeMixins, NormalizedUnitSpec} from '../spec';\nimport {stack, StackProperties} from '../stack';\nimport {Dict, duplicate} from '../util';\nimport {VgData, VgEncodeEntry, VgLayout, VgSignal} from '../vega.schema';\nimport {AxisIndex} from './axis/component';\nimport {parseUnitAxis} from './axis/parse';\nimport {parseData} from './data/parse';\nimport {assembleLayoutSignals} from './layoutsize/assemble';\nimport {parseUnitLayoutSize} from './layoutsize/parse';\nimport {LegendIndex} from './legend/component';\nimport {normalizeMarkDef} from './mark/init';\nimport {parseMarkGroup} from './mark/mark';\nimport {isLayerModel, Model, ModelWithField} from './model';\nimport {RepeaterValue, replaceRepeaterInEncoding} from './repeater';\nimport {ScaleIndex} from './scale/component';\nimport {assembleTopLevelSignals, assembleUnitSelectionData, assembleUnitSelectionMarks, assembleUnitSelectionSignals, parseUnitSelection} from './selection/selection';\n\n\n/**\n * Internal model of Vega-Lite specification for the compiler.\n */\nexport class UnitModel extends ModelWithField {\n public readonly type: 'unit' = 'unit';\n public readonly markDef: MarkDef;\n public readonly encoding: Encoding;\n\n public readonly specifiedScales: ScaleIndex = {};\n\n public readonly stack: StackProperties;\n\n protected specifiedAxes: AxisIndex = {};\n\n protected specifiedLegends: LegendIndex = {};\n\n public specifiedProjection: Projection = {};\n\n public readonly selection: Dict = {};\n public children: Model[] = [];\n\n constructor(spec: NormalizedUnitSpec, parent: Model, parentGivenName: string,\n parentGivenSize: LayoutSizeMixins = {}, repeater: RepeaterValue, config: Config, public fit: boolean) {\n\n super(spec, parent, parentGivenName, config, repeater, undefined);\n this.initSize({\n ...parentGivenSize,\n ...(spec.width ? {width: spec.width} : {}),\n ...(spec.height ? {height: spec.height} : {})\n });\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n\n const encoding = this.encoding = normalizeEncoding(replaceRepeaterInEncoding(spec.encoding || {}, repeater), mark);\n\n this.markDef = normalizeMarkDef(spec.mark, encoding, config);\n\n // calculate stack properties\n this.stack = stack(mark, encoding, this.config.stack);\n this.specifiedScales = this.initScales(mark, encoding);\n\n this.specifiedAxes = this.initAxes(encoding);\n this.specifiedLegends = this.initLegend(encoding);\n this.specifiedProjection = spec.projection;\n\n // Selections will be initialized upon parse.\n this.selection = spec.selection;\n }\n\n public get hasProjection(): boolean {\n const {encoding} = this;\n const isGeoShapeMark = this.mark === GEOSHAPE;\n const hasGeoPosition = encoding && GEOPOSITION_CHANNELS.some(\n channel => isFieldDef(encoding[channel])\n );\n return isGeoShapeMark || hasGeoPosition;\n }\n\n /**\n * Return specified Vega-lite scale domain for a particular channel\n * @param channel\n */\n public scaleDomain(channel: ScaleChannel): Domain {\n const scale = this.specifiedScales[channel];\n return scale ? scale.domain : undefined;\n }\n\n public axis(channel: Channel): Axis {\n return this.specifiedAxes[channel];\n }\n\n public legend(channel: Channel): Legend {\n return this.specifiedLegends[channel];\n }\n\n private initScales(mark: Mark, encoding: Encoding): ScaleIndex {\n return SCALE_CHANNELS.reduce((scales, channel) => {\n let fieldDef: FieldDef;\n let specifiedScale: Scale;\n\n const channelDef = encoding[channel];\n\n if (isFieldDef(channelDef)) {\n fieldDef = channelDef;\n specifiedScale = channelDef.scale;\n } else if (hasConditionalFieldDef(channelDef)) {\n fieldDef = channelDef.condition;\n specifiedScale = channelDef.condition['scale'];\n } else if (channel === 'x') {\n fieldDef = getFieldDef(encoding.x2);\n } else if (channel === 'y') {\n fieldDef = getFieldDef(encoding.y2);\n }\n\n if (fieldDef) {\n scales[channel] = specifiedScale || {};\n }\n return scales;\n }, {} as ScaleIndex);\n }\n\n private initAxes(encoding: Encoding): AxisIndex {\n return [X, Y].reduce(function(_axis, channel) {\n // Position Axis\n\n // TODO: handle ConditionFieldDef\n const channelDef = encoding[channel];\n if (isFieldDef(channelDef) ||\n (channel === X && isFieldDef(encoding.x2)) ||\n (channel === Y && isFieldDef(encoding.y2))) {\n\n const axisSpec = isFieldDef(channelDef) ? channelDef.axis : null;\n\n // We no longer support false in the schema, but we keep false here for backward compatibility.\n if (axisSpec !== null && axisSpec !== false) {\n _axis[channel] = {\n ...axisSpec\n };\n }\n }\n return _axis;\n }, {});\n }\n\n private initLegend(encoding: Encoding): LegendIndex {\n return NONPOSITION_SCALE_CHANNELS.reduce(function(_legend, channel) {\n const channelDef = encoding[channel];\n if (channelDef) {\n const legend = isFieldDef(channelDef) ? channelDef.legend :\n (hasConditionalFieldDef(channelDef)) ? channelDef.condition['legend'] : null;\n\n if (legend !== null && legend !== false) {\n _legend[channel] = {...legend};\n }\n }\n\n return _legend;\n }, {});\n }\n\n public parseData() {\n this.component.data = parseData(this);\n }\n\n public parseLayoutSize() {\n parseUnitLayoutSize(this);\n }\n\n public parseSelection() {\n this.component.selection = parseUnitSelection(this, this.selection);\n }\n\n public parseMarkGroup() {\n this.component.mark = parseMarkGroup(this);\n }\n\n public parseAxisAndHeader() {\n this.component.axes = parseUnitAxis(this);\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return assembleTopLevelSignals(this, signals);\n }\n\n public assembleSelectionSignals(): VgSignal[] {\n return assembleUnitSelectionSignals(this, []);\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return assembleUnitSelectionData(this, data);\n }\n\n public assembleLayout(): VgLayout {\n return null;\n }\n\n public assembleLayoutSignals(): VgSignal[] {\n return assembleLayoutSignals(this);\n }\n\n public assembleMarks() {\n let marks = this.component.mark || [];\n\n // If this unit is part of a layer, selections should augment\n // all in concert rather than each unit individually. This\n // ensures correct interleaving of clipping and brushed marks.\n if (!this.parent || !isLayerModel(this.parent)) {\n marks = assembleUnitSelectionMarks(this, marks);\n }\n\n return marks.map(this.correctDataNames);\n }\n\n public assembleLayoutSize(): VgEncodeEntry {\n return {\n width: this.getSizeSignalRef('width'),\n height: this.getSizeSignalRef('height')\n };\n }\n\n protected getMapping() {\n return this.encoding;\n }\n\n public toSpec(excludeConfig?: any, excludeData?: any) {\n const encoding = duplicate(this.encoding);\n let spec: any;\n\n spec = {\n mark: this.markDef,\n encoding: encoding\n };\n\n if (!excludeConfig) {\n spec.config = duplicate(this.config);\n }\n\n if (!excludeData) {\n spec.data = duplicate(this.data);\n }\n\n // remove defaults\n return spec;\n }\n\n public get mark(): Mark {\n return this.markDef.type;\n }\n\n public channelHasField(channel: Channel) {\n return vlEncoding.channelHasField(this.encoding, channel);\n }\n\n public fieldDef(channel: SingleDefChannel): FieldDef {\n const channelDef = this.encoding[channel] as ChannelDef;\n return getFieldDef(channelDef);\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/compositemark/boxplot.d.ts b/build/src/compositemark/boxplot.d.ts new file mode 100644 index 0000000000..610043219c --- /dev/null +++ b/build/src/compositemark/boxplot.d.ts @@ -0,0 +1,57 @@ +import { Config } from '../config'; +import { Encoding } from './../encoding'; +import { MarkConfig } from './../mark'; +import { GenericUnitSpec, NormalizedLayerSpec } from './../spec'; +import { Orient } from './../vega.schema'; +export declare const BOXPLOT: 'box-plot'; +export declare type BOXPLOT = typeof BOXPLOT; +export declare type BoxPlotStyle = 'boxWhisker' | 'box' | 'boxMid'; +export interface BoxPlotDef { + /** + * Type of the mark. For box plots, this should always be `"box-plot"`. + * [boxplot](https://vega.github.io/vega-lite/docs/compositemark.html#boxplot) + */ + type: BOXPLOT; + /** + * Orientation of the box plot. This is normally automatically determined, but can be specified when the orientation is ambiguous and cannot be automatically determined. + */ + orient?: Orient; + /** + * Extent is used to determine where the whiskers extend to. The options are + * - `"min-max": min and max are the lower and upper whiskers respectively. + * - A scalar (integer or floating point number) that will be multiplied by the IQR and the product will be added to the third quartile to get the upper whisker and subtracted from the first quartile to get the lower whisker. + * __Default value:__ `"1.5"`. + */ + extent?: 'min-max' | number; +} +export declare function isBoxPlotDef(mark: BOXPLOT | BoxPlotDef): mark is BoxPlotDef; +export declare const BOXPLOT_STYLES: BoxPlotStyle[]; +export interface BoxPlotConfig extends MarkConfig { + /** Size of the box and mid tick of a box plot */ + size?: number; + /** The default extent, which is used to determine where the whiskers extend to. The options are + * - `"min-max": min and max are the lower and upper whiskers respectively. + * - `"number": A scalar (integer or floating point number) that will be multiplied by the IQR and the product will be added to the third quartile to get the upper whisker and subtracted from the first quartile to get the lower whisker. + */ + extent?: 'min-max' | number; +} +export interface BoxPlotConfigMixins { + /** + * Box Config + * @hide + */ + box?: BoxPlotConfig; + /** + * @hide + */ + boxWhisker?: MarkConfig; + /** + * @hide + */ + boxMid?: MarkConfig; +} +export declare const VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX: { + [k in keyof BoxPlotConfigMixins]?: (keyof BoxPlotConfigMixins[k])[]; +}; +export declare function filterUnsupportedChannels(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>): GenericUnitSpec, BOXPLOT | BoxPlotDef>; +export declare function normalizeBoxPlot(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>, config: Config): NormalizedLayerSpec; diff --git a/build/src/compositemark/boxplot.js b/build/src/compositemark/boxplot.js new file mode 100644 index 0000000000..3b68cf8660 --- /dev/null +++ b/build/src/compositemark/boxplot.js @@ -0,0 +1,259 @@ +import * as tslib_1 from "tslib"; +import { isNumber } from 'vega-util'; +import { reduce } from '../encoding'; +import { forEach } from './../encoding'; +import { isContinuous, isFieldDef, vgField } from './../fielddef'; +import * as log from './../log'; +import { getMarkSpecificConfigMixins } from './common'; +export var BOXPLOT = 'box-plot'; +export function isBoxPlotDef(mark) { + return !!mark['type']; +} +export var BOXPLOT_STYLES = ['boxWhisker', 'box', 'boxMid']; +export var VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX = { + box: ['size', 'color', 'extent'], + boxWhisker: ['color'], + boxMid: ['color'] +}; +var supportedChannels = ['x', 'y', 'color', 'detail', 'opacity', 'size']; +export function filterUnsupportedChannels(spec) { + return tslib_1.__assign({}, spec, { encoding: reduce(spec.encoding, function (newEncoding, fieldDef, channel) { + if (supportedChannels.indexOf(channel) > -1) { + newEncoding[channel] = fieldDef; + } + else { + log.warn(log.message.incompatibleChannel(channel, BOXPLOT)); + } + return newEncoding; + }, {}) }); +} +export function normalizeBoxPlot(spec, config) { + var _a, _b, _c, _d; + spec = filterUnsupportedChannels(spec); + // TODO: use selection + var mark = spec.mark, encoding = spec.encoding, selection = spec.selection, _p = spec.projection, outerSpec = tslib_1.__rest(spec, ["mark", "encoding", "selection", "projection"]); + var kIQRScalar = undefined; + if (isNumber(config.box.extent)) { + kIQRScalar = config.box.extent; + } + if (isBoxPlotDef(mark)) { + if (mark.extent) { + if (mark.extent === 'min-max') { + kIQRScalar = undefined; + } + } + } + var orient = boxOrient(spec); + var _e = boxParams(spec, orient, kIQRScalar), transform = _e.transform, continuousAxisChannelDef = _e.continuousAxisChannelDef, continuousAxis = _e.continuousAxis, encodingWithoutContinuousAxis = _e.encodingWithoutContinuousAxis; + var color = encodingWithoutContinuousAxis.color, size = encodingWithoutContinuousAxis.size, encodingWithoutSizeColorAndContinuousAxis = tslib_1.__rest(encodingWithoutContinuousAxis, ["color", "size"]); + // Size encoding or the default config.box.size is applied to box and boxMid + var sizeMixins = size ? { size: size } : getMarkSpecificConfigMixins(config.box, 'size'); + var continuousAxisScaleAndAxis = {}; + if (continuousAxisChannelDef.scale) { + continuousAxisScaleAndAxis['scale'] = continuousAxisChannelDef.scale; + } + if (continuousAxisChannelDef.axis) { + continuousAxisScaleAndAxis['axis'] = continuousAxisChannelDef.axis; + } + return tslib_1.__assign({}, outerSpec, { transform: transform, layer: [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + encoding: tslib_1.__assign((_a = {}, _a[continuousAxis] = tslib_1.__assign({ field: 'lower_whisker_' + continuousAxisChannelDef.field, type: continuousAxisChannelDef.type }, continuousAxisScaleAndAxis), _a[continuousAxis + '2'] = { + field: 'lower_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _a), encodingWithoutSizeColorAndContinuousAxis, getMarkSpecificConfigMixins(config.boxWhisker, 'color')) + }, { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + encoding: tslib_1.__assign((_b = {}, _b[continuousAxis] = { + field: 'upper_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _b[continuousAxis + '2'] = { + field: 'upper_whisker_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _b), encodingWithoutSizeColorAndContinuousAxis, getMarkSpecificConfigMixins(config.boxWhisker, 'color')) + }, + tslib_1.__assign({}, (selection ? { selection: selection } : {}), { mark: { + type: 'bar', + style: 'box' + }, encoding: tslib_1.__assign((_c = {}, _c[continuousAxis] = { + field: 'lower_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _c[continuousAxis + '2'] = { + field: 'upper_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _c), encodingWithoutContinuousAxis, (encodingWithoutContinuousAxis.color ? {} : getMarkSpecificConfigMixins(config.box, 'color')), sizeMixins) }), + { + mark: { + type: 'tick', + style: 'boxMid' + }, + encoding: tslib_1.__assign((_d = {}, _d[continuousAxis] = { + field: 'mid_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _d), encodingWithoutSizeColorAndContinuousAxis, getMarkSpecificConfigMixins(config.boxMid, 'color'), sizeMixins) + } + ] }); +} +function boxOrient(spec) { + var mark = spec.mark, encoding = spec.encoding, _p = spec.projection, _outerSpec = tslib_1.__rest(spec, ["mark", "encoding", "projection"]); + if (isFieldDef(encoding.x) && isContinuous(encoding.x)) { + // x is continuous + if (isFieldDef(encoding.y) && isContinuous(encoding.y)) { + // both x and y are continuous + if (encoding.x.aggregate === undefined && encoding.y.aggregate === BOXPLOT) { + return 'vertical'; + } + else if (encoding.y.aggregate === undefined && encoding.x.aggregate === BOXPLOT) { + return 'horizontal'; + } + else if (encoding.x.aggregate === BOXPLOT && encoding.y.aggregate === BOXPLOT) { + throw new Error('Both x and y cannot have aggregate'); + } + else { + if (isBoxPlotDef(mark) && mark.orient) { + return mark.orient; + } + // default orientation = vertical + return 'vertical'; + } + } + // x is continuous but y is not + return 'horizontal'; + } + else if (isFieldDef(encoding.y) && isContinuous(encoding.y)) { + // y is continuous but x is not + return 'vertical'; + } + else { + // Neither x nor y is continuous. + throw new Error('Need a valid continuous axis for boxplots'); + } +} +function boxContinousAxis(spec, orient) { + var mark = spec.mark, encoding = spec.encoding, _p = spec.projection, _outerSpec = tslib_1.__rest(spec, ["mark", "encoding", "projection"]); + var continuousAxisChannelDef; + var continuousAxis; + if (orient === 'vertical') { + continuousAxis = 'y'; + continuousAxisChannelDef = encoding.y; // Safe to cast because if y is not continuous fielddef, the orient would not be vertical. + } + else { + continuousAxis = 'x'; + continuousAxisChannelDef = encoding.x; // Safe to cast because if x is not continuous fielddef, the orient would not be horizontal. + } + if (continuousAxisChannelDef && continuousAxisChannelDef.aggregate) { + var aggregate = continuousAxisChannelDef.aggregate, continuousAxisWithoutAggregate = tslib_1.__rest(continuousAxisChannelDef, ["aggregate"]); + if (aggregate !== BOXPLOT) { + log.warn("Continuous axis should not have customized aggregation function " + aggregate); + } + continuousAxisChannelDef = continuousAxisWithoutAggregate; + } + return { + continuousAxisChannelDef: continuousAxisChannelDef, + continuousAxis: continuousAxis + }; +} +function boxParams(spec, orient, kIQRScalar) { + var _a = boxContinousAxis(spec, orient), continuousAxisChannelDef = _a.continuousAxisChannelDef, continuousAxis = _a.continuousAxis; + var encoding = spec.encoding; + var isMinMax = kIQRScalar === undefined; + var aggregate = [ + { + op: 'q1', + field: continuousAxisChannelDef.field, + as: 'lower_box_' + continuousAxisChannelDef.field + }, + { + op: 'q3', + field: continuousAxisChannelDef.field, + as: 'upper_box_' + continuousAxisChannelDef.field + }, + { + op: 'median', + field: continuousAxisChannelDef.field, + as: 'mid_box_' + continuousAxisChannelDef.field + } + ]; + var postAggregateCalculates = []; + aggregate.push({ + op: 'min', + field: continuousAxisChannelDef.field, + as: (isMinMax ? 'lower_whisker_' : 'min_') + continuousAxisChannelDef.field + }); + aggregate.push({ + op: 'max', + field: continuousAxisChannelDef.field, + as: (isMinMax ? 'upper_whisker_' : 'max_') + continuousAxisChannelDef.field + }); + if (!isMinMax) { + postAggregateCalculates = [ + { + calculate: "datum.upper_box_" + continuousAxisChannelDef.field + " - datum.lower_box_" + continuousAxisChannelDef.field, + as: 'iqr_' + continuousAxisChannelDef.field + }, + { + calculate: "min(datum.upper_box_" + continuousAxisChannelDef.field + " + datum.iqr_" + continuousAxisChannelDef.field + " * " + kIQRScalar + ", datum.max_" + continuousAxisChannelDef.field + ")", + as: 'upper_whisker_' + continuousAxisChannelDef.field + }, + { + calculate: "max(datum.lower_box_" + continuousAxisChannelDef.field + " - datum.iqr_" + continuousAxisChannelDef.field + " * " + kIQRScalar + ", datum.min_" + continuousAxisChannelDef.field + ")", + as: 'lower_whisker_' + continuousAxisChannelDef.field + } + ]; + } + var groupby = []; + var bins = []; + var timeUnits = []; + var encodingWithoutContinuousAxis = {}; + forEach(encoding, function (channelDef, channel) { + if (channel === continuousAxis) { + // Skip continuous axis as we already handle it separately + return; + } + if (isFieldDef(channelDef)) { + if (channelDef.aggregate && channelDef.aggregate !== BOXPLOT) { + aggregate.push({ + op: channelDef.aggregate, + field: channelDef.field, + as: vgField(channelDef) + }); + } + else if (channelDef.aggregate === undefined) { + var transformedField = vgField(channelDef); + // Add bin or timeUnit transform if applicable + var bin = channelDef.bin; + if (bin) { + var field = channelDef.field; + bins.push({ bin: bin, field: field, as: transformedField }); + } + else if (channelDef.timeUnit) { + var timeUnit = channelDef.timeUnit, field = channelDef.field; + timeUnits.push({ timeUnit: timeUnit, field: field, as: transformedField }); + } + groupby.push(transformedField); + } + // now the field should refer to post-transformed field instead + encodingWithoutContinuousAxis[channel] = { + field: vgField(channelDef), + type: channelDef.type + }; + } + else { + // For value def, just copy + encodingWithoutContinuousAxis[channel] = encoding[channel]; + } + }); + return { + transform: [].concat(bins, timeUnits, [{ aggregate: aggregate, groupby: groupby }], postAggregateCalculates), + continuousAxisChannelDef: continuousAxisChannelDef, + continuousAxis: continuousAxis, + encodingWithoutContinuousAxis: encodingWithoutContinuousAxis + }; +} +//# sourceMappingURL=boxplot.js.map \ No newline at end of file diff --git a/build/src/compositemark/boxplot.js.map b/build/src/compositemark/boxplot.js.map new file mode 100644 index 0000000000..029b995a6d --- /dev/null +++ b/build/src/compositemark/boxplot.js.map @@ -0,0 +1 @@ +{"version":3,"file":"boxplot.js","sourceRoot":"","sources":["../../../src/compositemark/boxplot.ts"],"names":[],"mappings":"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","sourcesContent":["import {isNumber} from 'vega-util';\nimport {Channel} from '../channel';\nimport {Config} from '../config';\nimport {reduce} from '../encoding';\nimport {AggregatedFieldDef, BinTransform, CalculateTransform, TimeUnitTransform} from '../transform';\nimport {Encoding, forEach} from './../encoding';\nimport {Field, FieldDef, isContinuous, isFieldDef, PositionFieldDef, vgField} from './../fielddef';\nimport * as log from './../log';\nimport {MarkConfig} from './../mark';\nimport {GenericUnitSpec, NormalizedLayerSpec} from './../spec';\nimport {Orient} from './../vega.schema';\nimport {getMarkSpecificConfigMixins} from './common';\n\n\nexport const BOXPLOT: 'box-plot' = 'box-plot';\nexport type BOXPLOT = typeof BOXPLOT;\nexport type BoxPlotStyle = 'boxWhisker' | 'box' | 'boxMid';\n\n\nexport interface BoxPlotDef {\n /**\n * Type of the mark. For box plots, this should always be `\"box-plot\"`.\n * [boxplot](https://vega.github.io/vega-lite/docs/compositemark.html#boxplot)\n */\n type: BOXPLOT;\n\n /**\n * Orientation of the box plot. This is normally automatically determined, but can be specified when the orientation is ambiguous and cannot be automatically determined.\n */\n orient?: Orient;\n\n /**\n * Extent is used to determine where the whiskers extend to. The options are\n * - `\"min-max\": min and max are the lower and upper whiskers respectively.\n * - A scalar (integer or floating point number) that will be multiplied by the IQR and the product will be added to the third quartile to get the upper whisker and subtracted from the first quartile to get the lower whisker.\n * __Default value:__ `\"1.5\"`.\n */\n extent?: 'min-max' | number;\n}\n\nexport function isBoxPlotDef(mark: BOXPLOT | BoxPlotDef): mark is BoxPlotDef {\n return !!mark['type'];\n}\n\nexport const BOXPLOT_STYLES: BoxPlotStyle[] = ['boxWhisker', 'box', 'boxMid'];\n\nexport interface BoxPlotConfig extends MarkConfig {\n /** Size of the box and mid tick of a box plot */\n size?: number;\n /** The default extent, which is used to determine where the whiskers extend to. The options are\n * - `\"min-max\": min and max are the lower and upper whiskers respectively.\n * - `\"number\": A scalar (integer or floating point number) that will be multiplied by the IQR and the product will be added to the third quartile to get the upper whisker and subtracted from the first quartile to get the lower whisker.\n */\n extent?: 'min-max' | number;\n}\n\nexport interface BoxPlotConfigMixins {\n /**\n * Box Config\n * @hide\n */\n box?: BoxPlotConfig;\n\n /**\n * @hide\n */\n boxWhisker?: MarkConfig;\n\n /**\n * @hide\n */\n boxMid?: MarkConfig;\n}\n\nexport const VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX: {\n [k in keyof BoxPlotConfigMixins]?: (keyof BoxPlotConfigMixins[k])[]\n} = {\n box: ['size', 'color', 'extent'],\n boxWhisker: ['color'],\n boxMid: ['color']\n};\n\nconst supportedChannels: Channel[] = ['x', 'y', 'color', 'detail', 'opacity', 'size'];\nexport function filterUnsupportedChannels(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>): GenericUnitSpec, BOXPLOT | BoxPlotDef> {\n return {\n ...spec,\n encoding: reduce(spec.encoding, (newEncoding, fieldDef, channel) => {\n if (supportedChannels.indexOf(channel) > -1) {\n newEncoding[channel] = fieldDef;\n } else {\n log.warn(log.message.incompatibleChannel(channel, BOXPLOT));\n }\n return newEncoding;\n }, {}),\n };\n}\n\nexport function normalizeBoxPlot(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>, config: Config): NormalizedLayerSpec {\n spec = filterUnsupportedChannels(spec);\n // TODO: use selection\n const {mark, encoding, selection, projection: _p, ...outerSpec} = spec;\n\n let kIQRScalar: number = undefined;\n if (isNumber(config.box.extent)) {\n kIQRScalar = config.box.extent;\n }\n\n if (isBoxPlotDef(mark)) {\n if (mark.extent) {\n if(mark.extent === 'min-max') {\n kIQRScalar = undefined;\n }\n }\n }\n\n const orient: Orient = boxOrient(spec);\n const {transform, continuousAxisChannelDef, continuousAxis, encodingWithoutContinuousAxis} = boxParams(spec, orient, kIQRScalar);\n\n const {color, size, ...encodingWithoutSizeColorAndContinuousAxis} = encodingWithoutContinuousAxis;\n\n // Size encoding or the default config.box.size is applied to box and boxMid\n const sizeMixins = size ? {size} : getMarkSpecificConfigMixins(config.box, 'size');\n\n const continuousAxisScaleAndAxis = {};\n if (continuousAxisChannelDef.scale) {\n continuousAxisScaleAndAxis['scale'] = continuousAxisChannelDef.scale;\n }\n if (continuousAxisChannelDef.axis) {\n continuousAxisScaleAndAxis['axis'] = continuousAxisChannelDef.axis;\n }\n\n return {\n ...outerSpec,\n transform,\n layer: [\n { // lower whisker\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n encoding: {\n [continuousAxis]: {\n field: 'lower_whisker_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type,\n ...continuousAxisScaleAndAxis\n },\n [continuousAxis + '2']: {\n field: 'lower_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutSizeColorAndContinuousAxis,\n ...getMarkSpecificConfigMixins(config.boxWhisker, 'color')\n }\n }, { // upper whisker\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n encoding: {\n [continuousAxis]: {\n field: 'upper_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n [continuousAxis + '2']: {\n field: 'upper_whisker_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutSizeColorAndContinuousAxis,\n ...getMarkSpecificConfigMixins(config.boxWhisker, 'color')\n }\n }, { // box (q1 to q3)\n ...(selection ? {selection} : {}),\n mark: {\n type: 'bar',\n style: 'box'\n },\n encoding: {\n [continuousAxis]: {\n field: 'lower_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n [continuousAxis + '2']: {\n field: 'upper_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutContinuousAxis,\n ...(encodingWithoutContinuousAxis.color ? {} : getMarkSpecificConfigMixins(config.box, 'color')),\n ...sizeMixins,\n }\n }, { // mid tick\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n encoding: {\n [continuousAxis]: {\n field: 'mid_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutSizeColorAndContinuousAxis,\n ...getMarkSpecificConfigMixins(config.boxMid, 'color'),\n ...sizeMixins,\n }\n }\n ]\n };\n}\n\nfunction boxOrient(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>): Orient {\n const {mark: mark, encoding: encoding, projection: _p, ..._outerSpec} = spec;\n\n if (isFieldDef(encoding.x) && isContinuous(encoding.x)) {\n // x is continuous\n if (isFieldDef(encoding.y) && isContinuous(encoding.y)) {\n // both x and y are continuous\n if (encoding.x.aggregate === undefined && encoding.y.aggregate === BOXPLOT) {\n return 'vertical';\n } else if (encoding.y.aggregate === undefined && encoding.x.aggregate === BOXPLOT) {\n return 'horizontal';\n } else if (encoding.x.aggregate === BOXPLOT && encoding.y.aggregate === BOXPLOT) {\n throw new Error('Both x and y cannot have aggregate');\n } else {\n if (isBoxPlotDef(mark) && mark.orient) {\n return mark.orient;\n }\n\n // default orientation = vertical\n return 'vertical';\n }\n }\n\n // x is continuous but y is not\n return 'horizontal';\n } else if (isFieldDef(encoding.y) && isContinuous(encoding.y)) {\n // y is continuous but x is not\n return 'vertical';\n } else {\n // Neither x nor y is continuous.\n throw new Error('Need a valid continuous axis for boxplots');\n }\n}\n\n\nfunction boxContinousAxis(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>, orient: Orient) {\n const {mark: mark, encoding: encoding, projection: _p, ..._outerSpec} = spec;\n\n let continuousAxisChannelDef: PositionFieldDef;\n let continuousAxis: 'x' | 'y';\n\n if (orient === 'vertical') {\n continuousAxis = 'y';\n continuousAxisChannelDef = encoding.y as FieldDef; // Safe to cast because if y is not continuous fielddef, the orient would not be vertical.\n } else {\n continuousAxis = 'x';\n continuousAxisChannelDef = encoding.x as FieldDef; // Safe to cast because if x is not continuous fielddef, the orient would not be horizontal.\n }\n\n if (continuousAxisChannelDef && continuousAxisChannelDef.aggregate) {\n const {aggregate, ...continuousAxisWithoutAggregate} = continuousAxisChannelDef;\n if (aggregate !== BOXPLOT) {\n log.warn(`Continuous axis should not have customized aggregation function ${aggregate}`);\n }\n continuousAxisChannelDef = continuousAxisWithoutAggregate;\n }\n\n return {\n continuousAxisChannelDef,\n continuousAxis\n };\n}\n\nfunction boxParams(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>, orient: Orient, kIQRScalar: 'min-max' | number) {\n\n const {continuousAxisChannelDef, continuousAxis} = boxContinousAxis(spec, orient);\n const encoding = spec.encoding;\n\n const isMinMax = kIQRScalar === undefined;\n const aggregate: AggregatedFieldDef[] = [\n {\n op: 'q1',\n field: continuousAxisChannelDef.field,\n as: 'lower_box_' + continuousAxisChannelDef.field\n },\n {\n op: 'q3',\n field: continuousAxisChannelDef.field,\n as: 'upper_box_' + continuousAxisChannelDef.field\n },\n {\n op: 'median',\n field: continuousAxisChannelDef.field,\n as: 'mid_box_' + continuousAxisChannelDef.field\n }\n ];\n let postAggregateCalculates: CalculateTransform[] = [];\n\n aggregate.push({\n op: 'min',\n field: continuousAxisChannelDef.field,\n as: (isMinMax ? 'lower_whisker_' : 'min_') + continuousAxisChannelDef.field\n });\n aggregate.push({\n op: 'max',\n field: continuousAxisChannelDef.field,\n as: (isMinMax ? 'upper_whisker_' : 'max_') + continuousAxisChannelDef.field\n });\n\n if (!isMinMax) {\n postAggregateCalculates = [\n {\n calculate: `datum.upper_box_${continuousAxisChannelDef.field} - datum.lower_box_${continuousAxisChannelDef.field}`,\n as: 'iqr_' + continuousAxisChannelDef.field\n },\n {\n calculate: `min(datum.upper_box_${continuousAxisChannelDef.field} + datum.iqr_${continuousAxisChannelDef.field} * ${kIQRScalar}, datum.max_${continuousAxisChannelDef.field})`,\n as: 'upper_whisker_' + continuousAxisChannelDef.field\n },\n {\n calculate: `max(datum.lower_box_${continuousAxisChannelDef.field} - datum.iqr_${continuousAxisChannelDef.field} * ${kIQRScalar}, datum.min_${continuousAxisChannelDef.field})`,\n as: 'lower_whisker_' + continuousAxisChannelDef.field\n }\n ];\n }\n\n const groupby: string[] = [];\n const bins: BinTransform[] = [];\n const timeUnits: TimeUnitTransform[] = [];\n\n const encodingWithoutContinuousAxis: Encoding = {};\n forEach(encoding, (channelDef, channel) => {\n if (channel === continuousAxis) {\n // Skip continuous axis as we already handle it separately\n return;\n }\n if (isFieldDef(channelDef)) {\n if (channelDef.aggregate && channelDef.aggregate !== BOXPLOT) {\n aggregate.push({\n op: channelDef.aggregate,\n field: channelDef.field,\n as: vgField(channelDef)\n });\n } else if (channelDef.aggregate === undefined) {\n const transformedField = vgField(channelDef);\n\n // Add bin or timeUnit transform if applicable\n const bin = channelDef.bin;\n if (bin) {\n const {field} = channelDef;\n bins.push({bin, field, as: transformedField});\n } else if (channelDef.timeUnit) {\n const {timeUnit, field} = channelDef;\n timeUnits.push({timeUnit, field, as: transformedField});\n }\n\n groupby.push(transformedField);\n }\n // now the field should refer to post-transformed field instead\n encodingWithoutContinuousAxis[channel] = {\n field: vgField(channelDef),\n type: channelDef.type\n };\n } else {\n // For value def, just copy\n encodingWithoutContinuousAxis[channel] = encoding[channel];\n }\n });\n\n return {\n transform: [].concat(\n bins,\n timeUnits,\n [{aggregate, groupby}],\n postAggregateCalculates\n ),\n continuousAxisChannelDef,\n continuousAxis,\n encodingWithoutContinuousAxis\n };\n}\n"]} \ No newline at end of file diff --git a/build/src/compositemark/common.d.ts b/build/src/compositemark/common.d.ts new file mode 100644 index 0000000000..1857907f60 --- /dev/null +++ b/build/src/compositemark/common.d.ts @@ -0,0 +1,7 @@ +import { NonPositionChannel } from '../channel'; +import { MarkConfig } from '../mark'; +export declare function getMarkSpecificConfigMixins(markSpecificConfig: MarkConfig, channel: NonPositionChannel): { + [x: string]: { + value: any; + }; +}; diff --git a/build/src/compositemark/common.js b/build/src/compositemark/common.js new file mode 100644 index 0000000000..d00b6177e4 --- /dev/null +++ b/build/src/compositemark/common.js @@ -0,0 +1,6 @@ +export function getMarkSpecificConfigMixins(markSpecificConfig, channel) { + var _a; + var value = markSpecificConfig[channel]; + return value !== undefined ? (_a = {}, _a[channel] = { value: value }, _a) : {}; +} +//# sourceMappingURL=common.js.map \ No newline at end of file diff --git a/build/src/compositemark/common.js.map b/build/src/compositemark/common.js.map new file mode 100644 index 0000000000..0124ff83d8 --- /dev/null +++ b/build/src/compositemark/common.js.map @@ -0,0 +1 @@ +{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/compositemark/common.ts"],"names":[],"mappings":"AAGA,MAAM,sCAAsC,kBAA8B,EAAE,OAA2B;;IACrG,IAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,WAAE,GAAC,OAAO,IAAG,EAAC,KAAK,OAAA,EAAC,MAAE,CAAC,CAAC,EAAE,CAAC;AACzD,CAAC","sourcesContent":["import {NonPositionChannel} from '../channel';\nimport {MarkConfig} from '../mark';\n\nexport function getMarkSpecificConfigMixins(markSpecificConfig: MarkConfig, channel: NonPositionChannel) {\n const value = markSpecificConfig[channel];\n return value !== undefined ? {[channel]: {value}} : {};\n}\n"]} \ No newline at end of file diff --git a/build/src/compositemark/errorband.d.ts b/build/src/compositemark/errorband.d.ts new file mode 100644 index 0000000000..2fdeb1fb31 --- /dev/null +++ b/build/src/compositemark/errorband.d.ts @@ -0,0 +1,45 @@ +import { Config } from '../config'; +import { Encoding } from './../encoding'; +import { GenericUnitSpec, NormalizedLayerSpec } from './../spec'; +import { Orient } from './../vega.schema'; +import { GenericCompositeMarkDef, PartsMixins } from './common'; +import { ErrorBarCenter, ErrorBarExtent } from './errorbar'; +export declare const ERRORBAND: 'errorband'; +export declare type ErrorBand = typeof ERRORBAND; +export declare type ErrorBandPart = 'band' | 'borders'; +export declare const ERRORBAND_PARTS: ErrorBandPart[]; +export declare type ErrorBandPartsMixins = PartsMixins; +export interface ErrorBandConfig extends ErrorBandPartsMixins { + /** + * The center of the error band. Available options include: + * - `"mean"`: the mean of the data points. + * - `"median"`: the median of the data points. + * + * __Default value:__ `"mean"`. + * @hide + */ + center?: ErrorBarCenter; + /** + * The extent of the band. Available options include: + * - `"ci"`: Extend the band to the confidence interval of the mean. + * - `"stderr"`: The size of band are set to the value of standard error, extending from the mean. + * - `"stdev"`: The size of band are set to the value of standard deviation, extending from the mean. + * - `"iqr"`: Extend the band to the q1 and q3. + * + * __Default value:__ `"stderr"`. + */ + extent?: ErrorBarExtent; +} +export declare type ErrorBandDef = GenericCompositeMarkDef & ErrorBandConfig & { + /** + * Orientation of the error band. This is normally automatically determined, but can be specified when the orientation is ambiguous and cannot be automatically determined. + */ + orient?: Orient; +}; +export interface ErrorBandConfigMixins { + /** + * ErrorBand Config + */ + errorband?: ErrorBandConfig; +} +export declare function normalizeErrorBand(spec: GenericUnitSpec, ErrorBand | ErrorBandDef>, config: Config): NormalizedLayerSpec; diff --git a/build/src/compositemark/errorband.js b/build/src/compositemark/errorband.js new file mode 100644 index 0000000000..756df2ab43 --- /dev/null +++ b/build/src/compositemark/errorband.js @@ -0,0 +1,19 @@ +import * as tslib_1 from "tslib"; +import { keys } from '../util'; +import { makeCompositeAggregatePartFactory, } from './common'; +import { errorBarParams } from './errorbar'; +export var ERRORBAND = 'errorband'; +var ERRORBAND_PART_INDEX = { + band: 1, + borders: 1 +}; +export var ERRORBAND_PARTS = keys(ERRORBAND_PART_INDEX); +export function normalizeErrorBand(spec, config) { + var _a = errorBarParams(spec, ERRORBAND, config), transform = _a.transform, continuousAxisChannelDef = _a.continuousAxisChannelDef, continuousAxis = _a.continuousAxis, encodingWithoutContinuousAxis = _a.encodingWithoutContinuousAxis, markDef = _a.markDef, outerSpec = _a.outerSpec; + var makeErrorBandPart = makeCompositeAggregatePartFactory(markDef, continuousAxis, continuousAxisChannelDef, encodingWithoutContinuousAxis, config.errorband); + var is2D = spec.encoding.x !== undefined && spec.encoding.y !== undefined; + var bandMark = is2D ? 'area' : 'rect'; + var bordersMark = is2D ? 'line' : 'rule'; + return tslib_1.__assign({}, outerSpec, { transform: transform, layer: makeErrorBandPart('band', bandMark, 'lower', 'upper').concat(makeErrorBandPart('borders', bordersMark, 'lower'), makeErrorBandPart('borders', bordersMark, 'upper')) }); +} +//# sourceMappingURL=errorband.js.map \ No newline at end of file diff --git a/build/src/compositemark/errorband.js.map b/build/src/compositemark/errorband.js.map new file mode 100644 index 0000000000..50a329b4b8 --- /dev/null +++ b/build/src/compositemark/errorband.js.map @@ -0,0 +1 @@ +{"version":3,"file":"errorband.js","sourceRoot":"","sources":["../../../src/compositemark/errorband.ts"],"names":[],"mappings":";AACA,OAAO,EAAO,IAAI,EAAC,MAAM,SAAS,CAAC;AAInC,OAAO,EAEL,iCAAiC,GAElC,MAAM,UAAU,CAAC;AAClB,OAAO,EAAiC,cAAc,EAAC,MAAM,YAAY,CAAC;AAE1E,MAAM,CAAC,IAAM,SAAS,GAAgB,WAAW,CAAC;AAKlD,IAAM,oBAAoB,GAAwB;IAChD,IAAI,EAAE,CAAC;IACP,OAAO,EAAE,CAAC;CACX,CAAC;AAEF,MAAM,CAAC,IAAM,eAAe,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC;AA2C1D,MAAM,6BAA6B,IAAiE,EAAE,MAAc;IAC5G,IAAA,4CACqC,EADpC,wBAAS,EAAE,sDAAwB,EAAE,kCAAc,EAAE,gEAA6B,EAAE,oBAAO,EAAE,wBAAS,CACjE;IAE5C,IAAM,iBAAiB,GAAG,iCAAiC,CACvD,OAAO,EACP,cAAc,EACd,wBAAwB,EACxB,6BAA6B,EAC7B,MAAM,CAAC,SAAS,CACnB,CAAC;IAEF,IAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,SAAS,CAAC;IAC5E,IAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IACxC,IAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAE3C,4BACK,SAAS,IACZ,SAAS,WAAA,EACT,KAAK,EACA,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,QACrD,iBAAiB,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,EAClD,iBAAiB,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,KAEvD;AACJ,CAAC","sourcesContent":["import {Config} from '../config';\nimport {Flag, keys} from '../util';\nimport {Encoding} from './../encoding';\nimport {GenericUnitSpec, NormalizedLayerSpec} from './../spec';\nimport {Orient} from './../vega.schema';\nimport {\n GenericCompositeMarkDef,\n makeCompositeAggregatePartFactory,\n PartsMixins,\n} from './common';\nimport {ErrorBarCenter, ErrorBarExtent, errorBarParams} from './errorbar';\n\nexport const ERRORBAND: 'errorband' = 'errorband';\nexport type ErrorBand = typeof ERRORBAND;\n\nexport type ErrorBandPart = 'band' | 'borders';\n\nconst ERRORBAND_PART_INDEX: Flag = {\n band: 1,\n borders: 1\n};\n\nexport const ERRORBAND_PARTS = keys(ERRORBAND_PART_INDEX);\n\nexport type ErrorBandPartsMixins = PartsMixins;\n\nexport interface ErrorBandConfig extends ErrorBandPartsMixins {\n /**\n * The center of the error band. Available options include:\n * - `\"mean\"`: the mean of the data points.\n * - `\"median\"`: the median of the data points.\n *\n * __Default value:__ `\"mean\"`.\n * @hide\n */\n\n // center is not needed right now but will be added back to the schema if future features require it.\n center?: ErrorBarCenter;\n\n /**\n * The extent of the band. Available options include:\n * - `\"ci\"`: Extend the band to the confidence interval of the mean.\n * - `\"stderr\"`: The size of band are set to the value of standard error, extending from the mean.\n * - `\"stdev\"`: The size of band are set to the value of standard deviation, extending from the mean.\n * - `\"iqr\"`: Extend the band to the q1 and q3.\n *\n * __Default value:__ `\"stderr\"`.\n */\n extent?: ErrorBarExtent;\n}\n\nexport type ErrorBandDef = GenericCompositeMarkDef & ErrorBandConfig & {\n /**\n * Orientation of the error band. This is normally automatically determined, but can be specified when the orientation is ambiguous and cannot be automatically determined.\n */\n orient?: Orient;\n};\n\nexport interface ErrorBandConfigMixins {\n /**\n * ErrorBand Config\n */\n errorband?: ErrorBandConfig;\n}\n\nexport function normalizeErrorBand(spec: GenericUnitSpec, ErrorBand | ErrorBandDef>, config: Config): NormalizedLayerSpec {\n const {transform, continuousAxisChannelDef, continuousAxis, encodingWithoutContinuousAxis, markDef, outerSpec}\n = errorBarParams(spec, ERRORBAND, config);\n\n const makeErrorBandPart = makeCompositeAggregatePartFactory(\n markDef,\n continuousAxis,\n continuousAxisChannelDef,\n encodingWithoutContinuousAxis,\n config.errorband\n );\n\n const is2D = spec.encoding.x !== undefined && spec.encoding.y !== undefined;\n const bandMark = is2D ? 'area' : 'rect';\n const bordersMark = is2D ? 'line' : 'rule';\n\n return {\n ...outerSpec,\n transform,\n layer: [\n ...makeErrorBandPart('band', bandMark, 'lower', 'upper'),\n ...makeErrorBandPart('borders', bordersMark, 'lower'),\n ...makeErrorBandPart('borders', bordersMark, 'upper'),\n ]\n };\n}\n"]} \ No newline at end of file diff --git a/build/src/compositemark/errorbar.d.ts b/build/src/compositemark/errorbar.d.ts new file mode 100644 index 0000000000..4cfcbc24f9 --- /dev/null +++ b/build/src/compositemark/errorbar.d.ts @@ -0,0 +1,6 @@ +import { Field } from '../fielddef'; +import { Encoding } from './../encoding'; +import { GenericUnitSpec, NormalizedLayerSpec } from './../spec'; +export declare const ERRORBAR: 'error-bar'; +export declare type ERRORBAR = typeof ERRORBAR; +export declare function normalizeErrorBar(spec: GenericUnitSpec, ERRORBAR>): NormalizedLayerSpec; diff --git a/build/src/compositemark/errorbar.js b/build/src/compositemark/errorbar.js new file mode 100644 index 0000000000..dfe909191d --- /dev/null +++ b/build/src/compositemark/errorbar.js @@ -0,0 +1,25 @@ +import * as tslib_1 from "tslib"; +export var ERRORBAR = 'error-bar'; +export function normalizeErrorBar(spec) { + // TODO: use selection + var _m = spec.mark, _sel = spec.selection, _p = spec.projection, encoding = spec.encoding, outerSpec = tslib_1.__rest(spec, ["mark", "selection", "projection", "encoding"]); + var _s = encoding.size, encodingWithoutSize = tslib_1.__rest(encoding, ["size"]); + var _x2 = encoding.x2, _y2 = encoding.y2, encodingWithoutX2Y2 = tslib_1.__rest(encoding, ["x2", "y2"]); + var _x = encodingWithoutX2Y2.x, _y = encodingWithoutX2Y2.y, encodingWithoutX_X2_Y_Y2 = tslib_1.__rest(encodingWithoutX2Y2, ["x", "y"]); + if (!encoding.x2 && !encoding.y2) { + throw new Error('Neither x2 or y2 provided'); + } + return tslib_1.__assign({}, outerSpec, { layer: [ + { + mark: 'rule', + encoding: encodingWithoutSize + }, { + mark: 'tick', + encoding: encodingWithoutX2Y2 + }, { + mark: 'tick', + encoding: encoding.x2 ? tslib_1.__assign({ x: encoding.x2, y: encoding.y }, encodingWithoutX_X2_Y_Y2) : tslib_1.__assign({ x: encoding.x, y: encoding.y2 }, encodingWithoutX_X2_Y_Y2) + } + ] }); +} +//# sourceMappingURL=errorbar.js.map \ No newline at end of file diff --git a/build/src/compositemark/errorbar.js.map b/build/src/compositemark/errorbar.js.map new file mode 100644 index 0000000000..7218468226 --- /dev/null +++ b/build/src/compositemark/errorbar.js.map @@ -0,0 +1 @@ +{"version":3,"file":"errorbar.js","sourceRoot":"","sources":["../../../src/compositemark/errorbar.ts"],"names":[],"mappings":";AAKA,MAAM,CAAC,IAAM,QAAQ,GAAgB,WAAW,CAAC;AAGjD,MAAM,4BAA4B,IAAgD;IAChF,sBAAsB;IACf,IAAA,cAAQ,EAAE,qBAAe,EAAE,oBAAc,EAAE,wBAAQ,EAAE,iFAAY,CAAS;IAC1E,IAAA,kBAAQ,EAAE,wDAAsB,CAAa;IAC7C,IAAA,iBAAO,EAAE,iBAAO,EAAE,4DAAsB,CAAa;IACrD,IAAA,0BAAK,EAAE,0BAAK,EAAE,0EAA2B,CAAwB;IAExE,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;QAChC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;KAC9C;IAED,4BACK,SAAS,IACZ,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,mBAAmB;aAC9B,EAAC;gBACA,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,mBAAmB;aAC9B,EAAE;gBACD,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,oBACrB,CAAC,EAAE,QAAQ,CAAC,EAAE,EACd,CAAC,EAAE,QAAQ,CAAC,CAAC,IACV,wBAAwB,EAC3B,CAAC,oBACD,CAAC,EAAE,QAAQ,CAAC,CAAC,EACb,CAAC,EAAE,QAAQ,CAAC,EAAE,IACX,wBAAwB,CAC5B;aACF;SACF,IACD;AACJ,CAAC","sourcesContent":["import {Field} from '../fielddef';\nimport {Encoding} from './../encoding';\nimport {GenericUnitSpec, NormalizedLayerSpec} from './../spec';\n\n\nexport const ERRORBAR: 'error-bar' = 'error-bar';\nexport type ERRORBAR = typeof ERRORBAR;\n\nexport function normalizeErrorBar(spec: GenericUnitSpec, ERRORBAR>): NormalizedLayerSpec {\n // TODO: use selection\n const {mark: _m, selection: _sel, projection: _p, encoding, ...outerSpec} = spec;\n const {size: _s, ...encodingWithoutSize} = encoding;\n const {x2: _x2, y2: _y2, ...encodingWithoutX2Y2} = encoding;\n const {x: _x, y: _y, ...encodingWithoutX_X2_Y_Y2} = encodingWithoutX2Y2;\n\n if (!encoding.x2 && !encoding.y2) {\n throw new Error('Neither x2 or y2 provided');\n }\n\n return {\n ...outerSpec,\n layer: [\n {\n mark: 'rule',\n encoding: encodingWithoutSize\n },{ // Lower tick\n mark: 'tick',\n encoding: encodingWithoutX2Y2\n }, { // Upper tick\n mark: 'tick',\n encoding: encoding.x2 ? {\n x: encoding.x2,\n y: encoding.y,\n ...encodingWithoutX_X2_Y_Y2\n } : {\n x: encoding.x,\n y: encoding.y2,\n ...encodingWithoutX_X2_Y_Y2\n }\n }\n ]\n };\n}\n"]} \ No newline at end of file diff --git a/build/src/compositemark/index.d.ts b/build/src/compositemark/index.d.ts new file mode 100644 index 0000000000..1754bd9b7f --- /dev/null +++ b/build/src/compositemark/index.d.ts @@ -0,0 +1,26 @@ +import { Config } from './../config'; +import { AnyMark } from './../mark'; +import { GenericUnitSpec, NormalizedLayerSpec } from './../spec'; +import { BOXPLOT, BoxPlotConfigMixins, BoxPlotDef } from './boxplot'; +import { ERRORBAR } from './errorbar'; +import * as boxplot from './boxplot'; +export { BoxPlotConfig } from './boxplot'; +export declare type UnitNormalizer = (spec: GenericUnitSpec, config: Config) => NormalizedLayerSpec; +export declare function add(mark: string, normalizer: UnitNormalizer): void; +export declare function remove(mark: string): void; +export declare type CompositeMark = BOXPLOT | ERRORBAR; +export declare type CompositeMarkDef = BoxPlotDef; +export declare type CompositeAggregate = BOXPLOT; +export declare const COMPOSITE_MARK_STYLES: boxplot.BoxPlotStyle[]; +export declare type CompositeMarkStyle = typeof COMPOSITE_MARK_STYLES[0]; +export interface CompositeMarkConfigMixins extends BoxPlotConfigMixins { +} +export declare const VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX: { + box?: ("dir" | "font" | "text" | "shape" | "orient" | "extent" | "color" | "fill" | "stroke" | "opacity" | "size" | "tooltip" | "href" | "interpolate" | "angle" | "baseline" | "fontSize" | "fontWeight" | "limit" | "strokeWidth" | "strokeDash" | "strokeDashOffset" | "strokeOpacity" | "strokeJoin" | "strokeMiterLimit" | "fillOpacity" | "filled" | "strokeCap" | "tension" | "align" | "dx" | "dy" | "radius" | "ellipsis" | "theta" | "fontStyle" | "cursor" | "cornerRadius")[]; + boxWhisker?: ("dir" | "font" | "text" | "shape" | "orient" | "color" | "fill" | "stroke" | "opacity" | "size" | "tooltip" | "href" | "interpolate" | "angle" | "baseline" | "fontSize" | "fontWeight" | "limit" | "strokeWidth" | "strokeDash" | "strokeDashOffset" | "strokeOpacity" | "strokeJoin" | "strokeMiterLimit" | "fillOpacity" | "filled" | "strokeCap" | "tension" | "align" | "dx" | "dy" | "radius" | "ellipsis" | "theta" | "fontStyle" | "cursor" | "cornerRadius")[]; + boxMid?: ("dir" | "font" | "text" | "shape" | "orient" | "color" | "fill" | "stroke" | "opacity" | "size" | "tooltip" | "href" | "interpolate" | "angle" | "baseline" | "fontSize" | "fontWeight" | "limit" | "strokeWidth" | "strokeDash" | "strokeDashOffset" | "strokeOpacity" | "strokeJoin" | "strokeMiterLimit" | "fillOpacity" | "filled" | "strokeCap" | "tension" | "align" | "dx" | "dy" | "radius" | "ellipsis" | "theta" | "fontStyle" | "cursor" | "cornerRadius")[]; +}; +/** + * Transform a unit spec with composite mark into a normal layer spec. + */ +export declare function normalize(spec: GenericUnitSpec, config: Config): NormalizedLayerSpec; diff --git a/build/src/compositemark/index.js b/build/src/compositemark/index.js new file mode 100644 index 0000000000..e879f9dddc --- /dev/null +++ b/build/src/compositemark/index.js @@ -0,0 +1,38 @@ +import * as tslib_1 from "tslib"; +import { isMarkDef } from './../mark'; +import { BOXPLOT, normalizeBoxPlot, VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX } from './boxplot'; +import { ERRORBAR, normalizeErrorBar } from './errorbar'; +// This package import below makes the generated .d.ts file compatible with +// Typescript 2.7 so that libraries requiring us can use Typedoc (which +// currently is limited to Typescript 2.7). This comment and import can be +// removed when Typedoc is updated to Typescript 2.9 or later. See +// https://github.com/vega/vega-lite/issues/3862 for more details. +import * as boxplot from './boxplot'; +/** + * Registry index for all composite mark's normalizer + */ +var normalizerRegistry = {}; +export function add(mark, normalizer) { + normalizerRegistry[mark] = normalizer; +} +export function remove(mark) { + delete normalizerRegistry[mark]; +} +export var COMPOSITE_MARK_STYLES = boxplot.BOXPLOT_STYLES; +export var VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = tslib_1.__assign({}, VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX); +add(BOXPLOT, normalizeBoxPlot); +add(ERRORBAR, normalizeErrorBar); +/** + * Transform a unit spec with composite mark into a normal layer spec. + */ +export function normalize( +// This GenericUnitSpec has any as Encoding because unit specs with composite mark can have additional encoding channels. +spec, config) { + var mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var normalizer = normalizerRegistry[mark]; + if (normalizer) { + return normalizer(spec, config); + } + throw new Error("Invalid mark type \"" + mark + "\""); +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/src/compositemark/index.js.map b/build/src/compositemark/index.js.map new file mode 100644 index 0000000000..4e443637f5 --- /dev/null +++ b/build/src/compositemark/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/compositemark/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAU,SAAS,EAAC,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAC,OAAO,EAAmC,gBAAgB,EAAE,qCAAqC,EAAC,MAAM,WAAW,CAAC;AAC5H,OAAO,EAAC,QAAQ,EAAE,iBAAiB,EAAC,MAAM,YAAY,CAAC;AAEvD,2EAA2E;AAC3E,uEAAuE;AACvE,0EAA0E;AAC1E,kEAAkE;AAClE,kEAAkE;AAClE,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AAKrC;;GAEG;AACH,IAAM,kBAAkB,GAAqC,EAAE,CAAC;AAEhE,MAAM,cAAc,IAAY,EAAE,UAA0B;IAC1D,kBAAkB,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC;AACxC,CAAC;AAED,MAAM,iBAAiB,IAAY;IACjC,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAQD,MAAM,CAAC,IAAM,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC;AAK5D,MAAM,CAAC,IAAM,qDAAqD,wBAC7D,qCAAqC,CACzC,CAAC;AAEF,GAAG,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;AAC/B,GAAG,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;AAEjC;;GAEG;AACH,MAAM;AACF,yHAAyH;AACzH,IAAmC,EACnC,MAAc;IAGhB,IAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC/D,IAAM,UAAU,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,UAAU,EAAE;QACd,OAAO,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;KACjC;IAED,MAAM,IAAI,KAAK,CAAC,yBAAsB,IAAI,OAAG,CAAC,CAAC;AACjD,CAAC","sourcesContent":["import {Config} from './../config';\nimport {AnyMark, isMarkDef} from './../mark';\nimport {GenericUnitSpec, NormalizedLayerSpec} from './../spec';\nimport {BOXPLOT, BoxPlotConfigMixins, BoxPlotDef, normalizeBoxPlot, VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX} from './boxplot';\nimport {ERRORBAR, normalizeErrorBar} from './errorbar';\n\n// This package import below makes the generated .d.ts file compatible with\n// Typescript 2.7 so that libraries requiring us can use Typedoc (which\n// currently is limited to Typescript 2.7). This comment and import can be\n// removed when Typedoc is updated to Typescript 2.9 or later. See\n// https://github.com/vega/vega-lite/issues/3862 for more details.\nimport * as boxplot from './boxplot';\n\nexport {BoxPlotConfig} from './boxplot';\nexport type UnitNormalizer = (spec: GenericUnitSpec, config: Config)=> NormalizedLayerSpec;\n\n/**\n * Registry index for all composite mark's normalizer\n */\nconst normalizerRegistry: {[mark: string]: UnitNormalizer} = {};\n\nexport function add(mark: string, normalizer: UnitNormalizer) {\n normalizerRegistry[mark] = normalizer;\n}\n\nexport function remove(mark: string) {\n delete normalizerRegistry[mark];\n}\n\nexport type CompositeMark = BOXPLOT | ERRORBAR;\n\nexport type CompositeMarkDef = BoxPlotDef;\n\nexport type CompositeAggregate = BOXPLOT;\n\nexport const COMPOSITE_MARK_STYLES = boxplot.BOXPLOT_STYLES;\nexport type CompositeMarkStyle = typeof COMPOSITE_MARK_STYLES[0];\n\nexport interface CompositeMarkConfigMixins extends BoxPlotConfigMixins {}\n\nexport const VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = {\n ...VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX\n};\n\nadd(BOXPLOT, normalizeBoxPlot);\nadd(ERRORBAR, normalizeErrorBar);\n\n/**\n * Transform a unit spec with composite mark into a normal layer spec.\n */\nexport function normalize(\n // This GenericUnitSpec has any as Encoding because unit specs with composite mark can have additional encoding channels.\n spec: GenericUnitSpec,\n config: Config\n ): NormalizedLayerSpec {\n\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n const normalizer = normalizerRegistry[mark];\n if (normalizer) {\n return normalizer(spec, config);\n }\n\n throw new Error(`Invalid mark type \"${mark}\"`);\n}\n"]} \ No newline at end of file diff --git a/build/src/config.d.ts b/build/src/config.d.ts new file mode 100644 index 0000000000..e268bfdd7c --- /dev/null +++ b/build/src/config.d.ts @@ -0,0 +1,202 @@ +import { AxisConfigMixins } from './axis'; +import { CompositeMarkConfigMixins } from './compositemark/index'; +import { HeaderConfig } from './header'; +import { LegendConfig } from './legend'; +import { MarkConfigMixins } from './mark'; +import { ProjectionConfig } from './projection'; +import { ScaleConfig } from './scale'; +import { SelectionConfig } from './selection'; +import { StackOffset } from './stack'; +import { TopLevelProperties } from './toplevelprops'; +import { StrokeJoin, VgMarkConfig, VgScheme, VgTitleConfig } from './vega.schema'; +export interface ViewConfig { + /** + * The default width of the single plot or each plot in a trellis plot when the visualization has a continuous (non-ordinal) x-scale or ordinal x-scale with `rangeStep` = `null`. + * + * __Default value:__ `200` + * + */ + width?: number; + /** + * The default height of the single plot or each plot in a trellis plot when the visualization has a continuous (non-ordinal) y-scale with `rangeStep` = `null`. + * + * __Default value:__ `200` + * + */ + height?: number; + /** + * Whether the view should be clipped. + */ + clip?: boolean; + /** + * The fill color. + * + * __Default value:__ (none) + * + */ + fill?: string; + /** + * The fill opacity (value between [0,1]). + * + * __Default value:__ (none) + * + */ + fillOpacity?: number; + /** + * The stroke color. + * + * __Default value:__ (none) + * + */ + stroke?: string; + /** + * The stroke opacity (value between [0,1]). + * + * __Default value:__ (none) + * + */ + strokeOpacity?: number; + /** + * The stroke width, in pixels. + * + * __Default value:__ (none) + * + */ + strokeWidth?: number; + /** + * An array of alternating stroke, space lengths for creating dashed or dotted lines. + * + * __Default value:__ (none) + * + */ + strokeDash?: number[]; + /** + * The offset (in pixels) into which to begin drawing with the stroke dash array. + * + * __Default value:__ (none) + * + */ + strokeDashOffset?: number; + /** + * The stroke line join method. One of miter (default), round or bevel. + * + * __Default value:__ 'miter' + * + */ + strokeJoin?: StrokeJoin; + /** + * The stroke line join method. One of miter (default), round or bevel. + * + * __Default value:__ 'miter' + * + */ + strokeMiterLimit?: number; +} +export declare const defaultViewConfig: ViewConfig; +export declare type RangeConfigValue = (number | string)[] | VgScheme | { + step: number; +}; +export declare type RangeConfig = RangeConfigProps & { + [name: string]: RangeConfigValue; +}; +export interface RangeConfigProps { + /** + * Default range for _nominal_ (categorical) fields. + */ + category?: string[] | VgScheme; + /** + * Default range for diverging _quantitative_ fields. + */ + diverging?: string[] | VgScheme; + /** + * Default range for _quantitative_ heatmaps. + */ + heatmap?: string[] | VgScheme; + /** + * Default range for _ordinal_ fields. + */ + ordinal?: string[] | VgScheme; + /** + * Default range for _quantitative_ and _temporal_ fields. + */ + ramp?: string[] | VgScheme; + /** + * Default range palette for the `shape` channel. + */ + symbol?: string[]; +} +export interface VLOnlyConfig { + /** + * Default axis and legend title for count fields. + * + * __Default value:__ `'Number of Records'`. + * + * @type {string} + */ + countTitle?: string; + /** + * Defines how Vega-Lite should handle invalid values (`null` and `NaN`). + * - If set to `"filter"` (default), all data items with null values will be skipped (for line, trail, and area marks) or filtered (for other marks). + * - If `null`, all data items are included. In this case, invalid values will be interpreted as zeroes. + */ + invalidValues?: 'filter' | null; + /** + * Defines how Vega-Lite generates title for fields. There are three possible styles: + * - `"verbal"` (Default) - displays function in a verbal style (e.g., "Sum of field", "Year-month of date", "field (binned)"). + * - `"function"` - displays function using parentheses and capitalized texts (e.g., "SUM(field)", "YEARMONTH(date)", "BIN(field)"). + * - `"plain"` - displays only the field name without functions (e.g., "field", "date", "field"). + */ + fieldTitle?: 'verbal' | 'functional' | 'plain'; + /** + * D3 Number format for axis labels and text tables. For example "s" for SI units. Use [D3's number format pattern](https://github.com/d3/d3-format#locale_format). + */ + numberFormat?: string; + /** + * Default datetime format for axis and legend labels. The format can be set directly on each axis and legend. Use [D3's time format pattern](https://github.com/d3/d3-time-format#locale_format). + * + * __Default value:__ `''` (The format will be automatically determined). + * + */ + timeFormat?: string; + /** Default properties for [single view plots](https://vega.github.io/vega-lite/docs/spec.html#single). */ + view?: ViewConfig; + /** + * Scale configuration determines default properties for all [scales](https://vega.github.io/vega-lite/docs/scale.html). For a full list of scale configuration options, please see the [corresponding section of the scale documentation](https://vega.github.io/vega-lite/docs/scale.html#config). + */ + scale?: ScaleConfig; + /** An object hash for defining default properties for each type of selections. */ + selection?: SelectionConfig; + /** Default stack offset for stackable mark. */ + stack?: StackOffset; +} +export interface StyleConfigIndex { + [style: string]: VgMarkConfig; +} +export interface Config extends TopLevelProperties, VLOnlyConfig, MarkConfigMixins, CompositeMarkConfigMixins, AxisConfigMixins { + /** + * An object hash that defines default range arrays or schemes for using with scales. + * For a full list of scale range configuration options, please see the [corresponding section of the scale documentation](https://vega.github.io/vega-lite/docs/scale.html#config). + */ + range?: RangeConfig; + /** + * Legend configuration, which determines default properties for all [legends](https://vega.github.io/vega-lite/docs/legend.html). For a full list of legend configuration options, please see the [corresponding section of in the legend documentation](https://vega.github.io/vega-lite/docs/legend.html#config). + */ + legend?: LegendConfig; + /** + * Header configuration, which determines default properties for all [header](https://vega.github.io/vega-lite/docs/header.html). For a full list of header configuration options, please see the [corresponding section of in the header documentation](https://vega.github.io/vega-lite/docs/header.html#config). + */ + header?: HeaderConfig; + /** + * Title configuration, which determines default properties for all [titles](https://vega.github.io/vega-lite/docs/title.html). For a full list of title configuration options, please see the [corresponding section of the title documentation](https://vega.github.io/vega-lite/docs/title.html#config). + */ + title?: VgTitleConfig; + /** + * Projection configuration, which determines default properties for all [projections](https://vega.github.io/vega-lite/docs/projection.html). For a full list of projection configuration options, please see the [corresponding section of the projection documentation](https://vega.github.io/vega-lite/docs/projection.html#config). + */ + projection?: ProjectionConfig; + /** An object hash that defines key-value mappings to determine default properties for marks with a given [style](https://vega.github.io/vega-lite/docs/mark.html#mark-def). The keys represent styles names; the values have to be valid [mark configuration objects](https://vega.github.io/vega-lite/docs/mark.html#config). */ + style?: StyleConfigIndex; +} +export declare const defaultConfig: Config; +export declare function initConfig(config: Config): Config; +export declare function stripAndRedirectConfig(config: Config): Config; diff --git a/build/src/config.js b/build/src/config.js new file mode 100644 index 0000000000..27af4cbff4 --- /dev/null +++ b/build/src/config.js @@ -0,0 +1,133 @@ +import * as tslib_1 from "tslib"; +import { isObject } from 'vega-util'; +import { COMPOSITE_MARK_STYLES } from './compositemark'; +import { VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX } from './compositemark/index'; +import { VL_ONLY_GUIDE_CONFIG } from './guide'; +import { defaultLegendConfig } from './legend'; +import * as mark from './mark'; +import { PRIMITIVE_MARKS, VL_ONLY_MARK_CONFIG_PROPERTIES, VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX } from './mark'; +import { defaultScaleConfig } from './scale'; +import { defaultConfig as defaultSelectionConfig } from './selection'; +import { extractTitleConfig } from './title'; +import { duplicate, keys, mergeDeep } from './util'; +export var defaultViewConfig = { + width: 200, + height: 200 +}; +export var defaultConfig = { + padding: 5, + timeFormat: '', + countTitle: 'Number of Records', + invalidValues: 'filter', + view: defaultViewConfig, + mark: mark.defaultMarkConfig, + area: {}, + bar: mark.defaultBarConfig, + circle: {}, + geoshape: {}, + line: {}, + point: {}, + rect: {}, + rule: { color: 'black' }, + square: {}, + text: { color: 'black' }, + tick: mark.defaultTickConfig, + trail: {}, + box: { size: 14, extent: 1.5 }, + boxWhisker: {}, + boxMid: { color: 'white' }, + scale: defaultScaleConfig, + projection: {}, + axis: {}, + axisX: {}, + axisY: { minExtent: 30 }, + axisLeft: {}, + axisRight: {}, + axisTop: {}, + axisBottom: {}, + axisBand: {}, + legend: defaultLegendConfig, + selection: defaultSelectionConfig, + style: {}, + title: {}, +}; +export function initConfig(config) { + return mergeDeep(duplicate(defaultConfig), config); +} +var MARK_STYLES = ['view'].concat(PRIMITIVE_MARKS, COMPOSITE_MARK_STYLES); +var VL_ONLY_CONFIG_PROPERTIES = [ + 'padding', 'numberFormat', 'timeFormat', 'countTitle', + 'stack', 'scale', 'selection', 'invalidValues', + 'overlay' // FIXME: Redesign and unhide this +]; +var VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = tslib_1.__assign({ view: ['width', 'height'] }, VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX, VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX); +export function stripAndRedirectConfig(config) { + config = duplicate(config); + for (var _i = 0, VL_ONLY_CONFIG_PROPERTIES_1 = VL_ONLY_CONFIG_PROPERTIES; _i < VL_ONLY_CONFIG_PROPERTIES_1.length; _i++) { + var prop = VL_ONLY_CONFIG_PROPERTIES_1[_i]; + delete config[prop]; + } + // Remove Vega-Lite only axis/legend config + if (config.axis) { + for (var _a = 0, VL_ONLY_GUIDE_CONFIG_1 = VL_ONLY_GUIDE_CONFIG; _a < VL_ONLY_GUIDE_CONFIG_1.length; _a++) { + var prop = VL_ONLY_GUIDE_CONFIG_1[_a]; + delete config.axis[prop]; + } + } + if (config.legend) { + for (var _b = 0, VL_ONLY_GUIDE_CONFIG_2 = VL_ONLY_GUIDE_CONFIG; _b < VL_ONLY_GUIDE_CONFIG_2.length; _b++) { + var prop = VL_ONLY_GUIDE_CONFIG_2[_b]; + delete config.legend[prop]; + } + } + // Remove Vega-Lite only generic mark config + if (config.mark) { + for (var _c = 0, VL_ONLY_MARK_CONFIG_PROPERTIES_1 = VL_ONLY_MARK_CONFIG_PROPERTIES; _c < VL_ONLY_MARK_CONFIG_PROPERTIES_1.length; _c++) { + var prop = VL_ONLY_MARK_CONFIG_PROPERTIES_1[_c]; + delete config.mark[prop]; + } + } + for (var _d = 0, MARK_STYLES_1 = MARK_STYLES; _d < MARK_STYLES_1.length; _d++) { + var markType = MARK_STYLES_1[_d]; + // Remove Vega-Lite-only mark config + for (var _e = 0, VL_ONLY_MARK_CONFIG_PROPERTIES_2 = VL_ONLY_MARK_CONFIG_PROPERTIES; _e < VL_ONLY_MARK_CONFIG_PROPERTIES_2.length; _e++) { + var prop = VL_ONLY_MARK_CONFIG_PROPERTIES_2[_e]; + delete config[markType][prop]; + } + // Remove Vega-Lite only mark-specific config + var vlOnlyMarkSpecificConfigs = VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX[markType]; + if (vlOnlyMarkSpecificConfigs) { + for (var _f = 0, vlOnlyMarkSpecificConfigs_1 = vlOnlyMarkSpecificConfigs; _f < vlOnlyMarkSpecificConfigs_1.length; _f++) { + var prop = vlOnlyMarkSpecificConfigs_1[_f]; + delete config[markType][prop]; + } + } + // Redirect mark config to config.style so that mark config only affect its own mark type + // without affecting other marks that share the same underlying Vega marks. + // For example, config.rect should not affect bar marks. + redirectConfig(config, markType); + } + // Redirect config.title -- so that title config do not + // affect header labels, which also uses `title` directive to implement. + redirectConfig(config, 'title', 'group-title'); + // Remove empty config objects + for (var prop in config) { + if (isObject(config[prop]) && keys(config[prop]).length === 0) { + delete config[prop]; + } + } + return keys(config).length > 0 ? config : undefined; +} +function redirectConfig(config, prop, toProp) { + var propConfig = prop === 'title' ? extractTitleConfig(config.title).mark : config[prop]; + if (prop === 'view') { + toProp = 'cell'; // View's default style is "cell" + } + var style = tslib_1.__assign({}, propConfig, config.style[prop]); + // set config.style if it is not an empty object + if (keys(style).length > 0) { + config.style[toProp || prop] = style; + } + delete config[prop]; +} +//# sourceMappingURL=config.js.map \ No newline at end of file diff --git a/build/src/config.js.map b/build/src/config.js.map new file mode 100644 index 0000000000..65af8a599d --- /dev/null +++ b/build/src/config.js.map @@ -0,0 +1 @@ +{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import {isObject} from 'vega-util';\nimport {AxisConfigMixins} from './axis';\nimport {COMPOSITE_MARK_STYLES} from './compositemark';\nimport {CompositeMarkConfigMixins, CompositeMarkStyle, VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX} from './compositemark/index';\nimport {VL_ONLY_GUIDE_CONFIG} from './guide';\nimport {HeaderConfig} from './header';\nimport {defaultLegendConfig, LegendConfig} from './legend';\nimport * as mark from './mark';\nimport {Mark, MarkConfigMixins, PRIMITIVE_MARKS, VL_ONLY_MARK_CONFIG_PROPERTIES, VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX} from './mark';\nimport {ProjectionConfig} from './projection';\nimport {defaultScaleConfig, ScaleConfig} from './scale';\nimport {defaultConfig as defaultSelectionConfig, SelectionConfig} from './selection';\nimport {StackOffset} from './stack';\nimport {extractTitleConfig} from './title';\nimport {TopLevelProperties} from './toplevelprops';\nimport {duplicate, keys, mergeDeep} from './util';\nimport {StrokeJoin, VgMarkConfig, VgScheme, VgTitleConfig} from './vega.schema';\n\n\nexport interface ViewConfig {\n /**\n * The default width of the single plot or each plot in a trellis plot when the visualization has a continuous (non-ordinal) x-scale or ordinal x-scale with `rangeStep` = `null`.\n *\n * __Default value:__ `200`\n *\n */\n width?: number;\n\n /**\n * The default height of the single plot or each plot in a trellis plot when the visualization has a continuous (non-ordinal) y-scale with `rangeStep` = `null`.\n *\n * __Default value:__ `200`\n *\n */\n height?: number;\n\n /**\n * Whether the view should be clipped.\n */\n clip?: boolean;\n\n // FILL_STROKE_CONFIG\n /**\n * The fill color.\n *\n * __Default value:__ (none)\n *\n */\n fill?: string;\n\n /**\n * The fill opacity (value between [0,1]).\n *\n * __Default value:__ (none)\n *\n */\n fillOpacity?: number;\n\n /**\n * The stroke color.\n *\n * __Default value:__ (none)\n *\n */\n stroke?: string;\n\n /**\n * The stroke opacity (value between [0,1]).\n *\n * __Default value:__ (none)\n *\n */\n strokeOpacity?: number;\n\n /**\n * The stroke width, in pixels.\n *\n * __Default value:__ (none)\n *\n */\n strokeWidth?: number;\n\n /**\n * An array of alternating stroke, space lengths for creating dashed or dotted lines.\n *\n * __Default value:__ (none)\n *\n */\n strokeDash?: number[];\n\n /**\n * The offset (in pixels) into which to begin drawing with the stroke dash array.\n *\n * __Default value:__ (none)\n *\n */\n strokeDashOffset?: number;\n\n /**\n * The stroke line join method. One of miter (default), round or bevel.\n *\n * __Default value:__ 'miter'\n *\n */\n strokeJoin?: StrokeJoin;\n\n /**\n * The stroke line join method. One of miter (default), round or bevel.\n *\n * __Default value:__ 'miter'\n *\n */\n strokeMiterLimit?: number;\n}\n\nexport const defaultViewConfig: ViewConfig = {\n width: 200,\n height: 200\n};\n\nexport type RangeConfigValue = (number|string)[] | VgScheme | {step: number};\n\nexport type RangeConfig = RangeConfigProps & {[name: string]: RangeConfigValue};\n\nexport interface RangeConfigProps {\n /**\n * Default range for _nominal_ (categorical) fields.\n */\n category?: string[] | VgScheme;\n\n /**\n * Default range for diverging _quantitative_ fields.\n */\n diverging?: string[] | VgScheme;\n\n /**\n * Default range for _quantitative_ heatmaps.\n */\n heatmap?: string[] | VgScheme;\n\n /**\n * Default range for _ordinal_ fields.\n */\n ordinal?: string[] | VgScheme;\n\n /**\n * Default range for _quantitative_ and _temporal_ fields.\n */\n ramp?: string[] | VgScheme;\n\n /**\n * Default range palette for the `shape` channel.\n */\n symbol?: string[];\n}\n\nexport interface VLOnlyConfig {\n /**\n * Default axis and legend title for count fields.\n *\n * __Default value:__ `'Number of Records'`.\n *\n * @type {string}\n */\n countTitle?: string;\n\n /**\n * Defines how Vega-Lite should handle invalid values (`null` and `NaN`).\n * - If set to `\"filter\"` (default), all data items with null values will be skipped (for line, trail, and area marks) or filtered (for other marks).\n * - If `null`, all data items are included. In this case, invalid values will be interpreted as zeroes.\n */\n invalidValues?: 'filter' | null;\n\n /**\n * Defines how Vega-Lite generates title for fields. There are three possible styles:\n * - `\"verbal\"` (Default) - displays function in a verbal style (e.g., \"Sum of field\", \"Year-month of date\", \"field (binned)\").\n * - `\"function\"` - displays function using parentheses and capitalized texts (e.g., \"SUM(field)\", \"YEARMONTH(date)\", \"BIN(field)\").\n * - `\"plain\"` - displays only the field name without functions (e.g., \"field\", \"date\", \"field\").\n */\n fieldTitle?: 'verbal' | 'functional' | 'plain';\n\n /**\n * D3 Number format for axis labels and text tables. For example \"s\" for SI units. Use [D3's number format pattern](https://github.com/d3/d3-format#locale_format).\n */\n numberFormat?: string;\n\n /**\n * Default datetime format for axis and legend labels. The format can be set directly on each axis and legend. Use [D3's time format pattern](https://github.com/d3/d3-time-format#locale_format).\n *\n * __Default value:__ `''` (The format will be automatically determined).\n *\n */\n timeFormat?: string;\n\n\n /** Default properties for [single view plots](https://vega.github.io/vega-lite/docs/spec.html#single). */\n view?: ViewConfig;\n\n /**\n * Scale configuration determines default properties for all [scales](https://vega.github.io/vega-lite/docs/scale.html). For a full list of scale configuration options, please see the [corresponding section of the scale documentation](https://vega.github.io/vega-lite/docs/scale.html#config).\n */\n scale?: ScaleConfig;\n\n /** An object hash for defining default properties for each type of selections. */\n selection?: SelectionConfig;\n\n /** Default stack offset for stackable mark. */\n stack?: StackOffset;\n}\n\nexport interface StyleConfigIndex {\n [style: string]: VgMarkConfig;\n}\n\n\nexport interface Config extends TopLevelProperties, VLOnlyConfig, MarkConfigMixins, CompositeMarkConfigMixins, AxisConfigMixins {\n\n /**\n * An object hash that defines default range arrays or schemes for using with scales.\n * For a full list of scale range configuration options, please see the [corresponding section of the scale documentation](https://vega.github.io/vega-lite/docs/scale.html#config).\n */\n range?: RangeConfig;\n\n /**\n * Legend configuration, which determines default properties for all [legends](https://vega.github.io/vega-lite/docs/legend.html). For a full list of legend configuration options, please see the [corresponding section of in the legend documentation](https://vega.github.io/vega-lite/docs/legend.html#config).\n */\n legend?: LegendConfig;\n\n /**\n * Header configuration, which determines default properties for all [header](https://vega.github.io/vega-lite/docs/header.html). For a full list of header configuration options, please see the [corresponding section of in the header documentation](https://vega.github.io/vega-lite/docs/header.html#config).\n */\n header?: HeaderConfig;\n\n /**\n * Title configuration, which determines default properties for all [titles](https://vega.github.io/vega-lite/docs/title.html). For a full list of title configuration options, please see the [corresponding section of the title documentation](https://vega.github.io/vega-lite/docs/title.html#config).\n */\n title?: VgTitleConfig;\n\n /**\n * Projection configuration, which determines default properties for all [projections](https://vega.github.io/vega-lite/docs/projection.html). For a full list of projection configuration options, please see the [corresponding section of the projection documentation](https://vega.github.io/vega-lite/docs/projection.html#config).\n */\n projection?: ProjectionConfig;\n\n /** An object hash that defines key-value mappings to determine default properties for marks with a given [style](https://vega.github.io/vega-lite/docs/mark.html#mark-def). The keys represent styles names; the values have to be valid [mark configuration objects](https://vega.github.io/vega-lite/docs/mark.html#config). */\n style?: StyleConfigIndex;\n}\n\nexport const defaultConfig: Config = {\n padding: 5,\n timeFormat: '',\n countTitle: 'Number of Records',\n\n invalidValues: 'filter',\n\n view: defaultViewConfig,\n\n mark: mark.defaultMarkConfig,\n area: {},\n bar: mark.defaultBarConfig,\n circle: {},\n geoshape: {},\n line: {},\n point: {},\n rect: {},\n rule: {color: 'black'}, // Need this to override default color in mark config\n square: {},\n text: {color: 'black'}, // Need this to override default color in mark config\n tick: mark.defaultTickConfig,\n trail: {},\n\n box: {size: 14, extent: 1.5},\n boxWhisker: {},\n boxMid: {color: 'white'},\n\n scale: defaultScaleConfig,\n projection: {},\n axis: {},\n axisX: {},\n axisY: {minExtent: 30},\n axisLeft: {},\n axisRight: {},\n axisTop: {},\n axisBottom: {},\n axisBand: {},\n legend: defaultLegendConfig,\n\n selection: defaultSelectionConfig,\n style: {},\n\n title: {},\n};\n\nexport function initConfig(config: Config) {\n return mergeDeep(duplicate(defaultConfig), config);\n}\n\nconst MARK_STYLES = ['view'].concat(PRIMITIVE_MARKS, COMPOSITE_MARK_STYLES) as ('view' | Mark | CompositeMarkStyle)[];\n\n\nconst VL_ONLY_CONFIG_PROPERTIES: (keyof Config)[] = [\n 'padding', 'numberFormat', 'timeFormat', 'countTitle',\n 'stack', 'scale', 'selection', 'invalidValues',\n 'overlay' as keyof Config // FIXME: Redesign and unhide this\n];\n\nconst VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = {\n view: ['width', 'height'],\n ...VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX,\n ...VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX\n};\n\nexport function stripAndRedirectConfig(config: Config) {\n config = duplicate(config);\n\n for (const prop of VL_ONLY_CONFIG_PROPERTIES) {\n delete config[prop];\n }\n\n // Remove Vega-Lite only axis/legend config\n if (config.axis) {\n for (const prop of VL_ONLY_GUIDE_CONFIG) {\n delete config.axis[prop];\n }\n }\n if (config.legend) {\n for (const prop of VL_ONLY_GUIDE_CONFIG) {\n delete config.legend[prop];\n }\n }\n\n // Remove Vega-Lite only generic mark config\n if (config.mark) {\n for (const prop of VL_ONLY_MARK_CONFIG_PROPERTIES) {\n delete config.mark[prop];\n }\n }\n\n for (const markType of MARK_STYLES) {\n // Remove Vega-Lite-only mark config\n for (const prop of VL_ONLY_MARK_CONFIG_PROPERTIES) {\n delete config[markType][prop];\n }\n\n // Remove Vega-Lite only mark-specific config\n const vlOnlyMarkSpecificConfigs = VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX[markType];\n if (vlOnlyMarkSpecificConfigs) {\n for (const prop of vlOnlyMarkSpecificConfigs) {\n delete config[markType][prop];\n }\n }\n\n // Redirect mark config to config.style so that mark config only affect its own mark type\n // without affecting other marks that share the same underlying Vega marks.\n // For example, config.rect should not affect bar marks.\n redirectConfig(config, markType);\n }\n\n // Redirect config.title -- so that title config do not\n // affect header labels, which also uses `title` directive to implement.\n redirectConfig(config, 'title', 'group-title');\n\n // Remove empty config objects\n for (const prop in config) {\n if (isObject(config[prop]) && keys(config[prop]).length === 0) {\n delete config[prop];\n }\n }\n\n return keys(config).length > 0 ? config : undefined;\n}\n\nfunction redirectConfig(config: Config, prop: Mark | CompositeMarkStyle | 'title' | 'view', toProp?: string) {\n const propConfig: VgMarkConfig = prop === 'title' ? extractTitleConfig(config.title).mark : config[prop];\n\n if (prop === 'view') {\n toProp = 'cell'; // View's default style is \"cell\"\n }\n\n const style: VgMarkConfig = {\n ...propConfig,\n ...config.style[prop]\n };\n // set config.style if it is not an empty object\n if (keys(style).length > 0) {\n config.style[toProp || prop] = style;\n }\n delete config[prop];\n}\n"]} \ No newline at end of file diff --git a/build/src/data.d.ts b/build/src/data.d.ts new file mode 100644 index 0000000000..a6f34dd752 --- /dev/null +++ b/build/src/data.d.ts @@ -0,0 +1,115 @@ +import { VgData } from './vega.schema'; +export interface Parse { + [field: string]: null | string | 'string' | 'boolean' | 'date' | 'number'; +} +export interface DataFormatBase { + /** + * If set to `"auto"` (the default), perform automatic type inference to determine the desired data types. + * If set to `null`, disable type inference based on the spec and only use type inference based on the data. + * Alternatively, a parsing directive object can be provided for explicit data types. Each property of the object corresponds to a field name, and the value to the desired data type (one of `"number"`, `"boolean"`, `"date"`, or null (do not parse the field)). + * For example, `"parse": {"modified_on": "date"}` parses the `modified_on` field in each input record a Date value. + * + * For `"date"`, we parse data based using Javascript's [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse). + * For Specific date formats can be provided (e.g., `{foo: 'date:"%m%d%Y"'}`), using the [d3-time-format syntax](https://github.com/d3/d3-time-format#locale_format). UTC date format parsing is supported similarly (e.g., `{foo: 'utc:"%m%d%Y"'}`). See more about [UTC time](https://vega.github.io/vega-lite/docs/timeunit.html#utc) + */ + parse?: 'auto' | Parse | null; +} +export interface CsvDataFormat extends DataFormatBase { + /** + * Type of input data: `"json"`, `"csv"`, `"tsv"`, `"dsv"`. + * The default format type is determined by the extension of the file URL. + * If no extension is detected, `"json"` will be used by default. + */ + type?: 'csv' | 'tsv'; +} +export interface DsvDataFormat extends DataFormatBase { + /** + * Type of input data: `"json"`, `"csv"`, `"tsv"`, `"dsv"`. + * The default format type is determined by the extension of the file URL. + * If no extension is detected, `"json"` will be used by default. + */ + type?: 'dsv'; + /** + * The delimiter between records. The delimiter must be a single character (i.e., a single 16-bit code unit); so, ASCII delimiters are fine, but emoji delimiters are not. + * + * @minLength 1 + * @maxLength 1 + */ + delimiter: string; +} +export interface JsonDataFormat extends DataFormatBase { + /** + * Type of input data: `"json"`, `"csv"`, `"tsv"`, `"dsv"`. + * The default format type is determined by the extension of the file URL. + * If no extension is detected, `"json"` will be used by default. + */ + type?: 'json'; + /** + * The JSON property containing the desired data. + * This parameter can be used when the loaded JSON file may have surrounding structure or meta-data. + * For example `"property": "values.features"` is equivalent to retrieving `json.values.features` + * from the loaded JSON object. + */ + property?: string; +} +export interface TopoDataFormat extends DataFormatBase { + /** + * Type of input data: `"json"`, `"csv"`, `"tsv"`, `"dsv"`. + * The default format type is determined by the extension of the file URL. + * If no extension is detected, `"json"` will be used by default. + */ + type?: 'topojson'; + /** + * The name of the TopoJSON object set to convert to a GeoJSON feature collection. + * For example, in a map of the world, there may be an object set named `"countries"`. + * Using the feature property, we can extract this set and generate a GeoJSON feature object for each country. + */ + feature?: string; + /** + * The name of the TopoJSON object set to convert to mesh. + * Similar to the `feature` option, `mesh` extracts a named TopoJSON object set. + * Unlike the `feature` option, the corresponding geo data is returned as a single, unified mesh instance, not as individual GeoJSON features. + * Extracting a mesh is useful for more efficiently drawing borders or other geographic elements that you do not need to associate with specific regions such as individual countries, states or counties. + */ + mesh?: string; +} +export declare type DataFormat = CsvDataFormat | DsvDataFormat | JsonDataFormat | TopoDataFormat; +export declare type DataFormatType = 'json' | 'csv' | 'tsv' | 'dsv' | 'topojson'; +export declare type Data = UrlData | InlineData | NamedData; +export declare type InlineDataset = number[] | string[] | boolean[] | object[] | string | object; +export interface DataBase { + /** + * An object that specifies the format for parsing the data. + */ + format?: DataFormat; + /** + * Provide a placeholder name and bind data at runtime. + */ + name?: string; +} +export interface UrlData extends DataBase { + /** + * An URL from which to load the data set. Use the `format.type` property + * to ensure the loaded data is correctly parsed. + */ + url: string; +} +export interface InlineData extends DataBase { + /** + * The full data set, included inline. This can be an array of objects or primitive values, an object, or a string. + * Arrays of primitive values are ingested as objects with a `data` property. Strings are parsed according to the specified format type. + */ + values: InlineDataset; +} +export interface NamedData extends DataBase { + /** + * Provide a placeholder name and bind data at runtime. + */ + name: string; +} +export declare function isUrlData(data: Partial | Partial): data is UrlData; +export declare function isInlineData(data: Partial | Partial): data is InlineData; +export declare function isNamedData(data: Partial): data is NamedData; +export declare type DataSourceType = 'raw' | 'main' | 'row' | 'column' | 'lookup'; +export declare const MAIN: 'main'; +export declare const RAW: 'raw'; diff --git a/build/src/data.js b/build/src/data.js new file mode 100644 index 0000000000..7461fd6494 --- /dev/null +++ b/build/src/data.js @@ -0,0 +1,12 @@ +export function isUrlData(data) { + return !!data['url']; +} +export function isInlineData(data) { + return !!data['values']; +} +export function isNamedData(data) { + return !!data['name'] && !isUrlData(data) && !isInlineData(data); +} +export var MAIN = 'main'; +export var RAW = 'raw'; +//# sourceMappingURL=data.js.map \ No newline at end of file diff --git a/build/src/data.js.map b/build/src/data.js.map new file mode 100644 index 0000000000..02f84646cd --- /dev/null +++ b/build/src/data.js.map @@ -0,0 +1 @@ +{"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/data.ts"],"names":[],"mappings":"AAgIA,MAAM,oBAAoB,IAAqC;IAC7D,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,uBAAuB,IAAqC;IAChE,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,sBAAsB,IAAmB;IAC7C,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC;AAID,MAAM,CAAC,IAAM,IAAI,GAAW,MAAM,CAAC;AACnC,MAAM,CAAC,IAAM,GAAG,GAAU,KAAK,CAAC","sourcesContent":["/*\n * Constants and utilities for data.\n */\nimport {VgData} from './vega.schema';\n\nexport interface Parse {\n [field: string]: null | string | 'string' | 'boolean' | 'date' | 'number';\n}\n\nexport interface DataFormatBase {\n /**\n * If set to `\"auto\"` (the default), perform automatic type inference to determine the desired data types.\n * If set to `null`, disable type inference based on the spec and only use type inference based on the data.\n * Alternatively, a parsing directive object can be provided for explicit data types. Each property of the object corresponds to a field name, and the value to the desired data type (one of `\"number\"`, `\"boolean\"`, `\"date\"`, or null (do not parse the field)).\n * For example, `\"parse\": {\"modified_on\": \"date\"}` parses the `modified_on` field in each input record a Date value.\n *\n * For `\"date\"`, we parse data based using Javascript's [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).\n * For Specific date formats can be provided (e.g., `{foo: 'date:\"%m%d%Y\"'}`), using the [d3-time-format syntax](https://github.com/d3/d3-time-format#locale_format). UTC date format parsing is supported similarly (e.g., `{foo: 'utc:\"%m%d%Y\"'}`). See more about [UTC time](https://vega.github.io/vega-lite/docs/timeunit.html#utc)\n */\n parse?: 'auto' | Parse | null;\n}\n\nexport interface CsvDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'csv' | 'tsv';\n}\n\nexport interface DsvDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'dsv';\n\n /**\n * The delimiter between records. The delimiter must be a single character (i.e., a single 16-bit code unit); so, ASCII delimiters are fine, but emoji delimiters are not.\n *\n * @minLength 1\n * @maxLength 1\n */\n delimiter: string;\n}\n\nexport interface JsonDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'json';\n /**\n * The JSON property containing the desired data.\n * This parameter can be used when the loaded JSON file may have surrounding structure or meta-data.\n * For example `\"property\": \"values.features\"` is equivalent to retrieving `json.values.features`\n * from the loaded JSON object.\n */\n property?: string;\n}\n\nexport interface TopoDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'topojson';\n /**\n * The name of the TopoJSON object set to convert to a GeoJSON feature collection.\n * For example, in a map of the world, there may be an object set named `\"countries\"`.\n * Using the feature property, we can extract this set and generate a GeoJSON feature object for each country.\n */\n feature?: string;\n /**\n * The name of the TopoJSON object set to convert to mesh.\n * Similar to the `feature` option, `mesh` extracts a named TopoJSON object set.\n * Unlike the `feature` option, the corresponding geo data is returned as a single, unified mesh instance, not as individual GeoJSON features.\n * Extracting a mesh is useful for more efficiently drawing borders or other geographic elements that you do not need to associate with specific regions such as individual countries, states or counties.\n */\n mesh?: string;\n}\n\nexport type DataFormat = CsvDataFormat | DsvDataFormat | JsonDataFormat | TopoDataFormat;\n\nexport type DataFormatType = 'json' | 'csv' | 'tsv' | 'dsv' | 'topojson';\n\nexport type Data = UrlData | InlineData | NamedData;\n\nexport type InlineDataset = number[] | string[] | boolean[] | object[] | string | object;\n\nexport interface DataBase {\n /**\n * An object that specifies the format for parsing the data.\n */\n format?: DataFormat;\n /**\n * Provide a placeholder name and bind data at runtime.\n */\n name?: string;\n}\n\nexport interface UrlData extends DataBase {\n /**\n * An URL from which to load the data set. Use the `format.type` property\n * to ensure the loaded data is correctly parsed.\n */\n url: string;\n}\n\nexport interface InlineData extends DataBase {\n /**\n * The full data set, included inline. This can be an array of objects or primitive values, an object, or a string.\n * Arrays of primitive values are ingested as objects with a `data` property. Strings are parsed according to the specified format type.\n */\n values: InlineDataset;\n}\n\nexport interface NamedData extends DataBase {\n /**\n * Provide a placeholder name and bind data at runtime.\n */\n name: string;\n}\n\nexport function isUrlData(data: Partial | Partial): data is UrlData {\n return !!data['url'];\n}\n\nexport function isInlineData(data: Partial | Partial): data is InlineData {\n return !!data['values'];\n}\n\nexport function isNamedData(data: Partial): data is NamedData {\n return !!data['name'] && !isUrlData(data) && !isInlineData(data);\n}\n\nexport type DataSourceType = 'raw' | 'main' | 'row' | 'column' | 'lookup';\n\nexport const MAIN: 'main' = 'main';\nexport const RAW: 'raw' = 'raw';\n"]} \ No newline at end of file diff --git a/build/src/datetime.d.ts b/build/src/datetime.d.ts new file mode 100644 index 0000000000..bb69b23925 --- /dev/null +++ b/build/src/datetime.d.ts @@ -0,0 +1,105 @@ +/** + * @minimum 1 + * @maximum 12 + * @TJS-type integer + */ +export declare type Month = number; +/** + * @minimum 1 + * @maximum 7 + */ +export declare type Day = number; +/** + * Object for defining datetime in Vega-Lite Filter. + * If both month and quarter are provided, month has higher precedence. + * `day` cannot be combined with other date. + * We accept string for month and day names. + */ +export interface DateTime { + /** + * Integer value representing the year. + * @TJS-type integer + */ + year?: number; + /** + * Integer value representing the quarter of the year (from 1-4). + * @minimum 1 + * @maximum 4 + * @TJS-type integer + */ + quarter?: number; + /** One of: (1) integer value representing the month from `1`-`12`. `1` represents January; (2) case-insensitive month name (e.g., `"January"`); (3) case-insensitive, 3-character short month name (e.g., `"Jan"`). */ + month?: Month | string; + /** + * Integer value representing the date from 1-31. + * @minimum 1 + * @maximum 31 + * @TJS-type integer + */ + date?: number; + /** + * Value representing the day of a week. This can be one of: (1) integer value -- `1` represents Monday; (2) case-insensitive day name (e.g., `"Monday"`); (3) case-insensitive, 3-character short day name (e.g., `"Mon"`).
**Warning:** A DateTime definition object with `day`** should not be combined with `year`, `quarter`, `month`, or `date`. + */ + day?: Day | string; + /** + * Integer value representing the hour of a day from 0-23. + * @minimum 0 + * @maximum 23 + * @TJS-type integer + */ + hours?: number; + /** + * Integer value representing the minute segment of time from 0-59. + * @minimum 0 + * @maximum 59 + * @TJS-type integer + */ + minutes?: number; + /** + * Integer value representing the second segment (0-59) of a time value + * @minimum 0 + * @maximum 59 + * @TJS-type integer + */ + seconds?: number; + /** + * Integer value representing the millisecond segment of time. + * @minimum 0 + * @maximum 999 + * @TJS-type integer + */ + milliseconds?: number; + /** + * A boolean flag indicating if date time is in utc time. If false, the date time is in local time + */ + utc?: boolean; +} +/** + * Internal Object for defining datetime expressions. + * This is an expression version of DateTime. + * If both month and quarter are provided, month has higher precedence. + * `day` cannot be combined with other date. + */ +export interface DateTimeExpr { + year?: string; + quarter?: string; + month?: string; + date?: string; + day?: string; + hours?: string; + minutes?: string; + seconds?: string; + milliseconds?: string; + utc?: boolean; +} +export declare function isDateTime(o: any): o is DateTime; +export declare const MONTHS: string[]; +export declare const SHORT_MONTHS: string[]; +export declare const DAYS: string[]; +export declare const SHORT_DAYS: string[]; +/** + * Return Vega Expression for a particular date time. + * @param d + * @param normalize whether to normalize quarter, month, day. + */ +export declare function dateTimeExpr(d: DateTime | DateTimeExpr, normalize?: boolean): string; diff --git a/build/src/datetime.js b/build/src/datetime.js new file mode 100644 index 0000000000..2499947fc9 --- /dev/null +++ b/build/src/datetime.js @@ -0,0 +1,137 @@ +// DateTime definition object +import { isNumber } from 'vega-util'; +import * as log from './log'; +import { duplicate, keys } from './util'; +/* + * A designated year that starts on Sunday. + */ +var SUNDAY_YEAR = 2006; +export function isDateTime(o) { + return !!o && (!!o.year || !!o.quarter || !!o.month || !!o.date || !!o.day || + !!o.hours || !!o.minutes || !!o.seconds || !!o.milliseconds); +} +export var MONTHS = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december']; +export var SHORT_MONTHS = MONTHS.map(function (m) { return m.substr(0, 3); }); +export var DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']; +export var SHORT_DAYS = DAYS.map(function (d) { return d.substr(0, 3); }); +function normalizeQuarter(q) { + if (isNumber(q)) { + if (q > 4) { + log.warn(log.message.invalidTimeUnit('quarter', q)); + } + // We accept 1-based quarter, so need to readjust to 0-based quarter + return (q - 1) + ''; + } + else { + // Invalid quarter + throw new Error(log.message.invalidTimeUnit('quarter', q)); + } +} +function normalizeMonth(m) { + if (isNumber(m)) { + // We accept 1-based month, so need to readjust to 0-based month + return (m - 1) + ''; + } + else { + var lowerM = m.toLowerCase(); + var monthIndex = MONTHS.indexOf(lowerM); + if (monthIndex !== -1) { + return monthIndex + ''; // 0 for january, ... + } + var shortM = lowerM.substr(0, 3); + var shortMonthIndex = SHORT_MONTHS.indexOf(shortM); + if (shortMonthIndex !== -1) { + return shortMonthIndex + ''; + } + // Invalid month + throw new Error(log.message.invalidTimeUnit('month', m)); + } +} +function normalizeDay(d) { + if (isNumber(d)) { + // mod so that this can be both 0-based where 0 = sunday + // and 1-based where 7=sunday + return (d % 7) + ''; + } + else { + var lowerD = d.toLowerCase(); + var dayIndex = DAYS.indexOf(lowerD); + if (dayIndex !== -1) { + return dayIndex + ''; // 0 for january, ... + } + var shortD = lowerD.substr(0, 3); + var shortDayIndex = SHORT_DAYS.indexOf(shortD); + if (shortDayIndex !== -1) { + return shortDayIndex + ''; + } + // Invalid day + throw new Error(log.message.invalidTimeUnit('day', d)); + } +} +/** + * Return Vega Expression for a particular date time. + * @param d + * @param normalize whether to normalize quarter, month, day. + */ +export function dateTimeExpr(d, normalize) { + if (normalize === void 0) { normalize = false; } + var units = []; + if (normalize && d.day !== undefined) { + if (keys(d).length > 1) { + log.warn(log.message.droppedDay(d)); + d = duplicate(d); + delete d.day; + } + } + if (d.year !== undefined) { + units.push(d.year); + } + else if (d.day !== undefined) { + // Set year to 2006 for working with day since January 1 2006 is a Sunday + units.push(SUNDAY_YEAR); + } + else { + units.push(0); + } + if (d.month !== undefined) { + var month = normalize ? normalizeMonth(d.month) : d.month; + units.push(month); + } + else if (d.quarter !== undefined) { + var quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter; + units.push(quarter + '*3'); + } + else { + units.push(0); // months start at zero in JS + } + if (d.date !== undefined) { + units.push(d.date); + } + else if (d.day !== undefined) { + // HACK: Day only works as a standalone unit + // This is only correct because we always set year to 2006 for day + var day = normalize ? normalizeDay(d.day) : d.day; + units.push(day + '+1'); + } + else { + units.push(1); // Date starts at 1 in JS + } + // Note: can't use TimeUnit enum here as importing it will create + // circular dependency problem! + for (var _i = 0, _a = ['hours', 'minutes', 'seconds', 'milliseconds']; _i < _a.length; _i++) { + var timeUnit = _a[_i]; + if (d[timeUnit] !== undefined) { + units.push(d[timeUnit]); + } + else { + units.push(0); + } + } + if (d.utc) { + return "utc(" + units.join(', ') + ")"; + } + else { + return "datetime(" + units.join(', ') + ")"; + } +} +//# sourceMappingURL=datetime.js.map \ No newline at end of file diff --git a/build/src/datetime.js.map b/build/src/datetime.js.map new file mode 100644 index 0000000000..6e0af8b680 --- /dev/null +++ b/build/src/datetime.js.map @@ -0,0 +1 @@ +{"version":3,"file":"datetime.js","sourceRoot":"","sources":["../../src/datetime.ts"],"names":[],"mappings":"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","sourcesContent":["// DateTime definition object\n\nimport {isNumber} from 'vega-util';\nimport * as log from './log';\nimport {duplicate, keys} from './util';\n\n\n/*\n * A designated year that starts on Sunday.\n */\nconst SUNDAY_YEAR = 2006;\n\n/**\n * @minimum 1\n * @maximum 12\n * @TJS-type integer\n */\nexport type Month = number;\n\n/**\n * @minimum 1\n * @maximum 7\n */\nexport type Day = number;\n\n/**\n * Object for defining datetime in Vega-Lite Filter.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n * We accept string for month and day names.\n */\nexport interface DateTime {\n /**\n * Integer value representing the year.\n * @TJS-type integer\n */\n year?: number;\n\n /**\n * Integer value representing the quarter of the year (from 1-4).\n * @minimum 1\n * @maximum 4\n * @TJS-type integer\n */\n quarter?: number;\n\n /** One of: (1) integer value representing the month from `1`-`12`. `1` represents January; (2) case-insensitive month name (e.g., `\"January\"`); (3) case-insensitive, 3-character short month name (e.g., `\"Jan\"`). */\n month?: Month | string;\n\n /**\n * Integer value representing the date from 1-31.\n * @minimum 1\n * @maximum 31\n * @TJS-type integer\n */\n date?: number;\n\n /**\n * Value representing the day of a week. This can be one of: (1) integer value -- `1` represents Monday; (2) case-insensitive day name (e.g., `\"Monday\"`); (3) case-insensitive, 3-character short day name (e.g., `\"Mon\"`).
**Warning:** A DateTime definition object with `day`** should not be combined with `year`, `quarter`, `month`, or `date`.\n */\n day?: Day | string;\n\n /**\n * Integer value representing the hour of a day from 0-23.\n * @minimum 0\n * @maximum 23\n * @TJS-type integer\n */\n hours?: number;\n\n /**\n * Integer value representing the minute segment of time from 0-59.\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n minutes?: number;\n\n /**\n * Integer value representing the second segment (0-59) of a time value\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n seconds?: number;\n\n /**\n * Integer value representing the millisecond segment of time.\n * @minimum 0\n * @maximum 999\n * @TJS-type integer\n */\n milliseconds?: number;\n\n /**\n * A boolean flag indicating if date time is in utc time. If false, the date time is in local time\n */\n utc?: boolean;\n}\n\n\n/**\n * Internal Object for defining datetime expressions.\n * This is an expression version of DateTime.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n */\nexport interface DateTimeExpr {\n year?: string;\n quarter?: string;\n month?: string;\n date?: string;\n day?: string;\n hours?: string;\n minutes?: string;\n seconds?: string;\n milliseconds?: string;\n utc?: boolean;\n}\n\nexport function isDateTime(o: any): o is DateTime {\n return !!o && (!!o.year || !!o.quarter || !!o.month || !!o.date || !!o.day ||\n !!o.hours || !!o.minutes || !!o.seconds || !!o.milliseconds);\n}\n\nexport const MONTHS = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];\nexport const SHORT_MONTHS = MONTHS.map((m) => m.substr(0, 3));\n\nexport const DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];\nexport const SHORT_DAYS = DAYS.map((d) => d.substr(0,3));\n\nfunction normalizeQuarter(q: number | string) {\n if (isNumber(q)) {\n if (q > 4) {\n log.warn(log.message.invalidTimeUnit('quarter', q));\n }\n // We accept 1-based quarter, so need to readjust to 0-based quarter\n return (q - 1) + '';\n } else {\n // Invalid quarter\n throw new Error(log.message.invalidTimeUnit('quarter', q));\n }\n}\n\nfunction normalizeMonth(m: string | number) {\n if (isNumber(m)) {\n // We accept 1-based month, so need to readjust to 0-based month\n return (m - 1) + '';\n } else {\n const lowerM = m.toLowerCase();\n const monthIndex = MONTHS.indexOf(lowerM);\n if (monthIndex !== -1) {\n return monthIndex + ''; // 0 for january, ...\n }\n const shortM = lowerM.substr(0, 3);\n const shortMonthIndex = SHORT_MONTHS.indexOf(shortM);\n if (shortMonthIndex !== -1) {\n return shortMonthIndex + '';\n }\n // Invalid month\n throw new Error(log.message.invalidTimeUnit('month', m));\n }\n}\n\nfunction normalizeDay(d: string | number) {\n if (isNumber(d)) {\n // mod so that this can be both 0-based where 0 = sunday\n // and 1-based where 7=sunday\n return (d % 7) + '';\n } else {\n const lowerD = d.toLowerCase();\n const dayIndex = DAYS.indexOf(lowerD);\n if (dayIndex !== -1) {\n return dayIndex + ''; // 0 for january, ...\n }\n const shortD = lowerD.substr(0, 3);\n const shortDayIndex = SHORT_DAYS.indexOf(shortD);\n if (shortDayIndex !== -1) {\n return shortDayIndex + '';\n }\n // Invalid day\n throw new Error(log.message.invalidTimeUnit('day', d));\n }\n}\n\n/**\n * Return Vega Expression for a particular date time.\n * @param d\n * @param normalize whether to normalize quarter, month, day.\n */\nexport function dateTimeExpr(d: DateTime | DateTimeExpr, normalize = false) {\n const units: (string | number)[] = [];\n\n if (normalize && d.day !== undefined) {\n if (keys(d).length > 1) {\n log.warn(log.message.droppedDay(d));\n d = duplicate(d);\n delete d.day;\n }\n }\n\n if (d.year !== undefined) {\n units.push(d.year);\n } else if (d.day !== undefined) {\n // Set year to 2006 for working with day since January 1 2006 is a Sunday\n units.push(SUNDAY_YEAR);\n } else {\n units.push(0);\n }\n\n if (d.month !== undefined) {\n const month = normalize ? normalizeMonth(d.month) : d.month;\n units.push(month);\n } else if (d.quarter !== undefined) {\n const quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter;\n units.push(quarter + '*3');\n } else {\n units.push(0); // months start at zero in JS\n }\n\n if (d.date !== undefined) {\n units.push(d.date);\n } else if (d.day !== undefined) {\n // HACK: Day only works as a standalone unit\n // This is only correct because we always set year to 2006 for day\n const day = normalize ? normalizeDay(d.day) : d.day;\n units.push(day + '+1');\n } else {\n units.push(1); // Date starts at 1 in JS\n }\n\n // Note: can't use TimeUnit enum here as importing it will create\n // circular dependency problem!\n for (const timeUnit of ['hours', 'minutes', 'seconds', 'milliseconds']) {\n if (d[timeUnit] !== undefined) {\n units.push(d[timeUnit]);\n } else {\n units.push(0);\n }\n }\n\n if (d.utc) {\n return `utc(${units.join(', ')})`;\n } else {\n return `datetime(${units.join(', ')})`;\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/encoding.d.ts b/build/src/encoding.d.ts new file mode 100644 index 0000000000..50f5c4d41f --- /dev/null +++ b/build/src/encoding.d.ts @@ -0,0 +1,128 @@ +import { Channel } from './channel'; +import { FacetMapping } from './facet'; +import { Field, FieldDef, FieldDefWithCondition, MarkPropFieldDef, OrderFieldDef, PositionFieldDef, TextFieldDef, ValueDef, ValueDefWithCondition } from './fielddef'; +import { Mark } from './mark'; +export interface Encoding { + /** + * X coordinates of the marks, or width of horizontal `"bar"` and `"area"`. + */ + x?: PositionFieldDef | ValueDef; + /** + * Y coordinates of the marks, or height of vertical `"bar"` and `"area"`. + */ + y?: PositionFieldDef | ValueDef; + /** + * X2 coordinates for ranged `"area"`, `"bar"`, `"rect"`, and `"rule"`. + */ + x2?: FieldDef | ValueDef; + /** + * Y2 coordinates for ranged `"area"`, `"bar"`, `"rect"`, and `"rule"`. + */ + y2?: FieldDef | ValueDef; + /** + * Longitude position of geographically projected marks. + */ + longitude?: FieldDef; + /** + * Latitude position of geographically projected marks. + */ + latitude?: FieldDef; + /** + * Longitude-2 position for geographically projected ranged `"area"`, `"bar"`, `"rect"`, and `"rule"`. + */ + longitude2?: FieldDef; + /** + * Latitude-2 position for geographically projected ranged `"area"`, `"bar"`, `"rect"`, and `"rule"`. + */ + latitude2?: FieldDef; + /** + * Color of the marks – either fill or stroke color based on the `filled` property of mark definition. + * By default, `color` represents fill color for `"area"`, `"bar"`, `"tick"`, + * `"text"`, `"trail"`, `"circle"`, and `"square"` / stroke color for `"line"` and `"point"`. + * + * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property. + * + * _Note:_ + * 1) For fine-grained control over both fill and stroke colors of the marks, please use the `fill` and `stroke` channels. If either `fill` or `stroke` channel is specified, `color` channel will be ignored. + * 2) See the scale documentation for more information about customizing [color scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme). + */ + color?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * Fill color of the marks. + * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property. + * + * _Note:_ When using `fill` channel, `color ` channel will be ignored. To customize both fill and stroke, please use `fill` and `stroke` channels (not `fill` and `color`). + */ + fill?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * Stroke color of the marks. + * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property. + * + * _Note:_ When using `stroke` channel, `color ` channel will be ignored. To customize both stroke and fill, please use `stroke` and `fill` channels (not `stroke` and `color`). + */ + stroke?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * Opacity of the marks – either can be a value or a range. + * + * __Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `opacity` property. + */ + opacity?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * Size of the mark. + * - For `"point"`, `"square"` and `"circle"`, – the symbol size, or pixel area of the mark. + * - For `"bar"` and `"tick"` – the bar and tick's size. + * - For `"text"` – the text's font size. + * - Size is unsupported for `"line"`, `"area"`, and `"rect"`. (Use `"trail"` instead of line with varying size) + */ + size?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * For `point` marks the supported values are + * `"circle"` (default), `"square"`, `"cross"`, `"diamond"`, `"triangle-up"`, + * or `"triangle-down"`, or else a custom SVG path string. + * For `geoshape` marks it should be a field definition of the geojson data + * + * __Default value:__ If undefined, the default shape depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#point-config)'s `shape` property. + */ + shape?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * Additional levels of detail for grouping data in aggregate views and + * in line, trail, and area marks without mapping data to a specific visual channel. + */ + detail?: FieldDef | FieldDef[]; + /** + * A data field to use as a unique key for data binding. When a visualization’s data is updated, the key value will be used to match data elements to existing mark instances. Use a key channel to enable object constancy for transitions over dynamic data. + */ + key?: FieldDef; + /** + * Text of the `text` mark. + */ + text?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * The tooltip text to show upon mouse hover. + */ + tooltip?: FieldDefWithCondition> | ValueDefWithCondition> | TextFieldDef[]; + /** + * A URL to load upon mouse click. + */ + href?: FieldDefWithCondition> | ValueDefWithCondition>; + /** + * Order of the marks. + * - For stacked marks, this `order` channel encodes [stack order](https://vega.github.io/vega-lite/docs/stack.html#order). + * - For line and trail marks, this `order` channel encodes order of data points in the lines. This can be useful for creating [a connected scatterplot](https://vega.github.io/vega-lite/examples/connected_scatterplot.html). Setting `order` to `{"value": null}` makes the line marks use the original order in the data sources. + * - Otherwise, this `order` channel encodes layer order of the marks. + * + * __Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping. + */ + order?: OrderFieldDef | OrderFieldDef[] | ValueDef; +} +export interface EncodingWithFacet extends Encoding, FacetMapping { +} +export declare function channelHasField(encoding: EncodingWithFacet, channel: Channel): boolean; +export declare function isAggregate(encoding: EncodingWithFacet): boolean; +export declare function normalizeEncoding(encoding: Encoding, mark: Mark): Encoding; +export declare function isRanged(encoding: EncodingWithFacet): boolean; +export declare function fieldDefs(encoding: EncodingWithFacet): FieldDef[]; +export declare function forEach(mapping: any, f: (fd: FieldDef, c: Channel) => void, thisArg?: any): void; +export declare function reduce(mapping: U, f: (acc: any, fd: FieldDef, c: Channel) => U, init: T, thisArg?: any): any; diff --git a/build/src/encoding.js b/build/src/encoding.js new file mode 100644 index 0000000000..f50563cd41 --- /dev/null +++ b/build/src/encoding.js @@ -0,0 +1,154 @@ +import * as tslib_1 from "tslib"; +import { isArray } from 'vega-util'; +import { CHANNELS, isChannel, supportMark } from './channel'; +import { getFieldDef, hasConditionalFieldDef, isConditionalDef, isFieldDef, isValueDef, normalize, normalizeFieldDef } from './fielddef'; +import * as log from './log'; +import { Type } from './type'; +import { contains, keys, some } from './util'; +export function channelHasField(encoding, channel) { + var channelDef = encoding && encoding[channel]; + if (channelDef) { + if (isArray(channelDef)) { + return some(channelDef, function (fieldDef) { return !!fieldDef.field; }); + } + else { + return isFieldDef(channelDef) || hasConditionalFieldDef(channelDef); + } + } + return false; +} +export function isAggregate(encoding) { + return some(CHANNELS, function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + if (isArray(channelDef)) { + return some(channelDef, function (fieldDef) { return !!fieldDef.aggregate; }); + } + else { + var fieldDef = getFieldDef(channelDef); + return fieldDef && !!fieldDef.aggregate; + } + } + return false; + }); +} +export function normalizeEncoding(encoding, mark) { + return keys(encoding).reduce(function (normalizedEncoding, channel) { + var _a; + if (!isChannel(channel)) { + // Drop invalid channel + log.warn(log.message.invalidEncodingChannel(channel)); + return normalizedEncoding; + } + if (!supportMark(channel, mark)) { + // Drop unsupported channel + log.warn(log.message.incompatibleChannel(channel, mark)); + return normalizedEncoding; + } + // Drop line's size if the field is aggregated. + if (channel === 'size' && mark === 'line') { + var fieldDef = getFieldDef(encoding[channel]); + if (fieldDef && fieldDef.aggregate) { + log.warn(log.message.LINE_WITH_VARYING_SIZE); + return normalizedEncoding; + } + } + // Drop color if either fill or stroke is specified + if (channel === 'color' && ('fill' in encoding || 'stroke' in encoding)) { + log.warn(log.message.droppingColor('encoding', { fill: 'fill' in encoding, stroke: 'stroke' in encoding })); + return normalizedEncoding; + } + var channelDef = encoding[channel]; + if (channel === 'detail' || + (channel === 'order' && !isArray(channelDef) && !isValueDef(channelDef)) || + (channel === 'tooltip' && isArray(channelDef))) { + if (channelDef) { + // Array of fieldDefs for detail channel (or production rule) + normalizedEncoding[channel] = (isArray(channelDef) ? channelDef : [channelDef]) + .reduce(function (defs, fieldDef) { + if (!isFieldDef(fieldDef)) { + log.warn(log.message.emptyFieldDef(fieldDef, channel)); + } + else { + defs.push(normalizeFieldDef(fieldDef, channel)); + } + return defs; + }, []); + } + } + else { + var fieldDef = getFieldDef(encoding[channel]); + if (fieldDef && contains([Type.LATITUDE, Type.LONGITUDE], fieldDef.type)) { + var _b = channel, _ = normalizedEncoding[_b], newEncoding = tslib_1.__rest(normalizedEncoding, [typeof _b === "symbol" ? _b : _b + ""]); + var newChannel = channel === 'x' ? 'longitude' : + channel === 'y' ? 'latitude' : + channel === 'x2' ? 'longitude2' : + channel === 'y2' ? 'latitude2' : undefined; + log.warn(log.message.latLongDeprecated(channel, fieldDef.type, newChannel)); + return tslib_1.__assign({}, newEncoding, (_a = {}, _a[newChannel] = tslib_1.__assign({}, normalize(fieldDef, channel), { type: 'quantitative' }), _a)); + } + if (!isFieldDef(channelDef) && !isValueDef(channelDef) && !isConditionalDef(channelDef)) { + log.warn(log.message.emptyFieldDef(channelDef, channel)); + return normalizedEncoding; + } + normalizedEncoding[channel] = normalize(channelDef, channel); + } + return normalizedEncoding; + }, {}); +} +export function isRanged(encoding) { + return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2)); +} +export function fieldDefs(encoding) { + var arr = []; + CHANNELS.forEach(function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (isArray(channelDef) ? channelDef : [channelDef]).forEach(function (def) { + if (isFieldDef(def)) { + arr.push(def); + } + else if (hasConditionalFieldDef(def)) { + arr.push(def.condition); + } + }); + } + }); + return arr; +} +export function forEach(mapping, f, thisArg) { + if (!mapping) { + return; + } + var _loop_1 = function (channel) { + if (isArray(mapping[channel])) { + mapping[channel].forEach(function (channelDef) { + f.call(thisArg, channelDef, channel); + }); + } + else { + f.call(thisArg, mapping[channel], channel); + } + }; + for (var _i = 0, _a = keys(mapping); _i < _a.length; _i++) { + var channel = _a[_i]; + _loop_1(channel); + } +} +export function reduce(mapping, f, init, thisArg) { + if (!mapping) { + return init; + } + return keys(mapping).reduce(function (r, channel) { + var map = mapping[channel]; + if (isArray(map)) { + return map.reduce(function (r1, channelDef) { + return f.call(thisArg, r1, channelDef, channel); + }, r); + } + else { + return f.call(thisArg, r, map, channel); + } + }, init); +} +//# sourceMappingURL=encoding.js.map \ No newline at end of file diff --git a/build/src/encoding.js.map b/build/src/encoding.js.map new file mode 100644 index 0000000000..b320024a75 --- /dev/null +++ b/build/src/encoding.js.map @@ -0,0 +1 @@ +{"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../src/encoding.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport {isArray} from 'vega-util';\nimport {Channel, CHANNELS, isChannel, supportMark} from './channel';\nimport {FacetMapping} from './facet';\nimport {\n ChannelDef,\n Field,\n FieldDef,\n FieldDefWithCondition,\n getFieldDef,\n hasConditionalFieldDef,\n isConditionalDef,\n isFieldDef,\n isValueDef,\n MarkPropFieldDef,\n normalize,\n normalizeFieldDef,\n OrderFieldDef,\n PositionFieldDef,\n TextFieldDef,\n ValueDef,\n ValueDefWithCondition\n} from './fielddef';\nimport * as log from './log';\nimport {Mark} from './mark';\nimport {Type} from './type';\nimport {contains, keys, some} from './util';\n\nexport interface Encoding {\n /**\n * X coordinates of the marks, or width of horizontal `\"bar\"` and `\"area\"`.\n */\n x?: PositionFieldDef | ValueDef;\n\n /**\n * Y coordinates of the marks, or height of vertical `\"bar\"` and `\"area\"`.\n */\n y?: PositionFieldDef | ValueDef;\n\n /**\n * X2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n // TODO: Ham need to add default behavior\n x2?: FieldDef | ValueDef;\n\n /**\n * Y2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n // TODO: Ham need to add default behavior\n y2?: FieldDef | ValueDef;\n\n\n /**\n * Longitude position of geographically projected marks.\n */\n longitude?: FieldDef;\n\n /**\n * Latitude position of geographically projected marks.\n */\n latitude?: FieldDef;\n\n /**\n * Longitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n longitude2?: FieldDef;\n\n /**\n * Latitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n latitude2?: FieldDef;\n\n /**\n * Color of the marks – either fill or stroke color based on the `filled` property of mark definition.\n * By default, `color` represents fill color for `\"area\"`, `\"bar\"`, `\"tick\"`,\n * `\"text\"`, `\"trail\"`, `\"circle\"`, and `\"square\"` / stroke color for `\"line\"` and `\"point\"`.\n *\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_\n * 1) For fine-grained control over both fill and stroke colors of the marks, please use the `fill` and `stroke` channels. If either `fill` or `stroke` channel is specified, `color` channel will be ignored.\n * 2) See the scale documentation for more information about customizing [color scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme).\n */\n color?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * Fill color of the marks.\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_ When using `fill` channel, `color ` channel will be ignored. To customize both fill and stroke, please use `fill` and `stroke` channels (not `fill` and `color`).\n */\n fill?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n\n /**\n * Stroke color of the marks.\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_ When using `stroke` channel, `color ` channel will be ignored. To customize both stroke and fill, please use `stroke` and `fill` channels (not `stroke` and `color`).\n */\n stroke?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n\n /**\n * Opacity of the marks – either can be a value or a range.\n *\n * __Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `opacity` property.\n */\n opacity?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * Size of the mark.\n * - For `\"point\"`, `\"square\"` and `\"circle\"`, – the symbol size, or pixel area of the mark.\n * - For `\"bar\"` and `\"tick\"` – the bar and tick's size.\n * - For `\"text\"` – the text's font size.\n * - Size is unsupported for `\"line\"`, `\"area\"`, and `\"rect\"`. (Use `\"trail\"` instead of line with varying size)\n */\n size?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * For `point` marks the supported values are\n * `\"circle\"` (default), `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`,\n * or `\"triangle-down\"`, or else a custom SVG path string.\n * For `geoshape` marks it should be a field definition of the geojson data\n *\n * __Default value:__ If undefined, the default shape depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#point-config)'s `shape` property.\n */\n shape?: FieldDefWithCondition> | ValueDefWithCondition>; // TODO: maybe distinguish ordinal-only\n\n /**\n * Additional levels of detail for grouping data in aggregate views and\n * in line, trail, and area marks without mapping data to a specific visual channel.\n */\n detail?: FieldDef | FieldDef[];\n\n /**\n * A data field to use as a unique key for data binding. When a visualization’s data is updated, the key value will be used to match data elements to existing mark instances. Use a key channel to enable object constancy for transitions over dynamic data.\n */\n key?: FieldDef;\n\n /**\n * Text of the `text` mark.\n */\n text?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * The tooltip text to show upon mouse hover.\n */\n tooltip?: FieldDefWithCondition> | ValueDefWithCondition> | TextFieldDef[];\n\n /**\n * A URL to load upon mouse click.\n */\n href?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * Order of the marks.\n * - For stacked marks, this `order` channel encodes [stack order](https://vega.github.io/vega-lite/docs/stack.html#order).\n * - For line and trail marks, this `order` channel encodes order of data points in the lines. This can be useful for creating [a connected scatterplot](https://vega.github.io/vega-lite/examples/connected_scatterplot.html). Setting `order` to `{\"value\": null}` makes the line marks use the original order in the data sources.\n * - Otherwise, this `order` channel encodes layer order of the marks.\n *\n * __Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping.\n */\n order?: OrderFieldDef | OrderFieldDef[] | ValueDef;\n}\n\nexport interface EncodingWithFacet extends Encoding, FacetMapping {}\n\nexport function channelHasField(encoding: EncodingWithFacet, channel: Channel): boolean {\n const channelDef = encoding && encoding[channel];\n if (channelDef) {\n if (isArray(channelDef)) {\n return some(channelDef, (fieldDef) => !!fieldDef.field);\n } else {\n return isFieldDef(channelDef) || hasConditionalFieldDef(channelDef);\n }\n }\n return false;\n}\n\n\nexport function isAggregate(encoding: EncodingWithFacet) {\n return some(CHANNELS, (channel) => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n if (isArray(channelDef)) {\n return some(channelDef, (fieldDef) => !!fieldDef.aggregate);\n } else {\n const fieldDef = getFieldDef(channelDef);\n return fieldDef && !!fieldDef.aggregate;\n }\n }\n return false;\n });\n}\n\nexport function normalizeEncoding(encoding: Encoding, mark: Mark): Encoding {\n return keys(encoding).reduce((normalizedEncoding: Encoding, channel: Channel | string) => {\n if (!isChannel(channel)) {\n // Drop invalid channel\n log.warn(log.message.invalidEncodingChannel(channel));\n return normalizedEncoding;\n }\n\n if (!supportMark(channel, mark)) {\n // Drop unsupported channel\n\n log.warn(log.message.incompatibleChannel(channel, mark));\n return normalizedEncoding;\n }\n\n // Drop line's size if the field is aggregated.\n if (channel === 'size' && mark === 'line') {\n const fieldDef = getFieldDef(encoding[channel]);\n if (fieldDef && fieldDef.aggregate) {\n log.warn(log.message.LINE_WITH_VARYING_SIZE);\n return normalizedEncoding;\n }\n }\n\n // Drop color if either fill or stroke is specified\n if (channel === 'color' && ('fill' in encoding || 'stroke' in encoding) ) {\n log.warn(log.message.droppingColor('encoding', {fill: 'fill' in encoding, stroke: 'stroke' in encoding}));\n return normalizedEncoding;\n }\n\n const channelDef = encoding[channel];\n if (\n channel === 'detail' ||\n (channel === 'order' && !isArray(channelDef) && !isValueDef(channelDef)) ||\n (channel === 'tooltip' && isArray(channelDef))\n ) {\n if (channelDef) {\n // Array of fieldDefs for detail channel (or production rule)\n normalizedEncoding[channel] = (isArray(channelDef) ? channelDef : [channelDef])\n .reduce((defs: FieldDef[], fieldDef: FieldDef) => {\n if (!isFieldDef(fieldDef)) {\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n } else {\n defs.push(normalizeFieldDef(fieldDef, channel));\n }\n return defs;\n }, []);\n }\n } else {\n\n const fieldDef = getFieldDef(encoding[channel]);\n if (fieldDef && contains([Type.LATITUDE, Type.LONGITUDE], fieldDef.type)) {\n const {[channel]: _, ...newEncoding} = normalizedEncoding;\n const newChannel = channel === 'x' ? 'longitude' :\n channel === 'y' ? 'latitude' :\n channel === 'x2' ? 'longitude2' :\n channel === 'y2' ? 'latitude2' : undefined;\n log.warn(log.message.latLongDeprecated(channel, fieldDef.type, newChannel));\n return {\n ...newEncoding,\n [newChannel]: {\n ...normalize(fieldDef as any, channel),\n type: 'quantitative'\n }\n };\n }\n\n if (!isFieldDef(channelDef) && !isValueDef(channelDef) && !isConditionalDef(channelDef)) {\n log.warn(log.message.emptyFieldDef(channelDef, channel));\n return normalizedEncoding;\n }\n normalizedEncoding[channel] = normalize(channelDef as ChannelDef, channel);\n }\n return normalizedEncoding;\n }, {});\n}\n\n\nexport function isRanged(encoding: EncodingWithFacet) {\n return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2));\n}\n\nexport function fieldDefs(encoding: EncodingWithFacet): FieldDef[] {\n const arr: FieldDef[] = [];\n CHANNELS.forEach(function(channel) {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((def) => {\n if (isFieldDef(def)) {\n arr.push(def);\n } else if (hasConditionalFieldDef(def)) {\n arr.push(def.condition);\n }\n });\n }\n });\n return arr;\n}\n\nexport function forEach(mapping: any,\n f: (fd: FieldDef, c: Channel) => void,\n thisArg?: any) {\n if (!mapping) {\n return;\n }\n\n for (const channel of keys(mapping)) {\n if (isArray(mapping[channel])) {\n mapping[channel].forEach(function(channelDef: ChannelDef) {\n f.call(thisArg, channelDef, channel);\n });\n } else {\n f.call(thisArg, mapping[channel], channel);\n }\n }\n}\n\nexport function reduce(mapping: U,\n f: (acc: any, fd: FieldDef, c: Channel) => U,\n init: T, thisArg?: any) {\n if (!mapping) {\n return init;\n }\n\n return keys(mapping).reduce((r, channel) => {\n const map = mapping[channel];\n if (isArray(map)) {\n return map.reduce((r1: T, channelDef: ChannelDef) => {\n return f.call(thisArg, r1, channelDef, channel);\n }, r);\n } else {\n return f.call(thisArg, r, map, channel);\n }\n }, init);\n}\n"]} \ No newline at end of file diff --git a/build/src/facet.d.ts b/build/src/facet.d.ts new file mode 100644 index 0000000000..772b8e2388 --- /dev/null +++ b/build/src/facet.d.ts @@ -0,0 +1,18 @@ +import { SortableFieldDef } from './fielddef'; +import { Header } from './header'; +export interface FacetFieldDef extends SortableFieldDef { + /** + * An object defining properties of a facet's header. + */ + header?: Header; +} +export interface FacetMapping { + /** + * Vertical facets for trellis plots. + */ + row?: FacetFieldDef; + /** + * Horizontal facets for trellis plots. + */ + column?: FacetFieldDef; +} diff --git a/build/src/facet.js b/build/src/facet.js new file mode 100644 index 0000000000..fcb54fa58f --- /dev/null +++ b/build/src/facet.js @@ -0,0 +1 @@ +//# sourceMappingURL=facet.js.map \ No newline at end of file diff --git a/build/src/facet.js.map b/build/src/facet.js.map new file mode 100644 index 0000000000..19b0569f5c --- /dev/null +++ b/build/src/facet.js.map @@ -0,0 +1 @@ +{"version":3,"file":"facet.js","sourceRoot":"","sources":["../../src/facet.ts"],"names":[],"mappings":"","sourcesContent":["import {SortableFieldDef} from './fielddef';\nimport {Header} from './header';\n\nexport interface FacetFieldDef extends SortableFieldDef {\n /**\n * An object defining properties of a facet's header.\n */\n header?: Header;\n}\n\nexport interface FacetMapping {\n\n /**\n * Vertical facets for trellis plots.\n */\n row?: FacetFieldDef;\n\n /**\n * Horizontal facets for trellis plots.\n */\n column?: FacetFieldDef;\n}\n"]} \ No newline at end of file diff --git a/build/src/fielddef.d.ts b/build/src/fielddef.d.ts new file mode 100644 index 0000000000..7077e6672b --- /dev/null +++ b/build/src/fielddef.d.ts @@ -0,0 +1,283 @@ +import { AggregateOp } from 'vega'; +import { Axis } from './axis'; +import { BinParams } from './bin'; +import { Channel } from './channel'; +import { CompositeAggregate } from './compositemark'; +import { Config } from './config'; +import { DateTime } from './datetime'; +import { TitleMixins } from './guide'; +import { Legend } from './legend'; +import { LogicalOperand } from './logical'; +import { Predicate } from './predicate'; +import { Scale } from './scale'; +import { Sort, SortOrder } from './sort'; +import { StackOffset } from './stack'; +import { TimeUnit } from './timeunit'; +import { AggregatedFieldDef, WindowFieldDef } from './transform'; +import { Type } from './type'; +/** + * Definition object for a constant value of an encoding channel. + */ +export interface ValueDef { + /** + * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between `0` to `1` for opacity). + */ + value: number | string | boolean; +} +/** + * Generic type for conditional channelDef. + * F defines the underlying FieldDef type. + */ +export declare type ChannelDefWithCondition> = FieldDefWithCondition | ValueDefWithCondition; +export declare type Conditional = ConditionalPredicate | ConditionalSelection; +export declare type ConditionalPredicate = { + test: LogicalOperand; +} & T; +export declare type ConditionalSelection = { + /** + * A [selection name](https://vega.github.io/vega-lite/docs/selection.html), or a series of [composed selections](https://vega.github.io/vega-lite/docs/selection.html#compose). + */ + selection: LogicalOperand; +} & T; +export declare function isConditionalSelection(c: Conditional): c is ConditionalSelection; +export interface ConditionValueDefMixins { + /** + * One or more value definition(s) with a selection predicate. + * + * __Note:__ A field definition's `condition` property can only contain [value definitions](https://vega.github.io/vega-lite/docs/encoding.html#value-def) + * since Vega-Lite only allows at most one encoded field per encoding channel. + */ + condition?: Conditional | Conditional[]; +} +/** + * A FieldDef with Condition + * { + * condition: {value: ...}, + * field: ..., + * ... + * } + */ +export declare type FieldDefWithCondition> = F & ConditionValueDefMixins; +/** + * A ValueDef with Condition + * { + * condition: {field: ...} | {value: ...}, + * value: ..., + * } + */ +export interface ValueDefWithCondition> { + /** + * A field definition or one or more value definition(s) with a selection predicate. + */ + condition?: Conditional | Conditional | Conditional[]; + /** + * A constant value in visual domain. + */ + value?: number | string | boolean; +} +/** + * Reference to a repeated value. + */ +export declare type RepeatRef = { + repeat: 'row' | 'column'; +}; +export declare type Field = string | RepeatRef; +export declare function isRepeatRef(field: Field): field is RepeatRef; +/** @hide */ +export declare type HiddenCompositeAggregate = CompositeAggregate; +export declare type Aggregate = AggregateOp | HiddenCompositeAggregate; +export interface FieldDefBase { + /** + * __Required.__ A string defining the name of the field from which to pull a data value + * or an object defining iterated values from the [`repeat`](https://vega.github.io/vega-lite/docs/repeat.html) operator. + * + * __Note:__ Dots (`.`) and brackets (`[` and `]`) can be used to access nested objects (e.g., `"field": "foo.bar"` and `"field": "foo['bar']"`). + * If field names contain dots or brackets but are not nested, you can use `\\` to escape dots and brackets (e.g., `"a\\.b"` and `"a\\[0\\]"`). + * See more details about escaping in the [field documentation](https://vega.github.io/vega-lite/docs/field.html). + * + * __Note:__ `field` is not required if `aggregate` is `count`. + */ + field?: F; + /** + * Time unit (e.g., `year`, `yearmonth`, `month`, `hours`) for a temporal field. + * or [a temporal field that gets casted as ordinal](https://vega.github.io/vega-lite/docs/type.html#cast). + * + * __Default value:__ `undefined` (None) + */ + timeUnit?: TimeUnit; + /** + * A flag for binning a `quantitative` field, or [an object defining binning parameters](https://vega.github.io/vega-lite/docs/bin.html#params). + * If `true`, default [binning parameters](https://vega.github.io/vega-lite/docs/bin.html) will be applied. + * + * __Default value:__ `false` + */ + bin?: boolean | BinParams; + /** + * Aggregation function for the field + * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`). + * + * __Default value:__ `undefined` (None) + */ + aggregate?: Aggregate; +} +export declare function toFieldDefBase(fieldDef: FieldDef): FieldDefBase; +/** + * Definition object for a data field, its type and transformation of an encoding channel. + */ +export interface FieldDef extends FieldDefBase, TitleMixins { + /** + * The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or `"nominal"`). + * It can also be a `"geojson"` type for encoding ['geoshape'](https://vega.github.io/vega-lite/docs/geoshape.html). + */ + type: Type; +} +export interface SortableFieldDef extends FieldDef { + /** + * Sort order for the encoded field. + * + * For continuous fields (quantitative or temporal), `sort` can be either `"ascending"` or `"descending"`. + * + * For discrete fields, `sort` can be one of the following: + * - `"ascending"` or `"descending"` -- for sorting by the values' natural order in Javascript. + * - [A sort field definition](https://vega.github.io/vega-lite/docs/sort.html#sort-field) for sorting by another field. + * - [An array specifying the field values in preferred order](https://vega.github.io/vega-lite/docs/sort.html#sort-array). In this case, the sort order will obey the values in the array, followed by any unspecified values in their original order. For discrete time field, values in the sort array can be [date-time definition objects](types#datetime). In addition, for time units `"month"` and `"day"`, the values can be the month or day names (case insensitive) or their 3-letter initials (e.g., `"Mon"`, `"Tue"`). + * - `null` indicating no sort. + * + * __Default value:__ `"ascending"` + * + * __Note:__ `null` is not supported for `row` and `column`. + */ + sort?: Sort; +} +export interface ScaleFieldDef extends SortableFieldDef { + /** + * An object defining properties of the channel's scale, which is the function that transforms values in the data domain (numbers, dates, strings, etc) to visual values (pixels, colors, sizes) of the encoding channels. + * + * If `null`, the scale will be [disabled and the data value will be directly encoded](https://vega.github.io/vega-lite/docs/scale.html#disable). + * + * __Default value:__ If undefined, default [scale properties](https://vega.github.io/vega-lite/docs/scale.html) are applied. + */ + scale?: Scale | null; +} +export interface PositionFieldDef extends ScaleFieldDef { + /** + * An object defining properties of axis's gridlines, ticks and labels. + * If `null`, the axis for the encoding channel will be removed. + * + * __Default value:__ If undefined, default [axis properties](https://vega.github.io/vega-lite/docs/axis.html) are applied. + */ + axis?: Axis | null; + /** + * Type of stacking offset if the field should be stacked. + * `stack` is only applicable for `x` and `y` channels with continuous domains. + * For example, `stack` of `y` can be used to customize stacking for a vertical bar chart. + * + * `stack` can be one of the following values: + * - `"zero"`: stacking with baseline offset at zero value of the scale (for creating typical stacked [bar](https://vega.github.io/vega-lite/docs/stack.html#bar) and [area](https://vega.github.io/vega-lite/docs/stack.html#area) chart). + * - `"normalize"` - stacking with normalized domain (for creating [normalized stacked bar and area charts](https://vega.github.io/vega-lite/docs/stack.html#normalized).
+ * -`"center"` - stacking with center baseline (for [streamgraph](https://vega.github.io/vega-lite/docs/stack.html#streamgraph)). + * - `null` - No-stacking. This will produce layered [bar](https://vega.github.io/vega-lite/docs/stack.html#layered-bar-chart) and area chart. + * + * __Default value:__ `zero` for plots with all of the following conditions are true: + * (1) the mark is `bar` or `area`; + * (2) the stacked measure channel (x or y) has a linear scale; + * (3) At least one of non-position channels mapped to an unaggregated field that is different from x and y. Otherwise, `null` by default. + */ + stack?: StackOffset | null; +} +/** + * Field definition of a mark property, which can contain a legend. + */ +export interface MarkPropFieldDef extends ScaleFieldDef { + /** + * An object defining properties of the legend. + * If `null`, the legend for the encoding channel will be removed. + * + * __Default value:__ If undefined, default [legend properties](https://vega.github.io/vega-lite/docs/legend.html) are applied. + */ + legend?: Legend | null; +} +export interface OrderFieldDef extends FieldDef { + /** + * The sort order. One of `"ascending"` (default) or `"descending"`. + */ + sort?: SortOrder; +} +export interface TextFieldDef extends FieldDef { + /** + * The [formatting pattern](https://vega.github.io/vega-lite/docs/format.html) for a text field. If not defined, this will be determined automatically. + */ + format?: string; +} +export declare type ChannelDef = ChannelDefWithCondition>; +export declare function isConditionalDef(channelDef: ChannelDef): channelDef is ChannelDefWithCondition>; +/** + * Return if a channelDef is a ConditionalValueDef with ConditionFieldDef + */ +export declare function hasConditionalFieldDef(channelDef: ChannelDef): channelDef is (ValueDef & { + condition: Conditional>; +}); +export declare function hasConditionalValueDef(channelDef: ChannelDef): channelDef is (ValueDef & { + condition: Conditional | Conditional[]; +}); +export declare function isFieldDef(channelDef: ChannelDef): channelDef is FieldDef | PositionFieldDef | ScaleFieldDef | MarkPropFieldDef | OrderFieldDef | TextFieldDef; +export declare function isStringFieldDef(fieldDef: ChannelDef): fieldDef is FieldDef; +export declare function isValueDef(channelDef: ChannelDef): channelDef is ValueDef; +export declare function isScaleFieldDef(channelDef: ChannelDef): channelDef is ScaleFieldDef; +export interface FieldRefOption { + /** exclude bin, aggregate, timeUnit */ + nofn?: boolean; + /** Wrap the field with datum or parent (e.g., datum['...'] for Vega Expression */ + expr?: 'datum' | 'parent'; + /** prepend fn with custom function prefix */ + prefix?: string; + /** append suffix to the field ref for bin (default='start') */ + binSuffix?: 'end' | 'range' | 'mid'; + /** append suffix to the field ref (general) */ + suffix?: string; +} +export declare function vgField(fieldDef: FieldDefBase | WindowFieldDef | AggregatedFieldDef, opt?: FieldRefOption): string; +export declare function isDiscrete(fieldDef: FieldDef): boolean; +export declare function isContinuous(fieldDef: FieldDef): boolean; +export declare function isCount(fieldDef: FieldDefBase): boolean; +export declare type FieldTitleFormatter = (fieldDef: FieldDefBase, config: Config) => string; +export declare function verbalTitleFormatter(fieldDef: FieldDefBase, config: Config): string; +export declare function functionalTitleFormatter(fieldDef: FieldDefBase, config: Config): string; +export declare const defaultTitleFormatter: FieldTitleFormatter; +export declare function setTitleFormatter(formatter: FieldTitleFormatter): void; +export declare function resetTitleFormatter(): void; +export declare function title(fieldDef: FieldDefBase, config: Config): string; +export declare function defaultType(fieldDef: FieldDef, channel: Channel): Type; +/** + * Returns the fieldDef -- either from the outer channelDef or from the condition of channelDef. + * @param channelDef + */ +export declare function getFieldDef(channelDef: ChannelDef): FieldDef; +/** + * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + */ +export declare function normalize(channelDef: ChannelDef, channel: Channel): ChannelDef; +export declare function normalizeFieldDef(fieldDef: FieldDef, channel: Channel): FieldDef; +export declare function normalizeBin(bin: BinParams | boolean, channel: Channel): BinParams; +export declare function channelCompatibility(fieldDef: FieldDef, channel: Channel): { + compatible: boolean; + warning?: string; +}; +export declare function isNumberFieldDef(fieldDef: FieldDef): boolean; +export declare function isTimeFieldDef(fieldDef: FieldDef): boolean; +/** + * Getting a value associated with a fielddef. + * Convert the value to Vega expression if applicable (for datetime object, or string if the field def is temporal or has timeUnit) + */ +export declare function valueExpr(v: number | string | boolean | DateTime, { timeUnit, type, time, undefinedIfExprNotRequired }: { + timeUnit: TimeUnit; + type?: Type; + time?: boolean; + undefinedIfExprNotRequired?: boolean; +}): string; +/** + * Standardize value array -- convert each value to Vega expression if applicable + */ +export declare function valueArray(fieldDef: FieldDef, values: (number | string | boolean | DateTime)[]): (string | number | boolean | DateTime | { + signal: string; +})[]; diff --git a/build/src/fielddef.js b/build/src/fielddef.js new file mode 100644 index 0000000000..ccd4813867 --- /dev/null +++ b/build/src/fielddef.js @@ -0,0 +1,381 @@ +import * as tslib_1 from "tslib"; +import { isArray, isBoolean, isNumber, isString } from 'vega-util'; +import { isAggregateOp, isCountingAggregateOp } from './aggregate'; +import { autoMaxBins, binToString } from './bin'; +import { rangeType } from './channel'; +import { dateTimeExpr, isDateTime } from './datetime'; +import * as log from './log'; +import { getLocalTimeUnit, getTimeUnitParts, isLocalSingleTimeUnit, isUtcSingleTimeUnit, normalizeTimeUnit } from './timeunit'; +import { getFullName, QUANTITATIVE } from './type'; +import { flatAccessWithDatum, replacePathInField, titlecase } from './util'; +export function isConditionalSelection(c) { + return c['selection']; +} +export function isRepeatRef(field) { + return field && !isString(field) && 'repeat' in field; +} +export function toFieldDefBase(fieldDef) { + var field = fieldDef.field, timeUnit = fieldDef.timeUnit, bin = fieldDef.bin, aggregate = fieldDef.aggregate; + return tslib_1.__assign({}, (timeUnit ? { timeUnit: timeUnit } : {}), (bin ? { bin: bin } : {}), (aggregate ? { aggregate: aggregate } : {}), { field: field }); +} +export function isConditionalDef(channelDef) { + return !!channelDef && !!channelDef.condition; +} +/** + * Return if a channelDef is a ConditionalValueDef with ConditionFieldDef + */ +export function hasConditionalFieldDef(channelDef) { + return !!channelDef && !!channelDef.condition && !isArray(channelDef.condition) && isFieldDef(channelDef.condition); +} +export function hasConditionalValueDef(channelDef) { + return !!channelDef && !!channelDef.condition && (isArray(channelDef.condition) || isValueDef(channelDef.condition)); +} +export function isFieldDef(channelDef) { + return !!channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count'); +} +export function isStringFieldDef(fieldDef) { + return isFieldDef(fieldDef) && isString(fieldDef.field); +} +export function isValueDef(channelDef) { + return channelDef && 'value' in channelDef && channelDef['value'] !== undefined; +} +export function isScaleFieldDef(channelDef) { + return !!channelDef && (!!channelDef['scale'] || !!channelDef['sort']); +} +function isOpFieldDef(fieldDef) { + return !!fieldDef['op']; +} +export function vgField(fieldDef, opt) { + if (opt === void 0) { opt = {}; } + var field = fieldDef.field; + var prefix = opt.prefix; + var suffix = opt.suffix; + if (isCount(fieldDef)) { + field = 'count_*'; + } + else { + var fn = undefined; + if (!opt.nofn) { + if (isOpFieldDef(fieldDef)) { + fn = fieldDef.op; + } + else if (fieldDef.bin) { + fn = binToString(fieldDef.bin); + suffix = opt.binSuffix || ''; + } + else if (fieldDef.aggregate) { + fn = String(fieldDef.aggregate); + } + else if (fieldDef.timeUnit) { + fn = String(fieldDef.timeUnit); + } + } + if (fn) { + field = field ? fn + "_" + field : fn; + } + } + if (suffix) { + field = field + "_" + suffix; + } + if (prefix) { + field = prefix + "_" + field; + } + if (opt.expr) { + // Expression to access flattened field. No need to escape dots. + return flatAccessWithDatum(field, opt.expr); + } + else { + // We flattened all fields so paths should have become dot. + return replacePathInField(field); + } +} +export function isDiscrete(fieldDef) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + case 'geojson': + return true; + case 'quantitative': + return !!fieldDef.bin; + case 'latitude': + case 'longitude': + case 'temporal': + return false; + } + throw new Error(log.message.invalidFieldType(fieldDef.type)); +} +export function isContinuous(fieldDef) { + return !isDiscrete(fieldDef); +} +export function isCount(fieldDef) { + return fieldDef.aggregate === 'count'; +} +export function verbalTitleFormatter(fieldDef, config) { + var field = fieldDef.field, bin = fieldDef.bin, timeUnit = fieldDef.timeUnit, aggregate = fieldDef.aggregate; + if (aggregate === 'count') { + return config.countTitle; + } + else if (bin) { + return field + " (binned)"; + } + else if (timeUnit) { + var units = getTimeUnitParts(timeUnit).join('-'); + return field + " (" + units + ")"; + } + else if (aggregate) { + return titlecase(aggregate) + " of " + field; + } + return field; +} +export function functionalTitleFormatter(fieldDef, config) { + var fn = fieldDef.aggregate || fieldDef.timeUnit || (fieldDef.bin && 'bin'); + if (fn) { + return fn.toUpperCase() + '(' + fieldDef.field + ')'; + } + else { + return fieldDef.field; + } +} +export var defaultTitleFormatter = function (fieldDef, config) { + switch (config.fieldTitle) { + case 'plain': + return fieldDef.field; + case 'functional': + return functionalTitleFormatter(fieldDef, config); + default: + return verbalTitleFormatter(fieldDef, config); + } +}; +var titleFormatter = defaultTitleFormatter; +export function setTitleFormatter(formatter) { + titleFormatter = formatter; +} +export function resetTitleFormatter() { + setTitleFormatter(defaultTitleFormatter); +} +export function title(fieldDef, config) { + return titleFormatter(fieldDef, config); +} +export function defaultType(fieldDef, channel) { + if (fieldDef.timeUnit) { + return 'temporal'; + } + if (fieldDef.bin) { + return 'quantitative'; + } + switch (rangeType(channel)) { + case 'continuous': + return 'quantitative'; + case 'discrete': + return 'nominal'; + case 'flexible': // color + return 'nominal'; + default: + return 'quantitative'; + } +} +/** + * Returns the fieldDef -- either from the outer channelDef or from the condition of channelDef. + * @param channelDef + */ +export function getFieldDef(channelDef) { + if (isFieldDef(channelDef)) { + return channelDef; + } + else if (hasConditionalFieldDef(channelDef)) { + return channelDef.condition; + } + return undefined; +} +/** + * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + */ +export function normalize(channelDef, channel) { + if (isString(channelDef) || isNumber(channelDef) || isBoolean(channelDef)) { + var primitiveType = isString(channelDef) ? 'string' : + isNumber(channelDef) ? 'number' : 'boolean'; + log.warn(log.message.primitiveChannelDef(channel, primitiveType, channelDef)); + return { value: channelDef }; + } + // If a fieldDef contains a field, we need type. + if (isFieldDef(channelDef)) { + return normalizeFieldDef(channelDef, channel); + } + else if (hasConditionalFieldDef(channelDef)) { + return tslib_1.__assign({}, channelDef, { + // Need to cast as normalizeFieldDef normally return FieldDef, but here we know that it is definitely Condition + condition: normalizeFieldDef(channelDef.condition, channel) }); + } + return channelDef; +} +export function normalizeFieldDef(fieldDef, channel) { + // Drop invalid aggregate + if (fieldDef.aggregate && !isAggregateOp(fieldDef.aggregate)) { + var aggregate = fieldDef.aggregate, fieldDefWithoutAggregate = tslib_1.__rest(fieldDef, ["aggregate"]); + log.warn(log.message.invalidAggregate(fieldDef.aggregate)); + fieldDef = fieldDefWithoutAggregate; + } + // Normalize Time Unit + if (fieldDef.timeUnit) { + fieldDef = tslib_1.__assign({}, fieldDef, { timeUnit: normalizeTimeUnit(fieldDef.timeUnit) }); + } + // Normalize bin + if (fieldDef.bin) { + fieldDef = tslib_1.__assign({}, fieldDef, { bin: normalizeBin(fieldDef.bin, channel) }); + } + // Normalize Type + if (fieldDef.type) { + var fullType = getFullName(fieldDef.type); + if (fieldDef.type !== fullType) { + // convert short type to full type + fieldDef = tslib_1.__assign({}, fieldDef, { type: fullType }); + } + if (fieldDef.type !== 'quantitative') { + if (isCountingAggregateOp(fieldDef.aggregate)) { + log.warn(log.message.invalidFieldTypeForCountAggregate(fieldDef.type, fieldDef.aggregate)); + fieldDef = tslib_1.__assign({}, fieldDef, { type: 'quantitative' }); + } + } + } + else { + // If type is empty / invalid, then augment with default type + var newType = defaultType(fieldDef, channel); + log.warn(log.message.emptyOrInvalidFieldType(fieldDef.type, channel, newType)); + fieldDef = tslib_1.__assign({}, fieldDef, { type: newType }); + } + var _a = channelCompatibility(fieldDef, channel), compatible = _a.compatible, warning = _a.warning; + if (!compatible) { + log.warn(warning); + } + return fieldDef; +} +export function normalizeBin(bin, channel) { + if (isBoolean(bin)) { + return { maxbins: autoMaxBins(channel) }; + } + else if (!bin.maxbins && !bin.step) { + return tslib_1.__assign({}, bin, { maxbins: autoMaxBins(channel) }); + } + else { + return bin; + } +} +var COMPATIBLE = { compatible: true }; +export function channelCompatibility(fieldDef, channel) { + var type = fieldDef.type; + switch (channel) { + case 'row': + case 'column': + if (isContinuous(fieldDef)) { + return { + compatible: false, + warning: log.message.facetChannelShouldBeDiscrete(channel) + }; + } + return COMPATIBLE; + case 'x': + case 'y': + case 'color': + case 'fill': + case 'stroke': + case 'text': + case 'detail': + case 'key': + case 'tooltip': + case 'href': + return COMPATIBLE; + case 'longitude': + case 'longitude2': + case 'latitude': + case 'latitude2': + if (type !== QUANTITATIVE) { + return { + compatible: false, + warning: "Channel " + channel + " should be used with a quantitative field only, not " + fieldDef.type + " field." + }; + } + return COMPATIBLE; + case 'opacity': + case 'size': + case 'x2': + case 'y2': + if ((type === 'nominal' && !fieldDef['sort']) || type === 'geojson') { + return { + compatible: false, + warning: "Channel " + channel + " should not be used with an unsorted discrete field." + }; + } + return COMPATIBLE; + case 'shape': + if (fieldDef.type !== 'nominal' && fieldDef.type !== 'geojson') { + return { + compatible: false, + warning: 'Shape channel should be used with only either nominal or geojson data' + }; + } + return COMPATIBLE; + case 'order': + if (fieldDef.type === 'nominal' && !('sort' in fieldDef)) { + return { + compatible: false, + warning: "Channel order is inappropriate for nominal field, which has no inherent order." + }; + } + return COMPATIBLE; + } + throw new Error('channelCompatability not implemented for channel ' + channel); +} +export function isNumberFieldDef(fieldDef) { + return fieldDef.type === 'quantitative' || !!fieldDef.bin; +} +export function isTimeFieldDef(fieldDef) { + return fieldDef.type === 'temporal' || !!fieldDef.timeUnit; +} +/** + * Getting a value associated with a fielddef. + * Convert the value to Vega expression if applicable (for datetime object, or string if the field def is temporal or has timeUnit) + */ +export function valueExpr(v, _a) { + var timeUnit = _a.timeUnit, type = _a.type, time = _a.time, undefinedIfExprNotRequired = _a.undefinedIfExprNotRequired; + var _b; + var expr = undefined; + if (isDateTime(v)) { + expr = dateTimeExpr(v, true); + } + else if (isString(v) || isNumber(v)) { + if (timeUnit || type === 'temporal') { + if (isLocalSingleTimeUnit(timeUnit)) { + expr = dateTimeExpr((_b = {}, _b[timeUnit] = v, _b), true); + } + else if (isUtcSingleTimeUnit(timeUnit)) { + // FIXME is this really correct? + expr = valueExpr(v, { timeUnit: getLocalTimeUnit(timeUnit) }); + } + else { + // just pass the string to date function (which will call JS Date.parse()) + expr = "datetime(" + JSON.stringify(v) + ")"; + } + } + } + if (expr) { + return time ? "time(" + expr + ")" : expr; + } + // number or boolean or normal string + return undefinedIfExprNotRequired ? undefined : JSON.stringify(v); +} +/** + * Standardize value array -- convert each value to Vega expression if applicable + */ +export function valueArray(fieldDef, values) { + var timeUnit = fieldDef.timeUnit, type = fieldDef.type; + return values.map(function (v) { + var expr = valueExpr(v, { timeUnit: timeUnit, type: type, undefinedIfExprNotRequired: true }); + // return signal for the expression if we need an expression + if (expr !== undefined) { + return { signal: expr }; + } + // otherwise just return the original value + return v; + }); +} +//# sourceMappingURL=fielddef.js.map \ No newline at end of file diff --git a/build/src/fielddef.js.map b/build/src/fielddef.js.map new file mode 100644 index 0000000000..d521b0360d --- /dev/null +++ b/build/src/fielddef.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fielddef.js","sourceRoot":"","sources":["../../src/fielddef.ts"],"names":[],"mappings":"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","sourcesContent":["// Declaration and utility for variants of a field definition object\nimport {AggregateOp} from 'vega';\nimport {isArray, isBoolean, isNumber, isString} from 'vega-util';\nimport {isAggregateOp, isCountingAggregateOp} from './aggregate';\nimport {Axis} from './axis';\nimport {autoMaxBins, BinParams, binToString} from './bin';\nimport {Channel, rangeType} from './channel';\nimport {CompositeAggregate} from './compositemark';\nimport {Config} from './config';\nimport {DateTime, dateTimeExpr, isDateTime} from './datetime';\nimport {TitleMixins} from './guide';\nimport {Legend} from './legend';\nimport * as log from './log';\nimport {LogicalOperand} from './logical';\nimport {Predicate} from './predicate';\nimport {Scale} from './scale';\nimport {Sort, SortOrder} from './sort';\nimport {StackOffset} from './stack';\nimport {getLocalTimeUnit, getTimeUnitParts, isLocalSingleTimeUnit, isUtcSingleTimeUnit, normalizeTimeUnit, TimeUnit} from './timeunit';\nimport {AggregatedFieldDef, WindowFieldDef} from './transform';\nimport {getFullName, QUANTITATIVE, Type} from './type';\nimport {flatAccessWithDatum, replacePathInField, titlecase} from './util';\n\n\n/**\n * Definition object for a constant value of an encoding channel.\n */\nexport interface ValueDef {\n /**\n * A constant value in visual domain (e.g., `\"red\"` / \"#0099ff\" for color, values between `0` to `1` for opacity).\n */\n value: number | string | boolean;\n}\n\n/**\n * Generic type for conditional channelDef.\n * F defines the underlying FieldDef type.\n */\nexport type ChannelDefWithCondition> = FieldDefWithCondition | ValueDefWithCondition;\n\nexport type Conditional = ConditionalPredicate | ConditionalSelection;\n\nexport type ConditionalPredicate = {\n test: LogicalOperand;\n} & T;\n\nexport type ConditionalSelection = {\n /**\n * A [selection name](https://vega.github.io/vega-lite/docs/selection.html), or a series of [composed selections](https://vega.github.io/vega-lite/docs/selection.html#compose).\n */\n selection: LogicalOperand;\n} & T;\n\nexport function isConditionalSelection(c: Conditional): c is ConditionalSelection {\n return c['selection'];\n}\n\nexport interface ConditionValueDefMixins {\n /**\n * One or more value definition(s) with a selection predicate.\n *\n * __Note:__ A field definition's `condition` property can only contain [value definitions](https://vega.github.io/vega-lite/docs/encoding.html#value-def)\n * since Vega-Lite only allows at most one encoded field per encoding channel.\n */\n condition?: Conditional | Conditional[];\n}\n\n/**\n * A FieldDef with Condition\n * {\n * condition: {value: ...},\n * field: ...,\n * ...\n * }\n */\n\nexport type FieldDefWithCondition> = F & ConditionValueDefMixins;\n\n/**\n * A ValueDef with Condition\n * {\n * condition: {field: ...} | {value: ...},\n * value: ...,\n * }\n */\nexport interface ValueDefWithCondition> {\n /**\n * A field definition or one or more value definition(s) with a selection predicate.\n */\n condition?: Conditional | Conditional | Conditional[];\n\n /**\n * A constant value in visual domain.\n */\n value?: number | string | boolean;\n}\n\n/**\n * Reference to a repeated value.\n */\nexport type RepeatRef = {\n repeat: 'row' | 'column'\n};\n\nexport type Field = string | RepeatRef;\n\nexport function isRepeatRef(field: Field): field is RepeatRef {\n return field && !isString(field) && 'repeat' in field;\n}\n\n/** @hide */\nexport type HiddenCompositeAggregate = CompositeAggregate;\n\nexport type Aggregate = AggregateOp | HiddenCompositeAggregate;\n\nexport interface FieldDefBase {\n\n /**\n * __Required.__ A string defining the name of the field from which to pull a data value\n * or an object defining iterated values from the [`repeat`](https://vega.github.io/vega-lite/docs/repeat.html) operator.\n *\n * __Note:__ Dots (`.`) and brackets (`[` and `]`) can be used to access nested objects (e.g., `\"field\": \"foo.bar\"` and `\"field\": \"foo['bar']\"`).\n * If field names contain dots or brackets but are not nested, you can use `\\\\` to escape dots and brackets (e.g., `\"a\\\\.b\"` and `\"a\\\\[0\\\\]\"`).\n * See more details about escaping in the [field documentation](https://vega.github.io/vega-lite/docs/field.html).\n *\n * __Note:__ `field` is not required if `aggregate` is `count`.\n */\n field?: F;\n\n // function\n\n /**\n * Time unit (e.g., `year`, `yearmonth`, `month`, `hours`) for a temporal field.\n * or [a temporal field that gets casted as ordinal](https://vega.github.io/vega-lite/docs/type.html#cast).\n *\n * __Default value:__ `undefined` (None)\n */\n timeUnit?: TimeUnit;\n\n /**\n * A flag for binning a `quantitative` field, or [an object defining binning parameters](https://vega.github.io/vega-lite/docs/bin.html#params).\n * If `true`, default [binning parameters](https://vega.github.io/vega-lite/docs/bin.html) will be applied.\n *\n * __Default value:__ `false`\n */\n bin?: boolean | BinParams;\n\n /**\n * Aggregation function for the field\n * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).\n *\n * __Default value:__ `undefined` (None)\n */\n aggregate?: Aggregate;\n}\n\nexport function toFieldDefBase(fieldDef: FieldDef): FieldDefBase {\n const {field, timeUnit, bin, aggregate} = fieldDef;\n return {\n ...(timeUnit ? {timeUnit} : {}),\n ...(bin ? {bin} : {}),\n ...(aggregate ? {aggregate} : {}),\n field\n };\n}\n\n/**\n * Definition object for a data field, its type and transformation of an encoding channel.\n */\nexport interface FieldDef extends FieldDefBase, TitleMixins {\n /**\n * The encoded field's type of measurement (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, or `\"nominal\"`).\n * It can also be a `\"geojson\"` type for encoding ['geoshape'](https://vega.github.io/vega-lite/docs/geoshape.html).\n */\n // * or an initial character of the type name (`\"Q\"`, `\"T\"`, `\"O\"`, `\"N\"`).\n // * This property is case-insensitive.\n type: Type;\n}\n\nexport interface SortableFieldDef extends FieldDef {\n /**\n * Sort order for the encoded field.\n *\n * For continuous fields (quantitative or temporal), `sort` can be either `\"ascending\"` or `\"descending\"`.\n *\n * For discrete fields, `sort` can be one of the following:\n * - `\"ascending\"` or `\"descending\"` -- for sorting by the values' natural order in Javascript.\n * - [A sort field definition](https://vega.github.io/vega-lite/docs/sort.html#sort-field) for sorting by another field.\n * - [An array specifying the field values in preferred order](https://vega.github.io/vega-lite/docs/sort.html#sort-array). In this case, the sort order will obey the values in the array, followed by any unspecified values in their original order. For discrete time field, values in the sort array can be [date-time definition objects](types#datetime). In addition, for time units `\"month\"` and `\"day\"`, the values can be the month or day names (case insensitive) or their 3-letter initials (e.g., `\"Mon\"`, `\"Tue\"`).\n * - `null` indicating no sort.\n *\n * __Default value:__ `\"ascending\"`\n *\n * __Note:__ `null` is not supported for `row` and `column`.\n */\n sort?: Sort;\n}\n\nexport interface ScaleFieldDef extends SortableFieldDef {\n /**\n * An object defining properties of the channel's scale, which is the function that transforms values in the data domain (numbers, dates, strings, etc) to visual values (pixels, colors, sizes) of the encoding channels.\n *\n * If `null`, the scale will be [disabled and the data value will be directly encoded](https://vega.github.io/vega-lite/docs/scale.html#disable).\n *\n * __Default value:__ If undefined, default [scale properties](https://vega.github.io/vega-lite/docs/scale.html) are applied.\n */\n scale?: Scale | null;\n}\n\nexport interface PositionFieldDef extends ScaleFieldDef {\n /**\n * An object defining properties of axis's gridlines, ticks and labels.\n * If `null`, the axis for the encoding channel will be removed.\n *\n * __Default value:__ If undefined, default [axis properties](https://vega.github.io/vega-lite/docs/axis.html) are applied.\n */\n axis?: Axis | null;\n\n /**\n * Type of stacking offset if the field should be stacked.\n * `stack` is only applicable for `x` and `y` channels with continuous domains.\n * For example, `stack` of `y` can be used to customize stacking for a vertical bar chart.\n *\n * `stack` can be one of the following values:\n * - `\"zero\"`: stacking with baseline offset at zero value of the scale (for creating typical stacked [bar](https://vega.github.io/vega-lite/docs/stack.html#bar) and [area](https://vega.github.io/vega-lite/docs/stack.html#area) chart).\n * - `\"normalize\"` - stacking with normalized domain (for creating [normalized stacked bar and area charts](https://vega.github.io/vega-lite/docs/stack.html#normalized).
\n * -`\"center\"` - stacking with center baseline (for [streamgraph](https://vega.github.io/vega-lite/docs/stack.html#streamgraph)).\n * - `null` - No-stacking. This will produce layered [bar](https://vega.github.io/vega-lite/docs/stack.html#layered-bar-chart) and area chart.\n *\n * __Default value:__ `zero` for plots with all of the following conditions are true:\n * (1) the mark is `bar` or `area`;\n * (2) the stacked measure channel (x or y) has a linear scale;\n * (3) At least one of non-position channels mapped to an unaggregated field that is different from x and y. Otherwise, `null` by default.\n */\n stack?: StackOffset | null;\n}\n\n/**\n * Field definition of a mark property, which can contain a legend.\n */\nexport interface MarkPropFieldDef extends ScaleFieldDef {\n /**\n * An object defining properties of the legend.\n * If `null`, the legend for the encoding channel will be removed.\n *\n * __Default value:__ If undefined, default [legend properties](https://vega.github.io/vega-lite/docs/legend.html) are applied.\n */\n legend?: Legend | null;\n}\n\n// Detail\n\n// Order Path have no scale\n\nexport interface OrderFieldDef extends FieldDef {\n /**\n * The sort order. One of `\"ascending\"` (default) or `\"descending\"`.\n */\n sort?: SortOrder;\n}\n\nexport interface TextFieldDef extends FieldDef {\n /**\n * The [formatting pattern](https://vega.github.io/vega-lite/docs/format.html) for a text field. If not defined, this will be determined automatically.\n */\n format?: string;\n}\n\nexport type ChannelDef = ChannelDefWithCondition>;\n\nexport function isConditionalDef(channelDef: ChannelDef): channelDef is ChannelDefWithCondition> {\n return !!channelDef && !!channelDef.condition;\n}\n\n/**\n * Return if a channelDef is a ConditionalValueDef with ConditionFieldDef\n */\nexport function hasConditionalFieldDef(channelDef: ChannelDef): channelDef is (ValueDef & {condition: Conditional>}) {\n return !!channelDef && !!channelDef.condition && !isArray(channelDef.condition) && isFieldDef(channelDef.condition);\n}\n\nexport function hasConditionalValueDef(channelDef: ChannelDef): channelDef is (ValueDef & {condition: Conditional | Conditional[]}) {\n return !!channelDef && !!channelDef.condition && (\n isArray(channelDef.condition) || isValueDef(channelDef.condition)\n );\n}\n\nexport function isFieldDef(channelDef: ChannelDef): channelDef is FieldDef | PositionFieldDef | ScaleFieldDef | MarkPropFieldDef | OrderFieldDef | TextFieldDef {\n return !!channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count');\n}\n\nexport function isStringFieldDef(fieldDef: ChannelDef): fieldDef is FieldDef {\n return isFieldDef(fieldDef) && isString(fieldDef.field);\n}\n\nexport function isValueDef(channelDef: ChannelDef): channelDef is ValueDef {\n return channelDef && 'value' in channelDef && channelDef['value'] !== undefined;\n}\n\nexport function isScaleFieldDef(channelDef: ChannelDef): channelDef is ScaleFieldDef {\n return !!channelDef && (!!channelDef['scale'] || !!channelDef['sort']);\n}\n\nexport interface FieldRefOption {\n /** exclude bin, aggregate, timeUnit */\n nofn?: boolean;\n /** Wrap the field with datum or parent (e.g., datum['...'] for Vega Expression */\n expr?: 'datum' | 'parent';\n /** prepend fn with custom function prefix */\n prefix?: string;\n /** append suffix to the field ref for bin (default='start') */\n binSuffix?: 'end' | 'range' | 'mid';\n /** append suffix to the field ref (general) */\n suffix?: string;\n}\n\nfunction isOpFieldDef(fieldDef: FieldDefBase | WindowFieldDef | AggregatedFieldDef): fieldDef is WindowFieldDef | AggregatedFieldDef {\n return !!fieldDef['op'];\n}\n\nexport function vgField(fieldDef: FieldDefBase | WindowFieldDef | AggregatedFieldDef, opt: FieldRefOption = {}): string {\n let field = fieldDef.field;\n const prefix = opt.prefix;\n let suffix = opt.suffix;\n\n if (isCount(fieldDef)) {\n field = 'count_*';\n } else {\n let fn: string = undefined;\n\n if (!opt.nofn) {\n if (isOpFieldDef(fieldDef)) {\n fn = fieldDef.op;\n } else if (fieldDef.bin) {\n fn = binToString(fieldDef.bin);\n suffix = opt.binSuffix || '';\n } else if (fieldDef.aggregate) {\n fn = String(fieldDef.aggregate);\n } else if (fieldDef.timeUnit) {\n fn = String(fieldDef.timeUnit);\n }\n }\n\n if (fn) {\n field = field ? `${fn}_${field}` : fn;\n }\n }\n\n if (suffix) {\n field = `${field}_${suffix}`;\n }\n\n if (prefix) {\n field = `${prefix}_${field}`;\n }\n\n if (opt.expr) {\n // Expression to access flattened field. No need to escape dots.\n return flatAccessWithDatum(field, opt.expr);\n } else {\n // We flattened all fields so paths should have become dot.\n return replacePathInField(field);\n }\n}\n\nexport function isDiscrete(fieldDef: FieldDef) {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n case 'geojson':\n return true;\n case 'quantitative':\n return !!fieldDef.bin;\n case 'latitude':\n case 'longitude':\n case 'temporal':\n return false;\n }\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n\nexport function isContinuous(fieldDef: FieldDef) {\n return !isDiscrete(fieldDef);\n}\n\nexport function isCount(fieldDef: FieldDefBase) {\n return fieldDef.aggregate === 'count';\n}\n\nexport type FieldTitleFormatter = (fieldDef: FieldDefBase, config: Config) => string;\n\nexport function verbalTitleFormatter(fieldDef: FieldDefBase, config: Config) {\n const {field: field, bin, timeUnit, aggregate} = fieldDef;\n if (aggregate === 'count') {\n return config.countTitle;\n } else if (bin) {\n return `${field} (binned)`;\n } else if (timeUnit) {\n const units = getTimeUnitParts(timeUnit).join('-');\n return `${field} (${units})`;\n } else if (aggregate) {\n return `${titlecase(aggregate)} of ${field}`;\n }\n return field;\n}\n\nexport function functionalTitleFormatter(fieldDef: FieldDefBase, config: Config) {\n const fn = fieldDef.aggregate || fieldDef.timeUnit || (fieldDef.bin && 'bin');\n if (fn) {\n return fn.toUpperCase() + '(' + fieldDef.field + ')';\n } else {\n return fieldDef.field;\n }\n}\n\nexport const defaultTitleFormatter: FieldTitleFormatter = (fieldDef: FieldDefBase, config: Config) => {\n switch (config.fieldTitle) {\n case 'plain':\n return fieldDef.field;\n case 'functional':\n return functionalTitleFormatter(fieldDef, config);\n default:\n return verbalTitleFormatter(fieldDef, config);\n }\n};\n\nlet titleFormatter = defaultTitleFormatter;\n\nexport function setTitleFormatter(formatter: FieldTitleFormatter) {\n titleFormatter = formatter;\n}\n\nexport function resetTitleFormatter() {\n setTitleFormatter(defaultTitleFormatter);\n}\n\nexport function title(fieldDef: FieldDefBase, config: Config) {\n return titleFormatter(fieldDef, config);\n}\n\nexport function defaultType(fieldDef: FieldDef, channel: Channel): Type {\n if (fieldDef.timeUnit) {\n return 'temporal';\n }\n if (fieldDef.bin) {\n return 'quantitative';\n }\n switch (rangeType(channel)) {\n case 'continuous':\n return 'quantitative';\n case 'discrete':\n return 'nominal';\n case 'flexible': // color\n return 'nominal';\n default:\n return 'quantitative';\n }\n}\n\n/**\n * Returns the fieldDef -- either from the outer channelDef or from the condition of channelDef.\n * @param channelDef\n */\nexport function getFieldDef(channelDef: ChannelDef): FieldDef {\n if (isFieldDef(channelDef)) {\n return channelDef;\n } else if (hasConditionalFieldDef(channelDef)) {\n return channelDef.condition;\n }\n return undefined;\n}\n\n/**\n * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n */\nexport function normalize(channelDef: ChannelDef, channel: Channel): ChannelDef {\n if (isString(channelDef) || isNumber(channelDef) || isBoolean(channelDef)) {\n const primitiveType = isString(channelDef) ? 'string' :\n isNumber(channelDef) ? 'number' : 'boolean';\n log.warn(log.message.primitiveChannelDef(channel, primitiveType, channelDef));\n return {value: channelDef};\n }\n\n // If a fieldDef contains a field, we need type.\n if (isFieldDef(channelDef)) {\n return normalizeFieldDef(channelDef, channel);\n } else if (hasConditionalFieldDef(channelDef)) {\n return {\n ...channelDef,\n // Need to cast as normalizeFieldDef normally return FieldDef, but here we know that it is definitely Condition\n condition: normalizeFieldDef(channelDef.condition, channel) as Conditional>\n };\n }\n return channelDef;\n}\nexport function normalizeFieldDef(fieldDef: FieldDef, channel: Channel) {\n // Drop invalid aggregate\n if (fieldDef.aggregate && !isAggregateOp(fieldDef.aggregate)) {\n const {aggregate, ...fieldDefWithoutAggregate} = fieldDef;\n log.warn(log.message.invalidAggregate(fieldDef.aggregate));\n fieldDef = fieldDefWithoutAggregate;\n }\n\n // Normalize Time Unit\n if (fieldDef.timeUnit) {\n fieldDef = {\n ...fieldDef,\n timeUnit: normalizeTimeUnit(fieldDef.timeUnit)\n };\n }\n\n // Normalize bin\n if (fieldDef.bin) {\n fieldDef = {\n ...fieldDef,\n bin: normalizeBin(fieldDef.bin, channel)\n };\n }\n\n // Normalize Type\n if (fieldDef.type) {\n const fullType = getFullName(fieldDef.type);\n if (fieldDef.type !== fullType) {\n // convert short type to full type\n fieldDef = {\n ...fieldDef,\n type: fullType\n };\n }\n if (fieldDef.type !== 'quantitative') {\n if (isCountingAggregateOp(fieldDef.aggregate)) {\n log.warn(log.message.invalidFieldTypeForCountAggregate(fieldDef.type, fieldDef.aggregate));\n fieldDef = {\n ...fieldDef,\n type: 'quantitative'\n };\n }\n }\n } else {\n // If type is empty / invalid, then augment with default type\n const newType = defaultType(fieldDef, channel);\n log.warn(log.message.emptyOrInvalidFieldType(fieldDef.type, channel, newType));\n fieldDef = {\n ...fieldDef,\n type: newType\n };\n }\n\n const {compatible, warning} = channelCompatibility(fieldDef, channel);\n if (!compatible) {\n log.warn(warning);\n }\n return fieldDef;\n}\n\nexport function normalizeBin(bin: BinParams|boolean, channel: Channel) {\n if (isBoolean(bin)) {\n return {maxbins: autoMaxBins(channel)};\n } else if (!bin.maxbins && !bin.step) {\n return {...bin, maxbins: autoMaxBins(channel)};\n } else {\n return bin;\n }\n}\n\nconst COMPATIBLE = {compatible: true};\nexport function channelCompatibility(fieldDef: FieldDef, channel: Channel): {compatible: boolean; warning?: string;} {\n const type = fieldDef.type;\n\n switch (channel) {\n case 'row':\n case 'column':\n if (isContinuous(fieldDef)) {\n return {\n compatible: false,\n warning: log.message.facetChannelShouldBeDiscrete(channel)\n };\n }\n return COMPATIBLE;\n\n case 'x':\n case 'y':\n case 'color':\n case 'fill':\n case 'stroke':\n case 'text':\n case 'detail':\n case 'key':\n case 'tooltip':\n case 'href':\n return COMPATIBLE;\n\n case 'longitude':\n case 'longitude2':\n case 'latitude':\n case 'latitude2':\n if (type !== QUANTITATIVE) {\n return {\n compatible: false,\n warning: `Channel ${channel} should be used with a quantitative field only, not ${fieldDef.type} field.`\n };\n }\n return COMPATIBLE;\n\n case 'opacity':\n case 'size':\n case 'x2':\n case 'y2':\n if ((type === 'nominal' && !fieldDef['sort']) || type === 'geojson') {\n return {\n compatible: false,\n warning: `Channel ${channel} should not be used with an unsorted discrete field.`\n };\n }\n return COMPATIBLE;\n\n case 'shape':\n if (fieldDef.type !== 'nominal' && fieldDef.type !== 'geojson') {\n return {\n compatible: false,\n warning: 'Shape channel should be used with only either nominal or geojson data'\n };\n }\n return COMPATIBLE;\n\n case 'order':\n if (fieldDef.type === 'nominal' && !('sort' in fieldDef)) {\n return {\n compatible: false,\n warning: `Channel order is inappropriate for nominal field, which has no inherent order.`\n };\n }\n return COMPATIBLE;\n }\n throw new Error('channelCompatability not implemented for channel ' + channel);\n}\n\nexport function isNumberFieldDef(fieldDef: FieldDef) {\n return fieldDef.type === 'quantitative' || !!fieldDef.bin;\n}\n\nexport function isTimeFieldDef(fieldDef: FieldDef) {\n return fieldDef.type === 'temporal' || !!fieldDef.timeUnit;\n}\n\n\n/**\n * Getting a value associated with a fielddef.\n * Convert the value to Vega expression if applicable (for datetime object, or string if the field def is temporal or has timeUnit)\n */\nexport function valueExpr(\n v: number | string | boolean | DateTime,\n {timeUnit, type, time, undefinedIfExprNotRequired}: {\n timeUnit: TimeUnit,\n type?: Type,\n time?: boolean\n undefinedIfExprNotRequired?: boolean\n }\n): string {\n\n let expr = undefined;\n if (isDateTime(v)) {\n expr = dateTimeExpr(v, true);\n } else if (isString(v) || isNumber(v)) {\n if (timeUnit || type === 'temporal') {\n if (isLocalSingleTimeUnit(timeUnit)) {\n expr = dateTimeExpr({[timeUnit]: v}, true);\n } else if (isUtcSingleTimeUnit(timeUnit)) {\n // FIXME is this really correct?\n expr = valueExpr(v, {timeUnit: getLocalTimeUnit(timeUnit)});\n } else {\n // just pass the string to date function (which will call JS Date.parse())\n expr = `datetime(${JSON.stringify(v)})`;\n }\n }\n }\n if (expr) {\n return time ? `time(${expr})` : expr;\n }\n // number or boolean or normal string\n return undefinedIfExprNotRequired ? undefined : JSON.stringify(v);\n}\n\n/**\n * Standardize value array -- convert each value to Vega expression if applicable\n */\nexport function valueArray(\n fieldDef: FieldDef,\n values: (number | string | boolean | DateTime)[]\n) {\n const {timeUnit, type} = fieldDef;\n return values.map(v => {\n const expr = valueExpr(v, {timeUnit, type, undefinedIfExprNotRequired: true});\n // return signal for the expression if we need an expression\n if (expr !== undefined) {\n return {signal: expr};\n }\n // otherwise just return the original value\n return v;\n });\n}\n"]} \ No newline at end of file diff --git a/build/src/guide.d.ts b/build/src/guide.d.ts new file mode 100644 index 0000000000..eb1d139748 --- /dev/null +++ b/build/src/guide.d.ts @@ -0,0 +1,38 @@ +import { ConditionValueDefMixins, ValueDef } from './fielddef'; +import { VgEncodeChannel } from './vega.schema'; +export interface TitleMixins { + /** + * A title for the field. If `null`, the title will be removed. + * + * __Default value:__ derived from the field's name and transformation function (`aggregate`, `bin` and `timeUnit`). If the field has an aggregate function, the function is displayed as part of the title (e.g., `"Sum of Profit"`). If the field is binned or has a time unit applied, the applied function is shown in parentheses (e.g., `"Profit (binned)"`, `"Transaction Date (year-month)"`). Otherwise, the title is simply the field name. + * + * __Notes__: + * + * 1) You can customize the default field title format by providing the [`fieldTitle` property in the [config](https://vega.github.io/vega-lite/docs/config.html) or [`fieldTitle` function via the `compile` function's options](https://vega.github.io/vega-lite/docs/compile.html#field-title). + * + * 2) If both field definition's `title` and axis, header, or legend `title` are defined, axis/header/legend title will be used. + */ + title?: string | null; +} +export interface Guide extends TitleMixins { + /** + * The formatting pattern for labels. This is D3's [number format pattern](https://github.com/d3/d3-format#locale_format) for quantitative fields and D3's [time format pattern](https://github.com/d3/d3-time-format#locale_format) for time field. + * + * See the [format documentation](https://vega.github.io/vega-lite/docs/format.html) for more information. + * + * __Default value:__ derived from [numberFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for quantitative fields and from [timeFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for temporal fields. + */ + format?: string; +} +export interface VlOnlyGuideConfig { + /** + * Whether month names and weekday names should be abbreviated. + * + * __Default value:__ `false` + */ + shortTimeLabels?: boolean; +} +export declare type GuideEncodingEntry = { + [k in VgEncodeChannel]?: ValueDef & ConditionValueDefMixins; +}; +export declare const VL_ONLY_GUIDE_CONFIG: (keyof VlOnlyGuideConfig)[]; diff --git a/build/src/guide.js b/build/src/guide.js new file mode 100644 index 0000000000..d62abdb6ee --- /dev/null +++ b/build/src/guide.js @@ -0,0 +1,2 @@ +export var VL_ONLY_GUIDE_CONFIG = ['shortTimeLabels']; +//# sourceMappingURL=guide.js.map \ No newline at end of file diff --git a/build/src/guide.js.map b/build/src/guide.js.map new file mode 100644 index 0000000000..ff1d34a4a3 --- /dev/null +++ b/build/src/guide.js.map @@ -0,0 +1 @@ +{"version":3,"file":"guide.js","sourceRoot":"","sources":["../../src/guide.ts"],"names":[],"mappings":"AA2CA,MAAM,CAAC,IAAM,oBAAoB,GAAgC,CAAC,iBAAiB,CAAC,CAAC","sourcesContent":["import {ConditionValueDefMixins, ValueDef} from './fielddef';\nimport {VgEncodeChannel} from './vega.schema';\n\nexport interface TitleMixins {\n /**\n * A title for the field. If `null`, the title will be removed.\n *\n * __Default value:__ derived from the field's name and transformation function (`aggregate`, `bin` and `timeUnit`). If the field has an aggregate function, the function is displayed as part of the title (e.g., `\"Sum of Profit\"`). If the field is binned or has a time unit applied, the applied function is shown in parentheses (e.g., `\"Profit (binned)\"`, `\"Transaction Date (year-month)\"`). Otherwise, the title is simply the field name.\n *\n * __Notes__:\n *\n * 1) You can customize the default field title format by providing the [`fieldTitle` property in the [config](https://vega.github.io/vega-lite/docs/config.html) or [`fieldTitle` function via the `compile` function's options](https://vega.github.io/vega-lite/docs/compile.html#field-title).\n *\n * 2) If both field definition's `title` and axis, header, or legend `title` are defined, axis/header/legend title will be used.\n */\n title?: string | null;\n}\n\nexport interface Guide extends TitleMixins {\n /**\n * The formatting pattern for labels. This is D3's [number format pattern](https://github.com/d3/d3-format#locale_format) for quantitative fields and D3's [time format pattern](https://github.com/d3/d3-time-format#locale_format) for time field.\n *\n * See the [format documentation](https://vega.github.io/vega-lite/docs/format.html) for more information.\n *\n * __Default value:__ derived from [numberFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for quantitative fields and from [timeFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for temporal fields.\n */\n format?: string;\n}\nexport interface VlOnlyGuideConfig {\n\n /**\n * Whether month names and weekday names should be abbreviated.\n *\n * __Default value:__ `false`\n */\n shortTimeLabels?: boolean;\n}\n\n\nexport type GuideEncodingEntry = {\n [k in VgEncodeChannel]?: ValueDef & ConditionValueDefMixins;\n};\n\nexport const VL_ONLY_GUIDE_CONFIG: (keyof VlOnlyGuideConfig)[] = ['shortTimeLabels'];\n"]} \ No newline at end of file diff --git a/build/src/header.d.ts b/build/src/header.d.ts new file mode 100644 index 0000000000..445033c956 --- /dev/null +++ b/build/src/header.d.ts @@ -0,0 +1,96 @@ +import { TextBaseline } from 'vega'; +import { Guide } from './guide'; +import { FontWeight, VgTitleConfig } from './vega.schema'; +export declare const HEADER_TITLE_PROPERTIES_MAP: { + [k in keyof HeaderConfig]: keyof VgTitleConfig; +}; +export declare const HEADER_LABEL_PROPERTIES_MAP: { + [k in keyof HeaderConfig]: keyof VgTitleConfig; +}; +export declare const HEADER_TITLE_PROPERTIES: string[]; +export declare const HEADER_LABEL_PROPERTIES: string[]; +export interface HeaderConfig { + /** + * The anchor position for placing the title. One of `"start"`, `"middle"`, or `"end"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title. + * + * __Default value:__ `"middle"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. + * `"start"` for other composite views. + * + * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `"start"`. + */ + titleAnchor?: string; + /** + * The rotation angle of the header title. + * + * __Default value:__ `0`. + * + * @minimum -360 + * @maximum 360 + */ + titleAngle?: number; + /** + * Vertical text baseline for the header title. One of `"top"`, `"bottom"`, `"middle"`. + * + * __Default value:__ `"middle"` + */ + titleBaseline?: TextBaseline; + /** + * Color of the header title, can be in hex color code or regular color name. + */ + titleColor?: string; + /** + * Font of the header title. (e.g., `"Helvetica Neue"`). + */ + titleFont?: string; + /** + * Font size of the header title. + * + * @minimum 0 + */ + titleFontSize?: number; + /** + * Font weight of the header title. + * This can be either a string (e.g `"bold"`, `"normal"`) or a number (`100`, `200`, `300`, ..., `900` where `"normal"` = `400` and `"bold"` = `700`). + */ + titleFontWeight?: FontWeight; + /** + * The maximum length of the header title in pixels. The text value will be automatically truncated if the rendered size exceeds the limit. + * + * __Default value:__ `0`, indicating no limit + */ + titleLimit?: number; + /** + * The rotation angle of the header labels. + * + * __Default value:__ `0`. + * + * @minimum -360 + * @maximum 360 + */ + labelAngle?: number; + /** + * The color of the header label, can be in hex color code or regular color name. + */ + labelColor?: string; + /** + * The font of the header label. + */ + labelFont?: string; + /** + * The font size of the header label, in pixels. + * + * @minimum 0 + */ + labelFontSize?: number; + /** + * The maximum length of the header label in pixels. The text value will be automatically truncated if the rendered size exceeds the limit. + * + * __Default value:__ `0`, indicating no limit + */ + labelLimit?: number; +} +/** + * Headers of row / column channels for faceted plots. + */ +export interface Header extends HeaderConfig, Guide { +} diff --git a/build/src/header.js b/build/src/header.js new file mode 100644 index 0000000000..80a05f22c2 --- /dev/null +++ b/build/src/header.js @@ -0,0 +1,20 @@ +export var HEADER_TITLE_PROPERTIES_MAP = { + titleAnchor: 'anchor', + titleAngle: 'angle', + titleBaseline: 'baseline', + titleColor: 'color', + titleFont: 'font', + titleFontSize: 'fontSize', + titleFontWeight: 'fontWeight', + titleLimit: 'limit' +}; +export var HEADER_LABEL_PROPERTIES_MAP = { + labelAngle: 'angle', + labelColor: 'color', + labelFont: 'font', + labelFontSize: 'fontSize', + labelLimit: 'limit', +}; +export var HEADER_TITLE_PROPERTIES = Object.keys(HEADER_TITLE_PROPERTIES_MAP); +export var HEADER_LABEL_PROPERTIES = Object.keys(HEADER_LABEL_PROPERTIES_MAP); +//# sourceMappingURL=header.js.map \ No newline at end of file diff --git a/build/src/header.js.map b/build/src/header.js.map new file mode 100644 index 0000000000..4a7051b0ee --- /dev/null +++ b/build/src/header.js.map @@ -0,0 +1 @@ +{"version":3,"file":"header.js","sourceRoot":"","sources":["../../src/header.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,IAAM,2BAA2B,GAEpC;IACF,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,OAAO;IACnB,aAAa,EAAE,UAAU;IACzB,UAAU,EAAE,OAAO;IACnB,SAAS,EAAE,MAAM;IACjB,aAAa,EAAE,UAAU;IACzB,eAAe,EAAE,YAAY;IAC7B,UAAU,EAAE,OAAO;CACpB,CAAC;AAEF,MAAM,CAAC,IAAM,2BAA2B,GAEpC;IACF,UAAU,EAAE,OAAO;IACnB,UAAU,EAAE,OAAO;IACnB,SAAS,EAAE,MAAM;IACjB,aAAa,EAAE,UAAU;IACzB,UAAU,EAAE,OAAO;CACpB,CAAC;AAEF,MAAM,CAAC,IAAM,uBAAuB,GAAG,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;AAEhF,MAAM,CAAC,IAAM,uBAAuB,GAAG,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC","sourcesContent":["import {TextBaseline} from 'vega';\nimport {Guide} from './guide';\nimport {FontWeight, VgTitleConfig} from './vega.schema';\n\nexport const HEADER_TITLE_PROPERTIES_MAP: {\n [k in keyof HeaderConfig]: keyof VgTitleConfig\n} = {\n titleAnchor: 'anchor',\n titleAngle: 'angle',\n titleBaseline: 'baseline',\n titleColor: 'color',\n titleFont: 'font',\n titleFontSize: 'fontSize',\n titleFontWeight: 'fontWeight',\n titleLimit: 'limit'\n};\n\nexport const HEADER_LABEL_PROPERTIES_MAP: {\n [k in keyof HeaderConfig]: keyof VgTitleConfig\n} = {\n labelAngle: 'angle',\n labelColor: 'color',\n labelFont: 'font',\n labelFontSize: 'fontSize',\n labelLimit: 'limit',\n};\n\nexport const HEADER_TITLE_PROPERTIES = Object.keys(HEADER_TITLE_PROPERTIES_MAP);\n\nexport const HEADER_LABEL_PROPERTIES = Object.keys(HEADER_LABEL_PROPERTIES_MAP);\n\nexport interface HeaderConfig {\n // ---------- Title ----------\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"`, or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n *\n * __Default value:__ `\"middle\"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views.\n * `\"start\"` for other composite views.\n *\n * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `\"start\"`.\n */\n titleAnchor?: string;\n\n /**\n * The rotation angle of the header title.\n *\n * __Default value:__ `0`.\n *\n * @minimum -360\n * @maximum 360\n */\n titleAngle?: number;\n /**\n * Vertical text baseline for the header title. One of `\"top\"`, `\"bottom\"`, `\"middle\"`.\n *\n * __Default value:__ `\"middle\"`\n */\n titleBaseline?: TextBaseline;\n /**\n * Color of the header title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * Font of the header title. (e.g., `\"Helvetica Neue\"`).\n */\n titleFont?: string;\n\n /**\n * Font size of the header title.\n *\n * @minimum 0\n */\n titleFontSize?: number;\n\n /**\n * Font weight of the header title.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n titleFontWeight?: FontWeight;\n\n /**\n * The maximum length of the header title in pixels. The text value will be automatically truncated if the rendered size exceeds the limit.\n *\n * __Default value:__ `0`, indicating no limit\n */\n titleLimit?: number;\n\n // ---------- Label ----------\n /**\n * The rotation angle of the header labels.\n *\n * __Default value:__ `0`.\n *\n * @minimum -360\n * @maximum 360\n */\n labelAngle?: number;\n\n /**\n * The color of the header label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the header label.\n */\n labelFont?: string;\n\n /**\n * The font size of the header label, in pixels.\n *\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * The maximum length of the header label in pixels. The text value will be automatically truncated if the rendered size exceeds the limit.\n *\n * __Default value:__ `0`, indicating no limit\n */\n labelLimit?: number;\n}\n\n/**\n * Headers of row / column channels for faceted plots.\n */\nexport interface Header extends HeaderConfig, Guide {}\n"]} \ No newline at end of file diff --git a/build/src/index.d.ts b/build/src/index.d.ts new file mode 100644 index 0000000000..6ca4fe1c35 --- /dev/null +++ b/build/src/index.d.ts @@ -0,0 +1,28 @@ +import * as aggregate from './aggregate'; +import * as axis from './axis'; +import * as bin from './bin'; +import * as channel from './channel'; +import * as compositeMark from './compositemark'; +export { TopLevelSpec } from './spec'; +export { compile } from './compile/compile'; +export { Config } from './config'; +import * as config from './config'; +import * as data from './data'; +import * as datetime from './datetime'; +import * as encoding from './encoding'; +import * as facet from './facet'; +import * as fieldDef from './fielddef'; +import * as header from './header'; +import * as legend from './legend'; +import * as mark from './mark'; +import * as scale from './scale'; +import * as sort from './sort'; +import * as spec from './spec'; +import * as stack from './stack'; +import * as timeUnit from './timeunit'; +import * as transform from './transform'; +import * as type from './type'; +import * as util from './util'; +import * as validate from './validate'; +declare const version: string; +export { aggregate, axis, bin, channel, compositeMark, config, data, datetime, encoding, facet, fieldDef, header, legend, mark, scale, sort, spec, stack, timeUnit, transform, type, util, validate, version }; diff --git a/build/src/index.js b/build/src/index.js new file mode 100644 index 0000000000..c982dcca7d --- /dev/null +++ b/build/src/index.js @@ -0,0 +1,28 @@ +import * as aggregate from './aggregate'; +import * as axis from './axis'; +import * as bin from './bin'; +import * as channel from './channel'; +import * as compositeMark from './compositemark'; +export { compile } from './compile/compile'; +import * as config from './config'; +import * as data from './data'; +import * as datetime from './datetime'; +import * as encoding from './encoding'; +import * as facet from './facet'; +import * as fieldDef from './fielddef'; +import * as header from './header'; +import * as legend from './legend'; +import * as mark from './mark'; +import * as scale from './scale'; +import * as sort from './sort'; +import * as spec from './spec'; +import * as stack from './stack'; +import * as timeUnit from './timeunit'; +import * as transform from './transform'; +import * as type from './type'; +import * as util from './util'; +import * as validate from './validate'; +import pkg from '../package.json'; +var version = pkg.version; +export { aggregate, axis, bin, channel, compositeMark, config, data, datetime, encoding, facet, fieldDef, header, legend, mark, scale, sort, spec, stack, timeUnit, transform, type, util, validate, version }; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/src/index.js.map b/build/src/index.js.map new file mode 100644 index 0000000000..6f698bd3c3 --- /dev/null +++ b/build/src/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,aAAa,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AAEvC,OAAO,GAAG,MAAM,iBAAiB,CAAC;AAClC,IAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;AAE5B,OAAO,EAAC,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAC,CAAC","sourcesContent":["import * as aggregate from './aggregate';\nimport * as axis from './axis';\nimport * as bin from './bin';\nimport * as channel from './channel';\nimport * as compositeMark from './compositemark';\nexport {TopLevelSpec} from './spec';\nexport {compile} from './compile/compile';\nexport {Config} from './config';\nimport * as config from './config';\nimport * as data from './data';\nimport * as datetime from './datetime';\nimport * as encoding from './encoding';\nimport * as facet from './facet';\nimport * as fieldDef from './fielddef';\nimport * as header from './header';\nimport * as legend from './legend';\nimport * as mark from './mark';\nimport * as scale from './scale';\nimport * as sort from './sort';\nimport * as spec from './spec';\nimport * as stack from './stack';\nimport * as timeUnit from './timeunit';\nimport * as transform from './transform';\nimport * as type from './type';\nimport * as util from './util';\nimport * as validate from './validate';\n\nimport pkg from '../package.json';\nconst version = pkg.version;\n\nexport {aggregate, axis, bin, channel, compositeMark, config, data, datetime, encoding, facet, fieldDef, header, legend, mark, scale, sort, spec, stack, timeUnit, transform, type, util, validate, version};\n"]} \ No newline at end of file diff --git a/build/src/legend.d.ts b/build/src/legend.d.ts new file mode 100644 index 0000000000..5db1161dea --- /dev/null +++ b/build/src/legend.d.ts @@ -0,0 +1,64 @@ +import { DateTime } from './datetime'; +import { Guide, GuideEncodingEntry, VlOnlyGuideConfig } from './guide'; +import { VgLegendBase, VgLegendConfig } from './vega.schema'; +export interface LegendConfig extends VgLegendConfig, VlOnlyGuideConfig { +} +/** + * Properties of a legend or boolean flag for determining whether to show it. + */ +export interface Legend extends VgLegendBase, Guide { + /** + * Mark definitions for custom legend encoding. + * + * @hide + */ + encoding?: LegendEncoding; + /** + * The desired number of tick values for quantitative legends. + */ + tickCount?: number; + /** + * Explicitly set the visible legend values. + */ + values?: number[] | string[] | boolean[] | DateTime[]; + /** + * The type of the legend. Use `"symbol"` to create a discrete legend and `"gradient"` for a continuous color gradient. + * + * __Default value:__ `"gradient"` for non-binned quantitative fields and temporal fields; `"symbol"` otherwise. + */ + type?: 'symbol' | 'gradient'; + /** + * A non-positive integer indicating z-index of the legend. + * If zindex is 0, legend should be drawn behind all chart elements. + * To put them in front, use zindex = 1. + * @TJS-type integer + * @minimum 0 + */ + zindex?: number; +} +export declare type LegendEncoding = { + /** + * Custom encoding for the legend container. + * This can be useful for creating legend with custom x, y position. + */ + legend?: GuideEncodingEntry; + /** + * Custom encoding for the legend title text mark. + */ + title?: GuideEncodingEntry; + /** + * Custom encoding for legend label text marks. + */ + labels?: GuideEncodingEntry; + /** + * Custom encoding for legend symbol marks. + */ + symbols?: GuideEncodingEntry; + /** + * Custom encoding for legend gradient filled rect marks. + */ + gradient?: GuideEncodingEntry; +}; +export declare const defaultLegendConfig: LegendConfig; +export declare const LEGEND_PROPERTIES: ("title" | "padding" | "type" | "orient" | "zindex" | "tickCount" | "format" | "values" | "offset" | "entryPadding")[]; +export declare const VG_LEGEND_PROPERTIES: ("title" | "padding" | "type" | "shape" | "orient" | "zindex" | "tickCount" | "format" | "values" | "offset" | "encode" | "fill" | "stroke" | "opacity" | "size" | "entryPadding")[]; diff --git a/build/src/legend.js b/build/src/legend.js new file mode 100644 index 0000000000..91ca175279 --- /dev/null +++ b/build/src/legend.js @@ -0,0 +1,23 @@ +import * as tslib_1 from "tslib"; +import { flagKeys } from './util'; +export var defaultLegendConfig = {}; +var COMMON_LEGEND_PROPERTY_INDEX = { + entryPadding: 1, + format: 1, + offset: 1, + orient: 1, + padding: 1, + tickCount: 1, + title: 1, + type: 1, + values: 1, + zindex: 1 +}; +var VG_LEGEND_PROPERTY_INDEX = tslib_1.__assign({}, COMMON_LEGEND_PROPERTY_INDEX, { + // channel scales + opacity: 1, shape: 1, stroke: 1, fill: 1, size: 1, + // encode + encode: 1 }); +export var LEGEND_PROPERTIES = flagKeys(COMMON_LEGEND_PROPERTY_INDEX); +export var VG_LEGEND_PROPERTIES = flagKeys(VG_LEGEND_PROPERTY_INDEX); +//# sourceMappingURL=legend.js.map \ No newline at end of file diff --git a/build/src/legend.js.map b/build/src/legend.js.map new file mode 100644 index 0000000000..fee9a222f8 --- /dev/null +++ b/build/src/legend.js.map @@ -0,0 +1 @@ +{"version":3,"file":"legend.js","sourceRoot":"","sources":["../../src/legend.ts"],"names":[],"mappings":";AAEA,OAAO,EAAO,QAAQ,EAAC,MAAM,QAAQ,CAAC;AAwEtC,MAAM,CAAC,IAAM,mBAAmB,GAAiB,EAAE,CAAC;AAEpD,IAAM,4BAA4B,GAAoC;IACpE,YAAY,EAAE,CAAC;IACf,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;CACV,CAAC;AAEF,IAAM,wBAAwB,wBACzB,4BAA4B;IAC/B,iBAAiB;IACjB,OAAO,EAAE,CAAC,EACV,KAAK,EAAE,CAAC,EACR,MAAM,EAAE,CAAC,EACT,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,CAAC;IACP,SAAS;IACT,MAAM,EAAE,CAAC,GACV,CAAC;AAEF,MAAM,CAAC,IAAM,iBAAiB,GAAG,QAAQ,CAAC,4BAA4B,CAAC,CAAC;AAExE,MAAM,CAAC,IAAM,oBAAoB,GAAG,QAAQ,CAAC,wBAAwB,CAAC,CAAC","sourcesContent":["import {DateTime} from './datetime';\nimport {Guide, GuideEncodingEntry, VlOnlyGuideConfig} from './guide';\nimport {Flag, flagKeys} from './util';\nimport {VgLegend, VgLegendBase, VgLegendConfig} from './vega.schema';\n\n\nexport interface LegendConfig extends VgLegendConfig, VlOnlyGuideConfig {}\n\n/**\n * Properties of a legend or boolean flag for determining whether to show it.\n */\nexport interface Legend extends VgLegendBase, Guide {\n /**\n * Mark definitions for custom legend encoding.\n *\n * @hide\n */\n encoding?: LegendEncoding;\n\n /**\n * The desired number of tick values for quantitative legends.\n */\n tickCount?: number;\n\n /**\n * Explicitly set the visible legend values.\n */\n values?: number[] | string[] | boolean[] | DateTime[];\n\n /**\n * The type of the legend. Use `\"symbol\"` to create a discrete legend and `\"gradient\"` for a continuous color gradient.\n *\n * __Default value:__ `\"gradient\"` for non-binned quantitative fields and temporal fields; `\"symbol\"` otherwise.\n */\n type?: 'symbol' | 'gradient';\n\n /**\n * A non-positive integer indicating z-index of the legend.\n * If zindex is 0, legend should be drawn behind all chart elements.\n * To put them in front, use zindex = 1.\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n}\n\nexport type LegendEncoding = {\n /**\n * Custom encoding for the legend container.\n * This can be useful for creating legend with custom x, y position.\n */\n legend?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the legend title text mark.\n */\n title?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend label text marks.\n */\n labels?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend symbol marks.\n */\n symbols?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend gradient filled rect marks.\n */\n gradient?: GuideEncodingEntry;\n};\n\nexport const defaultLegendConfig: LegendConfig = {};\n\nconst COMMON_LEGEND_PROPERTY_INDEX: Flag = {\n entryPadding: 1,\n format: 1,\n offset: 1,\n orient: 1,\n padding: 1,\n tickCount: 1,\n title: 1,\n type: 1,\n values: 1,\n zindex: 1\n};\n\nconst VG_LEGEND_PROPERTY_INDEX: Flag = {\n ...COMMON_LEGEND_PROPERTY_INDEX,\n // channel scales\n opacity: 1,\n shape: 1,\n stroke: 1,\n fill: 1,\n size: 1,\n // encode\n encode: 1\n};\n\nexport const LEGEND_PROPERTIES = flagKeys(COMMON_LEGEND_PROPERTY_INDEX);\n\nexport const VG_LEGEND_PROPERTIES = flagKeys(VG_LEGEND_PROPERTY_INDEX);\n"]} \ No newline at end of file diff --git a/build/src/log.d.ts b/build/src/log.d.ts new file mode 100644 index 0000000000..bb94229287 --- /dev/null +++ b/build/src/log.d.ts @@ -0,0 +1,110 @@ +/** + * Vega-Lite's singleton logger utility. + */ +import { AggregateOp } from 'vega'; +import { LoggerInterface } from 'vega-util'; +import { Channel, GeoPositionChannel } from './channel'; +import { CompositeMark } from './compositemark'; +import { DateTime, DateTimeExpr } from './datetime'; +import { FieldDef } from './fielddef'; +import { Mark } from './mark'; +import { Projection } from './projection'; +import { ScaleType } from './scale'; +import { Type } from './type'; +import { VgSortField } from './vega.schema'; +export { LoggerInterface } from 'vega-util'; +/** + * Logger tool for checking if the code throws correct warning + */ +export declare class LocalLogger implements LoggerInterface { + warns: any[]; + infos: any[]; + debugs: any[]; + level(): this; + warn(...args: any[]): this; + info(...args: any[]): this; + debug(...args: any[]): this; +} +export declare function wrap(f: (logger: LocalLogger) => void): () => void; +/** + * Set the singleton logger to be a custom logger + */ +export declare function set(newLogger: LoggerInterface): LoggerInterface; +/** + * Reset the main logger to use the default Vega Logger + */ +export declare function reset(): LoggerInterface; +export declare function warn(..._: any[]): void; +export declare function info(..._: any[]): void; +export declare function debug(..._: any[]): void; +/** + * Collection of all Vega-Lite Error Messages + */ +export declare namespace message { + const INVALID_SPEC = "Invalid spec"; + const FIT_NON_SINGLE = "Autosize \"fit\" only works for single views and layered views."; + const CANNOT_FIX_RANGE_STEP_WITH_FIT = "Cannot use a fixed value of \"rangeStep\" when \"autosize\" is \"fit\"."; + function cannotProjectOnChannelWithoutField(channel: Channel): string; + function nearestNotSupportForContinuous(mark: string): string; + function selectionNotFound(name: string): string; + const SCALE_BINDINGS_CONTINUOUS = "Scale bindings are currently only supported for scales with unbinned, continuous domains."; + function noSuchRepeatedValue(field: string): string; + const CONCAT_CANNOT_SHARE_AXIS = "Axes cannot be shared in concatenated views."; + const REPEAT_CANNOT_SHARE_AXIS = "Axes cannot be shared in repeated views."; + function cannotSetTitleAnchor(type: string): string; + function unrecognizedParse(p: string): string; + function differentParse(field: string, local: string, ancestor: string): string; + function invalidTransformIgnored(transform: any): string; + const NO_FIELDS_NEEDS_AS = "If \"from.fields\" is not specified, \"as\" has to be a string that specifies the key to be used for the data from the secondary source."; + function encodingOverridden(channels: Channel[]): string; + function projectionOverridden(opt: { + parentProjection: Projection; + projection: Projection; + }): string; + function primitiveChannelDef(channel: Channel, type: 'string' | 'number' | 'boolean', value: string | number | boolean): string; + function invalidFieldType(type: Type): string; + function nonZeroScaleUsedWithLengthMark(mark: 'bar' | 'area', channel: Channel, opt: { + scaleType?: ScaleType; + zeroFalse?: boolean; + }): string; + function invalidFieldTypeForCountAggregate(type: Type, aggregate: string): string; + function invalidAggregate(aggregate: AggregateOp | string): string; + function emptyOrInvalidFieldType(type: Type | string, channel: Channel, newType: Type): string; + function droppingColor(type: 'encoding' | 'property', opt: { + fill?: boolean; + stroke?: boolean; + }): string; + function emptyFieldDef(fieldDef: FieldDef, channel: Channel): string; + function latLongDeprecated(channel: Channel, type: Type, newChannel: GeoPositionChannel): string; + const LINE_WITH_VARYING_SIZE = "Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead."; + function incompatibleChannel(channel: Channel, markOrFacet: Mark | 'facet' | CompositeMark, when?: string): string; + function invalidEncodingChannel(channel: string): string; + function facetChannelShouldBeDiscrete(channel: string): string; + function discreteChannelCannotEncode(channel: Channel, type: Type): string; + const BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = "Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead."; + function lineWithRange(hasX2: boolean, hasY2: boolean): string; + function orientOverridden(original: string, actual: string): string; + const CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = "custom domain scale cannot be unioned with default field-based domain"; + function cannotUseScalePropertyWithNonColor(prop: string): string; + function unaggregateDomainHasNoEffectForRawField(fieldDef: FieldDef): string; + function unaggregateDomainWithNonSharedDomainOp(aggregate: string): string; + function unaggregatedDomainWithLogScale(fieldDef: FieldDef): string; + function cannotApplySizeToNonOrientedMark(mark: Mark): string; + function rangeStepDropped(channel: Channel): string; + function scaleTypeNotWorkWithChannel(channel: Channel, scaleType: ScaleType, defaultScaleType: ScaleType): string; + function scaleTypeNotWorkWithFieldDef(scaleType: ScaleType, defaultScaleType: ScaleType): string; + function scalePropertyNotWorkWithScaleType(scaleType: ScaleType, propName: string, channel: Channel): string; + function scaleTypeNotWorkWithMark(mark: Mark, scaleType: ScaleType): string; + function mergeConflictingProperty(property: string | number | symbol, propertyOf: string | number | symbol, v1: T, v2: T): string; + function independentScaleMeansIndependentGuide(channel: Channel): string; + function domainSortDropped(sort: VgSortField): string; + const UNABLE_TO_MERGE_DOMAINS = "Unable to merge domains"; + const MORE_THAN_ONE_SORT = "Domains that should be unioned has conflicting sort properties. Sort will be set to true."; + const INVALID_CHANNEL_FOR_AXIS = "Invalid channel for axis."; + function cannotStackRangedMark(channel: Channel): string; + function cannotStackNonLinearScale(scaleType: ScaleType): string; + function stackNonSummativeAggregate(aggregate: string): string; + function invalidTimeUnit(unitName: string, value: string | number): string; + function dayReplacedWithDate(fullTimeUnit: string): string; + function droppedDay(d: DateTime | DateTimeExpr): string; +} diff --git a/build/src/log.js b/build/src/log.js new file mode 100644 index 0000000000..0321e45303 --- /dev/null +++ b/build/src/log.js @@ -0,0 +1,310 @@ +/** + * Vega-Lite's singleton logger utility. + */ +import { logger, Warn } from 'vega-util'; +import { stringify } from './util'; +/** + * Main (default) Vega Logger instance for Vega-Lite + */ +var main = logger(Warn); +var current = main; +/** + * Logger tool for checking if the code throws correct warning + */ +var LocalLogger = /** @class */ (function () { + function LocalLogger() { + this.warns = []; + this.infos = []; + this.debugs = []; + } + LocalLogger.prototype.level = function () { + return this; + }; + LocalLogger.prototype.warn = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var _a; + (_a = this.warns).push.apply(_a, args); + return this; + }; + LocalLogger.prototype.info = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var _a; + (_a = this.infos).push.apply(_a, args); + return this; + }; + LocalLogger.prototype.debug = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var _a; + (_a = this.debugs).push.apply(_a, args); + return this; + }; + return LocalLogger; +}()); +export { LocalLogger }; +export function wrap(f) { + return function () { + current = new LocalLogger(); + f(current); + reset(); + }; +} +/** + * Set the singleton logger to be a custom logger + */ +export function set(newLogger) { + current = newLogger; + return current; +} +/** + * Reset the main logger to use the default Vega Logger + */ +export function reset() { + current = main; + return current; +} +export function warn() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.warn.apply(current, arguments); +} +export function info() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.info.apply(current, arguments); +} +export function debug() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.debug.apply(current, arguments); +} +/** + * Collection of all Vega-Lite Error Messages + */ +export var message; +(function (message) { + message.INVALID_SPEC = 'Invalid spec'; + // FIT + message.FIT_NON_SINGLE = 'Autosize "fit" only works for single views and layered views.'; + message.CANNOT_FIX_RANGE_STEP_WITH_FIT = 'Cannot use a fixed value of "rangeStep" when "autosize" is "fit".'; + // SELECTION + function cannotProjectOnChannelWithoutField(channel) { + return "Cannot project a selection on encoding channel \"" + channel + "\", which has no field."; + } + message.cannotProjectOnChannelWithoutField = cannotProjectOnChannelWithoutField; + function nearestNotSupportForContinuous(mark) { + return "The \"nearest\" transform is not supported for " + mark + " marks."; + } + message.nearestNotSupportForContinuous = nearestNotSupportForContinuous; + function selectionNotFound(name) { + return "Cannot find a selection named \"" + name + "\""; + } + message.selectionNotFound = selectionNotFound; + message.SCALE_BINDINGS_CONTINUOUS = 'Scale bindings are currently only supported for scales with unbinned, continuous domains.'; + // REPEAT + function noSuchRepeatedValue(field) { + return "Unknown repeated value \"" + field + "\"."; + } + message.noSuchRepeatedValue = noSuchRepeatedValue; + // CONCAT + message.CONCAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in concatenated views.'; + // REPEAT + message.REPEAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in repeated views.'; + // TITLE + function cannotSetTitleAnchor(type) { + return "Cannot set title \"anchor\" for a " + type + " spec"; + } + message.cannotSetTitleAnchor = cannotSetTitleAnchor; + // DATA + function unrecognizedParse(p) { + return "Unrecognized parse \"" + p + "\"."; + } + message.unrecognizedParse = unrecognizedParse; + function differentParse(field, local, ancestor) { + return "An ancestor parsed field \"" + field + "\" as " + ancestor + " but a child wants to parse the field as " + local + "."; + } + message.differentParse = differentParse; + // TRANSFORMS + function invalidTransformIgnored(transform) { + return "Ignoring an invalid transform: " + stringify(transform) + "."; + } + message.invalidTransformIgnored = invalidTransformIgnored; + message.NO_FIELDS_NEEDS_AS = 'If "from.fields" is not specified, "as" has to be a string that specifies the key to be used for the data from the secondary source.'; + // ENCODING & FACET + function encodingOverridden(channels) { + return "Layer's shared " + channels.join(',') + " channel " + (channels.length === 1 ? 'is' : 'are') + " overriden"; + } + message.encodingOverridden = encodingOverridden; + function projectionOverridden(opt) { + var parentProjection = opt.parentProjection, projection = opt.projection; + return "Layer's shared projection " + stringify(parentProjection) + " is overridden by a child projection " + stringify(projection) + "."; + } + message.projectionOverridden = projectionOverridden; + function primitiveChannelDef(channel, type, value) { + return "Channel " + channel + " is a " + type + ". Converted to {value: " + stringify(value) + "}."; + } + message.primitiveChannelDef = primitiveChannelDef; + function invalidFieldType(type) { + return "Invalid field type \"" + type + "\""; + } + message.invalidFieldType = invalidFieldType; + function nonZeroScaleUsedWithLengthMark(mark, channel, opt) { + var scaleText = opt.scaleType ? opt.scaleType + " scale" : + opt.zeroFalse ? 'scale with zero=false' : + 'scale with custom domain that excludes zero'; + return "A " + scaleText + " is used to encode " + mark + "'s " + channel + ". This can be misleading as the " + (channel === 'x' ? 'width' : 'height') + " of the " + mark + " can be arbitrary based on the scale domain. You may want to use point mark instead."; + } + message.nonZeroScaleUsedWithLengthMark = nonZeroScaleUsedWithLengthMark; + function invalidFieldTypeForCountAggregate(type, aggregate) { + return "Invalid field type \"" + type + "\" for aggregate: \"" + aggregate + "\", using \"quantitative\" instead."; + } + message.invalidFieldTypeForCountAggregate = invalidFieldTypeForCountAggregate; + function invalidAggregate(aggregate) { + return "Invalid aggregation operator \"" + aggregate + "\""; + } + message.invalidAggregate = invalidAggregate; + function emptyOrInvalidFieldType(type, channel, newType) { + return "Invalid field type \"" + type + "\" for channel \"" + channel + "\", using \"" + newType + "\" instead."; + } + message.emptyOrInvalidFieldType = emptyOrInvalidFieldType; + function droppingColor(type, opt) { + var fill = opt.fill, stroke = opt.stroke; + return "Dropping color " + type + " as the plot also has " + (fill && stroke ? 'fill and stroke' : fill ? 'fill' : 'stroke'); + } + message.droppingColor = droppingColor; + function emptyFieldDef(fieldDef, channel) { + return "Dropping " + stringify(fieldDef) + " from channel \"" + channel + "\" since it does not contain data field or value."; + } + message.emptyFieldDef = emptyFieldDef; + function latLongDeprecated(channel, type, newChannel) { + return channel + "-encoding with type " + type + " is deprecated. Replacing with " + newChannel + "-encoding."; + } + message.latLongDeprecated = latLongDeprecated; + message.LINE_WITH_VARYING_SIZE = 'Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.'; + function incompatibleChannel(channel, markOrFacet, when) { + return channel + " dropped as it is incompatible with \"" + markOrFacet + "\"" + (when ? " when " + when : '') + "."; + } + message.incompatibleChannel = incompatibleChannel; + function invalidEncodingChannel(channel) { + return channel + "-encoding is dropped as " + channel + " is not a valid encoding channel."; + } + message.invalidEncodingChannel = invalidEncodingChannel; + function facetChannelShouldBeDiscrete(channel) { + return channel + " encoding should be discrete (ordinal / nominal / binned)."; + } + message.facetChannelShouldBeDiscrete = facetChannelShouldBeDiscrete; + function discreteChannelCannotEncode(channel, type) { + return "Using discrete channel \"" + channel + "\" to encode \"" + type + "\" field can be misleading as it does not encode " + (type === 'ordinal' ? 'order' : 'magnitude') + "."; + } + message.discreteChannelCannotEncode = discreteChannelCannotEncode; + // Mark + message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.'; + function lineWithRange(hasX2, hasY2) { + var channels = hasX2 && hasY2 ? 'x2 and y2' : hasX2 ? 'x2' : 'y2'; + return "Line mark is for continuous lines and thus cannot be used with " + channels + ". We will use the rule mark (line segments) instead."; + } + message.lineWithRange = lineWithRange; + function orientOverridden(original, actual) { + return "Specified orient \"" + original + "\" overridden with \"" + actual + "\""; + } + message.orientOverridden = orientOverridden; + // SCALE + message.CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = 'custom domain scale cannot be unioned with default field-based domain'; + function cannotUseScalePropertyWithNonColor(prop) { + return "Cannot use the scale property \"" + prop + "\" with non-color channel."; + } + message.cannotUseScalePropertyWithNonColor = cannotUseScalePropertyWithNonColor; + function unaggregateDomainHasNoEffectForRawField(fieldDef) { + return "Using unaggregated domain with raw field has no effect (" + stringify(fieldDef) + ")."; + } + message.unaggregateDomainHasNoEffectForRawField = unaggregateDomainHasNoEffectForRawField; + function unaggregateDomainWithNonSharedDomainOp(aggregate) { + return "Unaggregated domain not applicable for \"" + aggregate + "\" since it produces values outside the origin domain of the source data."; + } + message.unaggregateDomainWithNonSharedDomainOp = unaggregateDomainWithNonSharedDomainOp; + function unaggregatedDomainWithLogScale(fieldDef) { + return "Unaggregated domain is currently unsupported for log scale (" + stringify(fieldDef) + ")."; + } + message.unaggregatedDomainWithLogScale = unaggregatedDomainWithLogScale; + function cannotApplySizeToNonOrientedMark(mark) { + return "Cannot apply size to non-oriented mark \"" + mark + "\"."; + } + message.cannotApplySizeToNonOrientedMark = cannotApplySizeToNonOrientedMark; + function rangeStepDropped(channel) { + return "rangeStep for \"" + channel + "\" is dropped as top-level " + (channel === 'x' ? 'width' : 'height') + " is provided."; + } + message.rangeStepDropped = rangeStepDropped; + function scaleTypeNotWorkWithChannel(channel, scaleType, defaultScaleType) { + return "Channel \"" + channel + "\" does not work with \"" + scaleType + "\" scale. We are using \"" + defaultScaleType + "\" scale instead."; + } + message.scaleTypeNotWorkWithChannel = scaleTypeNotWorkWithChannel; + function scaleTypeNotWorkWithFieldDef(scaleType, defaultScaleType) { + return "FieldDef does not work with \"" + scaleType + "\" scale. We are using \"" + defaultScaleType + "\" scale instead."; + } + message.scaleTypeNotWorkWithFieldDef = scaleTypeNotWorkWithFieldDef; + function scalePropertyNotWorkWithScaleType(scaleType, propName, channel) { + return channel + "-scale's \"" + propName + "\" is dropped as it does not work with " + scaleType + " scale."; + } + message.scalePropertyNotWorkWithScaleType = scalePropertyNotWorkWithScaleType; + function scaleTypeNotWorkWithMark(mark, scaleType) { + return "Scale type \"" + scaleType + "\" does not work with mark \"" + mark + "\"."; + } + message.scaleTypeNotWorkWithMark = scaleTypeNotWorkWithMark; + function mergeConflictingProperty(property, propertyOf, v1, v2) { + return "Conflicting " + propertyOf.toString() + " property \"" + property.toString() + "\" (" + stringify(v1) + " and " + stringify(v2) + "). Using " + stringify(v1) + "."; + } + message.mergeConflictingProperty = mergeConflictingProperty; + function independentScaleMeansIndependentGuide(channel) { + return "Setting the scale to be independent for \"" + channel + "\" means we also have to set the guide (axis or legend) to be independent."; + } + message.independentScaleMeansIndependentGuide = independentScaleMeansIndependentGuide; + function domainSortDropped(sort) { + return "Dropping sort property " + stringify(sort) + " as unioned domains only support boolean or op 'count'."; + } + message.domainSortDropped = domainSortDropped; + message.UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains'; + message.MORE_THAN_ONE_SORT = 'Domains that should be unioned has conflicting sort properties. Sort will be set to true.'; + // AXIS + message.INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.'; + // STACK + function cannotStackRangedMark(channel) { + return "Cannot stack \"" + channel + "\" if there is already \"" + channel + "2\""; + } + message.cannotStackRangedMark = cannotStackRangedMark; + function cannotStackNonLinearScale(scaleType) { + return "Cannot stack non-linear scale (" + scaleType + ")"; + } + message.cannotStackNonLinearScale = cannotStackNonLinearScale; + function stackNonSummativeAggregate(aggregate) { + return "Stacking is applied even though the aggregate function is non-summative (\"" + aggregate + "\")"; + } + message.stackNonSummativeAggregate = stackNonSummativeAggregate; + // TIMEUNIT + function invalidTimeUnit(unitName, value) { + return "Invalid " + unitName + ": " + stringify(value); + } + message.invalidTimeUnit = invalidTimeUnit; + function dayReplacedWithDate(fullTimeUnit) { + return "Time unit \"" + fullTimeUnit + "\" is not supported. We are replacing it with " + fullTimeUnit.replace('day', 'date') + "."; + } + message.dayReplacedWithDate = dayReplacedWithDate; + function droppedDay(d) { + return "Dropping day from datetime " + stringify(d) + " as day cannot be combined with other units."; + } + message.droppedDay = droppedDay; +})(message || (message = {})); +//# sourceMappingURL=log.js.map \ No newline at end of file diff --git a/build/src/log.js.map b/build/src/log.js.map new file mode 100644 index 0000000000..0d2d5710f1 --- /dev/null +++ b/build/src/log.js.map @@ -0,0 +1 @@ +{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/log.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Vega-Lite's singleton logger utility.\n */\n\nimport {AggregateOp} from 'vega';\nimport {logger, LoggerInterface, Warn} from 'vega-util';\nimport {Channel, GeoPositionChannel} from './channel';\nimport {CompositeMark} from './compositemark';\nimport {DateTime, DateTimeExpr} from './datetime';\nimport {FieldDef} from './fielddef';\nimport {Mark} from './mark';\nimport {Projection} from './projection';\nimport {ScaleType} from './scale';\nimport {Type} from './type';\nimport {stringify} from './util';\nimport {VgSortField} from './vega.schema';\n\n\nexport {LoggerInterface} from 'vega-util';\n\n/**\n * Main (default) Vega Logger instance for Vega-Lite\n */\nconst main = logger(Warn);\nlet current: LoggerInterface = main;\n\n/**\n * Logger tool for checking if the code throws correct warning\n */\nexport class LocalLogger implements LoggerInterface {\n public warns: any[] = [];\n public infos: any[] = [];\n public debugs: any[] = [];\n\n public level() {\n return this;\n }\n\n public warn(...args: any[]) {\n this.warns.push(...args);\n return this;\n }\n\n public info(...args: any[]) {\n this.infos.push(...args);\n return this;\n }\n\n public debug(...args: any[]) {\n this.debugs.push(...args);\n return this;\n }\n}\n\nexport function wrap(f: (logger: LocalLogger) => void) {\n return () => {\n current = new LocalLogger();\n f(current as LocalLogger);\n reset();\n };\n}\n\n/**\n * Set the singleton logger to be a custom logger\n */\nexport function set(newLogger: LoggerInterface) {\n current = newLogger;\n return current;\n}\n\n/**\n * Reset the main logger to use the default Vega Logger\n */\nexport function reset() {\n current = main;\n return current;\n}\n\nexport function warn(..._: any[]) {\n current.warn.apply(current, arguments);\n}\n\nexport function info(..._: any[]) {\n current.info.apply(current, arguments);\n}\n\nexport function debug(..._: any[]) {\n current.debug.apply(current, arguments);\n}\n\n/**\n * Collection of all Vega-Lite Error Messages\n */\nexport namespace message {\n export const INVALID_SPEC = 'Invalid spec';\n\n // FIT\n export const FIT_NON_SINGLE = 'Autosize \"fit\" only works for single views and layered views.';\n\n export const CANNOT_FIX_RANGE_STEP_WITH_FIT = 'Cannot use a fixed value of \"rangeStep\" when \"autosize\" is \"fit\".';\n\n // SELECTION\n export function cannotProjectOnChannelWithoutField(channel: Channel) {\n return `Cannot project a selection on encoding channel \"${channel}\", which has no field.`;\n }\n\n export function nearestNotSupportForContinuous(mark: string) {\n return `The \"nearest\" transform is not supported for ${mark} marks.`;\n }\n\n export function selectionNotFound(name: string) {\n return `Cannot find a selection named \"${name}\"`;\n }\n\n export const SCALE_BINDINGS_CONTINUOUS = 'Scale bindings are currently only supported for scales with unbinned, continuous domains.';\n\n // REPEAT\n export function noSuchRepeatedValue(field: string) {\n return `Unknown repeated value \"${field}\".`;\n }\n\n // CONCAT\n export const CONCAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in concatenated views.';\n\n // REPEAT\n export const REPEAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in repeated views.';\n\n // TITLE\n export function cannotSetTitleAnchor(type: string) {\n return `Cannot set title \"anchor\" for a ${type} spec`;\n }\n\n // DATA\n export function unrecognizedParse(p: string) {\n return `Unrecognized parse \"${p}\".`;\n }\n\n export function differentParse(field: string, local: string, ancestor: string) {\n return `An ancestor parsed field \"${field}\" as ${ancestor} but a child wants to parse the field as ${local}.`;\n }\n\n // TRANSFORMS\n export function invalidTransformIgnored(transform: any) {\n return `Ignoring an invalid transform: ${stringify(transform)}.`;\n }\n\n export const NO_FIELDS_NEEDS_AS = 'If \"from.fields\" is not specified, \"as\" has to be a string that specifies the key to be used for the data from the secondary source.';\n\n // ENCODING & FACET\n\n export function encodingOverridden(channels: Channel[]) {\n return `Layer's shared ${channels.join(',')} channel ${channels.length === 1 ? 'is' : 'are'} overriden`;\n }\n export function projectionOverridden(opt: {parentProjection: Projection, projection: Projection}) {\n const {parentProjection, projection} = opt;\n return `Layer's shared projection ${stringify(parentProjection)} is overridden by a child projection ${stringify(projection)}.`;\n }\n\n export function primitiveChannelDef(channel: Channel, type: 'string' | 'number' | 'boolean', value: string | number | boolean) {\n return `Channel ${channel} is a ${type}. Converted to {value: ${stringify(value)}}.`;\n }\n\n export function invalidFieldType(type: Type) {\n return `Invalid field type \"${type}\"`;\n }\n\n export function nonZeroScaleUsedWithLengthMark(\n mark: 'bar' | 'area', channel: Channel,\n opt: {scaleType?: ScaleType, zeroFalse?: boolean}\n ) {\n const scaleText = opt.scaleType ? `${opt.scaleType} scale` :\n opt.zeroFalse ? 'scale with zero=false' :\n 'scale with custom domain that excludes zero';\n\n return `A ${scaleText} is used to encode ${mark}'s ${channel}. This can be misleading as the ${channel === 'x' ? 'width' : 'height'} of the ${mark} can be arbitrary based on the scale domain. You may want to use point mark instead.`;\n }\n\n export function invalidFieldTypeForCountAggregate(type: Type, aggregate: string) {\n return `Invalid field type \"${type}\" for aggregate: \"${aggregate}\", using \"quantitative\" instead.`;\n }\n\n export function invalidAggregate(aggregate: AggregateOp | string) {\n return `Invalid aggregation operator \"${aggregate}\"`;\n }\n\n export function emptyOrInvalidFieldType(type: Type | string, channel: Channel, newType: Type) {\n return `Invalid field type \"${type}\" for channel \"${channel}\", using \"${newType}\" instead.`;\n }\n export function droppingColor(type: 'encoding' | 'property', opt: {fill?: boolean, stroke?: boolean}) {\n const {fill, stroke} = opt;\n return `Dropping color ${type} as the plot also has ` + (\n fill && stroke ? 'fill and stroke' : fill ? 'fill' : 'stroke'\n );\n }\n\n export function emptyFieldDef(fieldDef: FieldDef, channel: Channel) {\n return `Dropping ${stringify(fieldDef)} from channel \"${channel}\" since it does not contain data field or value.`;\n }\n export function latLongDeprecated(channel: Channel, type: Type, newChannel: GeoPositionChannel) {\n return `${channel}-encoding with type ${type} is deprecated. Replacing with ${newChannel}-encoding.`;\n }\n\n export const LINE_WITH_VARYING_SIZE = 'Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.';\n\n export function incompatibleChannel(channel: Channel, markOrFacet: Mark | 'facet' | CompositeMark, when?: string) {\n return `${channel} dropped as it is incompatible with \"${markOrFacet}\"${when ? ` when ${when}` : ''}.`;\n }\n\n export function invalidEncodingChannel(channel: string) {\n return `${channel}-encoding is dropped as ${channel} is not a valid encoding channel.`;\n }\n\n export function facetChannelShouldBeDiscrete(channel: string) {\n return `${channel} encoding should be discrete (ordinal / nominal / binned).`;\n }\n\n export function discreteChannelCannotEncode(channel: Channel, type: Type) {\n return `Using discrete channel \"${channel}\" to encode \"${type}\" field can be misleading as it does not encode ${type === 'ordinal' ? 'order' : 'magnitude'}.`;\n }\n\n // Mark\n export const BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.';\n\n export function lineWithRange(hasX2: boolean, hasY2: boolean) {\n const channels = hasX2 && hasY2 ? 'x2 and y2' : hasX2 ? 'x2' : 'y2';\n return `Line mark is for continuous lines and thus cannot be used with ${channels}. We will use the rule mark (line segments) instead.`;\n }\n\n export function orientOverridden(original: string, actual: string) {\n return `Specified orient \"${original}\" overridden with \"${actual}\"`;\n }\n\n // SCALE\n export const CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = 'custom domain scale cannot be unioned with default field-based domain';\n\n export function cannotUseScalePropertyWithNonColor(prop: string) {\n return `Cannot use the scale property \"${prop}\" with non-color channel.`;\n }\n\n export function unaggregateDomainHasNoEffectForRawField(fieldDef: FieldDef) {\n return `Using unaggregated domain with raw field has no effect (${stringify(fieldDef)}).`;\n }\n\n export function unaggregateDomainWithNonSharedDomainOp(aggregate: string) {\n return `Unaggregated domain not applicable for \"${aggregate}\" since it produces values outside the origin domain of the source data.`;\n }\n\n export function unaggregatedDomainWithLogScale(fieldDef: FieldDef) {\n return `Unaggregated domain is currently unsupported for log scale (${stringify(fieldDef)}).`;\n }\n\n export function cannotApplySizeToNonOrientedMark(mark: Mark) {\n return `Cannot apply size to non-oriented mark \"${mark}\".`;\n }\n\n export function rangeStepDropped(channel: Channel) {\n return `rangeStep for \"${channel}\" is dropped as top-level ${\n channel === 'x' ? 'width' : 'height'} is provided.`;\n }\n\n export function scaleTypeNotWorkWithChannel(channel: Channel, scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `Channel \"${channel}\" does not work with \"${scaleType}\" scale. We are using \"${defaultScaleType}\" scale instead.`;\n }\n\n export function scaleTypeNotWorkWithFieldDef(scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `FieldDef does not work with \"${scaleType}\" scale. We are using \"${defaultScaleType}\" scale instead.`;\n }\n\n export function scalePropertyNotWorkWithScaleType(scaleType: ScaleType, propName: string, channel: Channel) {\n return `${channel}-scale's \"${propName}\" is dropped as it does not work with ${scaleType} scale.`;\n }\n\n export function scaleTypeNotWorkWithMark(mark: Mark, scaleType: ScaleType) {\n return `Scale type \"${scaleType}\" does not work with mark \"${mark}\".`;\n }\n\n export function mergeConflictingProperty(property: string | number | symbol, propertyOf: string | number | symbol, v1: T, v2: T) {\n return `Conflicting ${propertyOf.toString()} property \"${property.toString()}\" (${stringify(v1)} and ${stringify(v2)}). Using ${stringify(v1)}.`;\n }\n\n export function independentScaleMeansIndependentGuide(channel: Channel) {\n return `Setting the scale to be independent for \"${channel}\" means we also have to set the guide (axis or legend) to be independent.`;\n }\n\n export function domainSortDropped(sort: VgSortField) {\n return `Dropping sort property ${stringify(sort)} as unioned domains only support boolean or op 'count'.`;\n }\n\n export const UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains';\n\n export const MORE_THAN_ONE_SORT = 'Domains that should be unioned has conflicting sort properties. Sort will be set to true.';\n\n // AXIS\n export const INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.';\n\n // STACK\n export function cannotStackRangedMark(channel: Channel) {\n return `Cannot stack \"${channel}\" if there is already \"${channel}2\"`;\n }\n\n export function cannotStackNonLinearScale(scaleType: ScaleType) {\n return `Cannot stack non-linear scale (${scaleType})`;\n }\n\n export function stackNonSummativeAggregate(aggregate: string) {\n return `Stacking is applied even though the aggregate function is non-summative (\"${aggregate}\")`;\n }\n\n // TIMEUNIT\n export function invalidTimeUnit(unitName: string, value: string | number) {\n return `Invalid ${unitName}: ${stringify(value)}`;\n }\n\n export function dayReplacedWithDate(fullTimeUnit: string) {\n return `Time unit \"${fullTimeUnit}\" is not supported. We are replacing it with ${\n fullTimeUnit.replace('day', 'date')}.`;\n }\n\n export function droppedDay(d: DateTime | DateTimeExpr) {\n return `Dropping day from datetime ${stringify(d)} as day cannot be combined with other units.`;\n }\n}\n\n"]} \ No newline at end of file diff --git a/build/src/logical.d.ts b/build/src/logical.d.ts new file mode 100644 index 0000000000..8abc152b3b --- /dev/null +++ b/build/src/logical.d.ts @@ -0,0 +1,15 @@ +export declare type LogicalOperand = LogicalNot | LogicalAnd | LogicalOr | T; +export interface LogicalOr { + or: LogicalOperand[]; +} +export interface LogicalAnd { + and: LogicalOperand[]; +} +export interface LogicalNot { + not: LogicalOperand; +} +export declare function isLogicalOr(op: LogicalOperand): op is LogicalOr; +export declare function isLogicalAnd(op: LogicalOperand): op is LogicalAnd; +export declare function isLogicalNot(op: LogicalOperand): op is LogicalNot; +export declare function forEachLeaf(op: LogicalOperand, fn: (op: T) => void): void; +export declare function normalizeLogicalOperand(op: LogicalOperand, normalizer: (o: T) => T): LogicalOperand; diff --git a/build/src/logical.js b/build/src/logical.js new file mode 100644 index 0000000000..b314c4afdb --- /dev/null +++ b/build/src/logical.js @@ -0,0 +1,44 @@ +export function isLogicalOr(op) { + return !!op.or; +} +export function isLogicalAnd(op) { + return !!op.and; +} +export function isLogicalNot(op) { + return !!op.not; +} +export function forEachLeaf(op, fn) { + if (isLogicalNot(op)) { + forEachLeaf(op.not, fn); + } + else if (isLogicalAnd(op)) { + for (var _i = 0, _a = op.and; _i < _a.length; _i++) { + var subop = _a[_i]; + forEachLeaf(subop, fn); + } + } + else if (isLogicalOr(op)) { + for (var _b = 0, _c = op.or; _b < _c.length; _b++) { + var subop = _c[_b]; + forEachLeaf(subop, fn); + } + } + else { + fn(op); + } +} +export function normalizeLogicalOperand(op, normalizer) { + if (isLogicalNot(op)) { + return { not: normalizeLogicalOperand(op.not, normalizer) }; + } + else if (isLogicalAnd(op)) { + return { and: op.and.map(function (o) { return normalizeLogicalOperand(o, normalizer); }) }; + } + else if (isLogicalOr(op)) { + return { or: op.or.map(function (o) { return normalizeLogicalOperand(o, normalizer); }) }; + } + else { + return normalizer(op); + } +} +//# sourceMappingURL=logical.js.map \ No newline at end of file diff --git a/build/src/logical.js.map b/build/src/logical.js.map new file mode 100644 index 0000000000..1dafb7b0ee --- /dev/null +++ b/build/src/logical.js.map @@ -0,0 +1 @@ +{"version":3,"file":"logical.js","sourceRoot":"","sources":["../../src/logical.ts"],"names":[],"mappings":"AAcA,MAAM,sBAAsB,EAAuB;IACjD,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACjB,CAAC;AAED,MAAM,uBAAuB,EAAuB;IAClD,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC;AAClB,CAAC;AAED,MAAM,uBAAuB,EAAuB;IAClD,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC;AAClB,CAAC;AAED,MAAM,sBAAyB,EAAqB,EAAE,EAAmB;IACvE,IAAI,YAAY,CAAC,EAAE,CAAC,EAAE;QACpB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;KACzB;SAAM,IAAI,YAAY,CAAC,EAAE,CAAC,EAAE;QAC3B,KAAoB,UAAM,EAAN,KAAA,EAAE,CAAC,GAAG,EAAN,cAAM,EAAN,IAAM,EAAE;YAAvB,IAAM,KAAK,SAAA;YACd,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;SACxB;KACF;SAAM,IAAI,WAAW,CAAC,EAAE,CAAC,EAAE;QAC1B,KAAoB,UAAK,EAAL,KAAA,EAAE,CAAC,EAAE,EAAL,cAAK,EAAL,IAAK,EAAE;YAAtB,IAAM,KAAK,SAAA;YACd,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;SACxB;KACF;SAAM;QACL,EAAE,CAAC,EAAE,CAAC,CAAC;KACR;AACH,CAAC;AAED,MAAM,kCAAqC,EAAqB,EAAE,UAAuB;IACvF,IAAI,YAAY,CAAC,EAAE,CAAC,EAAE;QACpB,OAAO,EAAC,GAAG,EAAE,uBAAuB,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,CAAC,EAAC,CAAC;KAC3D;SAAM,IAAI,YAAY,CAAC,EAAE,CAAC,EAAE;QAC3B,OAAO,EAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,uBAAuB,CAAC,CAAC,EAAE,UAAU,CAAC,EAAtC,CAAsC,CAAC,EAAC,CAAC;KACvE;SAAM,IAAI,WAAW,CAAC,EAAE,CAAC,EAAE;QAC1B,OAAO,EAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,uBAAuB,CAAC,CAAC,EAAE,UAAU,CAAC,EAAtC,CAAsC,CAAC,EAAC,CAAC;KACrE;SAAM;QACL,OAAO,UAAU,CAAC,EAAE,CAAC,CAAC;KACvB;AACH,CAAC","sourcesContent":["export type LogicalOperand = LogicalNot | LogicalAnd | LogicalOr | T;\n\nexport interface LogicalOr {\n or: LogicalOperand[];\n}\n\nexport interface LogicalAnd {\n and: LogicalOperand[];\n}\n\nexport interface LogicalNot {\n not: LogicalOperand;\n}\n\nexport function isLogicalOr(op: LogicalOperand): op is LogicalOr {\n return !!op.or;\n}\n\nexport function isLogicalAnd(op: LogicalOperand): op is LogicalAnd {\n return !!op.and;\n}\n\nexport function isLogicalNot(op: LogicalOperand): op is LogicalNot {\n return !!op.not;\n}\n\nexport function forEachLeaf(op: LogicalOperand, fn: (op: T) => void) {\n if (isLogicalNot(op)) {\n forEachLeaf(op.not, fn);\n } else if (isLogicalAnd(op)) {\n for (const subop of op.and) {\n forEachLeaf(subop, fn);\n }\n } else if (isLogicalOr(op)) {\n for (const subop of op.or) {\n forEachLeaf(subop, fn);\n }\n } else {\n fn(op);\n }\n}\n\nexport function normalizeLogicalOperand(op: LogicalOperand, normalizer: (o: T) => T): LogicalOperand {\n if (isLogicalNot(op)) {\n return {not: normalizeLogicalOperand(op.not, normalizer)};\n } else if (isLogicalAnd(op)) {\n return {and: op.and.map(o => normalizeLogicalOperand(o, normalizer))};\n } else if (isLogicalOr(op)) {\n return {or: op.or.map(o => normalizeLogicalOperand(o, normalizer))};\n } else {\n return normalizer(op);\n }\n}\n"]} \ No newline at end of file diff --git a/build/src/mark.d.ts b/build/src/mark.d.ts new file mode 100644 index 0000000000..674a7b8e29 --- /dev/null +++ b/build/src/mark.d.ts @@ -0,0 +1,218 @@ +import { CompositeMark, CompositeMarkDef } from './compositemark/index'; +import { VgMarkConfig } from './vega.schema'; +export declare namespace Mark { + const AREA: 'area'; + const BAR: 'bar'; + const LINE: 'line'; + const POINT: 'point'; + const RECT: 'rect'; + const RULE: 'rule'; + const TEXT: 'text'; + const TICK: 'tick'; + const TRAIL: 'trail'; + const CIRCLE: 'circle'; + const SQUARE: 'square'; + const GEOSHAPE: 'geoshape'; +} +/** + * All types of primitive marks. + */ +export declare type Mark = typeof Mark.AREA | typeof Mark.BAR | typeof Mark.LINE | typeof Mark.TRAIL | typeof Mark.POINT | typeof Mark.TEXT | typeof Mark.TICK | typeof Mark.RECT | typeof Mark.RULE | typeof Mark.CIRCLE | typeof Mark.SQUARE | typeof Mark.GEOSHAPE; +export declare const AREA: "area"; +export declare const BAR: "bar"; +export declare const LINE: "line"; +export declare const POINT: "point"; +export declare const TEXT: "text"; +export declare const TICK: "tick"; +export declare const TRAIL: "trail"; +export declare const RECT: "rect"; +export declare const RULE: "rule"; +export declare const GEOSHAPE: "geoshape"; +export declare const CIRCLE: "circle"; +export declare const SQUARE: "square"; +export declare function isMark(m: string): m is Mark; +export declare function isPathMark(m: Mark | CompositeMark): m is 'line' | 'area' | 'trail'; +export declare const PRIMITIVE_MARKS: Mark[]; +export interface MarkConfig extends VgMarkConfig { + /** + * Whether the mark's color should be used as fill color instead of stroke color. + * + * __Default value:__ `true` for all marks except `point` and `false` for `point`. + * + * __Applicable for:__ `bar`, `point`, `circle`, `square`, and `area` marks. + * + * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config). + * + */ + filled?: boolean; + /** + * Default color. Note that `fill` and `stroke` have higher precedence than `color` and will override `color`. + * + * __Default value:__ `"#4682b4"` + * + * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config). + */ + color?: string; +} +export interface BarBinSpacingMixins { + /** + * Offset between bars for binned field. Ideal value for this is either 0 (Preferred by statisticians) or 1 (Vega-Lite Default, D3 example style). + * + * __Default value:__ `1` + * + * @minimum 0 + */ + binSpacing?: number; +} +/** @hide */ +export declare type HiddenComposite = CompositeMark | CompositeMarkDef; +export declare type AnyMark = HiddenComposite | Mark | MarkDef; +export declare function isMarkDef(mark: AnyMark): mark is (MarkDef | CompositeMarkDef); +export declare function isPrimitiveMark(mark: CompositeMark | CompositeMarkDef | Mark | MarkDef): mark is Mark; +export declare const STROKE_CONFIG: string[]; +export declare const FILL_CONFIG: string[]; +export declare const FILL_STROKE_CONFIG: any[]; +export declare const VL_ONLY_MARK_CONFIG_PROPERTIES: (keyof MarkConfig)[]; +export declare const VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX: { + [k in (typeof PRIMITIVE_MARKS[0])]?: (keyof MarkConfigMixins[k])[]; +}; +export declare const defaultMarkConfig: MarkConfig; +export interface MarkConfigMixins { + /** Mark Config */ + mark?: MarkConfig; + /** Area-Specific Config */ + area?: AreaConfig; + /** Bar-Specific Config */ + bar?: BarConfig; + /** Circle-Specific Config */ + circle?: MarkConfig; + /** Line-Specific Config */ + line?: LineConfig; + /** Point-Specific Config */ + point?: MarkConfig; + /** Rect-Specific Config */ + rect?: MarkConfig; + /** Rule-Specific Config */ + rule?: MarkConfig; + /** Square-Specific Config */ + square?: MarkConfig; + /** Text-Specific Config */ + text?: TextConfig; + /** Tick-Specific Config */ + tick?: TickConfig; + /** Trail-Specific Config */ + trail?: LineConfig; + /** Geoshape-Specific Config */ + geoshape?: MarkConfig; +} +export interface BarConfig extends BarBinSpacingMixins, MarkConfig { + /** + * The default size of the bars on continuous scales. + * + * __Default value:__ `5` + * + * @minimum 0 + */ + continuousBandSize?: number; + /** + * The size of the bars. If unspecified, the default size is `bandSize-1`, + * which provides 1 pixel offset between bars. + * @minimum 0 + */ + discreteBandSize?: number; +} +export declare type OverlayMarkDef = MarkConfig & MarkDefMixins; +export interface PointOverlayMixins { + /** + * A flag for overlaying points on top of line or area marks, or an object defining the properties of the overlayed points. + * + * - If this property is `"transparent"`, transparent points will be used (for enhancing tooltips and selections). + * + * - If this property is an empty object (`{}`) or `true`, filled points with default properties will be used. + * + * - If this property is `false`, no points would be automatically added to line or area marks. + * + * __Default value:__ `false`. + */ + point?: boolean | OverlayMarkDef | 'transparent'; +} +export interface LineConfig extends MarkConfig, PointOverlayMixins { +} +export interface LineOverlayMixins { + /** + * A flag for overlaying line on top of area marks, or an object defining the properties of the overlayed lines. + * + * - If this value is an empty object (`{}`) or `true`, lines with default properties will be used. + * + * - If this value is `false`, no lines would be automatically added to area marks. + * + * __Default value:__ `false`. + */ + line?: boolean | OverlayMarkDef; +} +export interface AreaConfig extends MarkConfig, PointOverlayMixins, LineOverlayMixins { +} +export interface TickThicknessMixins { + /** + * Thickness of the tick mark. + * + * __Default value:__ `1` + * + * @minimum 0 + */ + thickness?: number; +} +export interface MarkDefMixins { + /** + * A string or array of strings indicating the name of custom styles to apply to the mark. A style is a named collection of mark property defaults defined within the [style configuration](https://vega.github.io/vega-lite/docs/mark.html#style-config). If style is an array, later styles will override earlier styles. Any [mark properties](https://vega.github.io/vega-lite/docs/encoding.html#mark-prop) explicitly defined within the `encoding` will override a style default. + * + * __Default value:__ The mark's name. For example, a bar mark will have style `"bar"` by default. + * __Note:__ Any specified style will augment the default style. For example, a bar mark with `"style": "foo"` will receive from `config.style.bar` and `config.style.foo` (the specified style `"foo"` has higher precedence). + */ + style?: string | string[]; + /** + * Whether a mark be clipped to the enclosing group’s width and height. + */ + clip?: boolean; + /** + * Offset for x-position. + */ + xOffset?: number; + /** + * Offset for y-position. + */ + yOffset?: number; + /** + * Offset for x2-position. + */ + x2Offset?: number; + /** + * Offset for y2-position. + */ + y2Offset?: number; +} +export interface MarkDef extends BarBinSpacingMixins, MarkConfig, PointOverlayMixins, LineOverlayMixins, TickThicknessMixins, MarkDefMixins { + /** + * The mark type. + * One of `"bar"`, `"circle"`, `"square"`, `"tick"`, `"line"`, + * `"area"`, `"point"`, `"geoshape"`, `"rule"`, and `"text"`. + */ + type: Mark; +} +export declare const defaultBarConfig: BarConfig; +export interface TextConfig extends MarkConfig { + /** + * Whether month names and weekday names should be abbreviated. + */ + shortTimeLabels?: boolean; +} +export interface TickConfig extends MarkConfig, TickThicknessMixins { + /** + * The width of the ticks. + * + * __Default value:__ 2/3 of rangeStep. + * @minimum 0 + */ + bandSize?: number; +} +export declare const defaultTickConfig: TickConfig; diff --git a/build/src/mark.js b/build/src/mark.js new file mode 100644 index 0000000000..61f2ba8dba --- /dev/null +++ b/build/src/mark.js @@ -0,0 +1,82 @@ +import { toSet } from 'vega-util'; +import { contains, flagKeys } from './util'; +export var Mark; +(function (Mark) { + Mark.AREA = 'area'; + Mark.BAR = 'bar'; + Mark.LINE = 'line'; + Mark.POINT = 'point'; + Mark.RECT = 'rect'; + Mark.RULE = 'rule'; + Mark.TEXT = 'text'; + Mark.TICK = 'tick'; + Mark.TRAIL = 'trail'; + Mark.CIRCLE = 'circle'; + Mark.SQUARE = 'square'; + Mark.GEOSHAPE = 'geoshape'; +})(Mark || (Mark = {})); +export var AREA = Mark.AREA; +export var BAR = Mark.BAR; +export var LINE = Mark.LINE; +export var POINT = Mark.POINT; +export var TEXT = Mark.TEXT; +export var TICK = Mark.TICK; +export var TRAIL = Mark.TRAIL; +export var RECT = Mark.RECT; +export var RULE = Mark.RULE; +export var GEOSHAPE = Mark.GEOSHAPE; +export var CIRCLE = Mark.CIRCLE; +export var SQUARE = Mark.SQUARE; +// Using mapped type to declare index, ensuring we always have all marks when we add more. +var MARK_INDEX = { + area: 1, + bar: 1, + line: 1, + point: 1, + text: 1, + tick: 1, + trail: 1, + rect: 1, + geoshape: 1, + rule: 1, + circle: 1, + square: 1 +}; +export function isMark(m) { + return !!MARK_INDEX[m]; +} +export function isPathMark(m) { + return contains(['line', 'area', 'trail'], m); +} +export var PRIMITIVE_MARKS = flagKeys(MARK_INDEX); +export function isMarkDef(mark) { + return mark['type']; +} +var PRIMITIVE_MARK_INDEX = toSet(PRIMITIVE_MARKS); +export function isPrimitiveMark(mark) { + var markType = isMarkDef(mark) ? mark.type : mark; + return markType in PRIMITIVE_MARK_INDEX; +} +export var STROKE_CONFIG = ['stroke', 'strokeWidth', + 'strokeDash', 'strokeDashOffset', 'strokeOpacity', 'strokeJoin', 'strokeMiterLimit']; +export var FILL_CONFIG = ['fill', 'fillOpacity']; +export var FILL_STROKE_CONFIG = [].concat(STROKE_CONFIG, FILL_CONFIG); +export var VL_ONLY_MARK_CONFIG_PROPERTIES = ['filled', 'color']; +export var VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = { + area: ['line', 'point'], + bar: ['binSpacing', 'continuousBandSize', 'discreteBandSize'], + line: ['point'], + text: ['shortTimeLabels'], + tick: ['bandSize', 'thickness'] +}; +export var defaultMarkConfig = { + color: '#4c78a8', +}; +export var defaultBarConfig = { + binSpacing: 1, + continuousBandSize: 5 +}; +export var defaultTickConfig = { + thickness: 1 +}; +//# sourceMappingURL=mark.js.map \ No newline at end of file diff --git a/build/src/mark.js.map b/build/src/mark.js.map new file mode 100644 index 0000000000..21d95310f4 --- /dev/null +++ b/build/src/mark.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mark.js","sourceRoot":"","sources":["../../src/mark.ts"],"names":[],"mappings":"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","sourcesContent":["import {toSet} from 'vega-util';\nimport {CompositeMark, CompositeMarkDef} from './compositemark/index';\nimport {contains, flagKeys} from './util';\nimport {VgMarkConfig} from './vega.schema';\n\nexport namespace Mark {\n export const AREA: 'area' = 'area';\n export const BAR: 'bar' = 'bar';\n export const LINE: 'line' = 'line';\n export const POINT: 'point' = 'point';\n export const RECT: 'rect' = 'rect';\n export const RULE: 'rule' = 'rule';\n export const TEXT: 'text' = 'text';\n export const TICK: 'tick' = 'tick';\n export const TRAIL: 'trail' = 'trail';\n export const CIRCLE: 'circle' = 'circle';\n export const SQUARE: 'square' = 'square';\n export const GEOSHAPE: 'geoshape' = 'geoshape';\n}\n\n/**\n * All types of primitive marks.\n */\nexport type Mark = typeof Mark.AREA | typeof Mark.BAR | typeof Mark.LINE | typeof Mark.TRAIL | typeof Mark.POINT | typeof Mark.TEXT | typeof Mark.TICK | typeof Mark.RECT | typeof Mark.RULE | typeof Mark.CIRCLE | typeof Mark.SQUARE | typeof Mark.GEOSHAPE;\n\n\nexport const AREA = Mark.AREA;\nexport const BAR = Mark.BAR;\nexport const LINE = Mark.LINE;\nexport const POINT = Mark.POINT;\nexport const TEXT = Mark.TEXT;\nexport const TICK = Mark.TICK;\nexport const TRAIL = Mark.TRAIL;\nexport const RECT = Mark.RECT;\nexport const RULE = Mark.RULE;\nexport const GEOSHAPE = Mark.GEOSHAPE;\n\nexport const CIRCLE = Mark.CIRCLE;\nexport const SQUARE = Mark.SQUARE;\n\n// Using mapped type to declare index, ensuring we always have all marks when we add more.\nconst MARK_INDEX: {[M in Mark]: 1} = {\n area: 1,\n bar: 1,\n line: 1,\n point: 1,\n text: 1,\n tick: 1,\n trail: 1,\n rect: 1,\n geoshape: 1,\n rule: 1,\n circle: 1,\n square: 1\n};\n\nexport function isMark(m: string): m is Mark {\n return !!MARK_INDEX[m];\n}\n\nexport function isPathMark(m: Mark | CompositeMark): m is 'line' | 'area' | 'trail' {\n return contains(['line', 'area', 'trail'], m);\n}\n\nexport const PRIMITIVE_MARKS = flagKeys(MARK_INDEX);\n\n\nexport interface MarkConfig extends VgMarkConfig {\n // ---------- Color ----------\n /**\n * Whether the mark's color should be used as fill color instead of stroke color.\n *\n * __Default value:__ `true` for all marks except `point` and `false` for `point`.\n *\n * __Applicable for:__ `bar`, `point`, `circle`, `square`, and `area` marks.\n *\n * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n *\n */\n filled?: boolean;\n\n /**\n * Default color. Note that `fill` and `stroke` have higher precedence than `color` and will override `color`.\n *\n * __Default value:__ `\"#4682b4\"`\n *\n * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n */\n color?: string;\n}\n\nexport interface BarBinSpacingMixins {\n /**\n * Offset between bars for binned field. Ideal value for this is either 0 (Preferred by statisticians) or 1 (Vega-Lite Default, D3 example style).\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n binSpacing?: number;\n}\n\n\n/** @hide */\nexport type HiddenComposite = CompositeMark | CompositeMarkDef;\n\nexport type AnyMark =\n HiddenComposite |\n Mark |\n MarkDef;\n\nexport function isMarkDef(mark: AnyMark): mark is (MarkDef | CompositeMarkDef) {\n return mark['type'];\n}\n\nconst PRIMITIVE_MARK_INDEX = toSet(PRIMITIVE_MARKS);\n\nexport function isPrimitiveMark(mark: CompositeMark | CompositeMarkDef | Mark | MarkDef): mark is Mark {\n const markType = isMarkDef(mark) ? mark.type : mark;\n return markType in PRIMITIVE_MARK_INDEX;\n}\n\nexport const STROKE_CONFIG = ['stroke', 'strokeWidth',\n 'strokeDash', 'strokeDashOffset', 'strokeOpacity', 'strokeJoin', 'strokeMiterLimit'];\n\nexport const FILL_CONFIG = ['fill', 'fillOpacity'];\n\nexport const FILL_STROKE_CONFIG = [].concat(STROKE_CONFIG, FILL_CONFIG);\n\nexport const VL_ONLY_MARK_CONFIG_PROPERTIES: (keyof MarkConfig)[] = ['filled', 'color'];\n\nexport const VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX: {\n [k in (typeof PRIMITIVE_MARKS[0])]?: (keyof MarkConfigMixins[k])[]\n} = {\n area: ['line', 'point'],\n bar: ['binSpacing', 'continuousBandSize', 'discreteBandSize'],\n line: ['point'],\n text: ['shortTimeLabels'],\n tick: ['bandSize', 'thickness']\n};\n\nexport const defaultMarkConfig: MarkConfig = {\n color: '#4c78a8',\n};\n\nexport interface MarkConfigMixins {\n /** Mark Config */\n mark?: MarkConfig;\n\n // MARK-SPECIFIC CONFIGS\n /** Area-Specific Config */\n area?: AreaConfig;\n\n /** Bar-Specific Config */\n bar?: BarConfig;\n\n /** Circle-Specific Config */\n circle?: MarkConfig;\n\n /** Line-Specific Config */\n line?: LineConfig;\n\n /** Point-Specific Config */\n point?: MarkConfig;\n\n /** Rect-Specific Config */\n rect?: MarkConfig;\n\n /** Rule-Specific Config */\n rule?: MarkConfig;\n\n /** Square-Specific Config */\n square?: MarkConfig;\n\n /** Text-Specific Config */\n text?: TextConfig;\n\n /** Tick-Specific Config */\n tick?: TickConfig;\n\n /** Trail-Specific Config */\n trail?: LineConfig;\n\n /** Geoshape-Specific Config */\n geoshape?: MarkConfig;\n}\n\n\nexport interface BarConfig extends BarBinSpacingMixins, MarkConfig {\n\n /**\n * The default size of the bars on continuous scales.\n *\n * __Default value:__ `5`\n *\n * @minimum 0\n */\n continuousBandSize?: number;\n\n /**\n * The size of the bars. If unspecified, the default size is `bandSize-1`,\n * which provides 1 pixel offset between bars.\n * @minimum 0\n */\n discreteBandSize?: number;\n}\n\nexport type OverlayMarkDef = MarkConfig & MarkDefMixins;\n\nexport interface PointOverlayMixins {\n /**\n * A flag for overlaying points on top of line or area marks, or an object defining the properties of the overlayed points.\n *\n * - If this property is `\"transparent\"`, transparent points will be used (for enhancing tooltips and selections).\n *\n * - If this property is an empty object (`{}`) or `true`, filled points with default properties will be used.\n *\n * - If this property is `false`, no points would be automatically added to line or area marks.\n *\n * __Default value:__ `false`.\n */\n point?: boolean | OverlayMarkDef | 'transparent';\n}\n\nexport interface LineConfig extends MarkConfig, PointOverlayMixins {}\n\nexport interface LineOverlayMixins {\n /**\n * A flag for overlaying line on top of area marks, or an object defining the properties of the overlayed lines.\n *\n * - If this value is an empty object (`{}`) or `true`, lines with default properties will be used.\n *\n * - If this value is `false`, no lines would be automatically added to area marks.\n *\n * __Default value:__ `false`.\n */\n line?: boolean | OverlayMarkDef;\n}\n\nexport interface AreaConfig extends MarkConfig, PointOverlayMixins, LineOverlayMixins {}\n\nexport interface TickThicknessMixins {\n /**\n * Thickness of the tick mark.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n thickness?: number;\n}\n\nexport interface MarkDefMixins {\n /**\n * A string or array of strings indicating the name of custom styles to apply to the mark. A style is a named collection of mark property defaults defined within the [style configuration](https://vega.github.io/vega-lite/docs/mark.html#style-config). If style is an array, later styles will override earlier styles. Any [mark properties](https://vega.github.io/vega-lite/docs/encoding.html#mark-prop) explicitly defined within the `encoding` will override a style default.\n *\n * __Default value:__ The mark's name. For example, a bar mark will have style `\"bar\"` by default.\n * __Note:__ Any specified style will augment the default style. For example, a bar mark with `\"style\": \"foo\"` will receive from `config.style.bar` and `config.style.foo` (the specified style `\"foo\"` has higher precedence).\n */\n style?: string | string[];\n\n /**\n * Whether a mark be clipped to the enclosing group’s width and height.\n */\n clip?: boolean;\n\n // Offset properties should not be a part of config\n\n /**\n * Offset for x-position.\n */\n xOffset?: number;\n\n /**\n * Offset for y-position.\n */\n yOffset?: number;\n\n /**\n * Offset for x2-position.\n */\n x2Offset?: number;\n\n /**\n * Offset for y2-position.\n */\n y2Offset?: number;\n}\n\n// Point/Line OverlayMixins are only for area, line, and trail but we don't want to declare multiple types of MarkDef\nexport interface MarkDef extends BarBinSpacingMixins, MarkConfig, PointOverlayMixins, LineOverlayMixins, TickThicknessMixins, MarkDefMixins {\n /**\n * The mark type.\n * One of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"geoshape\"`, `\"rule\"`, and `\"text\"`.\n */\n type: Mark;\n}\n\nexport const defaultBarConfig: BarConfig = {\n binSpacing: 1,\n continuousBandSize: 5\n};\n\nexport interface TextConfig extends MarkConfig {\n /**\n * Whether month names and weekday names should be abbreviated.\n */\n shortTimeLabels?: boolean;\n}\n\nexport interface TickConfig extends MarkConfig, TickThicknessMixins {\n /**\n * The width of the ticks.\n *\n * __Default value:__ 2/3 of rangeStep.\n * @minimum 0\n */\n bandSize?: number;\n}\n\nexport const defaultTickConfig: TickConfig = {\n thickness: 1\n};\n"]} \ No newline at end of file diff --git a/build/src/package.json b/build/src/package.json new file mode 100644 index 0000000000..f295b19320 --- /dev/null +++ b/build/src/package.json @@ -0,0 +1,141 @@ +{ + "name": "vega-lite", + "author": "Jeffrey Heer, Dominik Moritz, Kanit \"Ham\" Wongsuphasawat", + "version": "2.5.1", + "collaborators": [ + "Kanit Wongsuphasawat (http://kanitw.yellowpigz.com)", + "Dominik Moritz (https://www.domoritz.de)", + "Jeffrey Heer (http://jheer.org)" + ], + "homepage": "https://vega.github.io/vega-lite/", + "description": "Vega-Lite is a concise high-level language for interactive visualization.", + "main": "build/vega-lite.js", + "unpkg": "build/vega-lite.min.js", + "jsdelivr": "build/vega-lite.min.js", + "module": "build/src/index", + "types": "build/src/index.d.ts", + "bin": { + "vl2png": "./bin/vl2png", + "vl2svg": "./bin/vl2svg", + "vl2vg": "./bin/vl2vg" + }, + "directories": { + "test": "test" + }, + "scripts": { + "prebuild": "mkdir -p build/src", + "build": "npm run build:only", + "build:only": "tsc && cp package.json build/src/ && rollup -c", + "postbuild": "uglifyjs build/vega-lite.js -cm --source-map content=build/vega-lite.js.map,filename=build/vega-lite.min.js.map -o build/vega-lite.min.js && npm run schema", + "build:examples": "npm run data && TZ=America/Los_Angeles scripts/build-examples.sh", + "build:examples-full": "TZ=America/Los_Angeles scripts/build-examples.sh 1", + "build:example": "TZ=America/Los_Angeles scripts/build-example.sh", + "build:toc": "bundle exec jekyll build -q && scripts/generate-toc", + "build:site": "tsc -p site && webpack --config site/webpack.config.js", + "build:versions": "scripts/update-version.sh", + "check:examples": "scripts/check-examples.sh", + "check:schema": "scripts/check-schema.sh", + "clean": "rm -rf build && rm -f examples/compiled/*.png && find site/examples ! -name 'index.md' -type f -delete", + "data": "rsync -r node_modules/vega-datasets/data/* data", + "deploy": "scripts/deploy.sh", + "deploy:gh": "scripts/deploy-gh.sh", + "deploy:schema": "scripts/deploy-schema.sh", + "preschema": "npm run prebuild", + "schema": "node --stack-size=1200 ./node_modules/.bin/ts-json-schema-generator --path tsconfig.json --type TopLevelSpec > build/vega-lite-schema.json && npm run renameschema && cp build/vega-lite-schema.json _data/", + "renameschema": "scripts/rename-schema.sh", + "presite": "npm run prebuild && npm run data && npm run build:site && npm run build:toc && npm run build:versions && scripts/create-example-pages", + "site": "bundle exec jekyll serve --incremental", + "lint": "tslint -p .", + "test": "jest test/ && npm run lint && npm run schema && jest examples/ && npm run test:runtime", + "test:inspect": "node --inspect-brk ./node_modules/.bin/jest --runInBand test", + "test:runtime": "TZ=America/Los_Angeles TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' wdio wdio.conf.js", + "test:runtime:generate": "rm -Rf test-runtime/resources && VL_GENERATE_TESTS=true npm run test:runtime", + "watch:build": "npm run build:only && concurrently --kill-others -n Typescript,Rollup 'tsc -w' 'rollup -c -w'", + "watch:site": "concurrently --kill-others -n Typescript,Webpack 'tsc -p site --watch' 'webpack --config site/webpack.config.js --mode development --watch'", + "watch:test": "jest --watch" + }, + "repository": { + "type": "git", + "url": "https://github.com/vega/vega-lite.git" + }, + "license": "BSD-3-Clause", + "bugs": { + "url": "https://github.com/vega/vega-lite/issues" + }, + "devDependencies": { + "@types/chai": "^4.1.3", + "@types/d3": "^5.0.0", + "@types/highlight.js": "^9.12.3", + "@types/jest": "^22.2.3", + "@types/mkdirp": "^0.5.2", + "@types/node": "^9.0.0", + "@types/webdriverio": "^4.10.2", + "ajv": "^6.5.0", + "chai": "^4.1.2", + "cheerio": "^1.0.0-rc.2", + "chromedriver": "^2.38.3", + "codecov": "^3.0.2", + "concurrently": "^3.5.1", + "d3": "^5.4.0", + "highlight.js": "^9.12.0", + "jest": "^23.1.0", + "mkdirp": "^0.5.1", + "rollup": "^0.59.4", + "rollup-plugin-commonjs": "^9.1.3", + "rollup-plugin-json": "^3.0.0", + "rollup-plugin-node-resolve": "^3.3.0", + "source-map-support": "^0.5.6", + "svg2png-many": "^0.0.7", + "ts-jest": "^22.4.6", + "ts-json-schema-generator": "^0.26.0", + "ts-node": "^6.0.5", + "tslint": "5.10.0", + "tslint-eslint-rules": "^5.3.1", + "typescript": "^2.9.1", + "uglify-js": "^3.3.28", + "vega": "^4.0.0-rc.2", + "vega-datasets": "^1.19.0", + "vega-embed": "^3.14.0", + "vega-tooltip": "^0.11.0", + "wdio-chromedriver-service": "^0.1.3", + "wdio-dot-reporter": "0.0.9", + "wdio-mocha-framework": "^0.5.13", + "wdio-static-server-service": "^1.0.1", + "webdriverio": "^4.12.0", + "webpack": "^4.10.2", + "webpack-cli": "^2.1.4", + "yaml-front-matter": "^4.0.0" + }, + "dependencies": { + "@types/json-stable-stringify": "^1.0.32", + "json-stable-stringify": "^1.0.1", + "tslib": "^1.9.2", + "vega-event-selector": "^2.0.0", + "vega-typings": "^0.3.4", + "vega-util": "^1.7.0", + "yargs": "^11.0.0" + }, + "jest": { + "transform": { + "^.+\\.tsx?$": "ts-jest" + }, + "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", + "moduleFileExtensions": [ + "ts", + "tsx", + "js", + "jsx", + "json", + "node" + ], + "testPathIgnorePatterns": [ + "node_modules", + "test-runtime", + "/build", + "_site", + "src" + ], + "coverageDirectory": "./coverage/", + "collectCoverage": false + } +} diff --git a/build/src/predicate.d.ts b/build/src/predicate.d.ts new file mode 100644 index 0000000000..1caa41ac00 --- /dev/null +++ b/build/src/predicate.d.ts @@ -0,0 +1,84 @@ +import { DataFlowNode } from './compile/data/dataflow'; +import { Model } from './compile/model'; +import { DateTime } from './datetime'; +import { LogicalOperand } from './logical'; +import { TimeUnit } from './timeunit'; +export declare type Predicate = FieldEqualPredicate | FieldRangePredicate | FieldOneOfPredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate | SelectionPredicate | string; +export declare type FieldPredicate = FieldEqualPredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate | FieldRangePredicate | FieldOneOfPredicate; +export interface SelectionPredicate { + /** + * Filter using a selection name. + */ + selection: LogicalOperand; +} +export declare function isSelectionPredicate(predicate: LogicalOperand): predicate is SelectionPredicate; +export interface FieldPredicateBase { + /** + * Time unit for the field to be filtered. + */ + timeUnit?: TimeUnit; + /** + * Field to be filtered. + */ + field: string; +} +export interface FieldEqualPredicate extends FieldPredicateBase { + /** + * The value that the field should be equal to. + */ + equal: string | number | boolean | DateTime; +} +export declare function isFieldEqualPredicate(predicate: any): predicate is FieldEqualPredicate; +export interface FieldLTPredicate extends FieldPredicateBase { + /** + * The value that the field should be less than. + */ + lt: string | number | DateTime; +} +export declare function isFieldLTPredicate(predicate: any): predicate is FieldLTPredicate; +export interface FieldLTEPredicate extends FieldPredicateBase { + /** + * The value that the field should be less than or equals to. + */ + lte: string | number | DateTime; +} +export declare function isFieldLTEPredicate(predicate: any): predicate is FieldLTEPredicate; +export interface FieldGTPredicate extends FieldPredicateBase { + /** + * The value that the field should be greater than. + */ + gt: string | number | DateTime; +} +export declare function isFieldGTPredicate(predicate: any): predicate is FieldGTPredicate; +export interface FieldGTEPredicate extends FieldPredicateBase { + /** + * The value that the field should be greater than or equals to. + */ + gte: string | number | DateTime; +} +export declare function isFieldGTEPredicate(predicate: any): predicate is FieldGTEPredicate; +export interface FieldRangePredicate extends FieldPredicateBase { + /** + * An array of inclusive minimum and maximum values + * for a field value of a data item to be included in the filtered data. + * @maxItems 2 + * @minItems 2 + */ + range: (number | DateTime | null)[]; +} +export declare function isFieldRangePredicate(predicate: any): predicate is FieldRangePredicate; +export interface FieldOneOfPredicate extends FieldPredicateBase { + /** + * A set of values that the `field`'s value should be a member of, + * for a data item included in the filtered data. + */ + oneOf: string[] | number[] | boolean[] | DateTime[]; +} +export declare function isFieldOneOfPredicate(predicate: any): predicate is FieldOneOfPredicate; +export declare function isFieldPredicate(predicate: Predicate): predicate is FieldOneOfPredicate | FieldEqualPredicate | FieldRangePredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate; +/** + * Converts a predicate into an expression. + */ +export declare function expression(model: Model, filterOp: LogicalOperand, node?: DataFlowNode): string; +export declare function fieldFilterExpression(predicate: FieldPredicate, useInRange?: boolean): string; +export declare function normalizePredicate(f: Predicate): Predicate; diff --git a/build/src/predicate.js b/build/src/predicate.js new file mode 100644 index 0000000000..3af789519c --- /dev/null +++ b/build/src/predicate.js @@ -0,0 +1,127 @@ +import * as tslib_1 from "tslib"; +import { isArray, isString } from 'vega-util'; +import { selectionPredicate } from './compile/selection/selection'; +import { valueExpr, vgField } from './fielddef'; +import { fieldExpr as timeUnitFieldExpr, normalizeTimeUnit } from './timeunit'; +import { logicalExpr } from './util'; +export function isSelectionPredicate(predicate) { + return predicate && predicate['selection']; +} +export function isFieldEqualPredicate(predicate) { + return predicate && !!predicate.field && predicate.equal !== undefined; +} +export function isFieldLTPredicate(predicate) { + return predicate && !!predicate.field && predicate.lt !== undefined; +} +export function isFieldLTEPredicate(predicate) { + return predicate && !!predicate.field && predicate.lte !== undefined; +} +export function isFieldGTPredicate(predicate) { + return predicate && !!predicate.field && predicate.gt !== undefined; +} +export function isFieldGTEPredicate(predicate) { + return predicate && !!predicate.field && predicate.gte !== undefined; +} +export function isFieldRangePredicate(predicate) { + if (predicate && predicate.field) { + if (isArray(predicate.range) && predicate.range.length === 2) { + return true; + } + } + return false; +} +export function isFieldOneOfPredicate(predicate) { + return predicate && !!predicate.field && (isArray(predicate.oneOf) || + isArray(predicate.in) // backward compatibility + ); +} +export function isFieldPredicate(predicate) { + return isFieldOneOfPredicate(predicate) || isFieldEqualPredicate(predicate) || isFieldRangePredicate(predicate) || isFieldLTPredicate(predicate) || isFieldGTPredicate(predicate) || isFieldLTEPredicate(predicate) || isFieldGTEPredicate(predicate); +} +/** + * Converts a predicate into an expression. + */ +// model is only used for selection filters. +export function expression(model, filterOp, node) { + return logicalExpr(filterOp, function (predicate) { + if (isString(predicate)) { + return predicate; + } + else if (isSelectionPredicate(predicate)) { + return selectionPredicate(model, predicate.selection, node); + } + else { // Filter Object + return fieldFilterExpression(predicate); + } + }); +} +function predicateValueExpr(v, timeUnit) { + return valueExpr(v, { timeUnit: timeUnit, time: true }); +} +function predicateValuesExpr(vals, timeUnit) { + return vals.map(function (v) { return predicateValueExpr(v, timeUnit); }); +} +// This method is used by Voyager. Do not change its behavior without changing Voyager. +export function fieldFilterExpression(predicate, useInRange) { + if (useInRange === void 0) { useInRange = true; } + var field = predicate.field, timeUnit = predicate.timeUnit; + var fieldExpr = timeUnit ? + // For timeUnit, cast into integer with time() so we can use ===, inrange, indexOf to compare values directly. + // TODO: We calculate timeUnit on the fly here. Consider if we would like to consolidate this with timeUnit pipeline + // TODO: support utc + ('time(' + timeUnitFieldExpr(timeUnit, field) + ')') : + vgField(predicate, { expr: 'datum' }); + if (isFieldEqualPredicate(predicate)) { + return fieldExpr + '===' + predicateValueExpr(predicate.equal, timeUnit); + } + else if (isFieldLTPredicate(predicate)) { + var upper = predicate.lt; + return fieldExpr + "<" + predicateValueExpr(upper, timeUnit); + } + else if (isFieldGTPredicate(predicate)) { + var lower = predicate.gt; + return fieldExpr + ">" + predicateValueExpr(lower, timeUnit); + } + else if (isFieldLTEPredicate(predicate)) { + var upper = predicate.lte; + return fieldExpr + "<=" + predicateValueExpr(upper, timeUnit); + } + else if (isFieldGTEPredicate(predicate)) { + var lower = predicate.gte; + return fieldExpr + ">=" + predicateValueExpr(lower, timeUnit); + } + else if (isFieldOneOfPredicate(predicate)) { + // "oneOf" was formerly "in" -- so we need to add backward compatibility + var oneOf = predicate.oneOf; + oneOf = oneOf || predicate['in']; + return 'indexof([' + + predicateValuesExpr(oneOf, timeUnit).join(',') + + '], ' + fieldExpr + ') !== -1'; + } + else if (isFieldRangePredicate(predicate)) { + var lower = predicate.range[0]; + var upper = predicate.range[1]; + if (lower !== null && upper !== null && useInRange) { + return 'inrange(' + fieldExpr + ', [' + + predicateValueExpr(lower, timeUnit) + ', ' + + predicateValueExpr(upper, timeUnit) + '])'; + } + var exprs = []; + if (lower !== null) { + exprs.push(fieldExpr + " >= " + predicateValueExpr(lower, timeUnit)); + } + if (upper !== null) { + exprs.push(fieldExpr + " <= " + predicateValueExpr(upper, timeUnit)); + } + return exprs.length > 0 ? exprs.join(' && ') : 'true'; + } + /* istanbul ignore next: it should never reach here */ + throw new Error("Invalid field predicate: " + JSON.stringify(predicate)); +} +export function normalizePredicate(f) { + if (isFieldPredicate(f) && f.timeUnit) { + return tslib_1.__assign({}, f, { timeUnit: normalizeTimeUnit(f.timeUnit) }); + } + return f; +} +//# sourceMappingURL=predicate.js.map \ No newline at end of file diff --git a/build/src/predicate.js.map b/build/src/predicate.js.map new file mode 100644 index 0000000000..41a0700aa1 --- /dev/null +++ b/build/src/predicate.js.map @@ -0,0 +1 @@ +{"version":3,"file":"predicate.js","sourceRoot":"","sources":["../../src/predicate.ts"],"names":[],"mappings":"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","sourcesContent":["import {isArray, isString} from 'vega-util';\nimport {DataFlowNode} from './compile/data/dataflow';\nimport {Model} from './compile/model';\nimport {selectionPredicate} from './compile/selection/selection';\nimport {DateTime} from './datetime';\nimport {valueExpr, vgField} from './fielddef';\nimport {LogicalOperand} from './logical';\nimport {fieldExpr as timeUnitFieldExpr, normalizeTimeUnit, TimeUnit} from './timeunit';\nimport {logicalExpr} from './util';\n\nexport type Predicate =\n // a) FieldPredicate (but we don't type FieldFilter here so the schema has no nesting\n // and thus the documentation shows all of the types clearly)\n FieldEqualPredicate | FieldRangePredicate | FieldOneOfPredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate |\n // b) Selection Predicate\n SelectionPredicate |\n // c) Vega Expression string\n string;\n\n\n\nexport type FieldPredicate = FieldEqualPredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate |FieldRangePredicate | FieldOneOfPredicate;\n\nexport interface SelectionPredicate {\n /**\n * Filter using a selection name.\n */\n selection: LogicalOperand;\n}\n\nexport function isSelectionPredicate(predicate: LogicalOperand): predicate is SelectionPredicate {\n return predicate && predicate['selection'];\n}\n\nexport interface FieldPredicateBase {\n // TODO: support aggregate\n\n /**\n * Time unit for the field to be filtered.\n */\n timeUnit?: TimeUnit;\n\n /**\n * Field to be filtered.\n */\n field: string;\n}\n\nexport interface FieldEqualPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be equal to.\n */\n equal: string | number | boolean | DateTime;\n\n}\n\nexport function isFieldEqualPredicate(predicate: any): predicate is FieldEqualPredicate {\n return predicate && !!predicate.field && predicate.equal !== undefined;\n}\n\nexport interface FieldLTPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be less than.\n */\n lt: string | number | DateTime;\n\n}\n\nexport function isFieldLTPredicate(predicate: any): predicate is FieldLTPredicate {\n return predicate && !!predicate.field && predicate.lt !== undefined;\n}\n\n\nexport interface FieldLTEPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be less than or equals to.\n */\n lte: string | number | DateTime;\n\n}\n\nexport function isFieldLTEPredicate(predicate: any): predicate is FieldLTEPredicate {\n return predicate && !!predicate.field && predicate.lte !== undefined;\n}\n\n\nexport interface FieldGTPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be greater than.\n */\n gt: string | number | DateTime;\n\n}\n\nexport function isFieldGTPredicate(predicate: any): predicate is FieldGTPredicate {\n return predicate && !!predicate.field && predicate.gt !== undefined;\n}\n\nexport interface FieldGTEPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be greater than or equals to.\n */\n gte: string | number | DateTime;\n\n}\n\nexport function isFieldGTEPredicate(predicate: any): predicate is FieldGTEPredicate {\n return predicate && !!predicate.field && predicate.gte !== undefined;\n}\n\nexport interface FieldRangePredicate extends FieldPredicateBase {\n /**\n * An array of inclusive minimum and maximum values\n * for a field value of a data item to be included in the filtered data.\n * @maxItems 2\n * @minItems 2\n */\n range: (number|DateTime|null)[];\n}\n\nexport function isFieldRangePredicate(predicate: any): predicate is FieldRangePredicate {\n if (predicate && predicate.field) {\n if (isArray(predicate.range) && predicate.range.length === 2) {\n return true;\n }\n }\n return false;\n}\n\nexport interface FieldOneOfPredicate extends FieldPredicateBase {\n /**\n * A set of values that the `field`'s value should be a member of,\n * for a data item included in the filtered data.\n */\n oneOf: string[] | number[] | boolean[] | DateTime[];\n\n}\n\nexport function isFieldOneOfPredicate(predicate: any): predicate is FieldOneOfPredicate {\n return predicate && !!predicate.field && (\n isArray(predicate.oneOf) ||\n isArray(predicate.in) // backward compatibility\n );\n}\n\nexport function isFieldPredicate(predicate: Predicate): predicate is FieldOneOfPredicate | FieldEqualPredicate | FieldRangePredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate {\n return isFieldOneOfPredicate(predicate) || isFieldEqualPredicate(predicate) || isFieldRangePredicate(predicate) || isFieldLTPredicate(predicate) || isFieldGTPredicate(predicate) || isFieldLTEPredicate(predicate) || isFieldGTEPredicate(predicate);\n}\n\n/**\n * Converts a predicate into an expression.\n */\n// model is only used for selection filters.\nexport function expression(model: Model, filterOp: LogicalOperand, node?: DataFlowNode): string {\n return logicalExpr(filterOp, (predicate: Predicate) => {\n if (isString(predicate)) {\n return predicate;\n } else if (isSelectionPredicate(predicate)) {\n return selectionPredicate(model, predicate.selection, node);\n } else { // Filter Object\n return fieldFilterExpression(predicate);\n }\n });\n}\n\nfunction predicateValueExpr(v: number | string | boolean | DateTime, timeUnit: TimeUnit) {\n return valueExpr(v, {timeUnit, time: true});\n}\n\nfunction predicateValuesExpr(vals: (number|string | boolean | DateTime)[], timeUnit: TimeUnit) {\n return vals.map((v) => predicateValueExpr(v, timeUnit));\n}\n\n// This method is used by Voyager. Do not change its behavior without changing Voyager.\nexport function fieldFilterExpression(predicate: FieldPredicate, useInRange=true) {\n const {field, timeUnit} = predicate;\n const fieldExpr = timeUnit ?\n // For timeUnit, cast into integer with time() so we can use ===, inrange, indexOf to compare values directly.\n // TODO: We calculate timeUnit on the fly here. Consider if we would like to consolidate this with timeUnit pipeline\n // TODO: support utc\n ('time(' + timeUnitFieldExpr(timeUnit, field) + ')') :\n vgField(predicate, {expr: 'datum'});\n\n if (isFieldEqualPredicate(predicate)) {\n return fieldExpr + '===' + predicateValueExpr(predicate.equal, timeUnit);\n } else if (isFieldLTPredicate(predicate)) {\n const upper = predicate.lt;\n return `${fieldExpr}<${predicateValueExpr(upper, timeUnit)}`;\n } else if (isFieldGTPredicate(predicate)) {\n const lower = predicate.gt;\n return `${fieldExpr}>${predicateValueExpr(lower, timeUnit)}`;\n } else if (isFieldLTEPredicate(predicate)) {\n const upper = predicate.lte;\n return `${fieldExpr}<=${predicateValueExpr(upper, timeUnit)}`;\n } else if (isFieldGTEPredicate(predicate)) {\n const lower = predicate.gte;\n return `${fieldExpr}>=${predicateValueExpr(lower, timeUnit)}`;\n } else if (isFieldOneOfPredicate(predicate)) {\n // \"oneOf\" was formerly \"in\" -- so we need to add backward compatibility\n let oneOf = predicate.oneOf;\n oneOf = oneOf || predicate['in'];\n return 'indexof([' +\n predicateValuesExpr(oneOf, timeUnit).join(',') +\n '], ' + fieldExpr + ') !== -1';\n } else if (isFieldRangePredicate(predicate)) {\n const lower = predicate.range[0];\n const upper = predicate.range[1];\n\n if (lower !== null && upper !== null && useInRange) {\n return 'inrange(' + fieldExpr + ', [' +\n predicateValueExpr(lower, timeUnit) + ', ' +\n predicateValueExpr(upper, timeUnit) + '])';\n }\n\n const exprs = [];\n if (lower !== null) {\n exprs.push(`${fieldExpr} >= ${predicateValueExpr(lower, timeUnit)}`);\n }\n if (upper !== null) {\n exprs.push(`${fieldExpr} <= ${predicateValueExpr(upper, timeUnit)}`);\n }\n\n return exprs.length > 0 ? exprs.join(' && ') : 'true';\n }\n\n /* istanbul ignore next: it should never reach here */\n throw new Error(`Invalid field predicate: ${JSON.stringify(predicate)}`);\n}\n\nexport function normalizePredicate(f: Predicate): Predicate {\n if (isFieldPredicate(f) && f.timeUnit) {\n return {\n ...f,\n timeUnit: normalizeTimeUnit(f.timeUnit)\n };\n }\n return f;\n}\n"]} \ No newline at end of file diff --git a/build/src/projection.d.ts b/build/src/projection.d.ts new file mode 100644 index 0000000000..7d0a2b4b22 --- /dev/null +++ b/build/src/projection.d.ts @@ -0,0 +1,49 @@ +import { VgProjectionType } from './vega.schema'; +export declare type ProjectionType = VgProjectionType; +export interface Projection { + /** + * The cartographic projection to use. This value is case-insensitive, for example `"albers"` and `"Albers"` indicate the same projection type. You can find all valid projection types [in the documentation](https://vega.github.io/vega-lite/docs/projection.html#projection-types). + * + * __Default value:__ `mercator` + */ + type?: ProjectionType; + /** + * Sets the projection’s clipping circle radius to the specified angle in degrees. If `null`, switches to [antimeridian](http://bl.ocks.org/mbostock/3788999) cutting rather than small-circle clipping. + */ + clipAngle?: number; + /** + * Sets the projection’s viewport clip extent to the specified bounds in pixels. The extent bounds are specified as an array `[[x0, y0], [x1, y1]]`, where `x0` is the left-side of the viewport, `y0` is the top, `x1` is the right and `y1` is the bottom. If `null`, no viewport clipping is performed. + */ + clipExtent?: number[][]; + /** + * Sets the projection’s center to the specified center, a two-element array of longitude and latitude in degrees. + * + * __Default value:__ `[0, 0]` + */ + center?: number[]; + /** + * Sets the projection’s three-axis rotation to the specified angles, which must be a two- or three-element array of numbers [`lambda`, `phi`, `gamma`] specifying the rotation angles in degrees about each spherical axis. (These correspond to yaw, pitch and roll.) + * + * __Default value:__ `[0, 0, 0]` + */ + rotate?: number[]; + /** + * Sets the threshold for the projection’s [adaptive resampling](http://bl.ocks.org/mbostock/3795544) to the specified value in pixels. This value corresponds to the [Douglas–Peucker distance](http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm). If precision is not specified, returns the projection’s current resampling precision which defaults to `√0.5 ≅ 0.70710…`. + */ + precision?: String; + coefficient?: number; + distance?: number; + fraction?: number; + lobes?: number; + parallel?: number; + radius?: number; + ratio?: number; + spacing?: number; + tilt?: number; +} +/** + * Any property of Projection can be in config + */ +export interface ProjectionConfig extends Projection { +} +export declare const PROJECTION_PROPERTIES: (keyof Projection)[]; diff --git a/build/src/projection.js b/build/src/projection.js new file mode 100644 index 0000000000..cac15ea781 --- /dev/null +++ b/build/src/projection.js @@ -0,0 +1,18 @@ +export var PROJECTION_PROPERTIES = [ + 'type', + 'clipAngle', + 'clipExtent', + 'center', + 'rotate', + 'precision', + 'coefficient', + 'distance', + 'fraction', + 'lobes', + 'parallel', + 'radius', + 'ratio', + 'spacing', + 'tilt' +]; +//# sourceMappingURL=projection.js.map \ No newline at end of file diff --git a/build/src/projection.js.map b/build/src/projection.js.map new file mode 100644 index 0000000000..343e0a8d9d --- /dev/null +++ b/build/src/projection.js.map @@ -0,0 +1 @@ +{"version":3,"file":"projection.js","sourceRoot":"","sources":["../../src/projection.ts"],"names":[],"mappings":"AA2DA,MAAM,CAAC,IAAM,qBAAqB,GAAyB;IACzD,MAAM;IACN,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,QAAQ;IACR,WAAW;IACX,aAAa;IACb,UAAU;IACV,UAAU;IACV,OAAO;IACP,UAAU;IACV,QAAQ;IACR,OAAO;IACP,SAAS;IACT,MAAM;CACP,CAAC","sourcesContent":["\nimport {VgProjectionType} from './vega.schema';\n\nexport type ProjectionType = VgProjectionType;\n\nexport interface Projection {\n /**\n * The cartographic projection to use. This value is case-insensitive, for example `\"albers\"` and `\"Albers\"` indicate the same projection type. You can find all valid projection types [in the documentation](https://vega.github.io/vega-lite/docs/projection.html#projection-types).\n *\n * __Default value:__ `mercator`\n */\n type?: ProjectionType;\n\n /**\n * Sets the projection’s clipping circle radius to the specified angle in degrees. If `null`, switches to [antimeridian](http://bl.ocks.org/mbostock/3788999) cutting rather than small-circle clipping.\n */\n clipAngle?: number;\n\n /**\n * Sets the projection’s viewport clip extent to the specified bounds in pixels. The extent bounds are specified as an array `[[x0, y0], [x1, y1]]`, where `x0` is the left-side of the viewport, `y0` is the top, `x1` is the right and `y1` is the bottom. If `null`, no viewport clipping is performed.\n */\n clipExtent?: number[][];\n\n /**\n * Sets the projection’s center to the specified center, a two-element array of longitude and latitude in degrees.\n *\n * __Default value:__ `[0, 0]`\n */\n center?: number[];\n\n /**\n * Sets the projection’s three-axis rotation to the specified angles, which must be a two- or three-element array of numbers [`lambda`, `phi`, `gamma`] specifying the rotation angles in degrees about each spherical axis. (These correspond to yaw, pitch and roll.)\n *\n * __Default value:__ `[0, 0, 0]`\n */\n rotate?: number[];\n\n /**\n * Sets the threshold for the projection’s [adaptive resampling](http://bl.ocks.org/mbostock/3795544) to the specified value in pixels. This value corresponds to the [Douglas–Peucker distance](http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm). If precision is not specified, returns the projection’s current resampling precision which defaults to `√0.5 ≅ 0.70710…`.\n */\n precision?: String;\n\n /* The following properties are all supported for specific types of projections. Consult the d3-geo-projection library for more information: https://github.com/d3/d3-geo-projection */\n coefficient?: number;\n distance?: number;\n fraction?: number;\n lobes?: number;\n parallel?: number;\n radius?: number;\n ratio?: number;\n spacing?: number;\n tilt?: number;\n}\n\n/**\n * Any property of Projection can be in config\n */\nexport interface ProjectionConfig extends Projection { }\n\nexport const PROJECTION_PROPERTIES: (keyof Projection)[] = [\n 'type',\n 'clipAngle',\n 'clipExtent',\n 'center',\n 'rotate',\n 'precision',\n 'coefficient',\n 'distance',\n 'fraction',\n 'lobes',\n 'parallel',\n 'radius',\n 'ratio',\n 'spacing',\n 'tilt'\n];\n"]} \ No newline at end of file diff --git a/build/src/repeat.d.ts b/build/src/repeat.d.ts new file mode 100644 index 0000000000..2d5d79a2de --- /dev/null +++ b/build/src/repeat.d.ts @@ -0,0 +1,10 @@ +export interface Repeat { + /** + * Vertical repeated views. + */ + row?: string[]; + /** + * Horizontal repeated views. + */ + column?: string[]; +} diff --git a/build/src/repeat.js b/build/src/repeat.js new file mode 100644 index 0000000000..fd40f45d56 --- /dev/null +++ b/build/src/repeat.js @@ -0,0 +1 @@ +//# sourceMappingURL=repeat.js.map \ No newline at end of file diff --git a/build/src/repeat.js.map b/build/src/repeat.js.map new file mode 100644 index 0000000000..e5b732594d --- /dev/null +++ b/build/src/repeat.js.map @@ -0,0 +1 @@ +{"version":3,"file":"repeat.js","sourceRoot":"","sources":["../../src/repeat.ts"],"names":[],"mappings":"","sourcesContent":["export interface Repeat {\n\n /**\n * Vertical repeated views.\n */\n row?: string[];\n\n /**\n * Horizontal repeated views.\n */\n column?: string[];\n}\n"]} \ No newline at end of file diff --git a/build/src/resolve.d.ts b/build/src/resolve.d.ts new file mode 100644 index 0000000000..f9d8296fde --- /dev/null +++ b/build/src/resolve.d.ts @@ -0,0 +1,19 @@ +import { NonPositionScaleChannel, PositionScaleChannel, ScaleChannel } from './channel'; +export declare type ResolveMode = 'independent' | 'shared'; +/** + * Defines how scales, axes, and legends from different specs should be combined. Resolve is a mapping from `scale`, `axis`, and `legend` to a mapping from channels to resolutions. + */ +export interface Resolve { + scale?: ScaleResolveMap; + axis?: AxisResolveMap; + legend?: LegendResolveMap; +} +export declare type ScaleResolveMap = { + [C in ScaleChannel]?: ResolveMode; +}; +export declare type AxisResolveMap = { + [C in PositionScaleChannel]?: ResolveMode; +}; +export declare type LegendResolveMap = { + [C in NonPositionScaleChannel]?: ResolveMode; +}; diff --git a/build/src/resolve.js b/build/src/resolve.js new file mode 100644 index 0000000000..082a6f58a4 --- /dev/null +++ b/build/src/resolve.js @@ -0,0 +1 @@ +//# sourceMappingURL=resolve.js.map \ No newline at end of file diff --git a/build/src/resolve.js.map b/build/src/resolve.js.map new file mode 100644 index 0000000000..52284b071b --- /dev/null +++ b/build/src/resolve.js.map @@ -0,0 +1 @@ +{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/resolve.ts"],"names":[],"mappings":"","sourcesContent":["import {NonPositionScaleChannel, PositionScaleChannel, ScaleChannel} from './channel';\n\n\nexport type ResolveMode = 'independent' | 'shared';\n\n/**\n * Defines how scales, axes, and legends from different specs should be combined. Resolve is a mapping from `scale`, `axis`, and `legend` to a mapping from channels to resolutions.\n */\nexport interface Resolve {\n scale?: ScaleResolveMap;\n\n axis?: AxisResolveMap;\n\n legend?: LegendResolveMap;\n}\n\nexport type ScaleResolveMap = {\n [C in ScaleChannel]?: ResolveMode\n};\n\nexport type AxisResolveMap = {\n [C in PositionScaleChannel]?: ResolveMode\n};\n\nexport type LegendResolveMap = {\n [C in NonPositionScaleChannel]?: ResolveMode\n};\n"]} \ No newline at end of file diff --git a/build/src/scale.d.ts b/build/src/scale.d.ts new file mode 100644 index 0000000000..f7f62b075c --- /dev/null +++ b/build/src/scale.d.ts @@ -0,0 +1,417 @@ +import { BinParams } from './bin'; +import { Channel } from './channel'; +import { DateTime } from './datetime'; +import { Type } from './type'; +import { ScaleInterpolate, ScaleInterpolateParams } from './vega.schema'; +export declare namespace ScaleType { + const LINEAR: 'linear'; + const BIN_LINEAR: 'bin-linear'; + const LOG: 'log'; + const POW: 'pow'; + const SQRT: 'sqrt'; + const TIME: 'time'; + const UTC: 'utc'; + const SEQUENTIAL: 'sequential'; + const QUANTILE: 'quantile'; + const QUANTIZE: 'quantize'; + const THRESHOLD: 'threshold'; + const ORDINAL: 'ordinal'; + const BIN_ORDINAL: 'bin-ordinal'; + const POINT: 'point'; + const BAND: 'band'; +} +export declare type ScaleType = typeof ScaleType.LINEAR | typeof ScaleType.BIN_LINEAR | typeof ScaleType.LOG | typeof ScaleType.POW | typeof ScaleType.SQRT | typeof ScaleType.TIME | typeof ScaleType.UTC | typeof ScaleType.SEQUENTIAL | // typeof ScaleType.QUANTILE | typeof ScaleType.QUANTIZE | typeof ScaleType.THRESHOLD | +typeof ScaleType.ORDINAL | typeof ScaleType.BIN_ORDINAL | typeof ScaleType.POINT | typeof ScaleType.BAND; +export declare const SCALE_TYPES: ScaleType[]; +/** + * Whether the two given scale types can be merged together. + */ +export declare function scaleCompatible(scaleType1: ScaleType, scaleType2: ScaleType): boolean; +/** + * Return scale categories -- only scale of the same categories can be merged together. + */ +export declare function scaleTypePrecedence(scaleType: ScaleType): number; +export declare const CONTINUOUS_TO_CONTINUOUS_SCALES: ScaleType[]; +export declare const CONTINUOUS_DOMAIN_SCALES: ScaleType[]; +export declare const DISCRETE_DOMAIN_SCALES: ScaleType[]; +export declare const TIME_SCALE_TYPES: ScaleType[]; +export declare function hasDiscreteDomain(type: ScaleType): type is 'ordinal' | 'bin-ordinal' | 'point' | 'band'; +export declare function isBinScale(type: ScaleType): type is 'bin-linear' | 'bin-ordinal'; +export declare function hasContinuousDomain(type: ScaleType): type is 'linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc' | 'sequential'; +export declare function isContinuousToContinuous(type: ScaleType): type is 'linear' | 'bin-linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc'; +export declare type NiceTime = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year'; +export interface ScaleConfig { + /** + * If true, rounds numeric output values to integers. + * This can be helpful for snapping to the pixel grid. + * (Only available for `x`, `y`, and `size` scales.) + */ + round?: boolean; + /** + * If true, values that exceed the data domain are clamped to either the minimum or maximum range value + */ + clamp?: boolean; + /** + * Default range step for `x` band and point scales of text marks. + * + * __Default value:__ `90` + * + * @minimum 0 + */ + textXRangeStep?: number; + /** + * Default range step for band and point scales of (1) the `y` channel + * and (2) the `x` channel when the mark is not `text`. + * + * __Default value:__ `21` + * + * @minimum 0 + */ + rangeStep?: number | null; + /** + * Default inner padding for `x` and `y` band-ordinal scales. + * + * __Default value:__ `0.1` + * + * @minimum 0 + * @maximum 1 + */ + bandPaddingInner?: number; + /** + * Default outer padding for `x` and `y` band-ordinal scales. + * If not specified, by default, band scale's paddingOuter is paddingInner/2. + * @minimum 0 + * @maximum 1 + */ + bandPaddingOuter?: number; + /** + * Default padding for continuous scales. + * + * __Default:__ `5` for continuous x-scale of a vertical bar and continuous y-scale of a horizontal bar.; `0` otherwise. + * + * @minimum 0 + */ + continuousPadding?: number; + /** + * Default outer padding for `x` and `y` point-ordinal scales. + * + * __Default value:__ `0.5` + * + * @minimum 0 + * @maximum 1 + */ + pointPadding?: number; + /** + * Use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis. + * + * This is equivalent to setting `domain` to `"unaggregate"` for aggregated _quantitative_ fields by default. + * + * This property only works with aggregate functions that produce values within the raw data domain (`"mean"`, `"average"`, `"median"`, `"q1"`, `"q3"`, `"min"`, `"max"`). For other aggregations that produce values outside of the raw data domain (e.g. `"count"`, `"sum"`), this property is ignored. + * + * __Default value:__ `false` + */ + useUnaggregatedDomain?: boolean; + /** + * The default max value for mapping quantitative fields to bar's size/bandSize. + * + * If undefined (default), we will use the scale's `rangeStep` - 1. + * @minimum 0 + */ + maxBandSize?: number; + /** + * The default min value for mapping quantitative fields to bar and tick's size/bandSize scale with zero=false. + * + * __Default value:__ `2` + * + * @minimum 0 + */ + minBandSize?: number; + /** + * The default max value for mapping quantitative fields to text's size/fontSize. + * + * __Default value:__ `40` + * + * @minimum 0 + */ + maxFontSize?: number; + /** + * The default min value for mapping quantitative fields to tick's size/fontSize scale with zero=false + * + * __Default value:__ `8` + * + * @minimum 0 + */ + minFontSize?: number; + /** + * Default minimum opacity for mapping a field to opacity. + * + * __Default value:__ `0.3` + * + * @minimum 0 + * @maximum 1 + */ + minOpacity?: number; + /** + * Default max opacity for mapping a field to opacity. + * + * __Default value:__ `0.8` + * + * @minimum 0 + * @maximum 1 + */ + maxOpacity?: number; + /** + * Default minimum value for point size scale with zero=false. + * + * __Default value:__ `9` + * + * @minimum 0 + */ + minSize?: number; + /** + * Default max value for point size scale. + * @minimum 0 + */ + maxSize?: number; + /** + * Default minimum strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks with zero=false. + * + * __Default value:__ `1` + * + * @minimum 0 + */ + minStrokeWidth?: number; + /** + * Default max strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks. + * + * __Default value:__ `4` + * + * @minimum 0 + */ + maxStrokeWidth?: number; +} +export declare const defaultScaleConfig: { + textXRangeStep: number; + rangeStep: number; + pointPadding: number; + bandPaddingInner: number; + facetSpacing: number; + minBandSize: number; + minFontSize: number; + maxFontSize: number; + minOpacity: number; + maxOpacity: number; + minSize: number; + minStrokeWidth: number; + maxStrokeWidth: number; +}; +export interface SchemeParams { + /** + * A color scheme name for sequential/ordinal scales (e.g., `"category10"` or `"viridis"`). + * + * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference. + */ + name: string; + /** + * For sequential and diverging schemes only, determines the extent of the color range to use. For example `[0.2, 1]` will rescale the color scheme such that color values in the range _[0, 0.2)_ are excluded from the scheme. + */ + extent?: number[]; + /** + * The number of colors to use in the scheme. This can be useful for scale types such as `"quantize"`, which use the length of the scale range to determine the number of discrete bins for the scale domain. + * + * @hide + */ + count?: number; +} +export declare type SelectionDomain = { + /** + * The name of a selection. + */ + selection: string; + /** + * The field name to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html) + * over multiple fields or encodings. + */ + field?: string; +} | { + /** + * The name of a selection. + */ + selection: string; + /** + * The encoding channel to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html) + * over multiple fields or encodings. + */ + encoding?: string; +}; +export declare type Domain = number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain; +export declare type Scheme = string | SchemeParams; +export declare type Range = number[] | string[] | string; +export declare function isExtendedScheme(scheme: string | SchemeParams): scheme is SchemeParams; +export declare function isSelectionDomain(domain: Domain): domain is SelectionDomain; +export interface Scale { + /** + * The type of scale. Vega-Lite supports the following categories of scale types: + * + * 1) [**Continuous Scales**](https://vega.github.io/vega-lite/docs/scale.html#continuous) -- mapping continuous domains to continuous output ranges ([`"linear"`](https://vega.github.io/vega-lite/docs/scale.html#linear), [`"pow"`](https://vega.github.io/vega-lite/docs/scale.html#pow), [`"sqrt"`](https://vega.github.io/vega-lite/docs/scale.html#sqrt), [`"log"`](https://vega.github.io/vega-lite/docs/scale.html#log), [`"time"`](https://vega.github.io/vega-lite/docs/scale.html#time), [`"utc"`](https://vega.github.io/vega-lite/docs/scale.html#utc), [`"sequential"`](https://vega.github.io/vega-lite/docs/scale.html#sequential)). + * + * 2) [**Discrete Scales**](https://vega.github.io/vega-lite/docs/scale.html#discrete) -- mapping discrete domains to discrete ([`"ordinal"`](https://vega.github.io/vega-lite/docs/scale.html#ordinal)) or continuous ([`"band"`](https://vega.github.io/vega-lite/docs/scale.html#band) and [`"point"`](https://vega.github.io/vega-lite/docs/scale.html#point)) output ranges. + * + * 3) [**Discretizing Scales**](https://vega.github.io/vega-lite/docs/scale.html#discretizing) -- mapping continuous domains to discrete output ranges ([`"bin-linear"`](https://vega.github.io/vega-lite/docs/scale.html#bin-linear) and [`"bin-ordinal"`](https://vega.github.io/vega-lite/docs/scale.html#bin-ordinal)). + * + * __Default value:__ please see the [scale type table](https://vega.github.io/vega-lite/docs/scale.html#type). + */ + type?: ScaleType; + /** + * Customized domain values. + * + * For _quantitative_ fields, `domain` can take the form of a two-element array with minimum and maximum values. [Piecewise scales](https://vega.github.io/vega-lite/docs/scale.html#piecewise) can be created by providing a `domain` with more than two entries. + * If the input field is aggregated, `domain` can also be a string value `"unaggregated"`, indicating that the domain should include the raw data values prior to the aggregation. + * + * For _temporal_ fields, `domain` can be a two-element array minimum and maximum values, in the form of either timestamps or the [DateTime definition objects](https://vega.github.io/vega-lite/docs/types.html#datetime). + * + * For _ordinal_ and _nominal_ fields, `domain` can be an array that lists valid input values. + * + * The `selection` property can be used to [interactively determine](https://vega.github.io/vega-lite/docs/selection.html#scale-domains) the scale domain. + */ + domain?: number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain; + /** + * If true, reverses the order of the scale range. + * __Default value:__ `false`. + * + * @hide + */ + reverse?: boolean; + /** + * The range of the scale. One of: + * + * - A string indicating a [pre-defined named scale range](https://vega.github.io/vega-lite/docs/scale.html#range-config) (e.g., example, `"symbol"`, or `"diverging"`). + * + * - For [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous), two-element array indicating minimum and maximum values, or an array with more than two entries for specifying a [piecewise scale](https://vega.github.io/vega-lite/docs/scale.html#piecewise). + * + * - For [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) and [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales, an array of desired output values. + * + * __Notes:__ + * + * 1) For [sequential](https://vega.github.io/vega-lite/docs/scale.html#sequential), [ordinal](https://vega.github.io/vega-lite/docs/scale.html#ordinal), and discretizing color scales, you can also specify a color [`scheme`](https://vega.github.io/vega-lite/docs/scale.html#scheme) instead of `range`. + * + * 2) Any directly specified `range` for `x` and `y` channels will be ignored. Range can be customized via the view's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` and `height`) or via [range steps and paddings properties](#range-step) for [band](#band) and [point](#point) scales. + */ + range?: number[] | string[] | string; + /** + * The distance between the starts of adjacent bands or points in [band](https://vega.github.io/vega-lite/docs/scale.html#band) and [point](https://vega.github.io/vega-lite/docs/scale.html#point) scales. + * + * If `rangeStep` is `null` or if the view contains the scale's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` for `x` scales and `height` for `y` scales), `rangeStep` will be automatically determined to fit the size of the view. + * + * __Default value:__ derived the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `textXRangeStep` (`90` by default) for x-scales of `text` marks and `rangeStep` (`21` by default) for x-scales of other marks and y-scales. + * + * __Warning__: If `rangeStep` is `null` and the cardinality of the scale's domain is higher than `width` or `height`, the rangeStep might become less than one pixel and the mark might not appear correctly. + * + * @minimum 0 + */ + rangeStep?: number | null; + /** + * A string indicating a color [scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme) name (e.g., `"category10"` or `"viridis"`) or a [scheme parameter object](https://vega.github.io/vega-lite/docs/scale.html#scheme-params). + * + * Discrete color schemes may be used with [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) or [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales. Continuous color schemes are intended for use with [sequential](https://vega.github.io/vega-lite/docs/scales.html#sequential) scales. + * + * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference. + */ + scheme?: string | SchemeParams; + /** + * If `true`, rounds numeric output values to integers. This can be helpful for snapping to the pixel grid. + * + * __Default value:__ `false`. + */ + round?: boolean; + /** + * For _[continuous](https://vega.github.io/vega-lite/docs/scale.html#continuous)_ scales, expands the scale domain to accommodate the specified number of pixels on each of the scale range. The scale range must represent pixels for this parameter to function as intended. Padding adjustment is performed prior to all other adjustments, including the effects of the zero, nice, domainMin, and domainMax properties. + * + * For _[band](https://vega.github.io/vega-lite/docs/scale.html#band)_ scales, shortcut for setting `paddingInner` and `paddingOuter` to the same value. + * + * For _[point](https://vega.github.io/vega-lite/docs/scale.html#point)_ scales, alias for `paddingOuter`. + * + * __Default value:__ For _continuous_ scales, derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `continuousPadding`. + * For _band and point_ scales, see `paddingInner` and `paddingOuter`. + * + * @minimum 0 + */ + padding?: number; + /** + * The inner padding (spacing) within each band step of band scales, as a fraction of the step size. This value must lie in the range [0,1]. + * + * For point scale, this property is invalid as point scales do not have internal band widths (only step sizes between bands). + * + * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingInner`. + * + * @minimum 0 + * @maximum 1 + */ + paddingInner?: number; + /** + * The outer padding (spacing) at the ends of the range of band and point scales, + * as a fraction of the step size. This value must lie in the range [0,1]. + * + * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingOuter` for band scales and `pointPadding` for point scales. + * + * @minimum 0 + * @maximum 1 + */ + paddingOuter?: number; + /** + * If `true`, values that exceed the data domain are clamped to either the minimum or maximum range value + * + * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `clamp` (`true` by default). + */ + clamp?: boolean; + /** + * Extending the domain so that it starts and ends on nice round values. This method typically modifies the scale’s domain, and may only extend the bounds to the nearest round value. Nicing is useful if the domain is computed from data and may be irregular. For example, for a domain of _[0.201479…, 0.996679…]_, a nice domain might be _[0.2, 1.0]_. + * + * For quantitative scales such as linear, `nice` can be either a boolean flag or a number. If `nice` is a number, it will represent a desired tick count. This allows greater control over the step size used to extend the bounds, guaranteeing that the returned ticks will exactly cover the domain. + * + * For temporal fields with time and utc scales, the `nice` value can be a string indicating the desired time interval. Legal values are `"millisecond"`, `"second"`, `"minute"`, `"hour"`, `"day"`, `"week"`, `"month"`, and `"year"`. Alternatively, `time` and `utc` scales can accept an object-valued interval specifier of the form `{"interval": "month", "step": 3}`, which includes a desired number of interval steps. Here, the domain would snap to quarter (Jan, Apr, Jul, Oct) boundaries. + * + * __Default value:__ `true` for unbinned _quantitative_ fields; `false` otherwise. + * + */ + nice?: boolean | number | NiceTime | { + interval: string; + step: number; + }; + /** + * The logarithm base of the `log` scale (default `10`). + */ + base?: number; + /** + * The exponent of the `pow` scale. + */ + exponent?: number; + /** + * If `true`, ensures that a zero baseline value is included in the scale domain. + * + * __Default value:__ `true` for x and y channels if the quantitative field is not binned and no custom `domain` is provided; `false` otherwise. + * + * __Note:__ Log, time, and utc scales do not support `zero`. + */ + zero?: boolean; + /** + * The interpolation method for range values. By default, a general interpolator for numbers, dates, strings and colors (in RGB space) is used. For color ranges, this property allows interpolation in alternative color spaces. Legal values include `rgb`, `hsl`, `hsl-long`, `lab`, `hcl`, `hcl-long`, `cubehelix` and `cubehelix-long` ('-long' variants use longer paths in polar coordinate spaces). If object-valued, this property accepts an object with a string-valued _type_ property and an optional numeric _gamma_ property applicable to rgb and cubehelix interpolators. For more, see the [d3-interpolate documentation](https://github.com/d3/d3-interpolate). + * + * __Note:__ Sequential scales do not support `interpolate` as they have a fixed interpolator. Since Vega-Lite uses sequential scales for quantitative fields by default, you have to set the scale `type` to other quantitative scale type such as `"linear"` to customize `interpolate`. + */ + interpolate?: ScaleInterpolate | ScaleInterpolateParams; +} +export declare const SCALE_PROPERTIES: ("reverse" | "base" | "padding" | "type" | "domain" | "range" | "zero" | "nice" | "rangeStep" | "scheme" | "round" | "paddingInner" | "paddingOuter" | "clamp" | "exponent" | "interpolate")[]; +export declare const NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES: ("reverse" | "base" | "padding" | "zero" | "nice" | "round" | "paddingInner" | "paddingOuter" | "clamp" | "exponent" | "interpolate")[]; +export declare const SCALE_TYPE_INDEX: ScaleTypeIndex; +export declare function scaleTypeSupportProperty(scaleType: ScaleType, propName: keyof Scale): boolean; +/** + * Returns undefined if the input channel supports the input scale property name + */ +export declare function channelScalePropertyIncompatability(channel: Channel, propName: keyof Scale): string; +export declare function scaleTypeSupportDataType(specifiedType: ScaleType, fieldDefType: Type, bin: boolean | BinParams): boolean; +export declare function channelSupportScaleType(channel: Channel, scaleType: ScaleType): boolean; +export declare function getSupportedScaleType(channel: Channel, fieldDefType: Type, bin?: boolean): ScaleType[]; +export interface ScaleTypeIndex { + [channel: string]: ScaleType[]; +} diff --git a/build/src/scale.js b/build/src/scale.js new file mode 100644 index 0000000000..3cb09c419f --- /dev/null +++ b/build/src/scale.js @@ -0,0 +1,287 @@ +import * as tslib_1 from "tslib"; +import { toSet } from 'vega-util'; +import { Channel, CHANNELS, isColorChannel } from './channel'; +import * as log from './log'; +import { Type, TYPE_INDEX } from './type'; +import { contains, flagKeys, keys } from './util'; +export var ScaleType; +(function (ScaleType) { + // Continuous - Quantitative + ScaleType.LINEAR = 'linear'; + ScaleType.BIN_LINEAR = 'bin-linear'; + ScaleType.LOG = 'log'; + ScaleType.POW = 'pow'; + ScaleType.SQRT = 'sqrt'; + // Continuous - Time + ScaleType.TIME = 'time'; + ScaleType.UTC = 'utc'; + // sequential + ScaleType.SEQUENTIAL = 'sequential'; + // Quantile, Quantize, threshold + ScaleType.QUANTILE = 'quantile'; + ScaleType.QUANTIZE = 'quantize'; + ScaleType.THRESHOLD = 'threshold'; + ScaleType.ORDINAL = 'ordinal'; + ScaleType.BIN_ORDINAL = 'bin-ordinal'; + ScaleType.POINT = 'point'; + ScaleType.BAND = 'band'; +})(ScaleType || (ScaleType = {})); +/** + * Index for scale categories -- only scale of the same categories can be merged together. + * Current implementation is trying to be conservative and avoid merging scale type that might not work together + */ +var SCALE_CATEGORY_INDEX = { + linear: 'numeric', + log: 'numeric', + pow: 'numeric', + sqrt: 'numeric', + 'bin-linear': 'bin-linear', + time: 'time', + utc: 'time', + sequential: 'sequential', + ordinal: 'ordinal', + 'bin-ordinal': 'bin-ordinal', + point: 'ordinal-position', + band: 'ordinal-position' +}; +export var SCALE_TYPES = keys(SCALE_CATEGORY_INDEX); +/** + * Whether the two given scale types can be merged together. + */ +export function scaleCompatible(scaleType1, scaleType2) { + var scaleCategory1 = SCALE_CATEGORY_INDEX[scaleType1]; + var scaleCategory2 = SCALE_CATEGORY_INDEX[scaleType2]; + return scaleCategory1 === scaleCategory2 || + (scaleCategory1 === 'ordinal-position' && scaleCategory2 === 'time') || + (scaleCategory2 === 'ordinal-position' && scaleCategory1 === 'time'); +} +/** + * Index for scale precedence -- high score = higher priority for merging. + */ +var SCALE_PRECEDENCE_INDEX = { + // numeric + linear: 0, + log: 1, + pow: 1, + sqrt: 1, + // time + time: 0, + utc: 0, + // ordinal-position -- these have higher precedence than continuous scales as they support more types of data + point: 10, + band: 11, + // non grouped types + 'bin-linear': 0, + sequential: 0, + ordinal: 0, + 'bin-ordinal': 0, +}; +/** + * Return scale categories -- only scale of the same categories can be merged together. + */ +export function scaleTypePrecedence(scaleType) { + return SCALE_PRECEDENCE_INDEX[scaleType]; +} +export var CONTINUOUS_TO_CONTINUOUS_SCALES = ['linear', 'bin-linear', 'log', 'pow', 'sqrt', 'time', 'utc']; +var CONTINUOUS_TO_CONTINUOUS_INDEX = toSet(CONTINUOUS_TO_CONTINUOUS_SCALES); +export var CONTINUOUS_DOMAIN_SCALES = CONTINUOUS_TO_CONTINUOUS_SCALES.concat(['sequential' /* TODO add 'quantile', 'quantize', 'threshold'*/]); +var CONTINUOUS_DOMAIN_INDEX = toSet(CONTINUOUS_DOMAIN_SCALES); +export var DISCRETE_DOMAIN_SCALES = ['ordinal', 'bin-ordinal', 'point', 'band']; +var DISCRETE_DOMAIN_INDEX = toSet(DISCRETE_DOMAIN_SCALES); +var BIN_SCALES_INDEX = toSet(['bin-linear', 'bin-ordinal']); +export var TIME_SCALE_TYPES = ['time', 'utc']; +export function hasDiscreteDomain(type) { + return type in DISCRETE_DOMAIN_INDEX; +} +export function isBinScale(type) { + return type in BIN_SCALES_INDEX; +} +export function hasContinuousDomain(type) { + return type in CONTINUOUS_DOMAIN_INDEX; +} +export function isContinuousToContinuous(type) { + return type in CONTINUOUS_TO_CONTINUOUS_INDEX; +} +export var defaultScaleConfig = { + textXRangeStep: 90, + rangeStep: 21, + pointPadding: 0.5, + bandPaddingInner: 0.1, + facetSpacing: 16, + minBandSize: 2, + minFontSize: 8, + maxFontSize: 40, + minOpacity: 0.3, + maxOpacity: 0.8, + // FIXME: revise if these *can* become ratios of rangeStep + minSize: 9, + minStrokeWidth: 1, + maxStrokeWidth: 4 +}; +export function isExtendedScheme(scheme) { + return scheme && !!scheme['name']; +} +export function isSelectionDomain(domain) { + return domain && domain['selection']; +} +var SCALE_PROPERTY_INDEX = { + type: 1, + domain: 1, + range: 1, + rangeStep: 1, + scheme: 1, + // Other properties + reverse: 1, + round: 1, + // quantitative / time + clamp: 1, + nice: 1, + // quantitative + base: 1, + exponent: 1, + interpolate: 1, + zero: 1, + // band/point + padding: 1, + paddingInner: 1, + paddingOuter: 1 +}; +export var SCALE_PROPERTIES = flagKeys(SCALE_PROPERTY_INDEX); +var type = SCALE_PROPERTY_INDEX.type, domain = SCALE_PROPERTY_INDEX.domain, range = SCALE_PROPERTY_INDEX.range, rangeStep = SCALE_PROPERTY_INDEX.rangeStep, scheme = SCALE_PROPERTY_INDEX.scheme, NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX = tslib_1.__rest(SCALE_PROPERTY_INDEX, ["type", "domain", "range", "rangeStep", "scheme"]); +export var NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES = flagKeys(NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX); +export var SCALE_TYPE_INDEX = generateScaleTypeIndex(); +export function scaleTypeSupportProperty(scaleType, propName) { + switch (propName) { + case 'type': + case 'domain': + case 'reverse': + case 'range': + return true; + case 'scheme': + return contains(['sequential', 'ordinal', 'bin-ordinal', 'quantile', 'quantize'], scaleType); + case 'interpolate': + // FIXME(https://github.com/vega/vega-lite/issues/2902) how about ordinal? + return contains(['linear', 'bin-linear', 'pow', 'log', 'sqrt', 'utc', 'time'], scaleType); + case 'round': + return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point'; + case 'padding': + return isContinuousToContinuous(scaleType) || contains(['point', 'band'], scaleType); + case 'paddingOuter': + case 'rangeStep': + return contains(['point', 'band'], scaleType); + case 'paddingInner': + return scaleType === 'band'; + case 'clamp': + return isContinuousToContinuous(scaleType) || scaleType === 'sequential'; + case 'nice': + return isContinuousToContinuous(scaleType) || scaleType === 'sequential' || scaleType === 'quantize'; + case 'exponent': + return scaleType === 'pow'; + case 'base': + return scaleType === 'log'; + case 'zero': + return hasContinuousDomain(scaleType) && !contains([ + 'log', + 'time', 'utc', + 'bin-linear', + 'threshold', + 'quantile' // quantile depends on distribution so zero does not matter + ], scaleType); + } + /* istanbul ignore next: should never reach here*/ + throw new Error("Invalid scale property " + propName + "."); +} +/** + * Returns undefined if the input channel supports the input scale property name + */ +export function channelScalePropertyIncompatability(channel, propName) { + switch (propName) { + case 'interpolate': + case 'scheme': + if (!isColorChannel(channel)) { + return log.message.cannotUseScalePropertyWithNonColor(channel); + } + return undefined; + case 'type': + case 'domain': + case 'range': + case 'base': + case 'exponent': + case 'nice': + case 'padding': + case 'paddingInner': + case 'paddingOuter': + case 'rangeStep': + case 'reverse': + case 'round': + case 'clamp': + case 'zero': + return undefined; // GOOD! + } + /* istanbul ignore next: it should never reach here */ + throw new Error("Invalid scale property \"" + propName + "\"."); +} +export function scaleTypeSupportDataType(specifiedType, fieldDefType, bin) { + if (contains([Type.ORDINAL, Type.NOMINAL], fieldDefType)) { + return specifiedType === undefined || hasDiscreteDomain(specifiedType); + } + else if (fieldDefType === Type.TEMPORAL) { + return contains([ScaleType.TIME, ScaleType.UTC, ScaleType.SEQUENTIAL, undefined], specifiedType); + } + else if (fieldDefType === Type.QUANTITATIVE) { + if (bin) { + return contains([ScaleType.BIN_LINEAR, ScaleType.BIN_ORDINAL, ScaleType.LINEAR], specifiedType); + } + return contains([ScaleType.LOG, ScaleType.POW, ScaleType.SQRT, ScaleType.QUANTILE, ScaleType.QUANTIZE, ScaleType.LINEAR, ScaleType.SEQUENTIAL, undefined], specifiedType); + } + return true; +} +export function channelSupportScaleType(channel, scaleType) { + switch (channel) { + case Channel.X: + case Channel.Y: + case Channel.SIZE: // TODO: size and opacity can support ordinal with more modification + case Channel.OPACITY: + // Although it generally doesn't make sense to use band with size and opacity, + // it can also work since we use band: 0.5 to get midpoint. + return isContinuousToContinuous(scaleType) || contains(['band', 'point'], scaleType); + case Channel.COLOR: + case Channel.FILL: + case Channel.STROKE: + return scaleType !== 'band'; // band does not make sense with color + case Channel.SHAPE: + return scaleType === 'ordinal'; // shape = lookup only + } + /* istanbul ignore next: it should never reach here */ + return false; +} +export function getSupportedScaleType(channel, fieldDefType, bin) { + return SCALE_TYPE_INDEX[generateScaleTypeIndexKey(channel, fieldDefType, bin)]; +} +// generates ScaleTypeIndex where keys are encoding channels and values are list of valid ScaleTypes +function generateScaleTypeIndex() { + var index = {}; + for (var _i = 0, CHANNELS_1 = CHANNELS; _i < CHANNELS_1.length; _i++) { + var channel = CHANNELS_1[_i]; + for (var _a = 0, _b = keys(TYPE_INDEX); _a < _b.length; _a++) { + var fieldDefType = _b[_a]; + for (var _c = 0, SCALE_TYPES_1 = SCALE_TYPES; _c < SCALE_TYPES_1.length; _c++) { + var scaleType = SCALE_TYPES_1[_c]; + for (var _d = 0, _e = [false, true]; _d < _e.length; _d++) { + var bin = _e[_d]; + var key = generateScaleTypeIndexKey(channel, fieldDefType, bin); + if (channelSupportScaleType(channel, scaleType) && scaleTypeSupportDataType(scaleType, fieldDefType, bin)) { + index[key] = index[key] || []; + index[key].push(scaleType); + } + } + } + } + } + return index; +} +function generateScaleTypeIndexKey(channel, fieldDefType, bin) { + var key = channel + '_' + fieldDefType; + return bin ? key + '_bin' : key; +} +//# sourceMappingURL=scale.js.map \ No newline at end of file diff --git a/build/src/scale.js.map b/build/src/scale.js.map new file mode 100644 index 0000000000..9599dcffb7 --- /dev/null +++ b/build/src/scale.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scale.js","sourceRoot":"","sources":["../../src/scale.ts"],"names":[],"mappings":"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","sourcesContent":["import {toSet} from 'vega-util';\nimport {BinParams} from './bin';\nimport {Channel, CHANNELS, isColorChannel} from './channel';\nimport {DateTime} from './datetime';\nimport * as log from './log';\nimport {Type, TYPE_INDEX} from './type';\nimport {contains, Flag, flagKeys, keys} from './util';\nimport {ScaleInterpolate, ScaleInterpolateParams} from './vega.schema';\n\nexport namespace ScaleType {\n // Continuous - Quantitative\n export const LINEAR: 'linear' = 'linear';\n export const BIN_LINEAR: 'bin-linear' = 'bin-linear';\n export const LOG: 'log' = 'log';\n export const POW: 'pow' = 'pow';\n export const SQRT: 'sqrt' = 'sqrt';\n // Continuous - Time\n export const TIME: 'time' = 'time';\n export const UTC: 'utc' = 'utc';\n // sequential\n export const SEQUENTIAL: 'sequential' = 'sequential';\n\n // Quantile, Quantize, threshold\n export const QUANTILE: 'quantile' = 'quantile';\n export const QUANTIZE: 'quantize' = 'quantize';\n export const THRESHOLD: 'threshold' = 'threshold';\n\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const BIN_ORDINAL: 'bin-ordinal' = 'bin-ordinal';\n export const POINT: 'point' = 'point';\n export const BAND: 'band' = 'band';\n}\n\nexport type ScaleType = typeof ScaleType.LINEAR | typeof ScaleType.BIN_LINEAR |\n typeof ScaleType.LOG | typeof ScaleType.POW | typeof ScaleType.SQRT |\n typeof ScaleType.TIME | typeof ScaleType.UTC |\n // TODO: add 'quantize', 'quantile', 'threshold' back when we really support them\n typeof ScaleType.SEQUENTIAL | // typeof ScaleType.QUANTILE | typeof ScaleType.QUANTIZE | typeof ScaleType.THRESHOLD |\n typeof ScaleType.ORDINAL | typeof ScaleType.BIN_ORDINAL | typeof ScaleType.POINT | typeof ScaleType.BAND;\n\n\n/**\n * Index for scale categories -- only scale of the same categories can be merged together.\n * Current implementation is trying to be conservative and avoid merging scale type that might not work together\n */\nconst SCALE_CATEGORY_INDEX: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleType]: ScaleType | 'numeric' | 'ordinal-position'\n} = {\n linear: 'numeric',\n log: 'numeric',\n pow: 'numeric',\n sqrt: 'numeric',\n 'bin-linear': 'bin-linear', // TODO: should bin-linear support merging with other\n time: 'time',\n utc: 'time',\n sequential: 'sequential',\n ordinal: 'ordinal',\n 'bin-ordinal': 'bin-ordinal', // TODO: should bin-ordinal support merging with other\n point: 'ordinal-position',\n band: 'ordinal-position'\n};\n\nexport const SCALE_TYPES = keys(SCALE_CATEGORY_INDEX) as ScaleType[];\n\n/**\n * Whether the two given scale types can be merged together.\n */\nexport function scaleCompatible(scaleType1: ScaleType, scaleType2: ScaleType) {\n const scaleCategory1 = SCALE_CATEGORY_INDEX[scaleType1];\n const scaleCategory2 = SCALE_CATEGORY_INDEX[scaleType2];\n return scaleCategory1 === scaleCategory2 ||\n (scaleCategory1 === 'ordinal-position' && scaleCategory2 === 'time') ||\n (scaleCategory2 === 'ordinal-position' && scaleCategory1 === 'time');\n}\n\n/**\n * Index for scale precedence -- high score = higher priority for merging.\n */\nconst SCALE_PRECEDENCE_INDEX: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleType]: number\n} = {\n // numeric\n linear: 0,\n log: 1,\n pow: 1,\n sqrt: 1,\n // time\n time: 0,\n utc: 0,\n // ordinal-position -- these have higher precedence than continuous scales as they support more types of data\n point: 10,\n band: 11, // band has higher precedence as it is better for interaction\n // non grouped types\n 'bin-linear': 0,\n sequential: 0,\n ordinal: 0,\n 'bin-ordinal': 0,\n};\n\n/**\n * Return scale categories -- only scale of the same categories can be merged together.\n */\nexport function scaleTypePrecedence(scaleType: ScaleType): number {\n return SCALE_PRECEDENCE_INDEX[scaleType];\n}\n\nexport const CONTINUOUS_TO_CONTINUOUS_SCALES: ScaleType[] = ['linear', 'bin-linear', 'log', 'pow', 'sqrt', 'time', 'utc'];\nconst CONTINUOUS_TO_CONTINUOUS_INDEX = toSet(CONTINUOUS_TO_CONTINUOUS_SCALES);\n\nexport const CONTINUOUS_DOMAIN_SCALES: ScaleType[] = CONTINUOUS_TO_CONTINUOUS_SCALES.concat(['sequential' /* TODO add 'quantile', 'quantize', 'threshold'*/]);\nconst CONTINUOUS_DOMAIN_INDEX = toSet(CONTINUOUS_DOMAIN_SCALES);\n\nexport const DISCRETE_DOMAIN_SCALES: ScaleType[] = ['ordinal', 'bin-ordinal', 'point', 'band'];\nconst DISCRETE_DOMAIN_INDEX = toSet(DISCRETE_DOMAIN_SCALES);\n\nconst BIN_SCALES_INDEX = toSet(['bin-linear', 'bin-ordinal']);\n\nexport const TIME_SCALE_TYPES: ScaleType[] = ['time', 'utc'];\n\nexport function hasDiscreteDomain(type: ScaleType): type is 'ordinal' | 'bin-ordinal' | 'point' | 'band' {\n return type in DISCRETE_DOMAIN_INDEX;\n}\n\nexport function isBinScale(type: ScaleType): type is 'bin-linear' | 'bin-ordinal' {\n return type in BIN_SCALES_INDEX;\n}\n\nexport function hasContinuousDomain(type: ScaleType):\n type is 'linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc'|\n 'sequential' /* TODO add | 'quantile' | 'quantize' | 'threshold' */ {\n return type in CONTINUOUS_DOMAIN_INDEX;\n}\n\nexport function isContinuousToContinuous(type: ScaleType): type is 'linear' | 'bin-linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc' {\n return type in CONTINUOUS_TO_CONTINUOUS_INDEX;\n}\n\nexport type NiceTime = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year';\n\nexport interface ScaleConfig {\n /**\n * If true, rounds numeric output values to integers.\n * This can be helpful for snapping to the pixel grid.\n * (Only available for `x`, `y`, and `size` scales.)\n */\n round?: boolean;\n\n /**\n * If true, values that exceed the data domain are clamped to either the minimum or maximum range value\n */\n clamp?: boolean;\n /**\n * Default range step for `x` band and point scales of text marks.\n *\n * __Default value:__ `90`\n *\n * @minimum 0\n */\n textXRangeStep?: number; // FIXME: consider if we will rename this \"tableColumnWidth\"\n\n /**\n * Default range step for band and point scales of (1) the `y` channel\n * and (2) the `x` channel when the mark is not `text`.\n *\n * __Default value:__ `21`\n *\n * @minimum 0\n */\n rangeStep?: number | null;\n\n /**\n * Default inner padding for `x` and `y` band-ordinal scales.\n *\n * __Default value:__ `0.1`\n *\n * @minimum 0\n * @maximum 1\n */\n bandPaddingInner?: number;\n\n /**\n * Default outer padding for `x` and `y` band-ordinal scales.\n * If not specified, by default, band scale's paddingOuter is paddingInner/2.\n * @minimum 0\n * @maximum 1\n */\n bandPaddingOuter?: number;\n\n /**\n * Default padding for continuous scales.\n *\n * __Default:__ `5` for continuous x-scale of a vertical bar and continuous y-scale of a horizontal bar.; `0` otherwise.\n *\n * @minimum 0\n */\n continuousPadding?: number;\n\n /**\n * Default outer padding for `x` and `y` point-ordinal scales.\n *\n * __Default value:__ `0.5`\n *\n * @minimum 0\n * @maximum 1\n */\n pointPadding?: number;\n\n /**\n * Use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis.\n *\n * This is equivalent to setting `domain` to `\"unaggregate\"` for aggregated _quantitative_ fields by default.\n *\n * This property only works with aggregate functions that produce values within the raw data domain (`\"mean\"`, `\"average\"`, `\"median\"`, `\"q1\"`, `\"q3\"`, `\"min\"`, `\"max\"`). For other aggregations that produce values outside of the raw data domain (e.g. `\"count\"`, `\"sum\"`), this property is ignored.\n *\n * __Default value:__ `false`\n */\n useUnaggregatedDomain?: boolean;\n\n // nice should depends on type (quantitative or temporal), so\n // let's not make a config.\n\n // Configs for Range\n\n /**\n * The default max value for mapping quantitative fields to bar's size/bandSize.\n *\n * If undefined (default), we will use the scale's `rangeStep` - 1.\n * @minimum 0\n */\n maxBandSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to bar and tick's size/bandSize scale with zero=false.\n *\n * __Default value:__ `2`\n *\n * @minimum 0\n */\n minBandSize?: number;\n\n /**\n * The default max value for mapping quantitative fields to text's size/fontSize.\n *\n * __Default value:__ `40`\n *\n * @minimum 0\n */\n maxFontSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to tick's size/fontSize scale with zero=false\n *\n * __Default value:__ `8`\n *\n * @minimum 0\n */\n minFontSize?: number;\n\n /**\n * Default minimum opacity for mapping a field to opacity.\n *\n * __Default value:__ `0.3`\n *\n * @minimum 0\n * @maximum 1\n */\n minOpacity?: number;\n\n /**\n * Default max opacity for mapping a field to opacity.\n *\n * __Default value:__ `0.8`\n *\n * @minimum 0\n * @maximum 1\n */\n maxOpacity?: number;\n\n\n /**\n * Default minimum value for point size scale with zero=false.\n *\n * __Default value:__ `9`\n *\n * @minimum 0\n */\n minSize?: number;\n\n /**\n * Default max value for point size scale.\n * @minimum 0\n */\n maxSize?: number;\n\n /**\n * Default minimum strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks with zero=false.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n minStrokeWidth?: number;\n\n /**\n * Default max strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks.\n *\n * __Default value:__ `4`\n *\n * @minimum 0\n */\n maxStrokeWidth?: number;\n}\n\nexport const defaultScaleConfig = {\n textXRangeStep: 90,\n rangeStep: 21,\n pointPadding: 0.5,\n bandPaddingInner: 0.1,\n facetSpacing: 16,\n\n minBandSize: 2,\n\n minFontSize: 8,\n maxFontSize: 40,\n\n minOpacity: 0.3,\n maxOpacity: 0.8,\n\n // FIXME: revise if these *can* become ratios of rangeStep\n minSize: 9, // Point size is area. For square point, 9 = 3 pixel ^ 2, not too small!\n\n minStrokeWidth: 1,\n maxStrokeWidth: 4\n};\n\nexport interface SchemeParams {\n /**\n * A color scheme name for sequential/ordinal scales (e.g., `\"category10\"` or `\"viridis\"`).\n *\n * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference.\n */\n name: string;\n\n /**\n * For sequential and diverging schemes only, determines the extent of the color range to use. For example `[0.2, 1]` will rescale the color scheme such that color values in the range _[0, 0.2)_ are excluded from the scheme.\n */\n extent?: number[];\n\n /**\n * The number of colors to use in the scheme. This can be useful for scale types such as `\"quantize\"`, which use the length of the scale range to determine the number of discrete bins for the scale domain.\n *\n * @hide\n */\n count?: number;\n}\n\nexport type SelectionDomain = {\n /**\n * The name of a selection.\n */\n selection: string,\n /**\n * The field name to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html)\n * over multiple fields or encodings.\n */\n field?: string\n} | {\n /**\n * The name of a selection.\n */\n selection: string,\n /**\n * The encoding channel to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html)\n * over multiple fields or encodings.\n */\n encoding?: string\n};\n\nexport type Domain = number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain;\nexport type Scheme = string | SchemeParams;\n\nexport type Range = number[] | string[] | string;\n\nexport function isExtendedScheme(scheme: string | SchemeParams): scheme is SchemeParams {\n return scheme && !!scheme['name'];\n}\n\nexport function isSelectionDomain(domain: Domain): domain is SelectionDomain {\n return domain && domain['selection'];\n}\n\nexport interface Scale {\n /**\n * The type of scale. Vega-Lite supports the following categories of scale types:\n *\n * 1) [**Continuous Scales**](https://vega.github.io/vega-lite/docs/scale.html#continuous) -- mapping continuous domains to continuous output ranges ([`\"linear\"`](https://vega.github.io/vega-lite/docs/scale.html#linear), [`\"pow\"`](https://vega.github.io/vega-lite/docs/scale.html#pow), [`\"sqrt\"`](https://vega.github.io/vega-lite/docs/scale.html#sqrt), [`\"log\"`](https://vega.github.io/vega-lite/docs/scale.html#log), [`\"time\"`](https://vega.github.io/vega-lite/docs/scale.html#time), [`\"utc\"`](https://vega.github.io/vega-lite/docs/scale.html#utc), [`\"sequential\"`](https://vega.github.io/vega-lite/docs/scale.html#sequential)).\n *\n * 2) [**Discrete Scales**](https://vega.github.io/vega-lite/docs/scale.html#discrete) -- mapping discrete domains to discrete ([`\"ordinal\"`](https://vega.github.io/vega-lite/docs/scale.html#ordinal)) or continuous ([`\"band\"`](https://vega.github.io/vega-lite/docs/scale.html#band) and [`\"point\"`](https://vega.github.io/vega-lite/docs/scale.html#point)) output ranges.\n *\n * 3) [**Discretizing Scales**](https://vega.github.io/vega-lite/docs/scale.html#discretizing) -- mapping continuous domains to discrete output ranges ([`\"bin-linear\"`](https://vega.github.io/vega-lite/docs/scale.html#bin-linear) and [`\"bin-ordinal\"`](https://vega.github.io/vega-lite/docs/scale.html#bin-ordinal)).\n *\n * __Default value:__ please see the [scale type table](https://vega.github.io/vega-lite/docs/scale.html#type).\n */\n type?: ScaleType;\n\n /**\n * Customized domain values.\n *\n * For _quantitative_ fields, `domain` can take the form of a two-element array with minimum and maximum values. [Piecewise scales](https://vega.github.io/vega-lite/docs/scale.html#piecewise) can be created by providing a `domain` with more than two entries.\n * If the input field is aggregated, `domain` can also be a string value `\"unaggregated\"`, indicating that the domain should include the raw data values prior to the aggregation.\n *\n * For _temporal_ fields, `domain` can be a two-element array minimum and maximum values, in the form of either timestamps or the [DateTime definition objects](https://vega.github.io/vega-lite/docs/types.html#datetime).\n *\n * For _ordinal_ and _nominal_ fields, `domain` can be an array that lists valid input values.\n *\n * The `selection` property can be used to [interactively determine](https://vega.github.io/vega-lite/docs/selection.html#scale-domains) the scale domain.\n */\n domain?: number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain;\n\n\n // Hide because we might not really need this.\n /**\n * If true, reverses the order of the scale range.\n * __Default value:__ `false`.\n *\n * @hide\n */\n reverse?: boolean;\n\n /**\n * The range of the scale. One of:\n *\n * - A string indicating a [pre-defined named scale range](https://vega.github.io/vega-lite/docs/scale.html#range-config) (e.g., example, `\"symbol\"`, or `\"diverging\"`).\n *\n * - For [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous), two-element array indicating minimum and maximum values, or an array with more than two entries for specifying a [piecewise scale](https://vega.github.io/vega-lite/docs/scale.html#piecewise).\n *\n * - For [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) and [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales, an array of desired output values.\n *\n * __Notes:__\n *\n * 1) For [sequential](https://vega.github.io/vega-lite/docs/scale.html#sequential), [ordinal](https://vega.github.io/vega-lite/docs/scale.html#ordinal), and discretizing color scales, you can also specify a color [`scheme`](https://vega.github.io/vega-lite/docs/scale.html#scheme) instead of `range`.\n *\n * 2) Any directly specified `range` for `x` and `y` channels will be ignored. Range can be customized via the view's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` and `height`) or via [range steps and paddings properties](#range-step) for [band](#band) and [point](#point) scales.\n */\n range?: number[] | string[] | string;\n\n // ordinal\n /**\n * The distance between the starts of adjacent bands or points in [band](https://vega.github.io/vega-lite/docs/scale.html#band) and [point](https://vega.github.io/vega-lite/docs/scale.html#point) scales.\n *\n * If `rangeStep` is `null` or if the view contains the scale's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` for `x` scales and `height` for `y` scales), `rangeStep` will be automatically determined to fit the size of the view.\n *\n * __Default value:__ derived the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `textXRangeStep` (`90` by default) for x-scales of `text` marks and `rangeStep` (`21` by default) for x-scales of other marks and y-scales.\n *\n * __Warning__: If `rangeStep` is `null` and the cardinality of the scale's domain is higher than `width` or `height`, the rangeStep might become less than one pixel and the mark might not appear correctly.\n *\n * @minimum 0\n */\n rangeStep?: number | null;\n\n /**\n * A string indicating a color [scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme) name (e.g., `\"category10\"` or `\"viridis\"`) or a [scheme parameter object](https://vega.github.io/vega-lite/docs/scale.html#scheme-params).\n *\n * Discrete color schemes may be used with [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) or [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales. Continuous color schemes are intended for use with [sequential](https://vega.github.io/vega-lite/docs/scales.html#sequential) scales.\n *\n * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference.\n */\n scheme?: string | SchemeParams;\n\n /**\n * If `true`, rounds numeric output values to integers. This can be helpful for snapping to the pixel grid.\n *\n * __Default value:__ `false`.\n */\n round?: boolean;\n\n /**\n * For _[continuous](https://vega.github.io/vega-lite/docs/scale.html#continuous)_ scales, expands the scale domain to accommodate the specified number of pixels on each of the scale range. The scale range must represent pixels for this parameter to function as intended. Padding adjustment is performed prior to all other adjustments, including the effects of the zero, nice, domainMin, and domainMax properties.\n *\n * For _[band](https://vega.github.io/vega-lite/docs/scale.html#band)_ scales, shortcut for setting `paddingInner` and `paddingOuter` to the same value.\n *\n * For _[point](https://vega.github.io/vega-lite/docs/scale.html#point)_ scales, alias for `paddingOuter`.\n *\n * __Default value:__ For _continuous_ scales, derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `continuousPadding`.\n * For _band and point_ scales, see `paddingInner` and `paddingOuter`.\n *\n * @minimum 0\n */\n padding?: number;\n\n /**\n * The inner padding (spacing) within each band step of band scales, as a fraction of the step size. This value must lie in the range [0,1].\n *\n * For point scale, this property is invalid as point scales do not have internal band widths (only step sizes between bands).\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingInner`.\n *\n * @minimum 0\n * @maximum 1\n */\n paddingInner?: number;\n\n /**\n * The outer padding (spacing) at the ends of the range of band and point scales,\n * as a fraction of the step size. This value must lie in the range [0,1].\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingOuter` for band scales and `pointPadding` for point scales.\n *\n * @minimum 0\n * @maximum 1\n */\n paddingOuter?: number;\n\n // typical\n /**\n * If `true`, values that exceed the data domain are clamped to either the minimum or maximum range value\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `clamp` (`true` by default).\n */\n clamp?: boolean;\n\n /**\n * Extending the domain so that it starts and ends on nice round values. This method typically modifies the scale’s domain, and may only extend the bounds to the nearest round value. Nicing is useful if the domain is computed from data and may be irregular. For example, for a domain of _[0.201479…, 0.996679…]_, a nice domain might be _[0.2, 1.0]_.\n *\n * For quantitative scales such as linear, `nice` can be either a boolean flag or a number. If `nice` is a number, it will represent a desired tick count. This allows greater control over the step size used to extend the bounds, guaranteeing that the returned ticks will exactly cover the domain.\n *\n * For temporal fields with time and utc scales, the `nice` value can be a string indicating the desired time interval. Legal values are `\"millisecond\"`, `\"second\"`, `\"minute\"`, `\"hour\"`, `\"day\"`, `\"week\"`, `\"month\"`, and `\"year\"`. Alternatively, `time` and `utc` scales can accept an object-valued interval specifier of the form `{\"interval\": \"month\", \"step\": 3}`, which includes a desired number of interval steps. Here, the domain would snap to quarter (Jan, Apr, Jul, Oct) boundaries.\n *\n * __Default value:__ `true` for unbinned _quantitative_ fields; `false` otherwise.\n *\n */\n nice?: boolean | number | NiceTime | {interval: string, step: number};\n\n /**\n * The logarithm base of the `log` scale (default `10`).\n */\n base?: number;\n\n /**\n * The exponent of the `pow` scale.\n */\n exponent?: number;\n\n /**\n * If `true`, ensures that a zero baseline value is included in the scale domain.\n *\n * __Default value:__ `true` for x and y channels if the quantitative field is not binned and no custom `domain` is provided; `false` otherwise.\n *\n * __Note:__ Log, time, and utc scales do not support `zero`.\n */\n zero?: boolean;\n\n /**\n * The interpolation method for range values. By default, a general interpolator for numbers, dates, strings and colors (in RGB space) is used. For color ranges, this property allows interpolation in alternative color spaces. Legal values include `rgb`, `hsl`, `hsl-long`, `lab`, `hcl`, `hcl-long`, `cubehelix` and `cubehelix-long` ('-long' variants use longer paths in polar coordinate spaces). If object-valued, this property accepts an object with a string-valued _type_ property and an optional numeric _gamma_ property applicable to rgb and cubehelix interpolators. For more, see the [d3-interpolate documentation](https://github.com/d3/d3-interpolate).\n *\n * __Note:__ Sequential scales do not support `interpolate` as they have a fixed interpolator. Since Vega-Lite uses sequential scales for quantitative fields by default, you have to set the scale `type` to other quantitative scale type such as `\"linear\"` to customize `interpolate`.\n */\n interpolate?: ScaleInterpolate | ScaleInterpolateParams;\n}\n\nconst SCALE_PROPERTY_INDEX: Flag = {\n type: 1,\n domain: 1,\n range: 1,\n rangeStep: 1,\n scheme: 1,\n // Other properties\n reverse: 1,\n round: 1,\n // quantitative / time\n clamp: 1,\n nice: 1,\n // quantitative\n base: 1,\n exponent: 1,\n interpolate: 1,\n zero: 1, // zero depends on domain\n // band/point\n padding: 1,\n paddingInner: 1,\n paddingOuter: 1\n};\n\nexport const SCALE_PROPERTIES = flagKeys(SCALE_PROPERTY_INDEX);\n\nconst {type, domain, range, rangeStep, scheme, ...NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX} = SCALE_PROPERTY_INDEX;\n\nexport const NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES = flagKeys(NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX);\n\nexport const SCALE_TYPE_INDEX = generateScaleTypeIndex();\n\nexport function scaleTypeSupportProperty(scaleType: ScaleType, propName: keyof Scale) {\n switch (propName) {\n case 'type':\n case 'domain':\n case 'reverse':\n case 'range':\n return true;\n case 'scheme':\n return contains(['sequential', 'ordinal', 'bin-ordinal', 'quantile', 'quantize'], scaleType);\n case 'interpolate':\n // FIXME(https://github.com/vega/vega-lite/issues/2902) how about ordinal?\n return contains(['linear', 'bin-linear', 'pow', 'log', 'sqrt', 'utc', 'time'], scaleType);\n case 'round':\n return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point';\n case 'padding':\n return isContinuousToContinuous(scaleType) || contains(['point', 'band'], scaleType);\n case 'paddingOuter':\n case 'rangeStep':\n return contains(['point', 'band'], scaleType);\n case 'paddingInner':\n return scaleType === 'band';\n case 'clamp':\n return isContinuousToContinuous(scaleType) || scaleType === 'sequential';\n case 'nice':\n return isContinuousToContinuous(scaleType) || scaleType === 'sequential' || scaleType as any === 'quantize';\n case 'exponent':\n return scaleType === 'pow';\n case 'base':\n return scaleType === 'log';\n case 'zero':\n return hasContinuousDomain(scaleType) && !contains([\n 'log', // log scale cannot have zero value\n 'time', 'utc', // zero is not meaningful for time\n 'bin-linear', // binning should not automatically add zero\n 'threshold', // threshold requires custom domain so zero does not matter\n 'quantile' // quantile depends on distribution so zero does not matter\n ], scaleType);\n }\n /* istanbul ignore next: should never reach here*/\n throw new Error(`Invalid scale property ${propName}.`);\n}\n\n/**\n * Returns undefined if the input channel supports the input scale property name\n */\nexport function channelScalePropertyIncompatability(channel: Channel, propName: keyof Scale): string {\n switch (propName) {\n case 'interpolate':\n case 'scheme':\n if (!isColorChannel(channel)) {\n return log.message.cannotUseScalePropertyWithNonColor(channel);\n }\n return undefined;\n case 'type':\n case 'domain':\n case 'range':\n case 'base':\n case 'exponent':\n case 'nice':\n case 'padding':\n case 'paddingInner':\n case 'paddingOuter':\n case 'rangeStep':\n case 'reverse':\n case 'round':\n case 'clamp':\n case 'zero':\n return undefined; // GOOD!\n }\n /* istanbul ignore next: it should never reach here */\n throw new Error(`Invalid scale property \"${propName}\".`);\n}\n\nexport function scaleTypeSupportDataType(specifiedType: ScaleType, fieldDefType: Type, bin: boolean|BinParams):boolean {\n if (contains([Type.ORDINAL, Type.NOMINAL], fieldDefType)) {\n return specifiedType === undefined || hasDiscreteDomain(specifiedType);\n } else if (fieldDefType === Type.TEMPORAL) {\n return contains([ScaleType.TIME, ScaleType.UTC, ScaleType.SEQUENTIAL, undefined], specifiedType);\n } else if (fieldDefType === Type.QUANTITATIVE) {\n if (bin) {\n return contains([ScaleType.BIN_LINEAR, ScaleType.BIN_ORDINAL, ScaleType.LINEAR], specifiedType);\n }\n return contains([ScaleType.LOG, ScaleType.POW, ScaleType.SQRT, ScaleType.QUANTILE, ScaleType.QUANTIZE, ScaleType.LINEAR, ScaleType.SEQUENTIAL, undefined], specifiedType);\n }\n\n return true;\n}\n\nexport function channelSupportScaleType(channel: Channel, scaleType: ScaleType): boolean {\n switch (channel) {\n case Channel.X:\n case Channel.Y:\n case Channel.SIZE: // TODO: size and opacity can support ordinal with more modification\n case Channel.OPACITY:\n // Although it generally doesn't make sense to use band with size and opacity,\n // it can also work since we use band: 0.5 to get midpoint.\n return isContinuousToContinuous(scaleType) || contains(['band', 'point'], scaleType);\n\n case Channel.COLOR:\n case Channel.FILL:\n case Channel.STROKE:\n return scaleType !== 'band'; // band does not make sense with color\n\n case Channel.SHAPE:\n return scaleType === 'ordinal'; // shape = lookup only\n }\n /* istanbul ignore next: it should never reach here */\n return false;\n}\n\nexport function getSupportedScaleType(channel: Channel, fieldDefType: Type, bin?: boolean) {\n return SCALE_TYPE_INDEX[generateScaleTypeIndexKey(channel, fieldDefType, bin)];\n}\n\nexport interface ScaleTypeIndex {\n [channel: string]: ScaleType[];\n}\n\n// generates ScaleTypeIndex where keys are encoding channels and values are list of valid ScaleTypes\nfunction generateScaleTypeIndex() {\n const index: ScaleTypeIndex = {};\n for (const channel of CHANNELS) {\n for (const fieldDefType of keys(TYPE_INDEX)) {\n for (const scaleType of SCALE_TYPES) {\n for (const bin of [false, true]) {\n const key = generateScaleTypeIndexKey(channel, fieldDefType, bin);\n if (channelSupportScaleType(channel, scaleType) && scaleTypeSupportDataType(scaleType, fieldDefType, bin)) {\n index[key] = index[key] || [];\n index[key].push(scaleType);\n }\n }\n }\n }\n }\n return index;\n}\n\nfunction generateScaleTypeIndexKey(channel: Channel, fieldDefType: Type, bin: boolean) {\n const key = channel + '_' + fieldDefType;\n return bin ? key + '_bin' : key;\n}\n"]} \ No newline at end of file diff --git a/build/src/selection.d.ts b/build/src/selection.d.ts new file mode 100644 index 0000000000..c81e849c37 --- /dev/null +++ b/build/src/selection.d.ts @@ -0,0 +1,183 @@ +import { SingleDefChannel } from './channel'; +import { VgBinding, VgEventStream } from './vega.schema'; +export declare const SELECTION_ID = "_vgsid_"; +export declare type SelectionType = 'single' | 'multi' | 'interval'; +export declare type SelectionResolution = 'global' | 'union' | 'intersect'; +export interface BaseSelectionDef { + /** + * A [Vega event stream](https://vega.github.io/vega/docs/event-streams/) (object or selector) that triggers the selection. + * For interval selections, the event stream must specify a [start and end](https://vega.github.io/vega/docs/event-streams/#between-filters). + */ + on?: VgEventStream; + /** + * With layered and multi-view displays, a strategy that determines how + * selections' data queries are resolved when applied in a filter transform, + * conditional encoding rule, or scale domain. + * + */ + resolve?: SelectionResolution; + /** + * An array of encoding channels. The corresponding data field values + * must match for a data tuple to fall within the selection. + */ + encodings?: SingleDefChannel[]; + /** + * An array of field names whose values must match for a data tuple to + * fall within the selection. + */ + fields?: string[]; + /** + * By default, all data values are considered to lie within an empty selection. + * When set to `none`, empty selections contain no data values. + */ + empty?: 'all' | 'none'; +} +export interface SingleSelectionConfig extends BaseSelectionDef { + /** + * Establish a two-way binding between a single selection and input elements + * (also known as dynamic query widgets). A binding takes the form of + * Vega's [input element binding definition](https://vega.github.io/vega/docs/signals/#bind) + * or can be a mapping between projected field/encodings and binding definitions. + * + * See the [bind transform](https://vega.github.io/vega-lite/docs/bind.html) documentation for more information. + */ + bind?: VgBinding | { + [key: string]: VgBinding; + }; + /** + * When true, an invisible voronoi diagram is computed to accelerate discrete + * selection. The data value _nearest_ the mouse cursor is added to the selection. + * + * See the [nearest transform](https://vega.github.io/vega-lite/docs/nearest.html) documentation for more information. + */ + nearest?: boolean; +} +export interface MultiSelectionConfig extends BaseSelectionDef { + /** + * Controls whether data values should be toggled or only ever inserted into + * multi selections. Can be `true`, `false` (for insertion only), or a + * [Vega expression](https://vega.github.io/vega/docs/expressions/). + * + * __Default value:__ `true`, which corresponds to `event.shiftKey` (i.e., + * data values are toggled when a user interacts with the shift-key pressed). + * + * See the [toggle transform](https://vega.github.io/vega-lite/docs/toggle.html) documentation for more information. + */ + toggle?: string | boolean; + /** + * When true, an invisible voronoi diagram is computed to accelerate discrete + * selection. The data value _nearest_ the mouse cursor is added to the selection. + * + * See the [nearest transform](https://vega.github.io/vega-lite/docs/nearest.html) documentation for more information. + */ + nearest?: boolean; +} +export interface BrushConfig { + /** + * The fill color of the interval mark. + * + * __Default value:__ `#333333` + * + */ + fill?: string; + /** + * The fill opacity of the interval mark (a value between 0 and 1). + * + * __Default value:__ `0.125` + */ + fillOpacity?: number; + /** + * The stroke color of the interval mark. + * + * __Default value:__ `#ffffff` + */ + stroke?: string; + /** + * The stroke opacity of the interval mark (a value between 0 and 1). + */ + strokeOpacity?: number; + /** + * The stroke width of the interval mark. + */ + strokeWidth?: number; + /** + * An array of alternating stroke and space lengths, + * for creating dashed or dotted lines. + */ + strokeDash?: number[]; + /** + * The offset (in pixels) with which to begin drawing the stroke dash array. + */ + strokeDashOffset?: number; +} +export interface IntervalSelectionConfig extends BaseSelectionDef { + /** + * When truthy, allows a user to interactively move an interval selection + * back-and-forth. Can be `true`, `false` (to disable panning), or a + * [Vega event stream definition](https://vega.github.io/vega/docs/event-streams/) + * which must include a start and end event to trigger continuous panning. + * + * __Default value:__ `true`, which corresponds to + * `[mousedown, window:mouseup] > window:mousemove!` which corresponds to + * clicks and dragging within an interval selection to reposition it. + */ + translate?: string | boolean; + /** + * When truthy, allows a user to interactively resize an interval selection. + * Can be `true`, `false` (to disable zooming), or a [Vega event stream + * definition](https://vega.github.io/vega/docs/event-streams/). Currently, + * only `wheel` events are supported. + * + * + * __Default value:__ `true`, which corresponds to `wheel!`. + */ + zoom?: string | boolean; + /** + * Establishes a two-way binding between the interval selection and the scales + * used within the same view. This allows a user to interactively pan and + * zoom the view. + */ + bind?: 'scales'; + /** + * An interval selection also adds a rectangle mark to depict the + * extents of the interval. The `mark` property can be used to customize the + * appearance of the mark. + */ + mark?: BrushConfig; +} +export interface SingleSelection extends SingleSelectionConfig { + type: 'single'; +} +export interface MultiSelection extends MultiSelectionConfig { + type: 'multi'; +} +export interface IntervalSelection extends IntervalSelectionConfig { + type: 'interval'; +} +export declare type SelectionDef = SingleSelection | MultiSelection | IntervalSelection; +export interface SelectionConfig { + /** + * The default definition for a [`single`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations + * for a single selection definition (except `type`) may be specified here. + * + * For instance, setting `single` to `{"on": "dblclick"}` populates single selections on double-click by default. + */ + single?: SingleSelectionConfig; + /** + * The default definition for a [`multi`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations + * for a multi selection definition (except `type`) may be specified here. + * + * For instance, setting `multi` to `{"toggle": "event.altKey"}` adds additional values to + * multi selections when clicking with the alt-key pressed by default. + */ + multi?: MultiSelectionConfig; + /** + * The default definition for an [`interval`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations + * for an interval selection definition (except `type`) may be specified here. + * + * For instance, setting `interval` to `{"translate": false}` disables the ability to move + * interval selections by default. + */ + interval?: IntervalSelectionConfig; +} +export declare const defaultConfig: SelectionConfig; diff --git a/build/src/selection.js b/build/src/selection.js new file mode 100644 index 0000000000..04cbbef056 --- /dev/null +++ b/build/src/selection.js @@ -0,0 +1,25 @@ +export var SELECTION_ID = '_vgsid_'; +export var defaultConfig = { + single: { + on: 'click', + fields: [SELECTION_ID], + resolve: 'global', + empty: 'all' + }, + multi: { + on: 'click', + fields: [SELECTION_ID], + toggle: 'event.shiftKey', + resolve: 'global', + empty: 'all' + }, + interval: { + on: '[mousedown, window:mouseup] > window:mousemove!', + encodings: ['x', 'y'], + translate: '[mousedown, window:mouseup] > window:mousemove!', + zoom: 'wheel!', + mark: { fill: '#333', fillOpacity: 0.125, stroke: 'white' }, + resolve: 'global' + } +}; +//# sourceMappingURL=selection.js.map \ No newline at end of file diff --git a/build/src/selection.js.map b/build/src/selection.js.map new file mode 100644 index 0000000000..e8158c4a5e --- /dev/null +++ b/build/src/selection.js.map @@ -0,0 +1 @@ +{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/selection.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,IAAM,YAAY,GAAG,SAAS,CAAC;AA2MtC,MAAM,CAAC,IAAM,aAAa,GAAmB;IAC3C,MAAM,EAAE;QACN,EAAE,EAAE,OAAO;QACX,MAAM,EAAE,CAAC,YAAY,CAAC;QACtB,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,KAAK;KACb;IACD,KAAK,EAAE;QACL,EAAE,EAAE,OAAO;QACX,MAAM,EAAE,CAAC,YAAY,CAAC;QACtB,MAAM,EAAE,gBAAgB;QACxB,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,KAAK;KACb;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,iDAAiD;QACrD,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;QACrB,SAAS,EAAE,iDAAiD;QAC5D,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAC;QACzD,OAAO,EAAE,QAAQ;KAClB;CACF,CAAC","sourcesContent":["import {SingleDefChannel} from './channel';\nimport {VgBinding, VgEventStream} from './vega.schema';\n\nexport const SELECTION_ID = '_vgsid_';\nexport type SelectionType = 'single' | 'multi' | 'interval';\nexport type SelectionResolution = 'global' | 'union' | 'intersect';\n\nexport interface BaseSelectionDef {\n /**\n * A [Vega event stream](https://vega.github.io/vega/docs/event-streams/) (object or selector) that triggers the selection.\n * For interval selections, the event stream must specify a [start and end](https://vega.github.io/vega/docs/event-streams/#between-filters).\n */\n on?: VgEventStream;\n /**\n * With layered and multi-view displays, a strategy that determines how\n * selections' data queries are resolved when applied in a filter transform,\n * conditional encoding rule, or scale domain.\n *\n */\n resolve?: SelectionResolution;\n\n // TODO(https://github.com/vega/vega-lite/issues/2596).\n // predicate?: string;\n // domain?: SelectionDomain;\n\n // Transforms\n\n /**\n * An array of encoding channels. The corresponding data field values\n * must match for a data tuple to fall within the selection.\n */\n encodings?: SingleDefChannel[];\n\n /**\n * An array of field names whose values must match for a data tuple to\n * fall within the selection.\n */\n fields?: string[];\n\n /**\n * By default, all data values are considered to lie within an empty selection.\n * When set to `none`, empty selections contain no data values.\n */\n empty?: 'all' | 'none';\n}\n\nexport interface SingleSelectionConfig extends BaseSelectionDef {\n /**\n * Establish a two-way binding between a single selection and input elements\n * (also known as dynamic query widgets). A binding takes the form of\n * Vega's [input element binding definition](https://vega.github.io/vega/docs/signals/#bind)\n * or can be a mapping between projected field/encodings and binding definitions.\n *\n * See the [bind transform](https://vega.github.io/vega-lite/docs/bind.html) documentation for more information.\n */\n bind?: VgBinding | {[key: string]: VgBinding};\n\n /**\n * When true, an invisible voronoi diagram is computed to accelerate discrete\n * selection. The data value _nearest_ the mouse cursor is added to the selection.\n *\n * See the [nearest transform](https://vega.github.io/vega-lite/docs/nearest.html) documentation for more information.\n */\n nearest?: boolean;\n}\n\nexport interface MultiSelectionConfig extends BaseSelectionDef {\n /**\n * Controls whether data values should be toggled or only ever inserted into\n * multi selections. Can be `true`, `false` (for insertion only), or a\n * [Vega expression](https://vega.github.io/vega/docs/expressions/).\n *\n * __Default value:__ `true`, which corresponds to `event.shiftKey` (i.e.,\n * data values are toggled when a user interacts with the shift-key pressed).\n *\n * See the [toggle transform](https://vega.github.io/vega-lite/docs/toggle.html) documentation for more information.\n */\n toggle?: string | boolean;\n\n /**\n * When true, an invisible voronoi diagram is computed to accelerate discrete\n * selection. The data value _nearest_ the mouse cursor is added to the selection.\n *\n * See the [nearest transform](https://vega.github.io/vega-lite/docs/nearest.html) documentation for more information.\n */\n nearest?: boolean;\n}\n\nexport interface BrushConfig {\n /**\n * The fill color of the interval mark.\n *\n * __Default value:__ `#333333`\n *\n */\n fill?: string;\n /**\n * The fill opacity of the interval mark (a value between 0 and 1).\n *\n * __Default value:__ `0.125`\n */\n fillOpacity?: number;\n /**\n * The stroke color of the interval mark.\n *\n * __Default value:__ `#ffffff`\n */\n stroke?: string;\n /**\n * The stroke opacity of the interval mark (a value between 0 and 1).\n */\n strokeOpacity?: number;\n /**\n * The stroke width of the interval mark.\n */\n strokeWidth?: number;\n /**\n * An array of alternating stroke and space lengths,\n * for creating dashed or dotted lines.\n */\n strokeDash?: number[];\n /**\n * The offset (in pixels) with which to begin drawing the stroke dash array.\n */\n strokeDashOffset?: number;\n}\n\nexport interface IntervalSelectionConfig extends BaseSelectionDef {\n /**\n * When truthy, allows a user to interactively move an interval selection\n * back-and-forth. Can be `true`, `false` (to disable panning), or a\n * [Vega event stream definition](https://vega.github.io/vega/docs/event-streams/)\n * which must include a start and end event to trigger continuous panning.\n *\n * __Default value:__ `true`, which corresponds to\n * `[mousedown, window:mouseup] > window:mousemove!` which corresponds to\n * clicks and dragging within an interval selection to reposition it.\n */\n translate?: string | boolean;\n\n /**\n * When truthy, allows a user to interactively resize an interval selection.\n * Can be `true`, `false` (to disable zooming), or a [Vega event stream\n * definition](https://vega.github.io/vega/docs/event-streams/). Currently,\n * only `wheel` events are supported.\n *\n *\n * __Default value:__ `true`, which corresponds to `wheel!`.\n */\n zoom?: string | boolean;\n\n /**\n * Establishes a two-way binding between the interval selection and the scales\n * used within the same view. This allows a user to interactively pan and\n * zoom the view.\n */\n bind?: 'scales';\n\n /**\n * An interval selection also adds a rectangle mark to depict the\n * extents of the interval. The `mark` property can be used to customize the\n * appearance of the mark.\n */\n mark?: BrushConfig;\n}\n\nexport interface SingleSelection extends SingleSelectionConfig {\n type: 'single';\n}\n\nexport interface MultiSelection extends MultiSelectionConfig {\n type: 'multi';\n}\n\nexport interface IntervalSelection extends IntervalSelectionConfig {\n type: 'interval';\n}\n\nexport type SelectionDef = SingleSelection | MultiSelection | IntervalSelection;\n\nexport interface SelectionConfig {\n /**\n * The default definition for a [`single`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations\n * for a single selection definition (except `type`) may be specified here.\n *\n * For instance, setting `single` to `{\"on\": \"dblclick\"}` populates single selections on double-click by default.\n */\n single?: SingleSelectionConfig;\n /**\n * The default definition for a [`multi`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations\n * for a multi selection definition (except `type`) may be specified here.\n *\n * For instance, setting `multi` to `{\"toggle\": \"event.altKey\"}` adds additional values to\n * multi selections when clicking with the alt-key pressed by default.\n */\n multi?: MultiSelectionConfig;\n /**\n * The default definition for an [`interval`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations\n * for an interval selection definition (except `type`) may be specified here.\n *\n * For instance, setting `interval` to `{\"translate\": false}` disables the ability to move\n * interval selections by default.\n */\n interval?: IntervalSelectionConfig;\n}\n\nexport const defaultConfig:SelectionConfig = {\n single: {\n on: 'click',\n fields: [SELECTION_ID],\n resolve: 'global',\n empty: 'all'\n },\n multi: {\n on: 'click',\n fields: [SELECTION_ID],\n toggle: 'event.shiftKey',\n resolve: 'global',\n empty: 'all'\n },\n interval: {\n on: '[mousedown, window:mouseup] > window:mousemove!',\n encodings: ['x', 'y'],\n translate: '[mousedown, window:mouseup] > window:mousemove!',\n zoom: 'wheel!',\n mark: {fill: '#333', fillOpacity: 0.125, stroke: 'white'},\n resolve: 'global'\n }\n};\n"]} \ No newline at end of file diff --git a/build/src/sort.d.ts b/build/src/sort.d.ts new file mode 100644 index 0000000000..ac3b26a3b1 --- /dev/null +++ b/build/src/sort.d.ts @@ -0,0 +1,43 @@ +import { AggregateOp } from 'vega'; +import { DateTime } from './datetime'; +import { VgComparatorOrder } from './vega.schema'; +export declare type SortOrder = VgComparatorOrder | null; +/** + * A sort definition for transform + */ +export interface SortField { + /** + * The name of the field to sort. + */ + field: string; + /** + * Whether to sort the field in ascending or descending order. + */ + order?: VgComparatorOrder; +} +/** + * A sort definition for sorting a discrete scale in an encoding field definition. + */ +export interface EncodingSortField { + /** + * The data [field](https://vega.github.io/vega-lite/docs/field.html) to sort by. + * + * __Default value:__ If unspecified, defaults to the field specified in the outer data reference. + */ + field?: F; + /** + * An [aggregate operation](https://vega.github.io/vega-lite/docs/aggregate.html#ops) to perform on the field prior to sorting (e.g., `"count"`, `"mean"` and `"median"`). + * This property is required in cases where the sort field and the data reference field do not match. + * The input data objects will be aggregated, grouped by the encoded data field. + * + * For a full list of operations, please see the documentation for [aggregate](https://vega.github.io/vega-lite/docs/aggregate.html#ops). + */ + op: AggregateOp; + /** + * The sort order. One of `"ascending"` (default), `"descending"`, or `null` (no not sort). + */ + order?: SortOrder; +} +export declare type Sort = number[] | string[] | boolean[] | DateTime[] | SortOrder | EncodingSortField | null; +export declare function isSortField(sort: Sort): sort is EncodingSortField; +export declare function isSortArray(sort: Sort): sort is number[] | string[] | boolean[] | DateTime[]; diff --git a/build/src/sort.js b/build/src/sort.js new file mode 100644 index 0000000000..7a0cceba8e --- /dev/null +++ b/build/src/sort.js @@ -0,0 +1,8 @@ +import { isArray } from 'vega-util'; +export function isSortField(sort) { + return !!sort && (sort['op'] === 'count' || !!sort['field']) && !!sort['op']; +} +export function isSortArray(sort) { + return !!sort && isArray(sort); +} +//# sourceMappingURL=sort.js.map \ No newline at end of file diff --git a/build/src/sort.js.map b/build/src/sort.js.map new file mode 100644 index 0000000000..85e8fee2a4 --- /dev/null +++ b/build/src/sort.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../src/sort.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAmDlC,MAAM,sBAAyB,IAAa;IAC1C,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,sBAAyB,IAAa;IAC1C,OAAO,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC","sourcesContent":["import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {DateTime} from './datetime';\nimport {VgComparatorOrder} from './vega.schema';\n\nexport type SortOrder = VgComparatorOrder | null;\n\n\n/**\n * A sort definition for transform\n */\nexport interface SortField {\n /**\n * The name of the field to sort.\n */\n field: string;\n\n /**\n * Whether to sort the field in ascending or descending order.\n */\n order?: VgComparatorOrder;\n}\n\n\n/**\n * A sort definition for sorting a discrete scale in an encoding field definition.\n */\n\nexport interface EncodingSortField {\n /**\n * The data [field](https://vega.github.io/vega-lite/docs/field.html) to sort by.\n *\n * __Default value:__ If unspecified, defaults to the field specified in the outer data reference.\n */\n field?: F;\n /**\n * An [aggregate operation](https://vega.github.io/vega-lite/docs/aggregate.html#ops) to perform on the field prior to sorting (e.g., `\"count\"`, `\"mean\"` and `\"median\"`).\n * This property is required in cases where the sort field and the data reference field do not match.\n * The input data objects will be aggregated, grouped by the encoded data field.\n *\n * For a full list of operations, please see the documentation for [aggregate](https://vega.github.io/vega-lite/docs/aggregate.html#ops).\n */\n op: AggregateOp;\n\n /**\n * The sort order. One of `\"ascending\"` (default), `\"descending\"`, or `null` (no not sort).\n */\n order?: SortOrder;\n}\n\nexport type Sort = number[] | string[] | boolean[] | DateTime[] | SortOrder | EncodingSortField | null;\n\nexport function isSortField(sort: Sort): sort is EncodingSortField {\n return !!sort && (sort['op'] === 'count' || !!sort['field']) && !!sort['op'];\n}\n\nexport function isSortArray(sort: Sort): sort is number[] | string[] | boolean[] | DateTime[] {\n return !!sort && isArray(sort);\n}\n"]} \ No newline at end of file diff --git a/build/src/spec.d.ts b/build/src/spec.d.ts new file mode 100644 index 0000000000..d38627ba01 --- /dev/null +++ b/build/src/spec.d.ts @@ -0,0 +1,204 @@ +import { Config } from './config'; +import { Data } from './data'; +import { Encoding, EncodingWithFacet } from './encoding'; +import { FacetMapping } from './facet'; +import { FieldDef, RepeatRef } from './fielddef'; +import { AnyMark, Mark, MarkDef } from './mark'; +import { Projection } from './projection'; +import { Repeat } from './repeat'; +import { Resolve } from './resolve'; +import { SelectionDef } from './selection'; +import { TitleParams } from './title'; +import { ConcatLayout, GenericCompositionLayout, TopLevelProperties } from './toplevelprops'; +import { Transform } from './transform'; +export declare type TopLevel = S & TopLevelProperties & { + /** + * URL to [JSON schema](http://json-schema.org/) for a Vega-Lite specification. Unless you have a reason to change this, use `https://vega.github.io/schema/vega-lite/v2.json`. Setting the `$schema` property allows automatic validation and autocomplete in editors that support JSON schema. + * @format uri + */ + $schema?: string; + /** + * Vega-Lite configuration object. This property can only be defined at the top-level of a specification. + */ + config?: Config; +}; +export declare type BaseSpec = Partial & { + /** + * Title for the plot. + */ + title?: string | TitleParams; + /** + * Name of the visualization for later reference. + */ + name?: string; + /** + * Description of this mark for commenting purpose. + */ + description?: string; + /** + * An object describing the data source + */ + data?: Data; + /** + * An array of data transformations such as filter and new field calculation. + */ + transform?: Transform[]; +}; +export declare type DataMixins = { + /** + * An object describing the data source + */ + data: Data; +}; +export interface LayoutSizeMixins { + /** + * The width of a visualization. + * + * __Default value:__ This will be determined by the following rules: + * + * - If a view's [`autosize`](https://vega.github.io/vega-lite/docs/size.html#autosize) type is `"fit"` or its x-channel has a [continuous scale](https://vega.github.io/vega-lite/docs/scale.html#continuous), the width will be the value of [`config.view.width`](https://vega.github.io/vega-lite/docs/spec.html#config). + * - For x-axis with a band or point scale: if [`rangeStep`](https://vega.github.io/vega-lite/docs/scale.html#band) is a numeric value or unspecified, the width is [determined by the range step, paddings, and the cardinality of the field mapped to x-channel](https://vega.github.io/vega-lite/docs/scale.html#band). Otherwise, if the `rangeStep` is `null`, the width will be the value of [`config.view.width`](https://vega.github.io/vega-lite/docs/spec.html#config). + * - If no field is mapped to `x` channel, the `width` will be the value of [`config.scale.textXRangeStep`](https://vega.github.io/vega-lite/docs/size.html#default-width-and-height) for `text` mark and the value of `rangeStep` for other marks. + * + * __Note:__ For plots with [`row` and `column` channels](https://vega.github.io/vega-lite/docs/encoding.html#facet), this represents the width of a single view. + * + * __See also:__ The documentation for [width and height](https://vega.github.io/vega-lite/docs/size.html) contains more examples. + */ + width?: number; + /** + * The height of a visualization. + * + * __Default value:__ + * - If a view's [`autosize`](https://vega.github.io/vega-lite/docs/size.html#autosize) type is `"fit"` or its y-channel has a [continuous scale](https://vega.github.io/vega-lite/docs/scale.html#continuous), the height will be the value of [`config.view.height`](https://vega.github.io/vega-lite/docs/spec.html#config). + * - For y-axis with a band or point scale: if [`rangeStep`](https://vega.github.io/vega-lite/docs/scale.html#band) is a numeric value or unspecified, the height is [determined by the range step, paddings, and the cardinality of the field mapped to y-channel](https://vega.github.io/vega-lite/docs/scale.html#band). Otherwise, if the `rangeStep` is `null`, the height will be the value of [`config.view.height`](https://vega.github.io/vega-lite/docs/spec.html#config). + * - If no field is mapped to `y` channel, the `height` will be the value of `rangeStep`. + * + * __Note__: For plots with [`row` and `column` channels](https://vega.github.io/vega-lite/docs/encoding.html#facet), this represents the height of a single view. + * + * __See also:__ The documentation for [width and height](https://vega.github.io/vega-lite/docs/size.html) contains more examples. + */ + height?: number; +} +export interface GenericUnitSpec, M> extends BaseSpec, LayoutSizeMixins { + /** + * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`, `"line"`, + * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition object](https://vega.github.io/vega-lite/docs/mark.html#mark-def). + */ + mark: M; + /** + * A key-value mapping between encoding channels and definition of fields. + */ + encoding?: E; + /** + * An object defining properties of geographic projection, which will be applied to `shape` path for `"geoshape"` marks + * and to `latitude` and `"longitude"` channels for other marks. + */ + projection?: Projection; + /** + * A key-value mapping between selection names and definitions. + */ + selection?: { + [name: string]: SelectionDef; + }; +} +export declare type NormalizedUnitSpec = GenericUnitSpec, Mark | MarkDef>; +/** + * Unit spec that can have a composite mark. + */ +export declare type CompositeUnitSpec = GenericUnitSpec, AnyMark>; +/** + * Unit spec that can have a composite mark and row or column channels. + */ +export declare type FacetedCompositeUnitSpec = GenericUnitSpec, AnyMark>; +export interface GenericLayerSpec> extends BaseSpec, LayoutSizeMixins { + /** + * Layer or single view specifications to be layered. + * + * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as layering facet specifications is not allowed. + */ + layer: (GenericLayerSpec | U)[]; + /** + * Scale, axis, and legend resolutions for layers. + */ + resolve?: Resolve; +} +/** + * Layer Spec with encoding and projection + */ +export interface ExtendedLayerSpec extends GenericLayerSpec { + /** + * A shared key-value mapping between encoding channels and definition of fields in the underlying layers. + */ + encoding?: Encoding; + /** + * An object defining properties of the geographic projection shared by underlying layers. + */ + projection?: Projection; +} +export declare type NormalizedLayerSpec = GenericLayerSpec; +export interface GenericFacetSpec, L extends GenericLayerSpec> extends BaseSpec, GenericCompositionLayout { + /** + * An object that describes mappings between `row` and `column` channels and their field definitions. + */ + facet: FacetMapping; + /** + * A specification of the view that gets faceted. + */ + spec: L | U; + /** + * Scale, axis, and legend resolutions for facets. + */ + resolve?: Resolve; +} +export declare type NormalizedFacetSpec = GenericFacetSpec; +export interface GenericRepeatSpec, L extends GenericLayerSpec> extends BaseSpec, GenericCompositionLayout { + /** + * An object that describes what fields should be repeated into views that are laid out as a `row` or `column`. + */ + repeat: Repeat; + spec: GenericSpec; + /** + * Scale and legend resolutions for repeated charts. + */ + resolve?: Resolve; +} +export declare type NormalizedRepeatSpec = GenericRepeatSpec; +export interface GenericVConcatSpec, L extends GenericLayerSpec> extends BaseSpec, ConcatLayout { + /** + * A list of views that should be concatenated and put into a column. + */ + vconcat: (GenericSpec)[]; + /** + * Scale, axis, and legend resolutions for vertically concatenated charts. + */ + resolve?: Resolve; +} +export interface GenericHConcatSpec, L extends GenericLayerSpec> extends BaseSpec, ConcatLayout { + /** + * A list of views that should be concatenated and put into a row. + */ + hconcat: (GenericSpec)[]; + /** + * Scale, axis, and legend resolutions for horizontally concatenated charts. + */ + resolve?: Resolve; +} +export declare type NormalizedConcatSpec = GenericVConcatSpec | GenericHConcatSpec; +export declare type GenericSpec, L extends GenericLayerSpec> = U | L | GenericFacetSpec | GenericRepeatSpec | GenericVConcatSpec | GenericHConcatSpec; +export declare type NormalizedSpec = GenericSpec; +export declare type TopLevelFacetedUnitSpec = TopLevel & DataMixins; +export declare type TopLevelFacetSpec = TopLevel> & DataMixins; +export declare type TopLevelSpec = TopLevelFacetedUnitSpec | TopLevelFacetSpec | TopLevel | TopLevel> | TopLevel> | TopLevel>; +export declare function isFacetSpec(spec: BaseSpec): spec is GenericFacetSpec; +export declare function isUnitSpec(spec: BaseSpec): spec is FacetedCompositeUnitSpec | NormalizedUnitSpec; +export declare function isLayerSpec(spec: BaseSpec): spec is GenericLayerSpec; +export declare function isRepeatSpec(spec: BaseSpec): spec is GenericRepeatSpec; +export declare function isConcatSpec(spec: BaseSpec): spec is GenericVConcatSpec | GenericHConcatSpec; +export declare function isVConcatSpec(spec: BaseSpec): spec is GenericVConcatSpec; +export declare function isHConcatSpec(spec: BaseSpec): spec is GenericHConcatSpec; +/** + * Decompose extended unit specs into composition of pure unit specs. + */ +export declare function normalize(spec: TopLevelSpec | GenericSpec | FacetedCompositeUnitSpec, config: Config): NormalizedSpec; +export declare function fieldDefs(spec: GenericSpec): FieldDef[]; +export declare function isStacked(spec: TopLevel, config?: Config): boolean; diff --git a/build/src/spec.js b/build/src/spec.js new file mode 100644 index 0000000000..bac19d29c4 --- /dev/null +++ b/build/src/spec.js @@ -0,0 +1,303 @@ +import * as tslib_1 from "tslib"; +import { isObject } from 'vega-util'; +import { COLUMN, ROW, X, X2, Y, Y2 } from './channel'; +import * as compositeMark from './compositemark'; +import * as vlEncoding from './encoding'; +import { channelHasField, isRanged } from './encoding'; +import * as log from './log'; +import { isMarkDef, isPathMark, isPrimitiveMark } from './mark'; +import { stack } from './stack'; +import { duplicate, hash, keys, omit, pick, vals } from './util'; +/* Custom type guards */ +export function isFacetSpec(spec) { + return spec['facet'] !== undefined; +} +export function isUnitSpec(spec) { + return !!spec['mark']; +} +export function isLayerSpec(spec) { + return spec['layer'] !== undefined; +} +export function isRepeatSpec(spec) { + return spec['repeat'] !== undefined; +} +export function isConcatSpec(spec) { + return isVConcatSpec(spec) || isHConcatSpec(spec); +} +export function isVConcatSpec(spec) { + return spec['vconcat'] !== undefined; +} +export function isHConcatSpec(spec) { + return spec['hconcat'] !== undefined; +} +/** + * Decompose extended unit specs into composition of pure unit specs. + */ +// TODO: consider moving this to another file. Maybe vl.spec.normalize or vl.normalize +export function normalize(spec, config) { + if (isFacetSpec(spec)) { + return normalizeFacet(spec, config); + } + if (isLayerSpec(spec)) { + return normalizeLayer(spec, config); + } + if (isRepeatSpec(spec)) { + return normalizeRepeat(spec, config); + } + if (isVConcatSpec(spec)) { + return normalizeVConcat(spec, config); + } + if (isHConcatSpec(spec)) { + return normalizeHConcat(spec, config); + } + if (isUnitSpec(spec)) { + var hasRow = channelHasField(spec.encoding, ROW); + var hasColumn = channelHasField(spec.encoding, COLUMN); + if (hasRow || hasColumn) { + return normalizeFacetedUnit(spec, config); + } + return normalizeNonFacetUnit(spec, config); + } + throw new Error(log.message.INVALID_SPEC); +} +function normalizeFacet(spec, config) { + var subspec = spec.spec, rest = tslib_1.__rest(spec, ["spec"]); + return tslib_1.__assign({}, rest, { + // TODO: remove "any" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760 + spec: normalize(subspec, config) }); +} +function mergeEncoding(opt) { + var parentEncoding = opt.parentEncoding, encoding = opt.encoding; + if (parentEncoding && encoding) { + var overriden = keys(parentEncoding).reduce(function (o, key) { + if (encoding[key]) { + o.push(key); + } + return o; + }, []); + if (overriden.length > 0) { + log.warn(log.message.encodingOverridden(overriden)); + } + } + var merged = tslib_1.__assign({}, (parentEncoding || {}), (encoding || {})); + return keys(merged).length > 0 ? merged : undefined; +} +function mergeProjection(opt) { + var parentProjection = opt.parentProjection, projection = opt.projection; + if (parentProjection && projection) { + log.warn(log.message.projectionOverridden({ parentProjection: parentProjection, projection: projection })); + } + return projection || parentProjection; +} +function normalizeLayer(spec, config, parentEncoding, parentProjection) { + var layer = spec.layer, encoding = spec.encoding, projection = spec.projection, rest = tslib_1.__rest(spec, ["layer", "encoding", "projection"]); + var mergedEncoding = mergeEncoding({ parentEncoding: parentEncoding, encoding: encoding }); + var mergedProjection = mergeProjection({ parentProjection: parentProjection, projection: projection }); + return tslib_1.__assign({}, rest, { layer: layer.map(function (subspec) { + if (isLayerSpec(subspec)) { + return normalizeLayer(subspec, config, mergedEncoding, mergedProjection); + } + return normalizeNonFacetUnit(subspec, config, mergedEncoding, mergedProjection); + }) }); +} +function normalizeRepeat(spec, config) { + var subspec = spec.spec, rest = tslib_1.__rest(spec, ["spec"]); + return tslib_1.__assign({}, rest, { spec: normalize(subspec, config) }); +} +function normalizeVConcat(spec, config) { + var vconcat = spec.vconcat, rest = tslib_1.__rest(spec, ["vconcat"]); + return tslib_1.__assign({}, rest, { vconcat: vconcat.map(function (subspec) { return normalize(subspec, config); }) }); +} +function normalizeHConcat(spec, config) { + var hconcat = spec.hconcat, rest = tslib_1.__rest(spec, ["hconcat"]); + return tslib_1.__assign({}, rest, { hconcat: hconcat.map(function (subspec) { return normalize(subspec, config); }) }); +} +function normalizeFacetedUnit(spec, config) { + // New encoding in the inside spec should not contain row / column + // as row/column should be moved to facet + var _a = spec.encoding, row = _a.row, column = _a.column, encoding = tslib_1.__rest(_a, ["row", "column"]); + // Mark and encoding should be moved into the inner spec + var mark = spec.mark, width = spec.width, projection = spec.projection, height = spec.height, selection = spec.selection, _ = spec.encoding, outerSpec = tslib_1.__rest(spec, ["mark", "width", "projection", "height", "selection", "encoding"]); + return tslib_1.__assign({}, outerSpec, { facet: tslib_1.__assign({}, (row ? { row: row } : {}), (column ? { column: column } : {})), spec: normalizeNonFacetUnit(tslib_1.__assign({}, (projection ? { projection: projection } : {}), { mark: mark }, (width ? { width: width } : {}), (height ? { height: height } : {}), { encoding: encoding }, (selection ? { selection: selection } : {})), config) }); +} +function isNonFacetUnitSpecWithPrimitiveMark(spec) { + return isPrimitiveMark(spec.mark); +} +function getPointOverlay(markDef, markConfig, encoding) { + if (markDef.point === 'transparent') { + return { opacity: 0 }; + } + else if (markDef.point) { // truthy : true or object + return isObject(markDef.point) ? markDef.point : {}; + } + else if (markDef.point !== undefined) { // false or null + return null; + } + else { // undefined (not disabled) + if (markConfig.point || encoding.shape) { + // enable point overlay if config[mark].point is truthy or if encoding.shape is provided + return isObject(markConfig.point) ? markConfig.point : {}; + } + // markDef.point is defined as falsy + return null; + } +} +function getLineOverlay(markDef, markConfig) { + if (markDef.line) { // true or object + return markDef.line === true ? {} : markDef.line; + } + else if (markDef.line !== undefined) { // false or null + return null; + } + else { // undefined (not disabled) + if (markConfig.line) { + // enable line overlay if config[mark].line is truthy + return markConfig.line === true ? {} : markConfig.line; + } + // markDef.point is defined as falsy + return null; + } +} +function normalizeNonFacetUnit(spec, config, parentEncoding, parentProjection) { + var encoding = spec.encoding, projection = spec.projection; + var mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + // merge parent encoding / projection first + if (parentEncoding || parentProjection) { + var mergedProjection = mergeProjection({ parentProjection: parentProjection, projection: projection }); + var mergedEncoding = mergeEncoding({ parentEncoding: parentEncoding, encoding: encoding }); + return normalizeNonFacetUnit(tslib_1.__assign({}, spec, (mergedProjection ? { projection: mergedProjection } : {}), (mergedEncoding ? { encoding: mergedEncoding } : {})), config); + } + if (isNonFacetUnitSpecWithPrimitiveMark(spec)) { + // TODO: thoroughly test + if (isRanged(encoding)) { + return normalizeRangedUnit(spec); + } + if (mark === 'line' && (encoding.x2 || encoding.y2)) { + log.warn(log.message.lineWithRange(!!encoding.x2, !!encoding.y2)); + return normalizeNonFacetUnit(tslib_1.__assign({ mark: 'rule' }, spec), config, parentEncoding, parentProjection); + } + if (isPathMark(mark)) { + return normalizePathOverlay(spec, config); + } + return spec; // Nothing to normalize + } + else { + return compositeMark.normalize(spec, config); + } +} +function normalizeRangedUnit(spec) { + var hasX = channelHasField(spec.encoding, X); + var hasY = channelHasField(spec.encoding, Y); + var hasX2 = channelHasField(spec.encoding, X2); + var hasY2 = channelHasField(spec.encoding, Y2); + if ((hasX2 && !hasX) || (hasY2 && !hasY)) { + var normalizedSpec = duplicate(spec); + if (hasX2 && !hasX) { + normalizedSpec.encoding.x = normalizedSpec.encoding.x2; + delete normalizedSpec.encoding.x2; + } + if (hasY2 && !hasY) { + normalizedSpec.encoding.y = normalizedSpec.encoding.y2; + delete normalizedSpec.encoding.y2; + } + return normalizedSpec; + } + return spec; +} +function dropLineAndPoint(markDef) { + var _point = markDef.point, _line = markDef.line, mark = tslib_1.__rest(markDef, ["point", "line"]); + return keys(mark).length > 1 ? mark : mark.type; +} +function normalizePathOverlay(spec, config) { + if (config === void 0) { config = {}; } + var _a; + // _ is used to denote a dropped property of the unit spec + // which should not be carried over to the layer spec + var selection = spec.selection, projection = spec.projection, encoding = spec.encoding, mark = spec.mark, outerSpec = tslib_1.__rest(spec, ["selection", "projection", "encoding", "mark"]); + var markDef = isMarkDef(mark) ? mark : { type: mark }; + var pointOverlay = getPointOverlay(markDef, config[markDef.type], encoding); + var lineOverlay = markDef.type === 'area' && getLineOverlay(markDef, config[markDef.type]); + if (!pointOverlay && !lineOverlay) { + return tslib_1.__assign({}, spec, { + // Do not include point / line overlay in the normalize spec + mark: dropLineAndPoint(markDef) }); + } + var layer = [tslib_1.__assign({}, (selection ? { selection: selection } : {}), { + // Do not include point / line overlay in the normalize spec + mark: dropLineAndPoint(tslib_1.__assign({}, markDef, (markDef.type === 'area' ? { opacity: 0.7 } : {}))), + // drop shape from encoding as this might be used to trigger point overlay + encoding: omit(encoding, ['shape']) })]; + // FIXME: determine rules for applying selections. + // Need to copy stack config to overlayed layer + var stackProps = stack(markDef, encoding, config ? config.stack : undefined); + var overlayEncoding = encoding; + if (stackProps) { + var stackFieldChannel = stackProps.fieldChannel, offset = stackProps.offset; + overlayEncoding = tslib_1.__assign({}, encoding, (_a = {}, _a[stackFieldChannel] = tslib_1.__assign({}, encoding[stackFieldChannel], (offset ? { stack: offset } : {})), _a)); + } + if (lineOverlay) { + layer.push(tslib_1.__assign({}, (projection ? { projection: projection } : {}), { mark: tslib_1.__assign({ type: 'line' }, pick(markDef, ['clip', 'interpolate']), lineOverlay), encoding: overlayEncoding })); + } + if (pointOverlay) { + layer.push(tslib_1.__assign({}, (projection ? { projection: projection } : {}), { mark: tslib_1.__assign({ type: 'point', opacity: 1, filled: true }, pick(markDef, ['clip']), pointOverlay), encoding: overlayEncoding })); + } + return tslib_1.__assign({}, outerSpec, { layer: layer }); +} +// TODO: add vl.spec.validate & move stuff from vl.validate to here +/* Accumulate non-duplicate fieldDefs in a dictionary */ +function accumulate(dict, defs) { + defs.forEach(function (fieldDef) { + // Consider only pure fieldDef properties (ignoring scale, axis, legend) + var pureFieldDef = ['field', 'type', 'value', 'timeUnit', 'bin', 'aggregate'].reduce(function (f, key) { + if (fieldDef[key] !== undefined) { + f[key] = fieldDef[key]; + } + return f; + }, {}); + var key = hash(pureFieldDef); + dict[key] = dict[key] || fieldDef; + }); + return dict; +} +/* Recursively get fieldDefs from a spec, returns a dictionary of fieldDefs */ +function fieldDefIndex(spec, dict) { + if (dict === void 0) { dict = {}; } + // FIXME(https://github.com/vega/vega-lite/issues/2207): Support fieldDefIndex for repeat + if (isLayerSpec(spec)) { + spec.layer.forEach(function (layer) { + if (isUnitSpec(layer)) { + accumulate(dict, vlEncoding.fieldDefs(layer.encoding)); + } + else { + fieldDefIndex(layer, dict); + } + }); + } + else if (isFacetSpec(spec)) { + accumulate(dict, vlEncoding.fieldDefs(spec.facet)); + fieldDefIndex(spec.spec, dict); + } + else if (isRepeatSpec(spec)) { + fieldDefIndex(spec.spec, dict); + } + else if (isConcatSpec(spec)) { + var childSpec = isVConcatSpec(spec) ? spec.vconcat : spec.hconcat; + childSpec.forEach(function (child) { return fieldDefIndex(child, dict); }); + } + else { // Unit Spec + accumulate(dict, vlEncoding.fieldDefs(spec.encoding)); + } + return dict; +} +/* Returns all non-duplicate fieldDefs in a spec in a flat array */ +export function fieldDefs(spec) { + return vals(fieldDefIndex(spec)); +} +export function isStacked(spec, config) { + config = config || spec.config; + if (isPrimitiveMark(spec.mark)) { + return stack(spec.mark, spec.encoding, config ? config.stack : undefined) !== null; + } + return false; +} +//# sourceMappingURL=spec.js.map \ No newline at end of file diff --git a/build/src/spec.js.map b/build/src/spec.js.map new file mode 100644 index 0000000000..1d92f156ce --- /dev/null +++ b/build/src/spec.js.map @@ -0,0 +1 @@ +{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/spec.ts"],"names":[],"mappings":"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","sourcesContent":["import {isObject} from 'vega-util';\nimport {COLUMN, ROW, X, X2, Y, Y2} from './channel';\nimport * as compositeMark from './compositemark';\nimport {Config} from './config';\nimport {Data} from './data';\nimport * as vlEncoding from './encoding';\nimport {channelHasField, Encoding, EncodingWithFacet, isRanged} from './encoding';\nimport {FacetMapping} from './facet';\nimport {Field, FieldDef, RepeatRef} from './fielddef';\nimport * as log from './log';\nimport {AnyMark, AreaConfig, isMarkDef, isPathMark, isPrimitiveMark, LineConfig, Mark, MarkConfig, MarkDef} from './mark';\nimport {Projection} from './projection';\nimport {Repeat} from './repeat';\nimport {Resolve} from './resolve';\nimport {SelectionDef} from './selection';\nimport {stack} from './stack';\nimport {TitleParams} from './title';\nimport {ConcatLayout, GenericCompositionLayout, TopLevelProperties} from './toplevelprops';\nimport {Transform} from './transform';\nimport {Dict, duplicate, hash, keys, omit, pick, vals} from './util';\n\n\nexport type TopLevel = S & TopLevelProperties & {\n /**\n * URL to [JSON schema](http://json-schema.org/) for a Vega-Lite specification. Unless you have a reason to change this, use `https://vega.github.io/schema/vega-lite/v2.json`. Setting the `$schema` property allows automatic validation and autocomplete in editors that support JSON schema.\n * @format uri\n */\n $schema?: string;\n\n /**\n * Vega-Lite configuration object. This property can only be defined at the top-level of a specification.\n */\n config?: Config;\n};\n\nexport type BaseSpec = Partial & {\n /**\n * Title for the plot.\n */\n title?: string | TitleParams;\n\n /**\n * Name of the visualization for later reference.\n */\n name?: string;\n\n /**\n * Description of this mark for commenting purpose.\n */\n description?: string;\n\n /**\n * An object describing the data source\n */\n data?: Data;\n\n /**\n * An array of data transformations such as filter and new field calculation.\n */\n transform?: Transform[];\n};\n\nexport type DataMixins = {\n /**\n * An object describing the data source\n */\n data: Data;\n};\n\n\n// TODO(https://github.com/vega/vega-lite/issues/2503): Make this generic so we can support some form of top-down sizing.\nexport interface LayoutSizeMixins {\n /**\n * The width of a visualization.\n *\n * __Default value:__ This will be determined by the following rules:\n *\n * - If a view's [`autosize`](https://vega.github.io/vega-lite/docs/size.html#autosize) type is `\"fit\"` or its x-channel has a [continuous scale](https://vega.github.io/vega-lite/docs/scale.html#continuous), the width will be the value of [`config.view.width`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - For x-axis with a band or point scale: if [`rangeStep`](https://vega.github.io/vega-lite/docs/scale.html#band) is a numeric value or unspecified, the width is [determined by the range step, paddings, and the cardinality of the field mapped to x-channel](https://vega.github.io/vega-lite/docs/scale.html#band). Otherwise, if the `rangeStep` is `null`, the width will be the value of [`config.view.width`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - If no field is mapped to `x` channel, the `width` will be the value of [`config.scale.textXRangeStep`](https://vega.github.io/vega-lite/docs/size.html#default-width-and-height) for `text` mark and the value of `rangeStep` for other marks.\n *\n * __Note:__ For plots with [`row` and `column` channels](https://vega.github.io/vega-lite/docs/encoding.html#facet), this represents the width of a single view.\n *\n * __See also:__ The documentation for [width and height](https://vega.github.io/vega-lite/docs/size.html) contains more examples.\n */\n width?: number;\n\n /**\n * The height of a visualization.\n *\n * __Default value:__\n * - If a view's [`autosize`](https://vega.github.io/vega-lite/docs/size.html#autosize) type is `\"fit\"` or its y-channel has a [continuous scale](https://vega.github.io/vega-lite/docs/scale.html#continuous), the height will be the value of [`config.view.height`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - For y-axis with a band or point scale: if [`rangeStep`](https://vega.github.io/vega-lite/docs/scale.html#band) is a numeric value or unspecified, the height is [determined by the range step, paddings, and the cardinality of the field mapped to y-channel](https://vega.github.io/vega-lite/docs/scale.html#band). Otherwise, if the `rangeStep` is `null`, the height will be the value of [`config.view.height`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - If no field is mapped to `y` channel, the `height` will be the value of `rangeStep`.\n *\n * __Note__: For plots with [`row` and `column` channels](https://vega.github.io/vega-lite/docs/encoding.html#facet), this represents the height of a single view.\n *\n * __See also:__ The documentation for [width and height](https://vega.github.io/vega-lite/docs/size.html) contains more examples.\n */\n height?: number;\n}\n\nexport interface GenericUnitSpec, M> extends BaseSpec, LayoutSizeMixins {\n\n /**\n * A string describing the mark type (one of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"rule\"`, `\"geoshape\"`, and `\"text\"`) or a [mark definition object](https://vega.github.io/vega-lite/docs/mark.html#mark-def).\n */\n mark: M;\n\n /**\n * A key-value mapping between encoding channels and definition of fields.\n */\n encoding?: E;\n\n\n /**\n * An object defining properties of geographic projection, which will be applied to `shape` path for `\"geoshape\"` marks\n * and to `latitude` and `\"longitude\"` channels for other marks.\n */\n projection?: Projection;\n\n /**\n * A key-value mapping between selection names and definitions.\n */\n selection?: {[name: string]: SelectionDef};\n}\n\nexport type NormalizedUnitSpec = GenericUnitSpec, Mark | MarkDef>;\n\n/**\n * Unit spec that can have a composite mark.\n */\nexport type CompositeUnitSpec = GenericUnitSpec, AnyMark>;\n\n/**\n * Unit spec that can have a composite mark and row or column channels.\n */\nexport type FacetedCompositeUnitSpec = GenericUnitSpec, AnyMark>;\n\nexport interface GenericLayerSpec> extends BaseSpec, LayoutSizeMixins {\n /**\n * Layer or single view specifications to be layered.\n *\n * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as layering facet specifications is not allowed.\n */\n layer: (GenericLayerSpec | U)[];\n\n /**\n * Scale, axis, and legend resolutions for layers.\n */\n resolve?: Resolve;\n}\n\n/**\n * Layer Spec with encoding and projection\n */\nexport interface ExtendedLayerSpec extends GenericLayerSpec {\n /**\n * A shared key-value mapping between encoding channels and definition of fields in the underlying layers.\n */\n encoding?: Encoding;\n\n\n /**\n * An object defining properties of the geographic projection shared by underlying layers.\n */\n projection?: Projection;\n}\n\nexport type NormalizedLayerSpec = GenericLayerSpec;\n\n\nexport interface GenericFacetSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n > extends BaseSpec, GenericCompositionLayout {\n /**\n * An object that describes mappings between `row` and `column` channels and their field definitions.\n */\n facet: FacetMapping;\n\n /**\n * A specification of the view that gets faceted.\n */\n spec: L | U;\n // TODO: replace this with GenericSpec once we support all cases;\n\n /**\n * Scale, axis, and legend resolutions for facets.\n */\n resolve?: Resolve;\n}\n\nexport type NormalizedFacetSpec = GenericFacetSpec;\n\nexport interface GenericRepeatSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> extends BaseSpec, GenericCompositionLayout {\n /**\n * An object that describes what fields should be repeated into views that are laid out as a `row` or `column`.\n */\n repeat: Repeat;\n\n spec: GenericSpec;\n\n /**\n * Scale and legend resolutions for repeated charts.\n */\n resolve?: Resolve;\n}\n\nexport type NormalizedRepeatSpec = GenericRepeatSpec;\n\nexport interface GenericVConcatSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> extends BaseSpec, ConcatLayout {\n /**\n * A list of views that should be concatenated and put into a column.\n */\n vconcat: (GenericSpec)[];\n\n /**\n * Scale, axis, and legend resolutions for vertically concatenated charts.\n */\n resolve?: Resolve;\n}\n\nexport interface GenericHConcatSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> extends BaseSpec, ConcatLayout {\n /**\n * A list of views that should be concatenated and put into a row.\n */\n hconcat: (GenericSpec)[];\n\n /**\n * Scale, axis, and legend resolutions for horizontally concatenated charts.\n */\n resolve?: Resolve;\n}\n\nexport type NormalizedConcatSpec =\n GenericVConcatSpec | GenericHConcatSpec;\n\nexport type GenericSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> = U | L | GenericFacetSpec | GenericRepeatSpec |\n GenericVConcatSpec |GenericHConcatSpec;\n\nexport type NormalizedSpec = GenericSpec;\n\nexport type TopLevelFacetedUnitSpec = TopLevel & DataMixins;\nexport type TopLevelFacetSpec = TopLevel> & DataMixins;\n\nexport type TopLevelSpec = TopLevelFacetedUnitSpec | TopLevelFacetSpec | TopLevel |\nTopLevel> | TopLevel> | TopLevel>;\n\n/* Custom type guards */\n\n\nexport function isFacetSpec(spec: BaseSpec): spec is GenericFacetSpec {\n return spec['facet'] !== undefined;\n}\n\nexport function isUnitSpec(spec: BaseSpec): spec is FacetedCompositeUnitSpec | NormalizedUnitSpec {\n return !!spec['mark'];\n}\n\nexport function isLayerSpec(spec: BaseSpec): spec is GenericLayerSpec {\n return spec['layer'] !== undefined;\n}\n\nexport function isRepeatSpec(spec: BaseSpec): spec is GenericRepeatSpec {\n return spec['repeat'] !== undefined;\n}\n\nexport function isConcatSpec(spec: BaseSpec):\n spec is GenericVConcatSpec |\n GenericHConcatSpec {\n return isVConcatSpec(spec) || isHConcatSpec(spec);\n}\n\nexport function isVConcatSpec(spec: BaseSpec): spec is GenericVConcatSpec {\n return spec['vconcat'] !== undefined;\n}\n\nexport function isHConcatSpec(spec: BaseSpec): spec is GenericHConcatSpec {\n return spec['hconcat'] !== undefined;\n}\n\n/**\n * Decompose extended unit specs into composition of pure unit specs.\n */\n// TODO: consider moving this to another file. Maybe vl.spec.normalize or vl.normalize\nexport function normalize(spec: TopLevelSpec | GenericSpec | FacetedCompositeUnitSpec, config: Config): NormalizedSpec {\n if (isFacetSpec(spec)) {\n return normalizeFacet(spec, config);\n }\n if (isLayerSpec(spec)) {\n return normalizeLayer(spec, config);\n }\n if (isRepeatSpec(spec)) {\n return normalizeRepeat(spec, config);\n }\n if (isVConcatSpec(spec)) {\n return normalizeVConcat(spec, config);\n }\n if (isHConcatSpec(spec)) {\n return normalizeHConcat(spec, config);\n }\n if (isUnitSpec(spec)) {\n const hasRow = channelHasField(spec.encoding, ROW);\n const hasColumn = channelHasField(spec.encoding, COLUMN);\n\n if (hasRow || hasColumn) {\n return normalizeFacetedUnit(spec, config);\n }\n return normalizeNonFacetUnit(spec, config);\n }\n throw new Error(log.message.INVALID_SPEC);\n}\n\nfunction normalizeFacet(spec: GenericFacetSpec, config: Config): NormalizedFacetSpec {\n const {spec: subspec, ...rest} = spec;\n return {\n ...rest,\n // TODO: remove \"any\" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760\n spec: normalize(subspec, config) as any\n };\n}\n\nfunction mergeEncoding(opt: {parentEncoding: Encoding, encoding: Encoding}): Encoding {\n const {parentEncoding, encoding} = opt;\n if (parentEncoding && encoding) {\n const overriden = keys(parentEncoding).reduce((o, key) => {\n if (encoding[key]) {\n o.push(key);\n }\n return o;\n }, []);\n\n if (overriden.length > 0) {\n log.warn(log.message.encodingOverridden(overriden));\n }\n }\n\n const merged = {\n ...(parentEncoding || {}),\n ...(encoding || {})\n };\n return keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeProjection(opt: {parentProjection: Projection, projection: Projection}) {\n const {parentProjection, projection} = opt;\n if (parentProjection && projection) {\n log.warn(log.message.projectionOverridden({parentProjection, projection}));\n }\n return projection || parentProjection;\n}\n\nfunction normalizeLayer(\n spec: ExtendedLayerSpec,\n config: Config,\n parentEncoding?: Encoding,\n parentProjection?: Projection\n): NormalizedLayerSpec {\n const {layer, encoding, projection, ...rest} = spec;\n const mergedEncoding = mergeEncoding({parentEncoding, encoding});\n const mergedProjection = mergeProjection({parentProjection, projection});\n return {\n ...rest,\n layer: layer.map((subspec) => {\n if (isLayerSpec(subspec)) {\n return normalizeLayer(subspec, config, mergedEncoding, mergedProjection);\n }\n return normalizeNonFacetUnit(subspec, config, mergedEncoding, mergedProjection);\n })\n };\n}\n\nfunction normalizeRepeat(spec: GenericRepeatSpec, config: Config): NormalizedRepeatSpec {\n const {spec: subspec, ...rest} = spec;\n return {\n ...rest,\n spec: normalize(subspec, config)\n };\n}\n\nfunction normalizeVConcat(spec: GenericVConcatSpec, config: Config): NormalizedConcatSpec {\n const {vconcat: vconcat, ...rest} = spec;\n return {\n ...rest,\n vconcat: vconcat.map((subspec) => normalize(subspec, config))\n };\n}\n\nfunction normalizeHConcat(spec: GenericHConcatSpec, config: Config): NormalizedConcatSpec {\n const {hconcat: hconcat, ...rest} = spec;\n return {\n ...rest,\n hconcat: hconcat.map((subspec) => normalize(subspec, config))\n };\n}\n\nfunction normalizeFacetedUnit(spec: FacetedCompositeUnitSpec, config: Config): NormalizedFacetSpec {\n // New encoding in the inside spec should not contain row / column\n // as row/column should be moved to facet\n const {row: row, column: column, ...encoding} = spec.encoding;\n\n // Mark and encoding should be moved into the inner spec\n const {mark, width, projection, height, selection, encoding: _, ...outerSpec} = spec;\n\n return {\n ...outerSpec,\n facet: {\n ...(row ? {row} : {}),\n ...(column ? {column}: {}),\n },\n spec: normalizeNonFacetUnit({\n ...(projection ? {projection} : {}),\n mark,\n ...(width ? {width} : {}),\n ...(height ? {height} : {}),\n encoding,\n ...(selection ? {selection} : {})\n }, config)\n };\n}\n\nfunction isNonFacetUnitSpecWithPrimitiveMark(spec: GenericUnitSpec, AnyMark>):\n spec is GenericUnitSpec, Mark> {\n return isPrimitiveMark(spec.mark);\n}\n\nfunction getPointOverlay(markDef: MarkDef, markConfig: LineConfig, encoding: Encoding): MarkConfig {\n if (markDef.point === 'transparent') {\n return {opacity: 0};\n } else if (markDef.point) { // truthy : true or object\n return isObject(markDef.point) ? markDef.point : {};\n } else if (markDef.point !== undefined) { // false or null\n return null;\n } else { // undefined (not disabled)\n if (markConfig.point || encoding.shape) {\n // enable point overlay if config[mark].point is truthy or if encoding.shape is provided\n return isObject(markConfig.point) ? markConfig.point : {};\n }\n // markDef.point is defined as falsy\n return null;\n }\n}\n\nfunction getLineOverlay(markDef: MarkDef, markConfig: AreaConfig): MarkConfig {\n if (markDef.line) { // true or object\n return markDef.line === true ? {} : markDef.line;\n } else if (markDef.line !== undefined) { // false or null\n return null;\n } else { // undefined (not disabled)\n if (markConfig.line) {\n // enable line overlay if config[mark].line is truthy\n return markConfig.line === true ? {} : markConfig.line;\n }\n // markDef.point is defined as falsy\n return null;\n }\n}\n\nfunction normalizeNonFacetUnit(\n spec: GenericUnitSpec, AnyMark>, config: Config,\n parentEncoding?: Encoding, parentProjection?: Projection\n): NormalizedUnitSpec | NormalizedLayerSpec {\n const {encoding, projection} = spec;\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n\n\n // merge parent encoding / projection first\n if (parentEncoding || parentProjection) {\n const mergedProjection = mergeProjection({parentProjection, projection});\n const mergedEncoding = mergeEncoding({parentEncoding, encoding});\n return normalizeNonFacetUnit({\n ...spec,\n ...(mergedProjection ? {projection: mergedProjection} : {}),\n ...(mergedEncoding ? {encoding: mergedEncoding} : {}),\n }, config);\n }\n\n if (isNonFacetUnitSpecWithPrimitiveMark(spec)) {\n // TODO: thoroughly test\n if (isRanged(encoding)) {\n return normalizeRangedUnit(spec);\n }\n\n if (mark === 'line' && (encoding.x2 || encoding.y2)) {\n log.warn(log.message.lineWithRange(!!encoding.x2, !!encoding.y2));\n\n return normalizeNonFacetUnit({\n mark: 'rule',\n ...spec\n }, config, parentEncoding, parentProjection);\n }\n\n if (isPathMark(mark)) {\n return normalizePathOverlay(spec, config);\n }\n\n return spec; // Nothing to normalize\n } else {\n return compositeMark.normalize(spec, config);\n }\n}\n\nfunction normalizeRangedUnit(spec: NormalizedUnitSpec) {\n const hasX = channelHasField(spec.encoding, X);\n const hasY = channelHasField(spec.encoding, Y);\n const hasX2 = channelHasField(spec.encoding, X2);\n const hasY2 = channelHasField(spec.encoding, Y2);\n if ((hasX2 && !hasX) || (hasY2 && !hasY)) {\n const normalizedSpec = duplicate(spec);\n if (hasX2 && !hasX) {\n normalizedSpec.encoding.x = normalizedSpec.encoding.x2;\n delete normalizedSpec.encoding.x2;\n }\n if (hasY2 && !hasY) {\n normalizedSpec.encoding.y = normalizedSpec.encoding.y2;\n delete normalizedSpec.encoding.y2;\n }\n\n return normalizedSpec;\n }\n return spec;\n}\n\nfunction dropLineAndPoint(markDef: MarkDef): MarkDef | Mark {\n const {point: _point, line: _line, ...mark} = markDef;\n\n return keys(mark).length > 1 ? mark : mark.type;\n}\n\nfunction normalizePathOverlay(spec: NormalizedUnitSpec, config: Config = {}): NormalizedLayerSpec | NormalizedUnitSpec {\n\n // _ is used to denote a dropped property of the unit spec\n // which should not be carried over to the layer spec\n const {selection, projection, encoding, mark, ...outerSpec} = spec;\n const markDef = isMarkDef(mark) ? mark : {type: mark};\n\n const pointOverlay = getPointOverlay(markDef, config[markDef.type], encoding);\n const lineOverlay = markDef.type === 'area' && getLineOverlay(markDef, config[markDef.type]);\n\n if (!pointOverlay && !lineOverlay) {\n return {\n ...spec,\n // Do not include point / line overlay in the normalize spec\n mark: dropLineAndPoint(markDef)\n };\n }\n\n const layer: NormalizedUnitSpec[] = [{\n ...(selection ? {selection} : {}),\n // Do not include point / line overlay in the normalize spec\n mark: dropLineAndPoint({\n ...markDef,\n // make area mark translucent by default\n // TODO: extract this 0.7 to be shared with default opacity for point/tick/...\n ...(markDef.type === 'area' ? {opacity: 0.7} : {}),\n }),\n // drop shape from encoding as this might be used to trigger point overlay\n encoding: omit(encoding, ['shape'])\n }];\n\n // FIXME: determine rules for applying selections.\n\n // Need to copy stack config to overlayed layer\n const stackProps = stack(markDef, encoding, config ? config.stack : undefined);\n\n let overlayEncoding = encoding;\n if (stackProps) {\n const {fieldChannel: stackFieldChannel, offset} = stackProps;\n overlayEncoding = {\n ...encoding,\n [stackFieldChannel]: {\n ...encoding[stackFieldChannel],\n ...(offset ? {stack: offset} : {})\n }\n };\n }\n\n if (lineOverlay) {\n layer.push({\n ...(projection ? {projection} : {}),\n mark: {\n type: 'line',\n ...pick(markDef, ['clip', 'interpolate']),\n ...lineOverlay\n },\n encoding: overlayEncoding\n });\n }\n if (pointOverlay) {\n layer.push({\n ...(projection ? {projection} : {}),\n mark: {\n type: 'point',\n opacity: 1,\n filled: true,\n ...pick(markDef, ['clip']),\n ...pointOverlay\n },\n encoding: overlayEncoding\n });\n }\n\n return {\n ...outerSpec,\n layer\n };\n}\n\n// TODO: add vl.spec.validate & move stuff from vl.validate to here\n\n/* Accumulate non-duplicate fieldDefs in a dictionary */\nfunction accumulate(dict: any, defs: FieldDef[]): any {\n defs.forEach(function(fieldDef) {\n // Consider only pure fieldDef properties (ignoring scale, axis, legend)\n const pureFieldDef = ['field', 'type', 'value', 'timeUnit', 'bin', 'aggregate'].reduce((f, key) => {\n if (fieldDef[key] !== undefined) {\n f[key] = fieldDef[key];\n }\n return f;\n }, {});\n const key = hash(pureFieldDef);\n dict[key] = dict[key] || fieldDef;\n });\n return dict;\n}\n\n/* Recursively get fieldDefs from a spec, returns a dictionary of fieldDefs */\nfunction fieldDefIndex(spec: GenericSpec, dict: Dict> = {}): Dict> {\n // FIXME(https://github.com/vega/vega-lite/issues/2207): Support fieldDefIndex for repeat\n if (isLayerSpec(spec)) {\n spec.layer.forEach(layer => {\n if (isUnitSpec(layer)) {\n accumulate(dict, vlEncoding.fieldDefs(layer.encoding));\n } else {\n fieldDefIndex(layer, dict);\n }\n });\n } else if (isFacetSpec(spec)) {\n accumulate(dict, vlEncoding.fieldDefs(spec.facet));\n fieldDefIndex(spec.spec, dict);\n } else if (isRepeatSpec(spec)) {\n fieldDefIndex(spec.spec, dict);\n } else if (isConcatSpec(spec)) {\n const childSpec = isVConcatSpec(spec) ? spec.vconcat : spec.hconcat;\n childSpec.forEach(child => fieldDefIndex(child, dict));\n } else { // Unit Spec\n accumulate(dict, vlEncoding.fieldDefs(spec.encoding));\n }\n return dict;\n}\n\n/* Returns all non-duplicate fieldDefs in a spec in a flat array */\nexport function fieldDefs(spec: GenericSpec): FieldDef[] {\n return vals(fieldDefIndex(spec));\n}\n\nexport function isStacked(spec: TopLevel, config?: Config): boolean {\n config = config || spec.config;\n if (isPrimitiveMark(spec.mark)) {\n return stack(spec.mark, spec.encoding,\n config ? config.stack : undefined\n ) !== null;\n }\n return false;\n}\n"]} \ No newline at end of file diff --git a/build/src/stack.d.ts b/build/src/stack.d.ts new file mode 100644 index 0000000000..134d9c3be8 --- /dev/null +++ b/build/src/stack.d.ts @@ -0,0 +1,28 @@ +import { NonPositionChannel } from './channel'; +import { Encoding } from './encoding'; +import { Field, FieldDef } from './fielddef'; +import { Mark, MarkDef } from './mark'; +export declare type StackOffset = 'zero' | 'center' | 'normalize'; +export declare function isStackOffset(s: string): s is StackOffset; +export interface StackProperties { + /** Dimension axis of the stack. */ + groupbyChannel: 'x' | 'y'; + /** Measure axis of the stack. */ + fieldChannel: 'x' | 'y'; + /** Stack-by fields e.g., color, detail */ + stackBy: { + fieldDef: FieldDef; + channel: NonPositionChannel; + }[]; + /** + * See `"stack"` property of Position Field Def. + */ + offset: StackOffset; + /** + * Whether this stack will produce impute transform + */ + impute: boolean; +} +export declare const STACKABLE_MARKS: ("square" | "area" | "circle" | "line" | "text" | "rule" | "point" | "bar" | "tick")[]; +export declare const STACK_BY_DEFAULT_MARKS: ("area" | "bar")[]; +export declare function stack(m: Mark | MarkDef, encoding: Encoding, stackConfig: StackOffset): StackProperties; diff --git a/build/src/stack.js b/build/src/stack.js new file mode 100644 index 0000000000..4c100116d3 --- /dev/null +++ b/build/src/stack.js @@ -0,0 +1,131 @@ +import { isArray } from 'vega-util'; +import { SUM_OPS } from './aggregate'; +import { NONPOSITION_CHANNELS, X, X2, Y2 } from './channel'; +import { channelHasField } from './encoding'; +import { getFieldDef, isFieldDef, isStringFieldDef, vgField } from './fielddef'; +import * as log from './log'; +import { AREA, BAR, CIRCLE, isMarkDef, isPathMark, LINE, POINT, RULE, SQUARE, TEXT, TICK } from './mark'; +import { ScaleType } from './scale'; +import { contains } from './util'; +var STACK_OFFSET_INDEX = { + zero: 1, + center: 1, + normalize: 1 +}; +export function isStackOffset(s) { + return !!STACK_OFFSET_INDEX[s]; +} +export var STACKABLE_MARKS = [BAR, AREA, RULE, POINT, CIRCLE, SQUARE, LINE, TEXT, TICK]; +export var STACK_BY_DEFAULT_MARKS = [BAR, AREA]; +function potentialStackedChannel(encoding) { + var xDef = encoding.x; + var yDef = encoding.y; + if (isFieldDef(xDef) && isFieldDef(yDef)) { + if (xDef.type === 'quantitative' && yDef.type === 'quantitative') { + if (xDef.stack) { + return 'x'; + } + else if (yDef.stack) { + return 'y'; + } + // if there is no explicit stacking, only apply stack if there is only one aggregate for x or y + if ((!!xDef.aggregate) !== (!!yDef.aggregate)) { + return xDef.aggregate ? 'x' : 'y'; + } + } + else if (xDef.type === 'quantitative') { + return 'x'; + } + else if (yDef.type === 'quantitative') { + return 'y'; + } + } + else if (isFieldDef(xDef) && xDef.type === 'quantitative') { + return 'x'; + } + else if (isFieldDef(yDef) && yDef.type === 'quantitative') { + return 'y'; + } + return undefined; +} +// Note: CompassQL uses this method and only pass in required properties of each argument object. +// If required properties change, make sure to update CompassQL. +export function stack(m, encoding, stackConfig) { + var mark = isMarkDef(m) ? m.type : m; + // Should have stackable mark + if (!contains(STACKABLE_MARKS, mark)) { + return null; + } + var fieldChannel = potentialStackedChannel(encoding); + if (!fieldChannel) { + return null; + } + var stackedFieldDef = encoding[fieldChannel]; + var stackedField = isStringFieldDef(stackedFieldDef) ? vgField(stackedFieldDef, {}) : undefined; + var dimensionChannel = fieldChannel === 'x' ? 'y' : 'x'; + var dimensionDef = encoding[dimensionChannel]; + var dimensionField = isStringFieldDef(dimensionDef) ? vgField(dimensionDef, {}) : undefined; + // Should have grouping level of detail that is different from the dimension field + var stackBy = NONPOSITION_CHANNELS.reduce(function (sc, channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (isArray(channelDef) ? channelDef : [channelDef]).forEach(function (cDef) { + var fieldDef = getFieldDef(cDef); + if (fieldDef.aggregate) { + return; + } + // Check whether the channel's field is identical to x/y's field or if the channel is a repeat + var f = isStringFieldDef(fieldDef) ? vgField(fieldDef, {}) : undefined; + if ( + // if fielddef is a repeat, just include it in the stack by + !f || + // otherwise, the field must be different from x and y fields. + (f !== dimensionField && f !== stackedField)) { + sc.push({ channel: channel, fieldDef: fieldDef }); + } + }); + } + return sc; + }, []); + if (stackBy.length === 0) { + return null; + } + // Automatically determine offset + var offset = undefined; + if (stackedFieldDef.stack !== undefined) { + offset = stackedFieldDef.stack; + } + else if (contains(STACK_BY_DEFAULT_MARKS, mark)) { + // Bar and Area with sum ops are automatically stacked by default + offset = stackConfig === undefined ? 'zero' : stackConfig; + } + else { + offset = stackConfig; + } + if (!offset || !isStackOffset(offset)) { + return null; + } + // warn when stacking non-linear + if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== ScaleType.LINEAR) { + log.warn(log.message.cannotStackNonLinearScale(stackedFieldDef.scale.type)); + } + // Check if it is a ranged mark + if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) { + if (stackedFieldDef.stack !== undefined) { + log.warn(log.message.cannotStackRangedMark(fieldChannel)); + } + return null; + } + // Warn if stacking summative aggregate + if (stackedFieldDef.aggregate && !contains(SUM_OPS, stackedFieldDef.aggregate)) { + log.warn(log.message.stackNonSummativeAggregate(stackedFieldDef.aggregate)); + } + return { + groupbyChannel: dimensionDef ? dimensionChannel : undefined, + fieldChannel: fieldChannel, + impute: isPathMark(mark), + stackBy: stackBy, + offset: offset + }; +} +//# sourceMappingURL=stack.js.map \ No newline at end of file diff --git a/build/src/stack.js.map b/build/src/stack.js.map new file mode 100644 index 0000000000..608c5bda41 --- /dev/null +++ b/build/src/stack.js.map @@ -0,0 +1 @@ +{"version":3,"file":"stack.js","sourceRoot":"","sources":["../../src/stack.ts"],"names":[],"mappings":"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","sourcesContent":["import {isArray} from 'vega-util';\nimport {SUM_OPS} from './aggregate';\nimport {NONPOSITION_CHANNELS, NonPositionChannel, X, X2, Y2} from './channel';\nimport {channelHasField, Encoding} from './encoding';\nimport {Field, FieldDef, getFieldDef, isFieldDef, isStringFieldDef, PositionFieldDef, vgField} from './fielddef';\nimport * as log from './log';\nimport {AREA, BAR, CIRCLE, isMarkDef, isPathMark, LINE, Mark, MarkDef, POINT, RULE, SQUARE, TEXT, TICK} from './mark';\nimport {ScaleType} from './scale';\nimport {contains, Flag} from './util';\n\n\nexport type StackOffset = 'zero' | 'center' | 'normalize';\n\nconst STACK_OFFSET_INDEX: Flag = {\n zero: 1,\n center: 1,\n normalize: 1\n};\n\nexport function isStackOffset(s: string): s is StackOffset {\n return !!STACK_OFFSET_INDEX[s];\n}\n\nexport interface StackProperties {\n /** Dimension axis of the stack. */\n groupbyChannel: 'x' | 'y';\n\n /** Measure axis of the stack. */\n fieldChannel: 'x' | 'y';\n\n /** Stack-by fields e.g., color, detail */\n stackBy: {\n fieldDef: FieldDef,\n channel: NonPositionChannel\n }[];\n\n /**\n * See `\"stack\"` property of Position Field Def.\n */\n offset: StackOffset;\n\n /**\n * Whether this stack will produce impute transform\n */\n impute: boolean;\n}\n\nexport const STACKABLE_MARKS = [BAR, AREA, RULE, POINT, CIRCLE, SQUARE, LINE, TEXT, TICK];\nexport const STACK_BY_DEFAULT_MARKS = [BAR, AREA];\n\n\nfunction potentialStackedChannel(encoding: Encoding): 'x' | 'y' | undefined {\n const xDef = encoding.x;\n const yDef = encoding.y;\n\n if (isFieldDef(xDef) && isFieldDef(yDef)) {\n if (xDef.type === 'quantitative' && yDef.type === 'quantitative') {\n if (xDef.stack) {\n return 'x';\n } else if (yDef.stack) {\n return 'y';\n }\n // if there is no explicit stacking, only apply stack if there is only one aggregate for x or y\n if ((!!xDef.aggregate) !== (!!yDef.aggregate)) {\n return xDef.aggregate ? 'x' : 'y';\n }\n } else if (xDef.type === 'quantitative') {\n return 'x';\n } else if (yDef.type === 'quantitative') {\n return 'y';\n }\n } else if (isFieldDef(xDef) && xDef.type === 'quantitative') {\n return 'x';\n } else if (isFieldDef(yDef) && yDef.type === 'quantitative') {\n return 'y';\n }\n return undefined;\n}\n\n// Note: CompassQL uses this method and only pass in required properties of each argument object.\n// If required properties change, make sure to update CompassQL.\nexport function stack(m: Mark | MarkDef, encoding: Encoding, stackConfig: StackOffset): StackProperties {\n const mark = isMarkDef(m) ? m.type : m;\n // Should have stackable mark\n if (!contains(STACKABLE_MARKS, mark)) {\n return null;\n }\n\n const fieldChannel = potentialStackedChannel(encoding);\n if (!fieldChannel) {\n return null;\n }\n\n const stackedFieldDef = encoding[fieldChannel] as PositionFieldDef;\n const stackedField = isStringFieldDef(stackedFieldDef) ? vgField(stackedFieldDef, {}) : undefined;\n\n const dimensionChannel = fieldChannel === 'x' ? 'y' : 'x';\n const dimensionDef = encoding[dimensionChannel];\n const dimensionField = isStringFieldDef(dimensionDef) ? vgField(dimensionDef, {}) : undefined;\n\n // Should have grouping level of detail that is different from the dimension field\n const stackBy = NONPOSITION_CHANNELS.reduce((sc, channel) => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((cDef) => {\n const fieldDef = getFieldDef(cDef);\n if (fieldDef.aggregate) {\n return;\n }\n\n // Check whether the channel's field is identical to x/y's field or if the channel is a repeat\n const f = isStringFieldDef(fieldDef) ? vgField(fieldDef, {}) : undefined;\n if (\n // if fielddef is a repeat, just include it in the stack by\n !f ||\n // otherwise, the field must be different from x and y fields.\n (f !== dimensionField && f !== stackedField)\n ) {\n sc.push({channel, fieldDef});\n }\n });\n }\n return sc;\n }, []);\n\n if (stackBy.length === 0) {\n return null;\n }\n\n // Automatically determine offset\n let offset: StackOffset = undefined;\n if (stackedFieldDef.stack !== undefined) {\n offset = stackedFieldDef.stack;\n } else if (contains(STACK_BY_DEFAULT_MARKS, mark)) {\n // Bar and Area with sum ops are automatically stacked by default\n offset = stackConfig === undefined ? 'zero' : stackConfig;\n } else {\n offset = stackConfig;\n }\n\n if (!offset || !isStackOffset(offset)) {\n return null;\n }\n\n // warn when stacking non-linear\n if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== ScaleType.LINEAR) {\n log.warn(log.message.cannotStackNonLinearScale(stackedFieldDef.scale.type));\n }\n\n // Check if it is a ranged mark\n if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) {\n if (stackedFieldDef.stack !== undefined) {\n log.warn(log.message.cannotStackRangedMark(fieldChannel));\n }\n return null;\n }\n\n // Warn if stacking summative aggregate\n if (stackedFieldDef.aggregate && !contains(SUM_OPS, stackedFieldDef.aggregate)) {\n log.warn(log.message.stackNonSummativeAggregate(stackedFieldDef.aggregate));\n }\n\n return {\n groupbyChannel: dimensionDef ? dimensionChannel : undefined,\n fieldChannel,\n impute: isPathMark(mark),\n stackBy,\n offset\n };\n}\n"]} \ No newline at end of file diff --git a/build/src/timeunit.d.ts b/build/src/timeunit.d.ts new file mode 100644 index 0000000000..7b3fb99f3e --- /dev/null +++ b/build/src/timeunit.d.ts @@ -0,0 +1,80 @@ +export declare namespace TimeUnit { + const YEAR: 'year'; + const MONTH: 'month'; + const DAY: 'day'; + const DATE: 'date'; + const HOURS: 'hours'; + const MINUTES: 'minutes'; + const SECONDS: 'seconds'; + const MILLISECONDS: 'milliseconds'; + const YEARMONTH: 'yearmonth'; + const YEARMONTHDATE: 'yearmonthdate'; + const YEARMONTHDATEHOURS: 'yearmonthdatehours'; + const YEARMONTHDATEHOURSMINUTES: 'yearmonthdatehoursminutes'; + const YEARMONTHDATEHOURSMINUTESSECONDS: 'yearmonthdatehoursminutesseconds'; + const MONTHDATE: 'monthdate'; + const HOURSMINUTES: 'hoursminutes'; + const HOURSMINUTESSECONDS: 'hoursminutesseconds'; + const MINUTESSECONDS: 'minutesseconds'; + const SECONDSMILLISECONDS: 'secondsmilliseconds'; + const QUARTER: 'quarter'; + const YEARQUARTER: 'yearquarter'; + const QUARTERMONTH: 'quartermonth'; + const YEARQUARTERMONTH: 'yearquartermonth'; + const UTCYEAR: 'utcyear'; + const UTCMONTH: 'utcmonth'; + const UTCDAY: 'utcday'; + const UTCDATE: 'utcdate'; + const UTCHOURS: 'utchours'; + const UTCMINUTES: 'utcminutes'; + const UTCSECONDS: 'utcseconds'; + const UTCMILLISECONDS: 'utcmilliseconds'; + const UTCYEARMONTH: 'utcyearmonth'; + const UTCYEARMONTHDATE: 'utcyearmonthdate'; + const UTCYEARMONTHDATEHOURS: 'utcyearmonthdatehours'; + const UTCYEARMONTHDATEHOURSMINUTES: 'utcyearmonthdatehoursminutes'; + const UTCYEARMONTHDATEHOURSMINUTESSECONDS: 'utcyearmonthdatehoursminutesseconds'; + const UTCMONTHDATE: 'utcmonthdate'; + const UTCHOURSMINUTES: 'utchoursminutes'; + const UTCHOURSMINUTESSECONDS: 'utchoursminutesseconds'; + const UTCMINUTESSECONDS: 'utcminutesseconds'; + const UTCSECONDSMILLISECONDS: 'utcsecondsmilliseconds'; + const UTCQUARTER: 'utcquarter'; + const UTCYEARQUARTER: 'utcyearquarter'; + const UTCQUARTERMONTH: 'utcquartermonth'; + const UTCYEARQUARTERMONTH: 'utcyearquartermonth'; +} +export declare type LocalSingleTimeUnit = typeof TimeUnit.YEAR | typeof TimeUnit.QUARTER | typeof TimeUnit.MONTH | typeof TimeUnit.DAY | typeof TimeUnit.DATE | typeof TimeUnit.HOURS | typeof TimeUnit.MINUTES | typeof TimeUnit.SECONDS | typeof TimeUnit.MILLISECONDS; +export declare const TIMEUNIT_PARTS: LocalSingleTimeUnit[]; +export declare function isLocalSingleTimeUnit(timeUnit: string): timeUnit is LocalSingleTimeUnit; +export declare type UtcSingleTimeUnit = typeof TimeUnit.UTCYEAR | typeof TimeUnit.UTCQUARTER | typeof TimeUnit.UTCMONTH | typeof TimeUnit.UTCDAY | typeof TimeUnit.UTCDATE | typeof TimeUnit.UTCHOURS | typeof TimeUnit.UTCMINUTES | typeof TimeUnit.UTCSECONDS | typeof TimeUnit.UTCMILLISECONDS; +export declare function isUtcSingleTimeUnit(timeUnit: string): timeUnit is UtcSingleTimeUnit; +export declare type SingleTimeUnit = LocalSingleTimeUnit | UtcSingleTimeUnit; +export declare type LocalMultiTimeUnit = typeof TimeUnit.YEARQUARTER | typeof TimeUnit.YEARQUARTERMONTH | typeof TimeUnit.YEARMONTH | typeof TimeUnit.YEARMONTHDATE | typeof TimeUnit.YEARMONTHDATEHOURS | typeof TimeUnit.YEARMONTHDATEHOURSMINUTES | typeof TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS | typeof TimeUnit.QUARTERMONTH | typeof TimeUnit.MONTHDATE | typeof TimeUnit.HOURSMINUTES | typeof TimeUnit.HOURSMINUTESSECONDS | typeof TimeUnit.MINUTESSECONDS | typeof TimeUnit.SECONDSMILLISECONDS; +export declare type UtcMultiTimeUnit = typeof TimeUnit.UTCYEARQUARTER | typeof TimeUnit.UTCYEARQUARTERMONTH | typeof TimeUnit.UTCYEARMONTH | typeof TimeUnit.UTCYEARMONTHDATE | typeof TimeUnit.UTCYEARMONTHDATEHOURS | typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTES | typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTESSECONDS | typeof TimeUnit.UTCQUARTERMONTH | typeof TimeUnit.UTCMONTHDATE | typeof TimeUnit.UTCHOURSMINUTES | typeof TimeUnit.UTCHOURSMINUTESSECONDS | typeof TimeUnit.UTCMINUTESSECONDS | typeof TimeUnit.UTCSECONDSMILLISECONDS; +export declare type MultiTimeUnit = LocalMultiTimeUnit | UtcMultiTimeUnit; +export declare type LocalTimeUnit = LocalSingleTimeUnit | LocalMultiTimeUnit; +export declare type UtcTimeUnit = UtcSingleTimeUnit | UtcMultiTimeUnit; +export declare function isUTCTimeUnit(t: string): t is UtcTimeUnit; +export declare function getLocalTimeUnit(t: UtcTimeUnit): LocalTimeUnit; +export declare type TimeUnit = SingleTimeUnit | MultiTimeUnit; +export declare const TIMEUNITS: TimeUnit[]; +export declare function isTimeUnit(t: string): t is TimeUnit; +/** + * Converts a date to only have the measurements relevant to the specified unit + * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00' + * Note: the base date is Jan 01 1900 00:00:00 + */ +export declare function convert(unit: TimeUnit, date: Date): Date; +export declare function getTimeUnitParts(timeUnit: TimeUnit): any[]; +/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */ +export declare function containsTimeUnit(fullTimeUnit: TimeUnit, timeUnit: TimeUnit): boolean; +/** + * Returns Vega expresssion for a given timeUnit and fieldRef + */ +export declare function fieldExpr(fullTimeUnit: TimeUnit, field: string): string; +/** + * returns the signal expression used for axis labels for a time unit + */ +export declare function formatExpression(timeUnit: TimeUnit, field: string, shortTimeLabels: boolean, isUTCScale: boolean): string; +export declare function normalizeTimeUnit(timeUnit: TimeUnit): TimeUnit; diff --git a/build/src/timeunit.js b/build/src/timeunit.js new file mode 100644 index 0000000000..5428acf7b8 --- /dev/null +++ b/build/src/timeunit.js @@ -0,0 +1,287 @@ +import * as tslib_1 from "tslib"; +import { dateTimeExpr } from './datetime'; +import * as log from './log'; +import { accessPathWithDatum, flagKeys } from './util'; +export var TimeUnit; +(function (TimeUnit) { + TimeUnit.YEAR = 'year'; + TimeUnit.MONTH = 'month'; + TimeUnit.DAY = 'day'; + TimeUnit.DATE = 'date'; + TimeUnit.HOURS = 'hours'; + TimeUnit.MINUTES = 'minutes'; + TimeUnit.SECONDS = 'seconds'; + TimeUnit.MILLISECONDS = 'milliseconds'; + TimeUnit.YEARMONTH = 'yearmonth'; + TimeUnit.YEARMONTHDATE = 'yearmonthdate'; + TimeUnit.YEARMONTHDATEHOURS = 'yearmonthdatehours'; + TimeUnit.YEARMONTHDATEHOURSMINUTES = 'yearmonthdatehoursminutes'; + TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS = 'yearmonthdatehoursminutesseconds'; + // MONTHDATE always include 29 February since we use year 0th (which is a leap year); + TimeUnit.MONTHDATE = 'monthdate'; + TimeUnit.HOURSMINUTES = 'hoursminutes'; + TimeUnit.HOURSMINUTESSECONDS = 'hoursminutesseconds'; + TimeUnit.MINUTESSECONDS = 'minutesseconds'; + TimeUnit.SECONDSMILLISECONDS = 'secondsmilliseconds'; + TimeUnit.QUARTER = 'quarter'; + TimeUnit.YEARQUARTER = 'yearquarter'; + TimeUnit.QUARTERMONTH = 'quartermonth'; + TimeUnit.YEARQUARTERMONTH = 'yearquartermonth'; + TimeUnit.UTCYEAR = 'utcyear'; + TimeUnit.UTCMONTH = 'utcmonth'; + TimeUnit.UTCDAY = 'utcday'; + TimeUnit.UTCDATE = 'utcdate'; + TimeUnit.UTCHOURS = 'utchours'; + TimeUnit.UTCMINUTES = 'utcminutes'; + TimeUnit.UTCSECONDS = 'utcseconds'; + TimeUnit.UTCMILLISECONDS = 'utcmilliseconds'; + TimeUnit.UTCYEARMONTH = 'utcyearmonth'; + TimeUnit.UTCYEARMONTHDATE = 'utcyearmonthdate'; + TimeUnit.UTCYEARMONTHDATEHOURS = 'utcyearmonthdatehours'; + TimeUnit.UTCYEARMONTHDATEHOURSMINUTES = 'utcyearmonthdatehoursminutes'; + TimeUnit.UTCYEARMONTHDATEHOURSMINUTESSECONDS = 'utcyearmonthdatehoursminutesseconds'; + // MONTHDATE always include 29 February since we use year 0th (which is a leap year); + TimeUnit.UTCMONTHDATE = 'utcmonthdate'; + TimeUnit.UTCHOURSMINUTES = 'utchoursminutes'; + TimeUnit.UTCHOURSMINUTESSECONDS = 'utchoursminutesseconds'; + TimeUnit.UTCMINUTESSECONDS = 'utcminutesseconds'; + TimeUnit.UTCSECONDSMILLISECONDS = 'utcsecondsmilliseconds'; + TimeUnit.UTCQUARTER = 'utcquarter'; + TimeUnit.UTCYEARQUARTER = 'utcyearquarter'; + TimeUnit.UTCQUARTERMONTH = 'utcquartermonth'; + TimeUnit.UTCYEARQUARTERMONTH = 'utcyearquartermonth'; +})(TimeUnit || (TimeUnit = {})); +/** Time Unit that only corresponds to only one part of Date objects. */ +var LOCAL_SINGLE_TIMEUNIT_INDEX = { + year: 1, + quarter: 1, + month: 1, + day: 1, + date: 1, + hours: 1, + minutes: 1, + seconds: 1, + milliseconds: 1 +}; +export var TIMEUNIT_PARTS = flagKeys(LOCAL_SINGLE_TIMEUNIT_INDEX); +export function isLocalSingleTimeUnit(timeUnit) { + return !!LOCAL_SINGLE_TIMEUNIT_INDEX[timeUnit]; +} +var UTC_SINGLE_TIMEUNIT_INDEX = { + utcyear: 1, + utcquarter: 1, + utcmonth: 1, + utcday: 1, + utcdate: 1, + utchours: 1, + utcminutes: 1, + utcseconds: 1, + utcmilliseconds: 1 +}; +export function isUtcSingleTimeUnit(timeUnit) { + return !!UTC_SINGLE_TIMEUNIT_INDEX[timeUnit]; +} +var LOCAL_MULTI_TIMEUNIT_INDEX = { + yearquarter: 1, + yearquartermonth: 1, + yearmonth: 1, + yearmonthdate: 1, + yearmonthdatehours: 1, + yearmonthdatehoursminutes: 1, + yearmonthdatehoursminutesseconds: 1, + quartermonth: 1, + monthdate: 1, + hoursminutes: 1, + hoursminutesseconds: 1, + minutesseconds: 1, + secondsmilliseconds: 1 +}; +var UTC_MULTI_TIMEUNIT_INDEX = { + utcyearquarter: 1, + utcyearquartermonth: 1, + utcyearmonth: 1, + utcyearmonthdate: 1, + utcyearmonthdatehours: 1, + utcyearmonthdatehoursminutes: 1, + utcyearmonthdatehoursminutesseconds: 1, + utcquartermonth: 1, + utcmonthdate: 1, + utchoursminutes: 1, + utchoursminutesseconds: 1, + utcminutesseconds: 1, + utcsecondsmilliseconds: 1 +}; +var UTC_TIMEUNIT_INDEX = tslib_1.__assign({}, UTC_SINGLE_TIMEUNIT_INDEX, UTC_MULTI_TIMEUNIT_INDEX); +export function isUTCTimeUnit(t) { + return !!UTC_TIMEUNIT_INDEX[t]; +} +export function getLocalTimeUnit(t) { + return t.substr(3); +} +var TIMEUNIT_INDEX = tslib_1.__assign({}, LOCAL_SINGLE_TIMEUNIT_INDEX, UTC_SINGLE_TIMEUNIT_INDEX, LOCAL_MULTI_TIMEUNIT_INDEX, UTC_MULTI_TIMEUNIT_INDEX); +export var TIMEUNITS = flagKeys(TIMEUNIT_INDEX); +export function isTimeUnit(t) { + return !!TIMEUNIT_INDEX[t]; +} +var SET_DATE_METHOD = { + year: 'setFullYear', + month: 'setMonth', + date: 'setDate', + hours: 'setHours', + minutes: 'setMinutes', + seconds: 'setSeconds', + milliseconds: 'setMilliseconds', + // Day and quarter have their own special cases + quarter: null, + day: null, +}; +/** + * Converts a date to only have the measurements relevant to the specified unit + * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00' + * Note: the base date is Jan 01 1900 00:00:00 + */ +export function convert(unit, date) { + var isUTC = isUTCTimeUnit(unit); + var result = isUTC ? + // start with uniform date + new Date(Date.UTC(0, 0, 1, 0, 0, 0, 0)) : + new Date(0, 0, 1, 0, 0, 0, 0); + for (var _i = 0, TIMEUNIT_PARTS_1 = TIMEUNIT_PARTS; _i < TIMEUNIT_PARTS_1.length; _i++) { + var timeUnitPart = TIMEUNIT_PARTS_1[_i]; + if (containsTimeUnit(unit, timeUnitPart)) { + switch (timeUnitPart) { + case TimeUnit.DAY: + throw new Error('Cannot convert to TimeUnits containing \'day\''); + case TimeUnit.QUARTER: { + var _a = dateMethods('month', isUTC), getDateMethod_1 = _a.getDateMethod, setDateMethod_1 = _a.setDateMethod; + // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3) + result[setDateMethod_1]((Math.floor(date[getDateMethod_1]() / 3)) * 3); + break; + } + default: + var _b = dateMethods(timeUnitPart, isUTC), getDateMethod = _b.getDateMethod, setDateMethod = _b.setDateMethod; + result[setDateMethod](date[getDateMethod]()); + } + } + } + return result; +} +function dateMethods(singleUnit, isUtc) { + var rawSetDateMethod = SET_DATE_METHOD[singleUnit]; + var setDateMethod = isUtc ? 'setUTC' + rawSetDateMethod.substr(3) : rawSetDateMethod; + var getDateMethod = 'get' + (isUtc ? 'UTC' : '') + rawSetDateMethod.substr(3); + return { setDateMethod: setDateMethod, getDateMethod: getDateMethod }; +} +export function getTimeUnitParts(timeUnit) { + return TIMEUNIT_PARTS.reduce(function (parts, part) { + if (containsTimeUnit(timeUnit, part)) { + return parts.concat(part); + } + return parts; + }, []); +} +/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */ +export function containsTimeUnit(fullTimeUnit, timeUnit) { + var index = fullTimeUnit.indexOf(timeUnit); + return index > -1 && + (timeUnit !== TimeUnit.SECONDS || + index === 0 || + fullTimeUnit.charAt(index - 1) !== 'i' // exclude milliseconds + ); +} +/** + * Returns Vega expresssion for a given timeUnit and fieldRef + */ +export function fieldExpr(fullTimeUnit, field) { + var fieldRef = accessPathWithDatum(field); + var utc = isUTCTimeUnit(fullTimeUnit) ? 'utc' : ''; + function func(timeUnit) { + if (timeUnit === TimeUnit.QUARTER) { + // quarter starting at 0 (0,3,6,9). + return "(" + utc + "quarter(" + fieldRef + ")-1)"; + } + else { + return "" + utc + timeUnit + "(" + fieldRef + ")"; + } + } + var d = TIMEUNIT_PARTS.reduce(function (dateExpr, tu) { + if (containsTimeUnit(fullTimeUnit, tu)) { + dateExpr[tu] = func(tu); + } + return dateExpr; + }, {}); + return dateTimeExpr(d); +} +/** + * returns the signal expression used for axis labels for a time unit + */ +export function formatExpression(timeUnit, field, shortTimeLabels, isUTCScale) { + if (!timeUnit) { + return undefined; + } + var dateComponents = []; + var expression = ''; + var hasYear = containsTimeUnit(timeUnit, TimeUnit.YEAR); + if (containsTimeUnit(timeUnit, TimeUnit.QUARTER)) { + // special expression for quarter as prefix + expression = "'Q' + quarter(" + field + ")"; + } + if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) { + // By default use short month name + dateComponents.push(shortTimeLabels !== false ? '%b' : '%B'); + } + if (containsTimeUnit(timeUnit, TimeUnit.DAY)) { + dateComponents.push(shortTimeLabels ? '%a' : '%A'); + } + else if (containsTimeUnit(timeUnit, TimeUnit.DATE)) { + dateComponents.push('%d' + (hasYear ? ',' : '')); // add comma if there is year + } + if (hasYear) { + dateComponents.push(shortTimeLabels ? '%y' : '%Y'); + } + var timeComponents = []; + if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) { + timeComponents.push('%H'); + } + if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) { + timeComponents.push('%M'); + } + if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) { + timeComponents.push('%S'); + } + if (containsTimeUnit(timeUnit, TimeUnit.MILLISECONDS)) { + timeComponents.push('%L'); + } + var dateTimeComponents = []; + if (dateComponents.length > 0) { + dateTimeComponents.push(dateComponents.join(' ')); + } + if (timeComponents.length > 0) { + dateTimeComponents.push(timeComponents.join(':')); + } + if (dateTimeComponents.length > 0) { + if (expression) { + // Add space between quarter and main time format + expression += " + ' ' + "; + } + // We only use utcFormat for utc scale + // For utc time units, the data is already converted as a part of timeUnit transform. + // Thus, utc time units should use timeFormat to avoid shifting the time twice. + if (isUTCScale) { + expression += "utcFormat(" + field + ", '" + dateTimeComponents.join(' ') + "')"; + } + else { + expression += "timeFormat(" + field + ", '" + dateTimeComponents.join(' ') + "')"; + } + } + // If expression is still an empty string, return undefined instead. + return expression || undefined; +} +export function normalizeTimeUnit(timeUnit) { + if (timeUnit !== 'day' && timeUnit.indexOf('day') >= 0) { + log.warn(log.message.dayReplacedWithDate(timeUnit)); + return timeUnit.replace('day', 'date'); + } + return timeUnit; +} +//# sourceMappingURL=timeunit.js.map \ No newline at end of file diff --git a/build/src/timeunit.js.map b/build/src/timeunit.js.map new file mode 100644 index 0000000000..d8eb2e2ece --- /dev/null +++ b/build/src/timeunit.js.map @@ -0,0 +1 @@ +{"version":3,"file":"timeunit.js","sourceRoot":"","sources":["../../src/timeunit.ts"],"names":[],"mappings":"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","sourcesContent":["import {DateTimeExpr, dateTimeExpr} from './datetime';\nimport * as log from './log';\nimport {accessPathWithDatum, Flag, flagKeys} from './util';\n\nexport namespace TimeUnit {\n export const YEAR: 'year' = 'year';\n export const MONTH: 'month' = 'month';\n export const DAY: 'day' = 'day';\n export const DATE: 'date' = 'date';\n export const HOURS: 'hours' = 'hours';\n export const MINUTES: 'minutes' = 'minutes';\n export const SECONDS: 'seconds' = 'seconds';\n export const MILLISECONDS: 'milliseconds' = 'milliseconds';\n export const YEARMONTH: 'yearmonth' = 'yearmonth';\n export const YEARMONTHDATE: 'yearmonthdate' = 'yearmonthdate';\n export const YEARMONTHDATEHOURS: 'yearmonthdatehours' = 'yearmonthdatehours';\n export const YEARMONTHDATEHOURSMINUTES: 'yearmonthdatehoursminutes' = 'yearmonthdatehoursminutes';\n export const YEARMONTHDATEHOURSMINUTESSECONDS: 'yearmonthdatehoursminutesseconds' = 'yearmonthdatehoursminutesseconds';\n\n // MONTHDATE always include 29 February since we use year 0th (which is a leap year);\n export const MONTHDATE: 'monthdate' = 'monthdate';\n export const HOURSMINUTES: 'hoursminutes' = 'hoursminutes';\n export const HOURSMINUTESSECONDS: 'hoursminutesseconds' = 'hoursminutesseconds';\n export const MINUTESSECONDS: 'minutesseconds' = 'minutesseconds';\n export const SECONDSMILLISECONDS: 'secondsmilliseconds' = 'secondsmilliseconds';\n export const QUARTER: 'quarter' = 'quarter';\n export const YEARQUARTER: 'yearquarter' = 'yearquarter';\n export const QUARTERMONTH: 'quartermonth' = 'quartermonth';\n export const YEARQUARTERMONTH: 'yearquartermonth' = 'yearquartermonth';\n export const UTCYEAR: 'utcyear' = 'utcyear';\n export const UTCMONTH: 'utcmonth' = 'utcmonth';\n export const UTCDAY: 'utcday' = 'utcday';\n export const UTCDATE: 'utcdate' = 'utcdate';\n export const UTCHOURS: 'utchours' = 'utchours';\n export const UTCMINUTES: 'utcminutes' = 'utcminutes';\n export const UTCSECONDS: 'utcseconds' = 'utcseconds';\n export const UTCMILLISECONDS: 'utcmilliseconds' = 'utcmilliseconds';\n export const UTCYEARMONTH: 'utcyearmonth' = 'utcyearmonth';\n export const UTCYEARMONTHDATE: 'utcyearmonthdate' = 'utcyearmonthdate';\n export const UTCYEARMONTHDATEHOURS: 'utcyearmonthdatehours' = 'utcyearmonthdatehours';\n export const UTCYEARMONTHDATEHOURSMINUTES: 'utcyearmonthdatehoursminutes' = 'utcyearmonthdatehoursminutes';\n export const UTCYEARMONTHDATEHOURSMINUTESSECONDS: 'utcyearmonthdatehoursminutesseconds' = 'utcyearmonthdatehoursminutesseconds';\n\n // MONTHDATE always include 29 February since we use year 0th (which is a leap year);\n export const UTCMONTHDATE: 'utcmonthdate' = 'utcmonthdate';\n export const UTCHOURSMINUTES: 'utchoursminutes' = 'utchoursminutes';\n export const UTCHOURSMINUTESSECONDS: 'utchoursminutesseconds' = 'utchoursminutesseconds';\n export const UTCMINUTESSECONDS: 'utcminutesseconds' = 'utcminutesseconds';\n export const UTCSECONDSMILLISECONDS: 'utcsecondsmilliseconds' = 'utcsecondsmilliseconds';\n export const UTCQUARTER: 'utcquarter' = 'utcquarter';\n export const UTCYEARQUARTER: 'utcyearquarter' = 'utcyearquarter';\n export const UTCQUARTERMONTH: 'utcquartermonth' = 'utcquartermonth';\n export const UTCYEARQUARTERMONTH: 'utcyearquartermonth' = 'utcyearquartermonth';\n}\n\nexport type LocalSingleTimeUnit =\n typeof TimeUnit.YEAR |\n typeof TimeUnit.QUARTER |\n typeof TimeUnit.MONTH |\n typeof TimeUnit.DAY |\n typeof TimeUnit.DATE |\n typeof TimeUnit.HOURS |\n typeof TimeUnit.MINUTES |\n typeof TimeUnit.SECONDS |\n typeof TimeUnit.MILLISECONDS;\n\n/** Time Unit that only corresponds to only one part of Date objects. */\nconst LOCAL_SINGLE_TIMEUNIT_INDEX: Flag = {\n year: 1,\n quarter: 1,\n month: 1,\n day: 1,\n date: 1,\n hours: 1,\n minutes: 1,\n seconds: 1,\n milliseconds: 1\n};\n\nexport const TIMEUNIT_PARTS = flagKeys(LOCAL_SINGLE_TIMEUNIT_INDEX);\n\nexport function isLocalSingleTimeUnit(timeUnit: string): timeUnit is LocalSingleTimeUnit {\n return !!LOCAL_SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport type UtcSingleTimeUnit =\n typeof TimeUnit.UTCYEAR |\n typeof TimeUnit.UTCQUARTER |\n typeof TimeUnit.UTCMONTH |\n typeof TimeUnit.UTCDAY |\n typeof TimeUnit.UTCDATE |\n typeof TimeUnit.UTCHOURS |\n typeof TimeUnit.UTCMINUTES |\n typeof TimeUnit.UTCSECONDS |\n typeof TimeUnit.UTCMILLISECONDS;\n\nconst UTC_SINGLE_TIMEUNIT_INDEX: Flag = {\n utcyear: 1,\n utcquarter: 1,\n utcmonth: 1,\n utcday: 1,\n utcdate: 1,\n utchours: 1,\n utcminutes: 1,\n utcseconds: 1,\n utcmilliseconds: 1\n};\n\nexport function isUtcSingleTimeUnit(timeUnit: string): timeUnit is UtcSingleTimeUnit {\n return !!UTC_SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport type SingleTimeUnit = LocalSingleTimeUnit | UtcSingleTimeUnit;\n\nexport type LocalMultiTimeUnit =\n // Local Time\n typeof TimeUnit.YEARQUARTER | typeof TimeUnit.YEARQUARTERMONTH |\n typeof TimeUnit.YEARMONTH | typeof TimeUnit.YEARMONTHDATE | typeof TimeUnit.YEARMONTHDATEHOURS | typeof TimeUnit.YEARMONTHDATEHOURSMINUTES| typeof TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS |\n typeof TimeUnit.QUARTERMONTH |\n typeof TimeUnit.MONTHDATE |\n typeof TimeUnit.HOURSMINUTES | typeof TimeUnit.HOURSMINUTESSECONDS |\n typeof TimeUnit.MINUTESSECONDS |\n typeof TimeUnit.SECONDSMILLISECONDS;\n\nconst LOCAL_MULTI_TIMEUNIT_INDEX: Flag = {\n yearquarter: 1,\n yearquartermonth: 1,\n\n yearmonth: 1,\n yearmonthdate: 1,\n yearmonthdatehours: 1,\n yearmonthdatehoursminutes: 1,\n yearmonthdatehoursminutesseconds: 1,\n\n quartermonth: 1,\n\n monthdate: 1,\n\n hoursminutes: 1,\n hoursminutesseconds: 1,\n\n minutesseconds: 1,\n\n secondsmilliseconds: 1\n};\n\nexport type UtcMultiTimeUnit =\n typeof TimeUnit.UTCYEARQUARTER | typeof TimeUnit.UTCYEARQUARTERMONTH |\n typeof TimeUnit.UTCYEARMONTH | typeof TimeUnit.UTCYEARMONTHDATE | typeof TimeUnit.UTCYEARMONTHDATEHOURS | typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTES| typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTESSECONDS |\n typeof TimeUnit.UTCQUARTERMONTH |\n typeof TimeUnit.UTCMONTHDATE |\n typeof TimeUnit.UTCHOURSMINUTES | typeof TimeUnit.UTCHOURSMINUTESSECONDS |\n typeof TimeUnit.UTCMINUTESSECONDS |\n typeof TimeUnit.UTCSECONDSMILLISECONDS;\n\nconst UTC_MULTI_TIMEUNIT_INDEX: Flag = {\n utcyearquarter: 1,\n utcyearquartermonth: 1,\n\n utcyearmonth: 1,\n utcyearmonthdate: 1,\n utcyearmonthdatehours: 1,\n utcyearmonthdatehoursminutes: 1,\n utcyearmonthdatehoursminutesseconds: 1,\n\n utcquartermonth: 1,\n\n utcmonthdate: 1,\n\n utchoursminutes: 1,\n utchoursminutesseconds: 1,\n\n utcminutesseconds: 1,\n\n utcsecondsmilliseconds: 1\n};\n\nexport type MultiTimeUnit = LocalMultiTimeUnit | UtcMultiTimeUnit;\n\n\nexport type LocalTimeUnit = LocalSingleTimeUnit | LocalMultiTimeUnit;\nexport type UtcTimeUnit = UtcSingleTimeUnit | UtcMultiTimeUnit;\n\nconst UTC_TIMEUNIT_INDEX: Flag = {\n ...UTC_SINGLE_TIMEUNIT_INDEX,\n ...UTC_MULTI_TIMEUNIT_INDEX\n};\n\nexport function isUTCTimeUnit(t: string): t is UtcTimeUnit {\n return !!UTC_TIMEUNIT_INDEX[t];\n}\n\nexport function getLocalTimeUnit(t: UtcTimeUnit): LocalTimeUnit {\n return t.substr(3) as LocalTimeUnit;\n}\n\nexport type TimeUnit = SingleTimeUnit | MultiTimeUnit;\n\nconst TIMEUNIT_INDEX: Flag = {\n ...LOCAL_SINGLE_TIMEUNIT_INDEX,\n ...UTC_SINGLE_TIMEUNIT_INDEX,\n ...LOCAL_MULTI_TIMEUNIT_INDEX,\n ...UTC_MULTI_TIMEUNIT_INDEX\n};\n\nexport const TIMEUNITS = flagKeys(TIMEUNIT_INDEX);\n\nexport function isTimeUnit(t: string): t is TimeUnit {\n return !!TIMEUNIT_INDEX[t];\n}\n\ntype DateMethodName = keyof Date;\n\nconst SET_DATE_METHOD: Record = {\n year: 'setFullYear',\n month: 'setMonth',\n date: 'setDate',\n hours: 'setHours',\n minutes: 'setMinutes',\n seconds: 'setSeconds',\n milliseconds: 'setMilliseconds',\n // Day and quarter have their own special cases\n quarter: null,\n day: null,\n};\n\n/**\n * Converts a date to only have the measurements relevant to the specified unit\n * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00'\n * Note: the base date is Jan 01 1900 00:00:00\n */\nexport function convert(unit: TimeUnit, date: Date): Date {\n const isUTC = isUTCTimeUnit(unit);\n const result: Date = isUTC ?\n // start with uniform date\n new Date(Date.UTC(0, 0, 1, 0, 0, 0, 0)) :\n new Date(0, 0, 1, 0, 0, 0, 0);\n for (const timeUnitPart of TIMEUNIT_PARTS) {\n if (containsTimeUnit(unit, timeUnitPart)) {\n switch (timeUnitPart) {\n case TimeUnit.DAY:\n throw new Error('Cannot convert to TimeUnits containing \\'day\\'');\n case TimeUnit.QUARTER: {\n const {getDateMethod, setDateMethod} = dateMethods('month', isUTC);\n // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3)\n result[setDateMethod]((Math.floor(date[getDateMethod]() / 3)) * 3);\n break;\n }\n default:\n const {getDateMethod, setDateMethod} = dateMethods(timeUnitPart, isUTC);\n result[setDateMethod](date[getDateMethod]());\n }\n }\n }\n return result;\n}\n\nfunction dateMethods(singleUnit: SingleTimeUnit, isUtc: boolean) {\n const rawSetDateMethod = SET_DATE_METHOD[singleUnit];\n const setDateMethod = isUtc ? 'setUTC' + rawSetDateMethod.substr(3) : rawSetDateMethod;\n const getDateMethod = 'get' + (isUtc ? 'UTC' : '') + rawSetDateMethod.substr(3);\n return {setDateMethod, getDateMethod};\n}\n\nexport function getTimeUnitParts(timeUnit: TimeUnit) {\n return TIMEUNIT_PARTS.reduce((parts, part) => {\n if (containsTimeUnit(timeUnit, part)) {\n return parts.concat(part);\n }\n return parts;\n }, []);\n}\n\n/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */\nexport function containsTimeUnit(fullTimeUnit: TimeUnit, timeUnit: TimeUnit) {\n const index = fullTimeUnit.indexOf(timeUnit);\n return index > -1 &&\n (\n timeUnit !== TimeUnit.SECONDS ||\n index === 0 ||\n fullTimeUnit.charAt(index-1) !== 'i' // exclude milliseconds\n );\n}\n\n/**\n * Returns Vega expresssion for a given timeUnit and fieldRef\n */\nexport function fieldExpr(fullTimeUnit: TimeUnit, field: string): string {\n const fieldRef = accessPathWithDatum(field);\n\n const utc = isUTCTimeUnit(fullTimeUnit) ? 'utc' : '';\n function func(timeUnit: TimeUnit) {\n if (timeUnit === TimeUnit.QUARTER) {\n // quarter starting at 0 (0,3,6,9).\n return `(${utc}quarter(${fieldRef})-1)`;\n } else {\n return `${utc}${timeUnit}(${fieldRef})`;\n }\n }\n\n const d = TIMEUNIT_PARTS.reduce((dateExpr: DateTimeExpr, tu: TimeUnit) => {\n if (containsTimeUnit(fullTimeUnit, tu)) {\n dateExpr[tu] = func(tu);\n }\n return dateExpr;\n }, {} as {[key in SingleTimeUnit]: string});\n\n return dateTimeExpr(d);\n}\n\n/**\n * returns the signal expression used for axis labels for a time unit\n */\nexport function formatExpression(timeUnit: TimeUnit, field: string, shortTimeLabels: boolean, isUTCScale: boolean): string {\n if (!timeUnit) {\n return undefined;\n }\n\n const dateComponents: string[] = [];\n let expression = '';\n const hasYear = containsTimeUnit(timeUnit, TimeUnit.YEAR);\n\n if (containsTimeUnit(timeUnit, TimeUnit.QUARTER)) {\n // special expression for quarter as prefix\n expression = `'Q' + quarter(${field})`;\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) {\n // By default use short month name\n dateComponents.push(shortTimeLabels !== false ? '%b' : '%B');\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.DAY)) {\n dateComponents.push(shortTimeLabels ? '%a' : '%A');\n } else if (containsTimeUnit(timeUnit, TimeUnit.DATE)) {\n dateComponents.push('%d' + (hasYear ? ',' : '')); // add comma if there is year\n }\n\n if (hasYear) {\n dateComponents.push(shortTimeLabels ? '%y' : '%Y');\n }\n\n const timeComponents: string[] = [];\n\n if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) {\n timeComponents.push('%H');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) {\n timeComponents.push('%M');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) {\n timeComponents.push('%S');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MILLISECONDS)) {\n timeComponents.push('%L');\n }\n\n const dateTimeComponents: string[] = [];\n if (dateComponents.length > 0) {\n dateTimeComponents.push(dateComponents.join(' '));\n }\n if (timeComponents.length > 0) {\n dateTimeComponents.push(timeComponents.join(':'));\n }\n\n if (dateTimeComponents.length > 0) {\n if (expression) {\n // Add space between quarter and main time format\n expression += ` + ' ' + `;\n }\n\n // We only use utcFormat for utc scale\n // For utc time units, the data is already converted as a part of timeUnit transform.\n // Thus, utc time units should use timeFormat to avoid shifting the time twice.\n if (isUTCScale) {\n expression += `utcFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n } else {\n expression += `timeFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n }\n }\n\n // If expression is still an empty string, return undefined instead.\n return expression || undefined;\n}\n\nexport function normalizeTimeUnit(timeUnit: TimeUnit): TimeUnit {\n if (timeUnit !== 'day' && timeUnit.indexOf('day') >= 0) {\n log.warn(log.message.dayReplacedWithDate(timeUnit));\n return timeUnit.replace('day', 'date') as TimeUnit;\n }\n return timeUnit;\n}\n"]} \ No newline at end of file diff --git a/build/src/title.d.ts b/build/src/title.d.ts new file mode 100644 index 0000000000..29805226d0 --- /dev/null +++ b/build/src/title.d.ts @@ -0,0 +1,36 @@ +import { Anchor, TitleOrient, VgMarkConfig, VgTitleConfig } from './vega.schema'; +export interface TitleBase { + /** + * The orientation of the title relative to the chart. One of `"top"` (the default), `"bottom"`, `"left"`, or `"right"`. + */ + orient?: TitleOrient; + /** + * The anchor position for placing the title. One of `"start"`, `"middle"`, or `"end"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title. + * + * __Default value:__ `"middle"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. + * `"start"` for other composite views. + * + * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `"start"`. + */ + anchor?: Anchor; + /** + * The orthogonal offset in pixels by which to displace the title from its position along the edge of the chart. + */ + offset?: number; + /** + * A [mark style property](https://vega.github.io/vega-lite/docs/config.html#style) to apply to the title text mark. + * + * __Default value:__ `"group-title"`. + */ + style?: string | string[]; +} +export interface TitleParams extends TitleBase { + /** + * The title text. + */ + text: string; +} +export declare function extractTitleConfig(titleConfig: VgTitleConfig): { + mark: VgMarkConfig; + nonMark: TitleBase; +}; diff --git a/build/src/title.js b/build/src/title.js new file mode 100644 index 0000000000..0ffbfaaa2c --- /dev/null +++ b/build/src/title.js @@ -0,0 +1,14 @@ +import * as tslib_1 from "tslib"; +export function extractTitleConfig(titleConfig) { + var + // These are non-mark title config that need to be hardcoded + anchor = titleConfig.anchor, offset = titleConfig.offset, orient = titleConfig.orient, + // color needs to be redirect to fill + color = titleConfig.color, + // The rest are mark config. + titleMarkConfig = tslib_1.__rest(titleConfig, ["anchor", "offset", "orient", "color"]); + var mark = tslib_1.__assign({}, titleMarkConfig, color ? { fill: color } : {}); + var nonMark = tslib_1.__assign({}, anchor ? { anchor: anchor } : {}, offset ? { offset: offset } : {}, orient ? { orient: orient } : {}); + return { mark: mark, nonMark: nonMark }; +} +//# sourceMappingURL=title.js.map \ No newline at end of file diff --git a/build/src/title.js.map b/build/src/title.js.map new file mode 100644 index 0000000000..2cf3e69dcc --- /dev/null +++ b/build/src/title.js.map @@ -0,0 +1 @@ +{"version":3,"file":"title.js","sourceRoot":"","sources":["../../src/title.ts"],"names":[],"mappings":";AAwCA,MAAM,6BAA6B,WAA0B;IAMzD;IADA,4DAA4D;IAC5D,2BAAM,EAAE,2BAAM,EAAE,2BAAM;IACtB,qCAAqC;IACrC,yBAAK;IACL,4BAA4B;IAC5B,sFAAkB,CACJ;IAEhB,IAAM,IAAI,wBACL,eAAe,EACf,KAAK,CAAC,CAAC,CAAC,EAAC,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC,CAAC,EAAE,CAC9B,CAAC;IAEF,IAAM,OAAO,wBACR,MAAM,CAAC,CAAC,CAAC,EAAC,MAAM,QAAA,EAAC,CAAC,CAAC,CAAC,EAAE,EACtB,MAAM,CAAC,CAAC,CAAC,EAAC,MAAM,QAAA,EAAC,CAAC,CAAC,CAAC,EAAE,EACtB,MAAM,CAAC,CAAC,CAAC,EAAC,MAAM,QAAA,EAAC,CAAC,CAAC,CAAC,EAAE,CAC1B,CAAC;IAEF,OAAO,EAAC,IAAI,MAAA,EAAE,OAAO,SAAA,EAAC,CAAC;AACzB,CAAC","sourcesContent":["import {Anchor, TitleOrient, VgMarkConfig, VgTitleConfig} from './vega.schema';\n\nexport interface TitleBase {\n /**\n * The orientation of the title relative to the chart. One of `\"top\"` (the default), `\"bottom\"`, `\"left\"`, or `\"right\"`.\n */\n orient?: TitleOrient;\n\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"`, or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n *\n * __Default value:__ `\"middle\"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views.\n * `\"start\"` for other composite views.\n *\n * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `\"start\"`.\n */\n anchor?: Anchor;\n\n /**\n * The orthogonal offset in pixels by which to displace the title from its position along the edge of the chart.\n */\n offset?: number;\n\n /**\n * A [mark style property](https://vega.github.io/vega-lite/docs/config.html#style) to apply to the title text mark.\n *\n * __Default value:__ `\"group-title\"`.\n */\n style?: string | string[];\n\n // TODO: name, encode, interactive, zindex\n}\n\nexport interface TitleParams extends TitleBase {\n /**\n * The title text.\n */\n text: string;\n}\n\nexport function extractTitleConfig(titleConfig: VgTitleConfig): {\n mark: VgMarkConfig,\n nonMark: TitleBase\n} {\n const {\n // These are non-mark title config that need to be hardcoded\n anchor, offset, orient,\n // color needs to be redirect to fill\n color,\n // The rest are mark config.\n ...titleMarkConfig\n } = titleConfig;\n\n const mark: VgMarkConfig = {\n ...titleMarkConfig,\n ...color ? {fill: color} : {}\n };\n\n const nonMark: TitleBase = {\n ...anchor ? {anchor} : {},\n ...offset ? {offset} : {},\n ...orient ? {orient} : {}\n };\n\n return {mark, nonMark};\n}\n"]} \ No newline at end of file diff --git a/build/src/toplevelprops.d.ts b/build/src/toplevelprops.d.ts new file mode 100644 index 0000000000..e06120e4dc --- /dev/null +++ b/build/src/toplevelprops.d.ts @@ -0,0 +1,130 @@ +import { InlineDataset } from './data'; +import { Dict } from './util'; +import { RowCol, VgLayoutAlign } from './vega.schema'; +/** + * @minimum 0 + */ +export declare type Padding = number | { + top?: number; + bottom?: number; + left?: number; + right?: number; +}; +export declare type Datasets = Dict; +export interface TopLevelProperties { + /** + * CSS color property to use as the background of visualization. + * + * __Default value:__ none (transparent) + */ + background?: string; + /** + * The default visualization padding, in pixels, from the edge of the visualization canvas to the data rectangle. If a number, specifies padding for all sides. + * If an object, the value should have the format `{"left": 5, "top": 5, "right": 5, "bottom": 5}` to specify padding for each side of the visualization. + * + * __Default value__: `5` + */ + padding?: Padding; + /** + * Sets how the visualization size should be determined. If a string, should be one of `"pad"`, `"fit"` or `"none"`. + * Object values can additionally specify parameters for content sizing and automatic resizing. + * `"fit"` is only supported for single and layered views that don't use `rangeStep`. + * + * __Default value__: `pad` + */ + autosize?: AutosizeType | AutoSizeParams; + /** + * A global data store for named datasets. This is a mapping from names to inline datasets. + * This can be an array of objects or primitive values or a string. Arrays of primitive values are ingested as objects with a `data` property. + */ + datasets?: Datasets; +} +export interface BoundsMixins { + /** + * The bounds calculation method to use for determining the extent of a sub-plot. One of `full` (the default) or `flush`. + * + * - If set to `full`, the entire calculated bounds (including axes, title, and legend) will be used. + * - If set to `flush`, only the specified width and height values for the sub-view will be used. The `flush` setting can be useful when attempting to place sub-plots without axes or legends into a uniform grid structure. + * + * __Default value:__ `"full"` + */ + bounds?: 'full' | 'flush'; +} +/** + * Base layout mixins for V/HConcatSpec. + * Concat layout should not have RowCol generic fo its property. + */ +export interface ConcatLayout extends BoundsMixins { + /** + * Boolean flag indicating if subviews should be centered relative to their respective rows or columns. + * + * __Default value:__ `false` + */ + center?: boolean; + /** + * The spacing in pixels between sub-views of the concat operator. + * + * __Default value__: `10` + */ + spacing?: number; +} +/** + * Base layout for FacetSpec and RepeatSpec. + * This is named "GenericComposition" layout as ConcatLayout is a GenericCompositionLayout too + * (but _not_ vice versa). + */ +export interface GenericCompositionLayout extends BoundsMixins { + /** + * The alignment to apply to grid rows and columns. + * The supported string values are `"all"`, `"each"`, and `"none"`. + * + * - For `"none"`, a flow layout will be used, in which adjacent subviews are simply placed one after the other. + * - For `"each"`, subviews will be aligned into a clean grid structure, but each row or column may be of variable size. + * - For `"all"`, subviews will be aligned and each row or column will be sized identically based on the maximum observed size. String values for this property will be applied to both grid rows and columns. + * + * Alternatively, an object value of the form `{"row": string, "column": string}` can be used to supply different alignments for rows and columns. + * + * __Default value:__ `"all"`. + */ + align?: VgLayoutAlign | RowCol; + /** + * Boolean flag indicating if subviews should be centered relative to their respective rows or columns. + * + * An object value of the form `{"row": boolean, "column": boolean}` can be used to supply different centering values for rows and columns. + * + * __Default value:__ `false` + */ + center?: boolean | RowCol; + /** + * The spacing in pixels between sub-views of the composition operator. + * An object of the form `{"row": number, "column": number}` can be used to set + * different spacing values for rows and columns. + * + * __Default value__: `10` + */ + spacing?: number | RowCol; +} +export declare function extractCompositionLayout(layout: GenericCompositionLayout): GenericCompositionLayout; +export declare type AutosizeType = 'pad' | 'fit' | 'none'; +export interface AutoSizeParams { + /** + * The sizing format type. One of `"pad"`, `"fit"` or `"none"`. See the [autosize type](https://vega.github.io/vega-lite/docs/size.html#autosize) documentation for descriptions of each. + * + * __Default value__: `"pad"` + */ + type?: AutosizeType; + /** + * A boolean flag indicating if autosize layout should be re-calculated on every view update. + * + * __Default value__: `false` + */ + resize?: boolean; + /** + * Determines how size calculation should be performed, one of `"content"` or `"padding"`. The default setting (`"content"`) interprets the width and height settings as the data rectangle (plotting) dimensions, to which padding is then added. In contrast, the `"padding"` setting includes the padding within the view size calculations, such that the width and height settings indicate the **total** intended size of the view. + * + * __Default value__: `"content"` + */ + contains?: 'content' | 'padding'; +} +export declare function normalizeAutoSize(topLevelAutosize: AutosizeType | AutoSizeParams, configAutosize: AutosizeType | AutoSizeParams, isUnitOrLayer?: boolean): AutoSizeParams; +export declare function extractTopLevelProperties(t: T): {}; diff --git a/build/src/toplevelprops.js b/build/src/toplevelprops.js new file mode 100644 index 0000000000..4b47374796 --- /dev/null +++ b/build/src/toplevelprops.js @@ -0,0 +1,34 @@ +import * as tslib_1 from "tslib"; +import { isString } from 'vega-util'; +import * as log from './log'; +export function extractCompositionLayout(layout) { + var _a = layout || {}, _b = _a.align, align = _b === void 0 ? undefined : _b, _c = _a.center, center = _c === void 0 ? undefined : _c, _d = _a.bounds, bounds = _d === void 0 ? undefined : _d, _e = _a.spacing, spacing = _e === void 0 ? undefined : _e; + return { align: align, bounds: bounds, center: center, spacing: spacing }; +} +function _normalizeAutoSize(autosize) { + return isString(autosize) ? { type: autosize } : autosize || {}; +} +export function normalizeAutoSize(topLevelAutosize, configAutosize, isUnitOrLayer) { + if (isUnitOrLayer === void 0) { isUnitOrLayer = true; } + var autosize = tslib_1.__assign({ type: 'pad' }, _normalizeAutoSize(configAutosize), _normalizeAutoSize(topLevelAutosize)); + if (autosize.type === 'fit') { + if (!isUnitOrLayer) { + log.warn(log.message.FIT_NON_SINGLE); + autosize.type = 'pad'; + } + } + return autosize; +} +var TOP_LEVEL_PROPERTIES = [ + 'background', 'padding', 'datasets' + // We do not include "autosize" here as it is supported by only unit and layer specs and thus need to be normalized +]; +export function extractTopLevelProperties(t) { + return TOP_LEVEL_PROPERTIES.reduce(function (o, p) { + if (t && t[p] !== undefined) { + o[p] = t[p]; + } + return o; + }, {}); +} +//# sourceMappingURL=toplevelprops.js.map \ No newline at end of file diff --git a/build/src/toplevelprops.js.map b/build/src/toplevelprops.js.map new file mode 100644 index 0000000000..e780b4cdc1 --- /dev/null +++ b/build/src/toplevelprops.js.map @@ -0,0 +1 @@ +{"version":3,"file":"toplevelprops.js","sourceRoot":"","sources":["../../src/toplevelprops.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAC;AAGnC,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAmH7B,MAAM,mCAAmC,MAAgC;IACjE,IAAA,iBAA+F,EAA9F,aAAiB,EAAjB,sCAAiB,EAAE,cAAkB,EAAlB,uCAAkB,EAAE,cAAkB,EAAlB,uCAAkB,EAAE,eAAmB,EAAnB,wCAAmB,CAAiB;IACtG,OAAO,EAAC,KAAK,OAAA,EAAE,MAAM,QAAA,EAAE,MAAM,QAAA,EAAE,OAAO,SAAA,EAAC,CAAC;AAC1C,CAAC;AA2BD,4BAA4B,QAAuC;IACjE,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC;AAChE,CAAC;AAED,MAAM,4BAA4B,gBAA+C,EAAE,cAA6C,EAAE,aAA6B;IAA7B,8BAAA,EAAA,oBAA6B;IAC7J,IAAM,QAAQ,sBACZ,IAAI,EAAE,KAAK,IACR,kBAAkB,CAAC,cAAc,CAAC,EAClC,kBAAkB,CAAC,gBAAgB,CAAC,CACxC,CAAC;IAEF,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,EAAE;QAC3B,IAAI,CAAC,aAAa,EAAE;YAClB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YACrC,QAAQ,CAAC,IAAI,GAAG,KAAK,CAAC;SACvB;KACF;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,IAAM,oBAAoB,GAAiC;IACzD,YAAY,EAAE,SAAS,EAAE,UAAU;IACnC,mHAAmH;CACpH,CAAC;AAEF,MAAM,oCAAkE,CAAI;IAC1E,OAAO,oBAAoB,CAAC,MAAM,CAAC,UAAC,CAAC,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE;YAC3B,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;SACb;QACD,OAAO,CAAC,CAAC;IACX,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC","sourcesContent":["import {isString} from 'vega-util';\n\nimport {InlineDataset} from './data';\nimport * as log from './log';\nimport {Dict} from './util';\nimport {RowCol, VgLayoutAlign} from './vega.schema';\n\n/**\n * @minimum 0\n */\nexport type Padding = number | {top?: number, bottom?: number, left?: number, right?: number};\n\nexport type Datasets = Dict;\n\nexport interface TopLevelProperties {\n /**\n * CSS color property to use as the background of visualization.\n *\n * __Default value:__ none (transparent)\n */\n background?: string;\n\n /**\n * The default visualization padding, in pixels, from the edge of the visualization canvas to the data rectangle. If a number, specifies padding for all sides.\n * If an object, the value should have the format `{\"left\": 5, \"top\": 5, \"right\": 5, \"bottom\": 5}` to specify padding for each side of the visualization.\n *\n * __Default value__: `5`\n */\n padding?: Padding;\n\n /**\n * Sets how the visualization size should be determined. If a string, should be one of `\"pad\"`, `\"fit\"` or `\"none\"`.\n * Object values can additionally specify parameters for content sizing and automatic resizing.\n * `\"fit\"` is only supported for single and layered views that don't use `rangeStep`.\n *\n * __Default value__: `pad`\n */\n autosize?: AutosizeType | AutoSizeParams;\n\n /**\n * A global data store for named datasets. This is a mapping from names to inline datasets.\n * This can be an array of objects or primitive values or a string. Arrays of primitive values are ingested as objects with a `data` property.\n */\n datasets?: Datasets;\n}\n\nexport interface BoundsMixins {\n /**\n * The bounds calculation method to use for determining the extent of a sub-plot. One of `full` (the default) or `flush`.\n *\n * - If set to `full`, the entire calculated bounds (including axes, title, and legend) will be used.\n * - If set to `flush`, only the specified width and height values for the sub-view will be used. The `flush` setting can be useful when attempting to place sub-plots without axes or legends into a uniform grid structure.\n *\n * __Default value:__ `\"full\"`\n */\n\n bounds?: 'full' | 'flush';\n}\n\n/**\n * Base layout mixins for V/HConcatSpec.\n * Concat layout should not have RowCol generic fo its property.\n */\nexport interface ConcatLayout extends BoundsMixins {\n /**\n * Boolean flag indicating if subviews should be centered relative to their respective rows or columns.\n *\n * __Default value:__ `false`\n */\n center?: boolean;\n\n /**\n * The spacing in pixels between sub-views of the concat operator.\n *\n * __Default value__: `10`\n */\n spacing?: number;\n}\n\n/**\n * Base layout for FacetSpec and RepeatSpec.\n * This is named \"GenericComposition\" layout as ConcatLayout is a GenericCompositionLayout too\n * (but _not_ vice versa).\n */\nexport interface GenericCompositionLayout extends BoundsMixins {\n /**\n * The alignment to apply to grid rows and columns.\n * The supported string values are `\"all\"`, `\"each\"`, and `\"none\"`.\n *\n * - For `\"none\"`, a flow layout will be used, in which adjacent subviews are simply placed one after the other.\n * - For `\"each\"`, subviews will be aligned into a clean grid structure, but each row or column may be of variable size.\n * - For `\"all\"`, subviews will be aligned and each row or column will be sized identically based on the maximum observed size. String values for this property will be applied to both grid rows and columns.\n *\n * Alternatively, an object value of the form `{\"row\": string, \"column\": string}` can be used to supply different alignments for rows and columns.\n *\n * __Default value:__ `\"all\"`.\n */\n align?: VgLayoutAlign | RowCol;\n\n /**\n * Boolean flag indicating if subviews should be centered relative to their respective rows or columns.\n *\n * An object value of the form `{\"row\": boolean, \"column\": boolean}` can be used to supply different centering values for rows and columns.\n *\n * __Default value:__ `false`\n */\n center?: boolean | RowCol;\n\n /**\n * The spacing in pixels between sub-views of the composition operator.\n * An object of the form `{\"row\": number, \"column\": number}` can be used to set\n * different spacing values for rows and columns.\n *\n * __Default value__: `10`\n */\n spacing?: number | RowCol;\n}\n\nexport function extractCompositionLayout(layout: GenericCompositionLayout): GenericCompositionLayout {\n const {align = undefined, center = undefined, bounds = undefined, spacing = undefined} = layout || {};\n return {align, bounds, center, spacing};\n}\n\nexport type AutosizeType = 'pad' | 'fit' | 'none';\n\nexport interface AutoSizeParams {\n /**\n * The sizing format type. One of `\"pad\"`, `\"fit\"` or `\"none\"`. See the [autosize type](https://vega.github.io/vega-lite/docs/size.html#autosize) documentation for descriptions of each.\n *\n * __Default value__: `\"pad\"`\n */\n type?: AutosizeType;\n\n /**\n * A boolean flag indicating if autosize layout should be re-calculated on every view update.\n *\n * __Default value__: `false`\n */\n resize?: boolean;\n\n /**\n * Determines how size calculation should be performed, one of `\"content\"` or `\"padding\"`. The default setting (`\"content\"`) interprets the width and height settings as the data rectangle (plotting) dimensions, to which padding is then added. In contrast, the `\"padding\"` setting includes the padding within the view size calculations, such that the width and height settings indicate the **total** intended size of the view.\n *\n * __Default value__: `\"content\"`\n */\n contains?: 'content' | 'padding';\n}\n\nfunction _normalizeAutoSize(autosize: AutosizeType | AutoSizeParams) {\n return isString(autosize) ? {type: autosize} : autosize || {};\n}\n\nexport function normalizeAutoSize(topLevelAutosize: AutosizeType | AutoSizeParams, configAutosize: AutosizeType | AutoSizeParams, isUnitOrLayer: boolean = true): AutoSizeParams {\n const autosize: AutoSizeParams = {\n type: 'pad',\n ..._normalizeAutoSize(configAutosize),\n ..._normalizeAutoSize(topLevelAutosize)\n };\n\n if (autosize.type === 'fit') {\n if (!isUnitOrLayer) {\n log.warn(log.message.FIT_NON_SINGLE);\n autosize.type = 'pad';\n }\n }\n\n return autosize;\n}\n\nconst TOP_LEVEL_PROPERTIES: (keyof TopLevelProperties)[] = [\n 'background', 'padding', 'datasets'\n // We do not include \"autosize\" here as it is supported by only unit and layer specs and thus need to be normalized\n];\n\nexport function extractTopLevelProperties(t: T) {\n return TOP_LEVEL_PROPERTIES.reduce((o, p) => {\n if (t && t[p] !== undefined) {\n o[p] = t[p];\n }\n return o;\n }, {});\n}\n"]} \ No newline at end of file diff --git a/build/src/transform.d.ts b/build/src/transform.d.ts new file mode 100644 index 0000000000..086ded645d --- /dev/null +++ b/build/src/transform.d.ts @@ -0,0 +1,217 @@ +import { AggregateOp } from 'vega'; +import { BinParams } from './bin'; +import { Data } from './data'; +import { LogicalOperand } from './logical'; +import { Predicate } from './predicate'; +import { SortField } from './sort'; +import { TimeUnit } from './timeunit'; +export interface FilterTransform { + /** + * The `filter` property must be one of the predicate definitions: + * + * 1) an [expression](https://vega.github.io/vega-lite/docs/types.html#expression) string, + * where `datum` can be used to refer to the current data object + * + * 2) one of the field predicates: [`equal`](https://vega.github.io/vega-lite/docs/filter.html#equal-predicate), + * [`lt`](https://vega.github.io/vega-lite/docs/filter.html#lt-predicate), + * [`lte`](https://vega.github.io/vega-lite/docs/filter.html#lte-predicate), + * [`gt`](https://vega.github.io/vega-lite/docs/filter.html#gt-predicate), + * [`gte`](https://vega.github.io/vega-lite/docs/filter.html#gte-predicate), + * [`range`](https://vega.github.io/vega-lite/docs/filter.html#range-predicate), + * or [`oneOf`](https://vega.github.io/vega-lite/docs/filter.html#one-of-predicate). + * + * 3) a [selection predicate](https://vega.github.io/vega-lite/docs/filter.html#selection-predicate) + * + * 4) a logical operand that combines (1), (2), or (3). + */ + filter: LogicalOperand; +} +export declare function isFilter(t: Transform): t is FilterTransform; +export interface CalculateTransform { + /** + * A [expression](https://vega.github.io/vega-lite/docs/types.html#expression) string. Use the variable `datum` to refer to the current data object. + */ + calculate: string; + /** + * The field for storing the computed formula value. + */ + as: string; +} +export interface BinTransform { + /** + * An object indicating bin properties, or simply `true` for using default bin parameters. + */ + bin: boolean | BinParams; + /** + * The data field to bin. + */ + field: string; + /** + * The output fields at which to write the start and end bin values. + */ + as: string | string[]; +} +export interface TimeUnitTransform { + /** + * The timeUnit. + */ + timeUnit: TimeUnit; + /** + * The data field to apply time unit. + */ + field: string; + /** + * The output field to write the timeUnit value. + */ + as: string; +} +export interface AggregateTransform { + /** + * Array of objects that define fields to aggregate. + */ + aggregate: AggregatedFieldDef[]; + /** + * The data fields to group by. If not specified, a single group containing all data objects will be used. + */ + groupby?: string[]; +} +export interface AggregatedFieldDef { + /** + * The aggregation operations to apply to the fields, such as sum, average or count. + * See the [full list of supported aggregation operations](https://vega.github.io/vega-lite/docs/aggregate.html#ops) + * for more information. + */ + op: AggregateOp; + /** + * The data field for which to compute aggregate function. This is required for all aggregation operations except `"count"`. + */ + field?: string; + /** + * The output field names to use for each aggregated field. + */ + as: string; +} +/** + * @hide + */ +export interface StackTransform { + /** + * The field which is stacked. + */ + stack: string; + /** + * The data fields to group by. + */ + groupby: string[]; + /** + * Mode for stacking marks. + * __Default value:__ `"zero"` + */ + offset?: 'zero' | 'center' | 'normalize'; + /** + * Field that determines the order of leaves in the stacked charts. + */ + sort?: SortField[]; + /** + * Output field names. This can be either a string or an array of strings with + * two elements denoting the name for the fields for stack start and stack end + * respectively. + * If a single string(eg."val") is provided, the end field will be "val_end". + */ + as: string | string[]; +} +export declare type WindowOnlyOp = 'row_number' | 'rank' | 'dense_rank' | 'percent_rank' | 'cume_dist' | 'ntile' | 'lag' | 'lead' | 'first_value' | 'last_value' | 'nth_value'; +export interface WindowFieldDef { + /** + * The window or aggregation operations to apply within a window, including `rank`, `lead`, `sum`, `average` or `count`. See the list of all supported operations [here](https://vega.github.io/vega-lite/docs/window.html#ops). + */ + op: AggregateOp | WindowOnlyOp; + /** + * Parameter values for the window functions. Parameter values can be omitted for operations that do not accept a parameter. + * + * See the list of all supported operations and their parameters [here](https://vega.github.io/vega-lite/docs/transforms/window.html). + */ + param?: number; + /** + * The data field for which to compute the aggregate or window function. This can be omitted for window functions that do not operate over a field such as `count`, `rank`, `dense_rank`. + */ + field?: string; + /** + * The output name for the window operation. + */ + as: string; +} +export interface WindowTransform { + /** + * The definition of the fields in the window, and what calculations to use. + */ + window: WindowFieldDef[]; + /** + * A frame specification as a two-element array indicating how the sliding window should proceed. The array entries should either be a number indicating the offset from the current data object, or null to indicate unbounded rows preceding or following the current data object. The default value is `[null, 0]`, indicating that the sliding window includes the current object and all preceding objects. The value `[-5, 5]` indicates that the window should include five objects preceding and five objects following the current object. Finally, `[null, null]` indicates that the window frame should always include all data objects. The only operators affected are the aggregation operations and the `first_value`, `last_value`, and `nth_value` window operations. The other window operations are not affected by this. + * + * __Default value:__: `[null, 0]` (includes the current object and all preceding objects) + */ + frame?: (null | number)[]; + /** + * Indicates if the sliding window frame should ignore peer values. (Peer values are those considered identical by the sort criteria). The default is false, causing the window frame to expand to include all peer values. If set to true, the window frame will be defined by offset values only. This setting only affects those operations that depend on the window frame, namely aggregation operations and the first_value, last_value, and nth_value window operations. + * + * __Default value:__ `false` + */ + ignorePeers?: boolean; + /** + * The data fields for partitioning the data objects into separate windows. If unspecified, all data points will be in a single group. + */ + groupby?: string[]; + /** + * A sort field definition for sorting data objects within a window. If two data objects are considered equal by the comparator, they are considered “peer” values of equal rank. If sort is not specified, the order is undefined: data objects are processed in the order they are observed and none are considered peers (the ignorePeers parameter is ignored and treated as if set to `true`). + */ + sort?: SortField[]; +} +export interface LookupData { + /** + * Secondary data source to lookup in. + */ + data: Data; + /** + * Key in data to lookup. + */ + key: string; + /** + * Fields in foreign data to lookup. + * If not specified, the entire object is queried. + */ + fields?: string[]; +} +export interface LookupTransform { + /** + * Key in primary data source. + */ + lookup: string; + /** + * Secondary data reference. + */ + from: LookupData; + /** + * The field or fields for storing the computed formula value. + * If `from.fields` is specified, the transform will use the same names for `as`. + * If `from.fields` is not specified, `as` has to be a string and we put the whole object into the data under the specified name. + */ + as?: string | string[]; + /** + * The default value to use if lookup fails. + * + * __Default value:__ `null` + */ + default?: string; +} +export declare function isLookup(t: Transform): t is LookupTransform; +export declare function isWindow(t: Transform): t is WindowTransform; +export declare function isCalculate(t: Transform): t is CalculateTransform; +export declare function isBin(t: Transform): t is BinTransform; +export declare function isTimeUnit(t: Transform): t is TimeUnitTransform; +export declare function isAggregate(t: Transform): t is AggregateTransform; +export declare function isStack(t: Transform): t is StackTransform; +export declare type Transform = FilterTransform | CalculateTransform | LookupTransform | BinTransform | TimeUnitTransform | AggregateTransform | WindowTransform | StackTransform; +export declare function normalizeTransform(transform: Transform[]): (CalculateTransform | LookupTransform | BinTransform | TimeUnitTransform | AggregateTransform | WindowTransform | StackTransform | { + filter: LogicalOperand; +})[]; diff --git a/build/src/transform.js b/build/src/transform.js new file mode 100644 index 0000000000..608da5ed7b --- /dev/null +++ b/build/src/transform.js @@ -0,0 +1,37 @@ +import { normalizeLogicalOperand } from './logical'; +import { normalizePredicate } from './predicate'; +export function isFilter(t) { + return t['filter'] !== undefined; +} +export function isLookup(t) { + return t['lookup'] !== undefined; +} +export function isWindow(t) { + return t['window'] !== undefined; +} +export function isCalculate(t) { + return t['calculate'] !== undefined; +} +export function isBin(t) { + return !!t['bin']; +} +export function isTimeUnit(t) { + return t['timeUnit'] !== undefined; +} +export function isAggregate(t) { + return t['aggregate'] !== undefined; +} +export function isStack(t) { + return t['stack'] !== undefined; +} +export function normalizeTransform(transform) { + return transform.map(function (t) { + if (isFilter(t)) { + return { + filter: normalizeLogicalOperand(t.filter, normalizePredicate) + }; + } + return t; + }); +} +//# sourceMappingURL=transform.js.map \ No newline at end of file diff --git a/build/src/transform.js.map b/build/src/transform.js.map new file mode 100644 index 0000000000..396a10b460 --- /dev/null +++ b/build/src/transform.js.map @@ -0,0 +1 @@ +{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../src/transform.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,uBAAuB,EAAC,MAAM,WAAW,CAAC;AAClE,OAAO,EAAC,kBAAkB,EAAY,MAAM,aAAa,CAAC;AA2B1D,MAAM,mBAAmB,CAAY;IACnC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC;AACnC,CAAC;AAgOD,MAAM,mBAAmB,CAAY;IACnC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC;AACnC,CAAC;AAED,MAAM,mBAAmB,CAAY;IACnC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC;AACnC,CAAC;AAED,MAAM,sBAAsB,CAAY;IACtC,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK,SAAS,CAAC;AACtC,CAAC;AAED,MAAM,gBAAgB,CAAY;IAChC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACpB,CAAC;AAED,MAAM,qBAAqB,CAAY;IACrC,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,SAAS,CAAC;AACrC,CAAC;AAED,MAAM,sBAAsB,CAAY;IACtC,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK,SAAS,CAAC;AACtC,CAAC;AAED,MAAM,kBAAkB,CAAY;IAClC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC;AAClC,CAAC;AAID,MAAM,6BAA6B,SAAsB;IACvD,OAAO,SAAS,CAAC,GAAG,CAAC,UAAA,CAAC;QACpB,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE;YACf,OAAO;gBACL,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC,MAAM,EAAE,kBAAkB,CAAC;aAC9D,CAAC;SACH;QACD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {AggregateOp} from 'vega';\n\nimport {BinParams} from './bin';\nimport {Data} from './data';\nimport {LogicalOperand, normalizeLogicalOperand} from './logical';\nimport {normalizePredicate, Predicate} from './predicate';\nimport {SortField} from './sort';\nimport {TimeUnit} from './timeunit';\n\nexport interface FilterTransform {\n /**\n * The `filter` property must be one of the predicate definitions:\n *\n * 1) an [expression](https://vega.github.io/vega-lite/docs/types.html#expression) string,\n * where `datum` can be used to refer to the current data object\n *\n * 2) one of the field predicates: [`equal`](https://vega.github.io/vega-lite/docs/filter.html#equal-predicate),\n * [`lt`](https://vega.github.io/vega-lite/docs/filter.html#lt-predicate),\n * [`lte`](https://vega.github.io/vega-lite/docs/filter.html#lte-predicate),\n * [`gt`](https://vega.github.io/vega-lite/docs/filter.html#gt-predicate),\n * [`gte`](https://vega.github.io/vega-lite/docs/filter.html#gte-predicate),\n * [`range`](https://vega.github.io/vega-lite/docs/filter.html#range-predicate),\n * or [`oneOf`](https://vega.github.io/vega-lite/docs/filter.html#one-of-predicate).\n *\n * 3) a [selection predicate](https://vega.github.io/vega-lite/docs/filter.html#selection-predicate)\n *\n * 4) a logical operand that combines (1), (2), or (3).\n */\n // TODO: https://github.com/vega/vega-lite/issues/2901\n filter: LogicalOperand;\n}\n\nexport function isFilter(t: Transform): t is FilterTransform {\n return t['filter'] !== undefined;\n}\n\nexport interface CalculateTransform {\n /**\n * A [expression](https://vega.github.io/vega-lite/docs/types.html#expression) string. Use the variable `datum` to refer to the current data object.\n */\n calculate: string;\n\n /**\n * The field for storing the computed formula value.\n */\n as: string;\n}\n\nexport interface BinTransform {\n /**\n * An object indicating bin properties, or simply `true` for using default bin parameters.\n */\n bin: boolean | BinParams;\n\n /**\n * The data field to bin.\n */\n field: string;\n\n /**\n * The output fields at which to write the start and end bin values.\n */\n as: string | string[];\n}\n\nexport interface TimeUnitTransform {\n /**\n * The timeUnit.\n */\n timeUnit: TimeUnit;\n\n /**\n * The data field to apply time unit.\n */\n field: string;\n\n /**\n * The output field to write the timeUnit value.\n */\n as: string;\n}\n\nexport interface AggregateTransform {\n /**\n * Array of objects that define fields to aggregate.\n */\n aggregate: AggregatedFieldDef[];\n\n /**\n * The data fields to group by. If not specified, a single group containing all data objects will be used.\n */\n groupby?: string[];\n}\n\nexport interface AggregatedFieldDef {\n /**\n * The aggregation operations to apply to the fields, such as sum, average or count.\n * See the [full list of supported aggregation operations](https://vega.github.io/vega-lite/docs/aggregate.html#ops)\n * for more information.\n */\n op: AggregateOp;\n\n /**\n * The data field for which to compute aggregate function. This is required for all aggregation operations except `\"count\"`.\n */\n field?: string;\n\n /**\n * The output field names to use for each aggregated field.\n */\n as: string;\n}\n\n\n/**\n * @hide\n */\nexport interface StackTransform {\n /**\n * The field which is stacked.\n */\n stack: string;\n /**\n * The data fields to group by.\n */\n groupby: string[];\n /**\n * Mode for stacking marks.\n * __Default value:__ `\"zero\"`\n */\n offset?: 'zero' | 'center' | 'normalize';\n /**\n * Field that determines the order of leaves in the stacked charts.\n */\n sort?: SortField[];\n /**\n * Output field names. This can be either a string or an array of strings with\n * two elements denoting the name for the fields for stack start and stack end\n * respectively.\n * If a single string(eg.\"val\") is provided, the end field will be \"val_end\".\n */\n as: string | string[];\n\n}\n\n\nexport type WindowOnlyOp =\n 'row_number' |\n 'rank' |\n 'dense_rank' |\n 'percent_rank' |\n 'cume_dist' |\n 'ntile' |\n 'lag' |\n 'lead' |\n 'first_value' |\n 'last_value' |\n 'nth_value';\n\nexport interface WindowFieldDef {\n /**\n * The window or aggregation operations to apply within a window, including `rank`, `lead`, `sum`, `average` or `count`. See the list of all supported operations [here](https://vega.github.io/vega-lite/docs/window.html#ops).\n */\n op: AggregateOp | WindowOnlyOp;\n\n /**\n * Parameter values for the window functions. Parameter values can be omitted for operations that do not accept a parameter.\n *\n * See the list of all supported operations and their parameters [here](https://vega.github.io/vega-lite/docs/transforms/window.html).\n */\n param?: number;\n\n /**\n * The data field for which to compute the aggregate or window function. This can be omitted for window functions that do not operate over a field such as `count`, `rank`, `dense_rank`.\n */\n field?: string;\n\n /**\n * The output name for the window operation.\n */\n as: string;\n}\n\nexport interface WindowTransform {\n /**\n * The definition of the fields in the window, and what calculations to use.\n */\n window: WindowFieldDef[];\n\n /**\n * A frame specification as a two-element array indicating how the sliding window should proceed. The array entries should either be a number indicating the offset from the current data object, or null to indicate unbounded rows preceding or following the current data object. The default value is `[null, 0]`, indicating that the sliding window includes the current object and all preceding objects. The value `[-5, 5]` indicates that the window should include five objects preceding and five objects following the current object. Finally, `[null, null]` indicates that the window frame should always include all data objects. The only operators affected are the aggregation operations and the `first_value`, `last_value`, and `nth_value` window operations. The other window operations are not affected by this.\n *\n * __Default value:__: `[null, 0]` (includes the current object and all preceding objects)\n */\n frame?: (null | number)[];\n\n /**\n * Indicates if the sliding window frame should ignore peer values. (Peer values are those considered identical by the sort criteria). The default is false, causing the window frame to expand to include all peer values. If set to true, the window frame will be defined by offset values only. This setting only affects those operations that depend on the window frame, namely aggregation operations and the first_value, last_value, and nth_value window operations.\n *\n * __Default value:__ `false`\n */\n ignorePeers?: boolean;\n\n /**\n * The data fields for partitioning the data objects into separate windows. If unspecified, all data points will be in a single group.\n */\n groupby?: string[];\n\n /**\n * A sort field definition for sorting data objects within a window. If two data objects are considered equal by the comparator, they are considered “peer” values of equal rank. If sort is not specified, the order is undefined: data objects are processed in the order they are observed and none are considered peers (the ignorePeers parameter is ignored and treated as if set to `true`).\n */\n sort?: SortField[];\n}\n\nexport interface LookupData {\n /**\n * Secondary data source to lookup in.\n */\n data: Data;\n /**\n * Key in data to lookup.\n */\n key: string;\n /**\n * Fields in foreign data to lookup.\n * If not specified, the entire object is queried.\n */\n fields?: string[];\n}\n\nexport interface LookupTransform {\n /**\n * Key in primary data source.\n */\n lookup: string;\n\n /**\n * Secondary data reference.\n */\n from: LookupData;\n\n /**\n * The field or fields for storing the computed formula value.\n * If `from.fields` is specified, the transform will use the same names for `as`.\n * If `from.fields` is not specified, `as` has to be a string and we put the whole object into the data under the specified name.\n */\n as?: string | string[];\n\n /**\n * The default value to use if lookup fails.\n *\n * __Default value:__ `null`\n */\n default?: string;\n}\n\n\n\nexport function isLookup(t: Transform): t is LookupTransform {\n return t['lookup'] !== undefined;\n}\n\nexport function isWindow(t: Transform): t is WindowTransform {\n return t['window'] !== undefined;\n}\n\nexport function isCalculate(t: Transform): t is CalculateTransform {\n return t['calculate'] !== undefined;\n}\n\nexport function isBin(t: Transform): t is BinTransform {\n return !!t['bin'];\n}\n\nexport function isTimeUnit(t: Transform): t is TimeUnitTransform {\n return t['timeUnit'] !== undefined;\n}\n\nexport function isAggregate(t: Transform): t is AggregateTransform {\n return t['aggregate'] !== undefined;\n}\n\nexport function isStack(t: Transform): t is StackTransform {\n return t['stack'] !== undefined;\n}\n\nexport type Transform = FilterTransform | CalculateTransform | LookupTransform | BinTransform | TimeUnitTransform | AggregateTransform | WindowTransform | StackTransform;\n\nexport function normalizeTransform(transform: Transform[]) {\n return transform.map(t => {\n if (isFilter(t)) {\n return {\n filter: normalizeLogicalOperand(t.filter, normalizePredicate)\n };\n }\n return t;\n });\n}\n"]} \ No newline at end of file diff --git a/build/src/type.d.ts b/build/src/type.d.ts new file mode 100644 index 0000000000..3036050339 --- /dev/null +++ b/build/src/type.d.ts @@ -0,0 +1,28 @@ +import { Flag } from './util'; +/** Constants and utilities for data type */ +/** Data type based on level of measurement */ +export declare namespace Type { + const QUANTITATIVE: 'quantitative'; + const ORDINAL: 'ordinal'; + const TEMPORAL: 'temporal'; + const NOMINAL: 'nominal'; + const LATITUDE: 'latitude'; + const LONGITUDE: 'longitude'; + const GEOJSON: 'geojson'; +} +export declare type BasicType = typeof Type.QUANTITATIVE | typeof Type.ORDINAL | typeof Type.TEMPORAL | typeof Type.NOMINAL; +export declare type GeoType = typeof Type.LATITUDE | typeof Type.LONGITUDE | typeof Type.GEOJSON; +export declare type Type = BasicType | GeoType; +export declare const TYPE_INDEX: Flag; +export declare function isType(t: any): t is Type; +export declare const QUANTITATIVE: "quantitative"; +export declare const ORDINAL: "ordinal"; +export declare const TEMPORAL: "temporal"; +export declare const NOMINAL: "nominal"; +export declare const GEOJSON: "geojson"; +/** + * Get full, lowercase type name for a given type. + * @param type + * @return Full type name. + */ +export declare function getFullName(type: Type | string): Type; diff --git a/build/src/type.js b/build/src/type.js new file mode 100644 index 0000000000..eb938b9650 --- /dev/null +++ b/build/src/type.js @@ -0,0 +1,62 @@ +/** Constants and utilities for data type */ +/** Data type based on level of measurement */ +export var Type; +(function (Type) { + Type.QUANTITATIVE = 'quantitative'; + Type.ORDINAL = 'ordinal'; + Type.TEMPORAL = 'temporal'; + Type.NOMINAL = 'nominal'; + Type.LATITUDE = 'latitude'; + Type.LONGITUDE = 'longitude'; + Type.GEOJSON = 'geojson'; +})(Type || (Type = {})); +export var TYPE_INDEX = { + quantitative: 1, + ordinal: 1, + temporal: 1, + nominal: 1, + latitude: 1, + longitude: 1, + geojson: 1 +}; +export function isType(t) { + return !!TYPE_INDEX[t]; +} +export var QUANTITATIVE = Type.QUANTITATIVE; +export var ORDINAL = Type.ORDINAL; +export var TEMPORAL = Type.TEMPORAL; +export var NOMINAL = Type.NOMINAL; +export var GEOJSON = Type.GEOJSON; +/** + * Get full, lowercase type name for a given type. + * @param type + * @return Full type name. + */ +export function getFullName(type) { + if (type) { + type = type.toLowerCase(); + switch (type) { + case 'q': + case QUANTITATIVE: + return 'quantitative'; + case 't': + case TEMPORAL: + return 'temporal'; + case 'o': + case ORDINAL: + return 'ordinal'; + case 'n': + case NOMINAL: + return 'nominal'; + case Type.LATITUDE: + return 'latitude'; + case Type.LONGITUDE: + return 'longitude'; + case GEOJSON: + return 'geojson'; + } + } + // If we get invalid input, return undefined type. + return undefined; +} +//# sourceMappingURL=type.js.map \ No newline at end of file diff --git a/build/src/type.js.map b/build/src/type.js.map new file mode 100644 index 0000000000..8ae8bf9590 --- /dev/null +++ b/build/src/type.js.map @@ -0,0 +1 @@ +{"version":3,"file":"type.js","sourceRoot":"","sources":["../../src/type.ts"],"names":[],"mappings":"AACA,4CAA4C;AAC5C,8CAA8C;AAE9C,MAAM,KAAW,IAAI,CASpB;AATD,WAAiB,IAAI;IACN,iBAAY,GAAmB,cAAc,CAAC;IAC9C,YAAO,GAAc,SAAS,CAAC;IAC/B,aAAQ,GAAe,UAAU,CAAC;IAClC,YAAO,GAAc,SAAS,CAAC;IAE/B,aAAQ,GAAe,UAAU,CAAC;IAClC,cAAS,GAAgB,WAAW,CAAC;IACrC,YAAO,GAAc,SAAS,CAAC;AAC9C,CAAC,EATgB,IAAI,KAAJ,IAAI,QASpB;AAMD,MAAM,CAAC,IAAM,UAAU,GAAe;IACpC,YAAY,EAAE,CAAC;IACf,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,CAAC;IACX,SAAS,EAAE,CAAC;IACZ,OAAO,EAAE,CAAC;CACX,CAAC;AAEF,MAAM,iBAAiB,CAAM;IAC3B,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,IAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;AAC9C,MAAM,CAAC,IAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;AACpC,MAAM,CAAC,IAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;AACtC,MAAM,CAAC,IAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;AAEpC,MAAM,CAAC,IAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;AAEpC;;;;GAIG;AACH,MAAM,sBAAsB,IAAiB;IAC3C,IAAI,IAAI,EAAE;QACR,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC1B,QAAQ,IAAI,EAAE;YACZ,KAAK,GAAG,CAAC;YACT,KAAK,YAAY;gBACf,OAAO,cAAc,CAAC;YACxB,KAAK,GAAG,CAAC;YACT,KAAK,QAAQ;gBACX,OAAO,UAAU,CAAC;YACpB,KAAK,GAAG,CAAC;YACT,KAAK,OAAO;gBACV,OAAO,SAAS,CAAC;YACnB,KAAK,GAAG,CAAC;YACT,KAAK,OAAO;gBACV,OAAO,SAAS,CAAC;YACnB,KAAK,IAAI,CAAC,QAAQ;gBAChB,OAAO,UAAU,CAAC;YACpB,KAAK,IAAI,CAAC,SAAS;gBACjB,OAAO,WAAW,CAAC;YACrB,KAAK,OAAO;gBACV,OAAO,SAAS,CAAC;SACpB;KACF;IACD,kDAAkD;IAClD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import {Flag} from './util';\n/** Constants and utilities for data type */\n/** Data type based on level of measurement */\n\nexport namespace Type {\n export const QUANTITATIVE: 'quantitative' = 'quantitative';\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const TEMPORAL: 'temporal' = 'temporal';\n export const NOMINAL: 'nominal' = 'nominal';\n\n export const LATITUDE: 'latitude' = 'latitude';\n export const LONGITUDE: 'longitude' = 'longitude';\n export const GEOJSON: 'geojson' = 'geojson';\n}\nexport type BasicType = typeof Type.QUANTITATIVE | typeof Type.ORDINAL | typeof Type.TEMPORAL | typeof Type.NOMINAL;\nexport type GeoType = typeof Type.LATITUDE | typeof Type.LONGITUDE | typeof Type.GEOJSON;\n\nexport type Type = BasicType | GeoType;\n\nexport const TYPE_INDEX: Flag = {\n quantitative: 1,\n ordinal: 1,\n temporal: 1,\n nominal: 1,\n latitude: 1,\n longitude: 1,\n geojson: 1\n};\n\nexport function isType(t: any): t is Type {\n return !!TYPE_INDEX[t];\n}\n\nexport const QUANTITATIVE = Type.QUANTITATIVE;\nexport const ORDINAL = Type.ORDINAL;\nexport const TEMPORAL = Type.TEMPORAL;\nexport const NOMINAL = Type.NOMINAL;\n\nexport const GEOJSON = Type.GEOJSON;\n\n/**\n * Get full, lowercase type name for a given type.\n * @param type\n * @return Full type name.\n */\nexport function getFullName(type: Type|string): Type {\n if (type) {\n type = type.toLowerCase();\n switch (type) {\n case 'q':\n case QUANTITATIVE:\n return 'quantitative';\n case 't':\n case TEMPORAL:\n return 'temporal';\n case 'o':\n case ORDINAL:\n return 'ordinal';\n case 'n':\n case NOMINAL:\n return 'nominal';\n case Type.LATITUDE:\n return 'latitude';\n case Type.LONGITUDE:\n return 'longitude';\n case GEOJSON:\n return 'geojson';\n }\n }\n // If we get invalid input, return undefined type.\n return undefined;\n}\n"]} \ No newline at end of file diff --git a/build/src/util.d.ts b/build/src/util.d.ts new file mode 100644 index 0000000000..e8b341febf --- /dev/null +++ b/build/src/util.d.ts @@ -0,0 +1,102 @@ +import stableStringify from 'json-stable-stringify'; +import { LogicalOperand } from './logical'; +/** + * Creates an object composed of the picked object properties. + * + * Example: (from lodash) + * + * var object = {'a': 1, 'b': '2', 'c': 3}; + * pick(object, ['a', 'c']); + * // → {'a': 1, 'c': 3} + * + */ +export declare function pick(obj: T, props: K[]): Pick; +/** + * The opposite of _.pick; this method creates an object composed of the own + * and inherited enumerable string keyed properties of object that are not omitted. + */ +export declare function omit(obj: T, props: K[]): Omit; +/** + * Converts any object into a string representation that can be consumed by humans. + */ +export declare const stringify: typeof stableStringify; +/** + * Converts any object into a string of limited size, or a number. + */ +export declare function hash(a: any): string | number; +export declare function contains(array: T[], item: T): boolean; +/** Returns the array without the elements in item */ +export declare function without(array: T[], excludedItems: T[]): T[]; +export declare function union(array: T[], other: T[]): T[]; +/** + * Returns true if any item returns true. + */ +export declare function some(arr: T[], f: (d: T, k?: any, i?: any) => boolean): boolean; +/** + * Returns true if all items return true. + */ +export declare function every(arr: T[], f: (d: T, k?: any, i?: any) => boolean): boolean; +export declare function flatten(arrays: any[]): any; +/** + * recursively merges src into dest + */ +export declare function mergeDeep(dest: T, ...src: Partial[]): T; +export declare function unique(values: T[], f: (item: T) => string | number): T[]; +export interface Dict { + [key: string]: T; +} +export declare type StringSet = Dict; +/** + * Returns true if the two dictionaries disagree. Applies only to defined values. + */ +export declare function differ(dict: Dict, other: Dict): boolean; +export declare function hasIntersection(a: StringSet, b: StringSet): boolean; +export declare function isNumeric(num: string | number): boolean; +export declare function differArray(array: T[], other: T[]): boolean; +export declare const keys: (o: T) => Extract[]; +export declare function vals(x: { + [key: string]: T; +}): T[]; +export declare type Flag = { + [K in S]: 1; +}; +export declare function flagKeys(f: Flag): S[]; +export declare function duplicate(obj: T): T; +export declare function isBoolean(b: any): b is boolean; +/** + * Convert a string into a valid variable name + */ +export declare function varName(s: string): string; +export declare function logicalExpr(op: LogicalOperand, cb: Function): string; +export declare type Omit = Pick>; +/** + * Delete nested property of an object, and delete the ancestors of the property if they become empty. + */ +export declare function deleteNestedProperty(obj: any, orderedProps: string[]): boolean; +export declare function titlecase(s: string): string; +/** + * Converts a path to an access path with datum. + * @param path The field name. + * @param datum The string to use for `datum`. + */ +export declare function accessPathWithDatum(path: string, datum?: string): string; +/** + * Return access with datum to the falttened field. + * @param path The field name. + * @param datum The string to use for `datum`. + */ +export declare function flatAccessWithDatum(path: string, datum?: string): string; +/** + * Replaces path accesses with access to non-nested field. + * For example, `foo["bar"].baz` becomes `foo\\.bar\\.baz`. + */ +export declare function replacePathInField(path: string): string; +/** + * Remove path accesses with access from field. + * For example, `foo["bar"].baz` becomes `foo.bar.baz`. + */ +export declare function removePathFromField(path: string): string; +/** + * Count the depth of the path. Returns 1 for fields that are not nested. + */ +export declare function accessPathDepth(path: string): number; diff --git a/build/src/util.js b/build/src/util.js new file mode 100644 index 0000000000..073d0a0447 --- /dev/null +++ b/build/src/util.js @@ -0,0 +1,295 @@ +import * as tslib_1 from "tslib"; +import stableStringify from 'json-stable-stringify'; +import { isArray, isNumber, isString, splitAccessPath, stringValue } from 'vega-util'; +import { isLogicalAnd, isLogicalNot, isLogicalOr } from './logical'; +/** + * Creates an object composed of the picked object properties. + * + * Example: (from lodash) + * + * var object = {'a': 1, 'b': '2', 'c': 3}; + * pick(object, ['a', 'c']); + * // → {'a': 1, 'c': 3} + * + */ +export function pick(obj, props) { + var copy = {}; + for (var _i = 0, props_1 = props; _i < props_1.length; _i++) { + var prop = props_1[_i]; + if (obj.hasOwnProperty(prop)) { + copy[prop] = obj[prop]; + } + } + return copy; +} +/** + * The opposite of _.pick; this method creates an object composed of the own + * and inherited enumerable string keyed properties of object that are not omitted. + */ +export function omit(obj, props) { + var copy = tslib_1.__assign({}, obj); + for (var _i = 0, props_2 = props; _i < props_2.length; _i++) { + var prop = props_2[_i]; + delete copy[prop]; + } + return copy; +} +/** + * Converts any object into a string representation that can be consumed by humans. + */ +export var stringify = stableStringify; +/** + * Converts any object into a string of limited size, or a number. + */ +export function hash(a) { + if (isNumber(a)) { + return a; + } + var str = isString(a) ? a : stableStringify(a); + // short strings can be used as hash directly, longer strings are hashed to reduce memory usage + if (str.length < 100) { + return str; + } + // from http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/ + var h = 0; + for (var i = 0; i < str.length; i++) { + var char = str.charCodeAt(i); + h = ((h << 5) - h) + char; + h = h & h; // Convert to 32bit integer + } + return h; +} +export function contains(array, item) { + return array.indexOf(item) > -1; +} +/** Returns the array without the elements in item */ +export function without(array, excludedItems) { + return array.filter(function (item) { return !contains(excludedItems, item); }); +} +export function union(array, other) { + return array.concat(without(other, array)); +} +/** + * Returns true if any item returns true. + */ +export function some(arr, f) { + var i = 0; + for (var k = 0; k < arr.length; k++) { + if (f(arr[k], k, i++)) { + return true; + } + } + return false; +} +/** + * Returns true if all items return true. + */ +export function every(arr, f) { + var i = 0; + for (var k = 0; k < arr.length; k++) { + if (!f(arr[k], k, i++)) { + return false; + } + } + return true; +} +export function flatten(arrays) { + return [].concat.apply([], arrays); +} +/** + * recursively merges src into dest + */ +export function mergeDeep(dest) { + var src = []; + for (var _i = 1; _i < arguments.length; _i++) { + src[_i - 1] = arguments[_i]; + } + for (var _a = 0, src_1 = src; _a < src_1.length; _a++) { + var s = src_1[_a]; + dest = deepMerge_(dest, s); + } + return dest; +} +// recursively merges src into dest +function deepMerge_(dest, src) { + if (typeof src !== 'object' || src === null) { + return dest; + } + for (var p in src) { + if (!src.hasOwnProperty(p)) { + continue; + } + if (src[p] === undefined) { + continue; + } + if (typeof src[p] !== 'object' || isArray(src[p]) || src[p] === null) { + dest[p] = src[p]; + } + else if (typeof dest[p] !== 'object' || dest[p] === null) { + dest[p] = mergeDeep(isArray(src[p].constructor) ? [] : {}, src[p]); + } + else { + mergeDeep(dest[p], src[p]); + } + } + return dest; +} +export function unique(values, f) { + var results = []; + var u = {}; + var v; + for (var _i = 0, values_1 = values; _i < values_1.length; _i++) { + var val = values_1[_i]; + v = f(val); + if (v in u) { + continue; + } + u[v] = 1; + results.push(val); + } + return results; +} +/** + * Returns true if the two dictionaries disagree. Applies only to defined values. + */ +export function differ(dict, other) { + for (var key in dict) { + if (dict.hasOwnProperty(key)) { + if (other[key] && dict[key] && other[key] !== dict[key]) { + return true; + } + } + } + return false; +} +export function hasIntersection(a, b) { + for (var key in a) { + if (key in b) { + return true; + } + } + return false; +} +export function isNumeric(num) { + return !isNaN(num); +} +export function differArray(array, other) { + if (array.length !== other.length) { + return true; + } + array.sort(); + other.sort(); + for (var i = 0; i < array.length; i++) { + if (other[i] !== array[i]) { + return true; + } + } + return false; +} +// This is a stricter version of Object.keys but with better types. See https://github.com/Microsoft/TypeScript/pull/12253#issuecomment-263132208 +export var keys = Object.keys; +export function vals(x) { + var _vals = []; + for (var k in x) { + if (x.hasOwnProperty(k)) { + _vals.push(x[k]); + } + } + return _vals; +} +export function flagKeys(f) { + return keys(f); +} +export function duplicate(obj) { + return JSON.parse(JSON.stringify(obj)); +} +export function isBoolean(b) { + return b === true || b === false; +} +/** + * Convert a string into a valid variable name + */ +export function varName(s) { + // Replace non-alphanumeric characters (anything besides a-zA-Z0-9_) with _ + var alphanumericS = s.replace(/\W/g, '_'); + // Add _ if the string has leading numbers. + return (s.match(/^\d+/) ? '_' : '') + alphanumericS; +} +export function logicalExpr(op, cb) { + if (isLogicalNot(op)) { + return '!(' + logicalExpr(op.not, cb) + ')'; + } + else if (isLogicalAnd(op)) { + return '(' + op.and.map(function (and) { return logicalExpr(and, cb); }).join(') && (') + ')'; + } + else if (isLogicalOr(op)) { + return '(' + op.or.map(function (or) { return logicalExpr(or, cb); }).join(') || (') + ')'; + } + else { + return cb(op); + } +} +/** + * Delete nested property of an object, and delete the ancestors of the property if they become empty. + */ +export function deleteNestedProperty(obj, orderedProps) { + if (orderedProps.length === 0) { + return true; + } + var prop = orderedProps.shift(); + if (deleteNestedProperty(obj[prop], orderedProps)) { + delete obj[prop]; + } + return Object.keys(obj).length === 0; +} +export function titlecase(s) { + return s.charAt(0).toUpperCase() + s.substr(1); +} +/** + * Converts a path to an access path with datum. + * @param path The field name. + * @param datum The string to use for `datum`. + */ +export function accessPathWithDatum(path, datum) { + if (datum === void 0) { datum = 'datum'; } + var pieces = splitAccessPath(path); + var prefixes = []; + for (var i = 1; i <= pieces.length; i++) { + var prefix = "[" + pieces.slice(0, i).map(stringValue).join('][') + "]"; + prefixes.push("" + datum + prefix); + } + return prefixes.join(' && '); +} +/** + * Return access with datum to the falttened field. + * @param path The field name. + * @param datum The string to use for `datum`. + */ +export function flatAccessWithDatum(path, datum) { + if (datum === void 0) { datum = 'datum'; } + return datum + "[" + stringValue(splitAccessPath(path).join('.')) + "]"; +} +/** + * Replaces path accesses with access to non-nested field. + * For example, `foo["bar"].baz` becomes `foo\\.bar\\.baz`. + */ +export function replacePathInField(path) { + return "" + splitAccessPath(path).map(function (p) { return p.replace('.', '\\.'); }).join('\\.'); +} +/** + * Remove path accesses with access from field. + * For example, `foo["bar"].baz` becomes `foo.bar.baz`. + */ +export function removePathFromField(path) { + return "" + splitAccessPath(path).join('.'); +} +/** + * Count the depth of the path. Returns 1 for fields that are not nested. + */ +export function accessPathDepth(path) { + if (!path) { + return 0; + } + return splitAccessPath(path).length; +} +//# sourceMappingURL=util.js.map \ No newline at end of file diff --git a/build/src/util.js.map b/build/src/util.js.map new file mode 100644 index 0000000000..0dd8714397 --- /dev/null +++ b/build/src/util.js.map @@ -0,0 +1 @@ +{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"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","sourcesContent":["import stableStringify from 'json-stable-stringify';\nimport {isArray, isNumber, isString, splitAccessPath, stringValue} from 'vega-util';\nimport {isLogicalAnd, isLogicalNot, isLogicalOr, LogicalOperand} from './logical';\n\n/**\n * Creates an object composed of the picked object properties.\n *\n * Example: (from lodash)\n *\n * var object = {'a': 1, 'b': '2', 'c': 3};\n * pick(object, ['a', 'c']);\n * // → {'a': 1, 'c': 3}\n *\n */\nexport function pick(obj: T, props: K[]): Pick {\n const copy: any = {};\n for (const prop of props) {\n if (obj.hasOwnProperty(prop)) {\n copy[prop] = obj[prop];\n }\n }\n return copy;\n}\n\n/**\n * The opposite of _.pick; this method creates an object composed of the own\n * and inherited enumerable string keyed properties of object that are not omitted.\n */\nexport function omit(obj: T, props: K[]): Omit {\n const copy = {...obj as any};\n for (const prop of props) {\n delete copy[prop];\n }\n return copy;\n}\n\n/**\n * Converts any object into a string representation that can be consumed by humans.\n */\nexport const stringify = stableStringify;\n\n/**\n * Converts any object into a string of limited size, or a number.\n */\nexport function hash(a: any) {\n if (isNumber(a)) {\n return a;\n }\n\n const str = isString(a) ? a : stableStringify(a);\n\n // short strings can be used as hash directly, longer strings are hashed to reduce memory usage\n if (str.length < 100) {\n return str;\n }\n\n // from http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/\n let h = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n h = ((h<<5)-h)+char;\n h = h & h; // Convert to 32bit integer\n }\n return h;\n}\n\nexport function contains(array: T[], item: T) {\n return array.indexOf(item) > -1;\n}\n\n/** Returns the array without the elements in item */\nexport function without(array: T[], excludedItems: T[]) {\n return array.filter(item => !contains(excludedItems, item));\n}\n\nexport function union(array: T[], other: T[]) {\n return array.concat(without(other, array));\n}\n\n/**\n * Returns true if any item returns true.\n */\nexport function some(arr: T[], f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (let k = 0; k(arr: T[], f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (let k = 0; k(dest: T, ...src: Partial[]): T {\n for (const s of src) {\n dest = deepMerge_(dest, s);\n }\n return dest;\n}\n\n// recursively merges src into dest\nfunction deepMerge_(dest: any, src: any) {\n if (typeof src !== 'object' || src === null) {\n return dest;\n }\n\n for (const p in src) {\n if (!src.hasOwnProperty(p)) {\n continue;\n }\n if (src[p] === undefined) {\n continue;\n }\n if (typeof src[p] !== 'object' || isArray(src[p]) || src[p] === null) {\n dest[p] = src[p];\n } else if (typeof dest[p] !== 'object' || dest[p] === null) {\n dest[p] = mergeDeep(isArray(src[p].constructor) ? [] : {}, src[p]);\n } else {\n mergeDeep(dest[p], src[p]);\n }\n }\n return dest;\n}\n\nexport function unique(values: T[], f: (item: T) => string | number): T[] {\n const results: any[] = [];\n const u = {};\n let v: string | number;\n for (const val of values) {\n v = f(val);\n if (v in u) {\n continue;\n }\n u[v] = 1;\n results.push(val);\n }\n return results;\n}\n\nexport interface Dict {\n [key: string]: T;\n}\n\nexport type StringSet = Dict;\n\n/**\n * Returns true if the two dictionaries disagree. Applies only to defined values.\n */\nexport function differ(dict: Dict, other: Dict) {\n for (const key in dict) {\n if (dict.hasOwnProperty(key)) {\n if (other[key] && dict[key] && other[key] !== dict[key]) {\n return true;\n }\n }\n }\n return false;\n}\n\nexport function hasIntersection(a: StringSet, b: StringSet) {\n for (const key in a) {\n if (key in b) {\n return true;\n }\n }\n return false;\n}\n\nexport function isNumeric(num: string | number) {\n return !isNaN(num as any);\n}\n\nexport function differArray(array: T[], other: T[]) {\n if (array.length !== other.length) {\n return true;\n }\n\n array.sort();\n other.sort();\n\n for (let i = 0; i < array.length; i++) {\n if (other[i] !== array[i]) {\n return true;\n }\n }\n\n return false;\n}\n\n// This is a stricter version of Object.keys but with better types. See https://github.com/Microsoft/TypeScript/pull/12253#issuecomment-263132208\nexport const keys = Object.keys as (o: T) => (Extract)[];\n\nexport function vals(x: {[key: string]: T}): T[] {\n const _vals: T[] = [];\n for (const k in x) {\n if (x.hasOwnProperty(k)) {\n _vals.push(x[k]);\n }\n }\n return _vals;\n}\n\n// Using mapped type to declare a collect of flags for a string literal type S\n// https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types\nexport type Flag = {\n [K in S]: 1\n};\n\nexport function flagKeys(f: Flag): S[] {\n return keys(f) as S[];\n}\n\nexport function duplicate(obj: T): T {\n return JSON.parse(JSON.stringify(obj));\n}\n\nexport function isBoolean(b: any): b is boolean {\n return b === true || b === false;\n}\n\n/**\n * Convert a string into a valid variable name\n */\nexport function varName(s: string): string {\n // Replace non-alphanumeric characters (anything besides a-zA-Z0-9_) with _\n const alphanumericS = s.replace(/\\W/g, '_');\n\n // Add _ if the string has leading numbers.\n return (s.match(/^\\d+/) ? '_' : '') + alphanumericS;\n}\n\nexport function logicalExpr(op: LogicalOperand, cb: Function): string {\n if (isLogicalNot(op)) {\n return '!(' + logicalExpr(op.not, cb) + ')';\n } else if (isLogicalAnd(op)) {\n return '(' + op.and.map((and: LogicalOperand) => logicalExpr(and, cb)).join(') && (') + ')';\n } else if (isLogicalOr(op)) {\n return '(' + op.or.map((or: LogicalOperand) => logicalExpr(or, cb)).join(') || (') + ')';\n } else {\n return cb(op);\n }\n}\n\nexport type Omit = Pick>;\n\n/**\n * Delete nested property of an object, and delete the ancestors of the property if they become empty.\n */\nexport function deleteNestedProperty(obj: any, orderedProps: string[]) {\n if (orderedProps.length === 0) {\n return true;\n }\n const prop = orderedProps.shift();\n if (deleteNestedProperty(obj[prop], orderedProps)) {\n delete obj[prop];\n }\n return Object.keys(obj).length === 0;\n}\n\nexport function titlecase(s: string) {\n return s.charAt(0).toUpperCase() + s.substr(1);\n}\n\n/**\n * Converts a path to an access path with datum.\n * @param path The field name.\n * @param datum The string to use for `datum`.\n */\nexport function accessPathWithDatum(path: string, datum='datum') {\n const pieces = splitAccessPath(path);\n const prefixes = [];\n for (let i = 1; i <= pieces.length; i++) {\n const prefix = `[${pieces.slice(0,i).map(stringValue).join('][')}]`;\n prefixes.push(`${datum}${prefix}`);\n }\n return prefixes.join(' && ');\n}\n\n/**\n * Return access with datum to the falttened field.\n * @param path The field name.\n * @param datum The string to use for `datum`.\n */\nexport function flatAccessWithDatum(path: string, datum='datum') {\n return `${datum}[${stringValue(splitAccessPath(path).join('.'))}]`;\n}\n\n/**\n * Replaces path accesses with access to non-nested field.\n * For example, `foo[\"bar\"].baz` becomes `foo\\\\.bar\\\\.baz`.\n */\nexport function replacePathInField(path: string) {\n return `${splitAccessPath(path).map(p => p.replace('.', '\\\\.')).join('\\\\.')}`;\n}\n\n/**\n * Remove path accesses with access from field.\n * For example, `foo[\"bar\"].baz` becomes `foo.bar.baz`.\n */\nexport function removePathFromField(path: string) {\n return `${splitAccessPath(path).join('.')}`;\n}\n\n/**\n * Count the depth of the path. Returns 1 for fields that are not nested.\n */\nexport function accessPathDepth(path: string) {\n if (!path) {\n return 0;\n }\n return splitAccessPath(path).length;\n}\n"]} \ No newline at end of file diff --git a/build/src/validate.d.ts b/build/src/validate.d.ts new file mode 100644 index 0000000000..58369b36b0 --- /dev/null +++ b/build/src/validate.d.ts @@ -0,0 +1,31 @@ +import { FacetedCompositeUnitSpec } from './spec'; +export interface RequiredChannelMap { + [mark: string]: Array; +} +/** + * Required Encoding Channels for each mark type + */ +export declare const DEFAULT_REQUIRED_CHANNEL_MAP: RequiredChannelMap; +export interface SupportedChannelMap { + [mark: string]: { + [channel: string]: boolean; + }; +} +/** + * Supported Encoding Channel for each mark type + */ +export declare const DEFAULT_SUPPORTED_CHANNEL_TYPE: SupportedChannelMap; +/** + * Further check if encoding mapping of a spec is invalid and + * return error if it is invalid. + * + * This checks if + * (1) all the required encoding channels for the mark type are specified + * (2) all the specified encoding channels are supported by the mark type + * @param {[type]} spec [description] + * @param {RequiredChannelMap = DefaultRequiredChannelMap} requiredChannelMap + * @param {SupportedChannelMap = DefaultSupportedChannelMap} supportedChannelMap + * @return {String} Return one reason why the encoding is invalid, + * or null if the encoding is valid. + */ +export declare function getEncodingMappingError(spec: FacetedCompositeUnitSpec, requiredChannelMap?: RequiredChannelMap, supportedChannelMap?: SupportedChannelMap): string; diff --git a/build/src/validate.js b/build/src/validate.js new file mode 100644 index 0000000000..7a5882fff6 --- /dev/null +++ b/build/src/validate.js @@ -0,0 +1,67 @@ +import { toSet } from 'vega-util'; +import { isMarkDef } from './mark'; +import { BAR } from './mark'; +/** + * Required Encoding Channels for each mark type + */ +export var DEFAULT_REQUIRED_CHANNEL_MAP = { + text: ['text'], + line: ['x', 'y'], + trail: ['x', 'y'], + area: ['x', 'y'] +}; +/** + * Supported Encoding Channel for each mark type + */ +export var DEFAULT_SUPPORTED_CHANNEL_TYPE = { + bar: toSet(['row', 'column', 'x', 'y', 'size', 'color', 'fill', 'stroke', 'detail']), + line: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'color', 'detail']), + trail: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'color', 'detail', 'size']), + area: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'detail']), + tick: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'detail']), + circle: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail']), + square: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail']), + point: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail', 'shape']), + geoshape: toSet(['row', 'column', 'color', 'fill', 'stroke', 'detail', 'shape']), + text: toSet(['row', 'column', 'size', 'color', 'fill', 'stroke', 'text']) // TODO(#724) revise +}; +// TODO: consider if we should add validate method and +// requires ZSchema in the main vega-lite repo +/** + * Further check if encoding mapping of a spec is invalid and + * return error if it is invalid. + * + * This checks if + * (1) all the required encoding channels for the mark type are specified + * (2) all the specified encoding channels are supported by the mark type + * @param {[type]} spec [description] + * @param {RequiredChannelMap = DefaultRequiredChannelMap} requiredChannelMap + * @param {SupportedChannelMap = DefaultSupportedChannelMap} supportedChannelMap + * @return {String} Return one reason why the encoding is invalid, + * or null if the encoding is valid. + */ +export function getEncodingMappingError(spec, requiredChannelMap, supportedChannelMap) { + if (requiredChannelMap === void 0) { requiredChannelMap = DEFAULT_REQUIRED_CHANNEL_MAP; } + if (supportedChannelMap === void 0) { supportedChannelMap = DEFAULT_SUPPORTED_CHANNEL_TYPE; } + var mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var encoding = spec.encoding; + var requiredChannels = requiredChannelMap[mark]; + var supportedChannels = supportedChannelMap[mark]; + for (var i in requiredChannels) { // all required channels are in encoding` + if (!(requiredChannels[i] in encoding)) { + return 'Missing encoding channel \"' + requiredChannels[i] + + '\" for mark \"' + mark + '\"'; + } + } + for (var channel in encoding) { // all channels in encoding are supported + if (!supportedChannels[channel]) { + return 'Encoding channel \"' + channel + + '\" is not supported by mark type \"' + mark + '\"'; + } + } + if (mark === BAR && !encoding.x && !encoding.y) { + return 'Missing both x and y for bar'; + } + return null; +} +//# sourceMappingURL=validate.js.map \ No newline at end of file diff --git a/build/src/validate.js.map b/build/src/validate.js.map new file mode 100644 index 0000000000..204880202a --- /dev/null +++ b/build/src/validate.js.map @@ -0,0 +1 @@ +{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/validate.ts"],"names":[],"mappings":"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","sourcesContent":["import {toSet} from 'vega-util';\nimport {isMarkDef} from './mark';\nimport {BAR} from './mark';\nimport {FacetedCompositeUnitSpec} from './spec';\n\n\n\n// TODO: move to vl.spec.validator?\nexport interface RequiredChannelMap {\n [mark: string]: Array;\n}\n\n/**\n * Required Encoding Channels for each mark type\n */\nexport const DEFAULT_REQUIRED_CHANNEL_MAP: RequiredChannelMap = {\n text: ['text'],\n line: ['x', 'y'],\n trail: ['x', 'y'],\n area: ['x', 'y']\n};\n\nexport interface SupportedChannelMap {\n [mark: string]: {\n [channel: string]: boolean\n };\n}\n\n/**\n * Supported Encoding Channel for each mark type\n */\nexport const DEFAULT_SUPPORTED_CHANNEL_TYPE: SupportedChannelMap = {\n bar: toSet(['row', 'column', 'x', 'y', 'size', 'color', 'fill', 'stroke', 'detail']),\n line: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'color', 'detail']),\n trail: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'color', 'detail', 'size']),\n area: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'detail']),\n tick: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'detail']),\n circle: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail']),\n square: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail']),\n point: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail', 'shape']),\n geoshape: toSet(['row', 'column', 'color', 'fill', 'stroke', 'detail', 'shape']),\n text: toSet(['row', 'column', 'size', 'color', 'fill', 'stroke', 'text']) // TODO(#724) revise\n};\n\n// TODO: consider if we should add validate method and\n// requires ZSchema in the main vega-lite repo\n\n/**\n * Further check if encoding mapping of a spec is invalid and\n * return error if it is invalid.\n *\n * This checks if\n * (1) all the required encoding channels for the mark type are specified\n * (2) all the specified encoding channels are supported by the mark type\n * @param {[type]} spec [description]\n * @param {RequiredChannelMap = DefaultRequiredChannelMap} requiredChannelMap\n * @param {SupportedChannelMap = DefaultSupportedChannelMap} supportedChannelMap\n * @return {String} Return one reason why the encoding is invalid,\n * or null if the encoding is valid.\n */\nexport function getEncodingMappingError(spec: FacetedCompositeUnitSpec,\n requiredChannelMap: RequiredChannelMap = DEFAULT_REQUIRED_CHANNEL_MAP,\n supportedChannelMap: SupportedChannelMap = DEFAULT_SUPPORTED_CHANNEL_TYPE\n ) {\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n const encoding = spec.encoding;\n const requiredChannels = requiredChannelMap[mark];\n const supportedChannels = supportedChannelMap[mark];\n\n for (const i in requiredChannels) { // all required channels are in encoding`\n if (!(requiredChannels[i] in encoding)) {\n return 'Missing encoding channel \\\"' + requiredChannels[i] +\n '\\\" for mark \\\"' + mark + '\\\"';\n }\n }\n\n for (const channel in encoding) { // all channels in encoding are supported\n if (!supportedChannels[channel]) {\n return 'Encoding channel \\\"' + channel +\n '\\\" is not supported by mark type \\\"' + mark + '\\\"';\n }\n }\n\n if (mark === BAR && !encoding.x && !encoding.y) {\n return 'Missing both x and y for bar';\n }\n\n return null;\n}\n"]} \ No newline at end of file diff --git a/build/src/vega.schema.d.ts b/build/src/vega.schema.d.ts new file mode 100644 index 0000000000..f1ace046da --- /dev/null +++ b/build/src/vega.schema.d.ts @@ -0,0 +1,1053 @@ +import { AggregateOp } from 'vega'; +import { BaseBin } from './bin'; +import { NiceTime, ScaleType } from './scale'; +import { SortOrder } from './sort'; +import { StackOffset } from './stack'; +import { WindowOnlyOp } from './transform'; +export interface VgData { + name: string; + source?: string; + values?: any; + format?: { + type?: string; + parse?: string | object; + property?: string; + feature?: string; + mesh?: string; + }; + url?: string; + transform?: VgTransform[]; +} +export interface VgParentRef { + parent: string; +} +export declare type VgFieldRef = string | VgParentRef | VgParentRef[]; +export declare type VgSortField = true | { + field?: VgFieldRef; + op: AggregateOp; + order?: SortOrder; +}; +/** + * Unioned domains can only be sorted by count aggregate. + */ +export declare type VgUnionSortField = true | { + op: 'count'; + order?: SortOrder; +}; +export interface VgDataRef { + data: string; + field: VgFieldRef; + sort?: VgSortField; +} +export interface VgSignalRef { + signal: string; +} +export declare function isVgSignalRef(o: any): o is VgSignalRef; +export declare type VgEventStream = any; +export interface VgValueRef { + value?: number | string | boolean; + field?: string | { + datum?: string; + group?: string; + parent?: string; + }; + signal?: string; + scale?: string; + mult?: number; + offset?: number | VgValueRef; + band?: boolean | number | VgValueRef; +} +export interface DataRefUnionDomain { + fields: (any[] | VgDataRef | VgSignalRef)[]; + sort?: VgUnionSortField; +} +export interface VgFieldRefUnionDomain { + data: string; + fields: VgFieldRef[]; + sort?: VgUnionSortField; +} +export declare type VgScheme = { + scheme: string; + extent?: number[]; + count?: number; +}; +export declare type VgRange = string | VgDataRef | (number | string | VgDataRef | VgSignalRef)[] | VgScheme | VgRangeStep; +export declare type VgRangeStep = { + step: number | VgSignalRef; +}; +export declare function isVgRangeStep(range: VgRange): range is VgRangeStep; +export declare type VgNonUnionDomain = any[] | VgDataRef | VgSignalRef; +export declare type VgDomain = VgNonUnionDomain | DataRefUnionDomain | VgFieldRefUnionDomain; +export declare type VgMarkGroup = any; +export declare type VgProjectionType = 'albers' | 'albersUsa' | 'azimuthalEqualArea' | 'azimuthalEquidistant' | 'conicConformal' | 'conicEqualArea' | 'conicEquidistant' | 'equirectangular' | 'gnomonic' | 'mercator' | 'orthographic' | 'stereographic' | 'transverseMercator'; +export declare type VgProjection = { + name: string; + type?: VgProjectionType; + clipAngle?: number; + clipExtent?: number[][]; + scale?: number; + translate?: number[]; + center?: number[]; + /** + * The rotation of the projection. + */ + rotate?: number[]; + precision?: String; + fit?: VgSignalRef | Object | any[]; + extent?: VgSignalRef | number[][]; + size?: VgSignalRef | (number | VgSignalRef)[]; + coefficient?: number; + distance?: number; + fraction?: number; + lobes?: number; + parallel?: number; + radius?: number; + ratio?: number; + spacing?: number; + tilt?: number; +}; +export interface VgScale { + name: string; + type: ScaleType; + domain: VgDomain; + domainRaw?: VgSignalRef; + range: VgRange; + clamp?: boolean; + base?: number; + exponent?: number; + interpolate?: ScaleInterpolate | ScaleInterpolateParams; + nice?: boolean | number | NiceTime | { + interval: string; + step: number; + }; + padding?: number; + paddingInner?: number; + paddingOuter?: number; + reverse?: boolean; + round?: boolean; + zero?: boolean; +} +export declare type ScaleInterpolate = 'rgb' | 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long'; +export interface ScaleInterpolateParams { + type: 'rgb' | 'cubehelix' | 'cubehelix-long'; + gamma?: number; +} +export declare type VgLayoutAlign = 'none' | 'each' | 'all'; +export declare type RowCol = { + row?: T; + column?: T; +}; +export interface VgLayout { + center?: boolean | RowCol; + padding?: number | RowCol; + headerBand?: number | RowCol; + footerBand?: number | RowCol; + offset?: number | { + rowHeader?: number; + rowFooter?: number; + rowTitle?: number; + columnHeader?: number; + columnFooter?: number; + columnTitle?: number; + }; + bounds?: 'full' | 'flush'; + columns?: number | { + signal: string; + }; + align?: VgLayoutAlign | RowCol; +} +export declare function isDataRefUnionedDomain(domain: VgDomain): domain is DataRefUnionDomain; +export declare function isFieldRefUnionDomain(domain: VgDomain): domain is VgFieldRefUnionDomain; +export declare function isDataRefDomain(domain: VgDomain): domain is VgDataRef; +export declare function isSignalRefDomain(domain: VgDomain): domain is VgSignalRef; +export interface VgEventHandler { + events: string[] | VgSignalRef; + update?: string; + encode?: string; + force?: boolean; + between?: any[]; +} +export interface VgSignal { + name: string; + bind?: string; + description?: string; + on?: VgEventHandler[]; + update?: string; + react?: boolean; + value?: string | number | boolean | {} | VgSignalRef; + push?: string; +} +export declare type VgEncodeChannel = 'x' | 'x2' | 'xc' | 'width' | 'y' | 'y2' | 'yc' | 'height' | 'opacity' | 'fill' | 'fillOpacity' | 'stroke' | 'strokeWidth' | 'strokeCap' | 'strokeOpacity' | 'strokeDash' | 'strokeDashOffset' | 'strokeMiterLimit' | 'strokeJoin' | 'cursor' | 'clip' | 'size' | 'shape' | 'path' | 'innerRadius' | 'outerRadius' | 'startAngle' | 'endAngle' | 'interpolate' | 'tension' | 'orient' | 'url' | 'align' | 'baseline' | 'text' | 'dir' | 'ellipsis' | 'limit' | 'dx' | 'dy' | 'radius' | 'theta' | 'angle' | 'font' | 'fontSize' | 'fontWeight' | 'fontStyle' | 'tooltip' | 'href' | 'cursor' | 'defined' | 'cornerRadius'; +export declare type VgEncodeEntry = { + [k in VgEncodeChannel]?: VgValueRef | (VgValueRef & { + test?: string; + })[]; +}; +export declare type AxisOrient = 'top' | 'right' | 'left' | 'bottom'; +export interface VgAxis { + scale: string; + domain?: boolean; + format?: string; + grid?: boolean; + gridScale?: string; + labels?: boolean; + labelBound?: boolean | number; + labelFlush?: boolean | number; + labelPadding?: number; + labelOverlap?: boolean | 'parity' | 'greedy'; + maxExtent?: number; + minExtent?: number; + offset?: number; + orient?: AxisOrient; + position?: number; + ticks?: boolean; + tickCount?: number; + tickSize?: number; + title?: string; + titlePadding?: number; + values?: any[] | VgSignalRef; + zindex?: number; + encode?: VgAxisEncode; +} +export declare type LegendType = 'symbol' | 'gradient'; +export interface VgLegend { + fill?: string; + stroke?: string; + size?: string; + shape?: string; + opacity?: string; + entryPadding?: number; + format?: string; + offset?: number; + orient?: LegendOrient; + padding?: number; + tickCount?: number; + title?: string; + type?: LegendType; + values?: any[] | VgSignalRef; + zindex?: number; + encode?: VgLegendEncode; +} +export interface VgBinTransform extends BaseBin { + type: 'bin'; + extent?: number[] | { + signal: string; + }; + field: string; + as: string[]; + signal?: string; +} +export interface VgExtentTransform { + type: 'extent'; + field: string; + signal: string; +} +export interface VgFormulaTransform { + type: 'formula'; + as: string; + expr: string; +} +export interface VgFilterTransform { + type: 'filter'; + expr: string; +} +export interface VgAggregateTransform { + type: 'aggregate'; + groupby?: VgFieldRef[]; + fields?: VgFieldRef[]; + ops?: AggregateOp[]; + as?: string[]; + cross?: boolean; + drop?: boolean; +} +export interface VgCollectTransform { + type: 'collect'; + sort: VgSort; +} +export interface VgLookupTransform { + type: 'lookup'; + from: string; + key: string; + fields: string[]; + values?: string[]; + as?: string[]; + default?: string; +} +export interface VgStackTransform { + type: 'stack'; + offset?: StackOffset; + groupby: string[]; + field: string; + sort: VgSort; + as: string[]; +} +export interface VgIdentifierTransform { + type: 'identifier'; + as: string; +} +export declare type VgTransform = VgBinTransform | VgExtentTransform | VgFormulaTransform | VgAggregateTransform | VgFilterTransform | VgImputeTransform | VgStackTransform | VgCollectTransform | VgLookupTransform | VgIdentifierTransform | VgGeoPointTransform | VgGeoJSONTransform | VgGeoJSONTransform | VgWindowTransform; +export interface VgGeoPointTransform { + type: 'geopoint'; + projection: string; + fields: VgFieldRef[]; + as?: string[]; +} +export interface VgGeoShapeTransform { + type: 'geoshape'; + projection: string; + field?: VgFieldRef; + as?: string; +} +export interface VgGeoJSONTransform { + type: 'geojson'; + fields?: VgFieldRef[]; + geojson?: VgFieldRef; + signal: string; +} +export declare type VgPostEncodingTransform = VgGeoShapeTransform; +export interface VgAxisEncode { + ticks?: VgGuideEncode; + labels?: VgGuideEncode; + title?: VgGuideEncode; + grid?: VgGuideEncode; + domain?: VgGuideEncode; +} +export interface VgLegendEncode { + title?: VgGuideEncode; + labels?: VgGuideEncode; + legend?: VgGuideEncode; + symbols?: VgGuideEncode; + gradient?: VgGuideEncode; +} +export declare type VgGuideEncode = any; +export declare type VgSort = { + field: string; + order?: VgComparatorOrder; +} | { + field: string[]; + order?: (VgComparatorOrder)[]; +}; +export interface VgImputeTransform { + type: 'impute'; + groupby?: string[]; + field: string; + key: string; + keyvals?: string[]; + method?: 'value' | 'median' | 'max' | 'min' | 'mean'; + value?: any; +} +export declare type VgCheckboxBinding = { + input: 'checkbox'; + element?: string; +}; +export declare type VgRadioBinding = { + input: 'radio'; + options: string[]; + element?: string; +}; +export declare type VgSelectBinding = { + input: 'select'; + options: string[]; + element?: string; +}; +export declare type VgRangeBinding = { + input: 'range'; + min?: number; + max?: number; + step?: number; + element?: string; +}; +export declare type VgGenericBinding = { + input: string; + element?: string; +}; +export declare type VgBinding = VgCheckboxBinding | VgRadioBinding | VgSelectBinding | VgRangeBinding | VgGenericBinding; +/** + * Base object for Vega's Axis and Axis Config. + * All of these properties are both properties of Vega's Axis and Axis Config. + */ +export interface VgAxisBase { + /** + * A boolean flag indicating if the domain (the axis baseline) should be included as part of the axis. + * + * __Default value:__ `true` + */ + domain?: boolean; + /** + * A boolean flag indicating if grid lines should be included as part of the axis + * + * __Default value:__ `true` for [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous) that are not binned; otherwise, `false`. + */ + grid?: boolean; + /** + * A boolean flag indicating if labels should be included as part of the axis. + * + * __Default value:__ `true`. + */ + labels?: boolean; + /** + * Indicates if labels should be hidden if they exceed the axis range. If `false `(the default) no bounds overlap analysis is performed. If `true`, labels will be hidden if they exceed the axis range by more than 1 pixel. If this property is a number, it specifies the pixel tolerance: the maximum amount by which a label bounding box may exceed the axis range. + * + * __Default value:__ `false`. + */ + labelBound?: boolean | number; + /** + * Indicates if the first and last axis labels should be aligned flush with the scale range. Flush alignment for a horizontal axis will left-align the first label and right-align the last label. For vertical axes, bottom and top text baselines are applied instead. If this property is a number, it also indicates the number of pixels by which to offset the first and last labels; for example, a value of 2 will flush-align the first and last labels and also push them 2 pixels outward from the center of the axis. The additional adjustment can sometimes help the labels better visually group with corresponding axis ticks. + * + * __Default value:__ `true` for axis of a continuous x-scale. Otherwise, `false`. + */ + labelFlush?: boolean | number; + /** + * The strategy to use for resolving overlap of axis labels. If `false` (the default), no overlap reduction is attempted. If set to `true` or `"parity"`, a strategy of removing every other label is used (this works well for standard linear axes). If set to `"greedy"`, a linear scan of the labels is performed, removing any labels that overlaps with the last visible label (this often works better for log-scaled axes). + * + * __Default value:__ `true` for non-nominal fields with non-log scales; `"greedy"` for log scales; otherwise `false`. + */ + labelOverlap?: boolean | 'parity' | 'greedy'; + /** + * The padding, in pixels, between axis and text labels. + */ + labelPadding?: number; + /** + * Boolean value that determines whether the axis should include ticks. + */ + ticks?: boolean; + /** + * The size in pixels of axis ticks. + * + * @minimum 0 + */ + tickSize?: number; + /** + * Max length for axis title if the title is automatically generated from the field's description. + * + * @minimum 0 + * __Default value:__ `undefined`. + */ + titleMaxLength?: number; + /** + * The padding, in pixels, between title and axis. + */ + titlePadding?: number; + /** + * The minimum extent in pixels that axis ticks and labels should use. This determines a minimum offset value for axis titles. + * + * __Default value:__ `30` for y-axis; `undefined` for x-axis. + */ + minExtent?: number; + /** + * The maximum extent in pixels that axis ticks and labels should use. This determines a maximum offset value for axis titles. + * + * __Default value:__ `undefined`. + */ + maxExtent?: number; +} +export interface VgAxisConfig extends VgAxisBase { + /** + * An interpolation fraction indicating where, for `band` scales, axis ticks should be positioned. A value of `0` places ticks at the left edge of their bands. A value of `0.5` places ticks in the middle of their bands. + */ + bandPosition?: number; + /** + * Stroke width of axis domain line + * + * __Default value:__ (none, using Vega default). + */ + domainWidth?: number; + /** + * Color of axis domain line. + * + * __Default value:__ (none, using Vega default). + */ + domainColor?: string; + /** + * Color of gridlines. + */ + gridColor?: string; + /** + * The offset (in pixels) into which to begin drawing with the grid dash array. + */ + gridDash?: number[]; + /** + * The stroke opacity of grid (value between [0,1]) + * + * __Default value:__ (`1` by default) + * @minimum 0 + * @maximum 1 + */ + gridOpacity?: number; + /** + * The grid width, in pixels. + * @minimum 0 + */ + gridWidth?: number; + /** + * The color of the axis's tick. + */ + tickColor?: string; + /** + * The rotation angle of the axis labels. + * + * __Default value:__ `-90` for nominal and ordinal fields; `0` otherwise. + * + * @minimum -360 + * @maximum 360 + */ + labelAngle?: number; + /** + * The color of the tick label, can be in hex color code or regular color name. + */ + labelColor?: string; + /** + * The font of the tick label. + */ + labelFont?: string; + /** + * The font size of the label, in pixels. + * + * @minimum 0 + */ + labelFontSize?: number; + /** + * Maximum allowed pixel width of axis tick labels. + */ + labelLimit?: number; + /** + * Boolean flag indicating if pixel position values should be rounded to the nearest integer. + */ + tickRound?: boolean; + /** + * The width, in pixels, of ticks. + * + * @minimum 0 + */ + tickWidth?: number; + /** + * Horizontal text alignment of axis titles. + */ + titleAlign?: string; + /** + * Angle in degrees of axis titles. + */ + titleAngle?: number; + /** + * Vertical text baseline for axis titles. + */ + titleBaseline?: string; + /** + * Color of the title, can be in hex color code or regular color name. + */ + titleColor?: string; + /** + * Font of the title. (e.g., `"Helvetica Neue"`). + */ + titleFont?: string; + /** + * Font size of the title. + * + * @minimum 0 + */ + titleFontSize?: number; + /** + * Font weight of the title. + * This can be either a string (e.g `"bold"`, `"normal"`) or a number (`100`, `200`, `300`, ..., `900` where `"normal"` = `400` and `"bold"` = `700`). + */ + titleFontWeight?: FontWeight; + /** + * Maximum allowed pixel width of axis titles. + */ + titleLimit?: number; + /** + * X-coordinate of the axis title relative to the axis group. + */ + titleX?: number; + /** + * Y-coordinate of the axis title relative to the axis group. + */ + titleY?: number; +} +export declare type LegendOrient = 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'none'; +export interface VgLegendBase { + /** + * Padding (in pixels) between legend entries in a symbol legend. + */ + entryPadding?: number; + /** + * The orientation of the legend, which determines how the legend is positioned within the scene. One of "left", "right", "top-left", "top-right", "bottom-left", "bottom-right", "none". + * + * __Default value:__ `"right"` + */ + orient?: LegendOrient; + /** + * The offset, in pixels, by which to displace the legend from the edge of the enclosing group or data rectangle. + * + * __Default value:__ `0` + */ + offset?: number; + /** + * The padding, in pixels, between the legend and axis. + */ + padding?: number; +} +export interface VgLegendConfig extends VgLegendBase { + /** + * Corner radius for the full legend. + */ + cornerRadius?: number; + /** + * Background fill color for the full legend. + */ + fillColor?: string; + /** + * Border stroke color for the full legend. + */ + strokeColor?: string; + /** + * Border stroke dash pattern for the full legend. + */ + strokeDash?: number[]; + /** + * Border stroke width for the full legend. + */ + strokeWidth?: number; + /** + * The color of the gradient stroke, can be in hex color code or regular color name. + */ + gradientStrokeColor?: string; + /** + * The width of the gradient stroke, in pixels. + * @minimum 0 + */ + gradientStrokeWidth?: number; + /** + * The height of the gradient, in pixels. + * @minimum 0 + */ + gradientHeight?: number; + /** + * Text baseline for color ramp gradient labels. + */ + gradientLabelBaseline?: string; + /** + * The maximum allowed length in pixels of color ramp gradient labels. + */ + gradientLabelLimit?: number; + /** + * Vertical offset in pixels for color ramp gradient labels. + */ + gradientLabelOffset?: number; + /** + * The width of the gradient, in pixels. + * @minimum 0 + */ + gradientWidth?: number; + /** + * The alignment of the legend label, can be left, middle or right. + */ + labelAlign?: string; + /** + * The position of the baseline of legend label, can be top, middle or bottom. + */ + labelBaseline?: string; + /** + * The color of the legend label, can be in hex color code or regular color name. + */ + labelColor?: string; + /** + * The font of the legend label. + */ + labelFont?: string; + /** + * The font size of legend label. + * + * __Default value:__ `10`. + * + * @minimum 0 + */ + labelFontSize?: number; + /** + * Maximum allowed pixel width of axis tick labels. + */ + labelLimit?: number; + /** + * The offset of the legend label. + * @minimum 0 + */ + labelOffset?: number; + /** + * The color of the legend symbol, + */ + symbolColor?: string; + /** + * Default shape type (such as "circle") for legend symbols. + */ + symbolType?: string; + /** + * The size of the legend symbol, in pixels. + * @minimum 0 + */ + symbolSize?: number; + /** + * The width of the symbol's stroke. + * @minimum 0 + */ + symbolStrokeWidth?: number; + /** + * Horizontal text alignment for legend titles. + */ + titleAlign?: string; + /** + * Vertical text baseline for legend titles. + */ + titleBaseline?: string; + /** + * The color of the legend title, can be in hex color code or regular color name. + */ + titleColor?: string; + /** + * The font of the legend title. + */ + titleFont?: string; + /** + * The font size of the legend title. + */ + titleFontSize?: number; + /** + * The font weight of the legend title. + * This can be either a string (e.g `"bold"`, `"normal"`) or a number (`100`, `200`, `300`, ..., `900` where `"normal"` = `400` and `"bold"` = `700`). + */ + titleFontWeight?: FontWeight; + /** + * Maximum allowed pixel width of axis titles. + */ + titleLimit?: number; + /** + * The padding, in pixels, between title and legend. + */ + titlePadding?: number; +} +export declare type FontStyle = 'normal' | 'italic'; +export declare type FontWeightString = 'normal' | 'bold'; +/** + * @TJS-type integer + * @minimum 100 + * @maximum 900 + */ +export declare type FontWeightNumber = number; +export declare type FontWeight = FontWeightString | FontWeightNumber; +export declare type HorizontalAlign = 'left' | 'right' | 'center'; +export declare type Interpolate = 'linear' | 'linear-closed' | 'step' | 'step-before' | 'step-after' | 'basis' | 'basis-open' | 'basis-closed' | 'cardinal' | 'cardinal-open' | 'cardinal-closed' | 'bundle' | 'monotone'; +export declare type Orient = 'horizontal' | 'vertical'; +export declare type VerticalAlign = 'top' | 'middle' | 'bottom'; +export declare type Cursor = 'auto' | 'default' | 'none' | 'context-menu' | 'help' | 'pointer' | 'progress' | 'wait' | 'cell' | 'crosshair' | 'text' | 'vertical-text' | 'alias' | 'copy' | 'move' | 'no-drop' | 'not-allowed' | 'e-resize' | 'n-resize' | 'ne-resize' | 'nw-resize' | 's-resize' | 'se-resize' | 'sw-resize' | 'w-resize' | 'ew-resize' | 'ns-resize' | 'nesw-resize' | 'nwse-resize' | 'col-resize' | 'row-resize' | 'all-scroll' | 'zoom-in' | 'zoom-out' | 'grab' | 'grabbing'; +export declare type StrokeCap = 'butt' | 'round' | 'square'; +export declare type StrokeJoin = 'miter' | 'round' | 'bevel'; +export declare type Dir = 'ltr' | 'rtl'; +export interface VgMarkConfig { + /** + * Default Fill Color. This has higher precedence than `config.color` + * + * __Default value:__ (None) + * + */ + fill?: string; + /** + * Default Stroke Color. This has higher precedence than `config.color` + * + * __Default value:__ (None) + * + */ + stroke?: string; + /** + * The overall opacity (value between [0,1]). + * + * __Default value:__ `0.7` for non-aggregate plots with `point`, `tick`, `circle`, or `square` marks or layered `bar` charts and `1` otherwise. + * + * @minimum 0 + * @maximum 1 + */ + opacity?: number; + /** + * The fill opacity (value between [0,1]). + * + * __Default value:__ `1` + * + * @minimum 0 + * @maximum 1 + */ + fillOpacity?: number; + /** + * The stroke opacity (value between [0,1]). + * + * __Default value:__ `1` + * + * @minimum 0 + * @maximum 1 + */ + strokeOpacity?: number; + /** + * The stroke width, in pixels. + * + * @minimum 0 + */ + strokeWidth?: number; + /** + * The stroke cap for line ending style. One of `"butt"`, `"round"`, or `"square"`. + * + * __Default value:__ `"square"` + */ + strokeCap?: StrokeCap; + /** + * An array of alternating stroke, space lengths for creating dashed or dotted lines. + */ + strokeDash?: number[]; + /** + * The offset (in pixels) into which to begin drawing with the stroke dash array. + */ + strokeDashOffset?: number; + /** + * The stroke line join method. One of `"miter"`, `"round"` or `"bevel"`. + * + * __Default value:__ `"miter"` + */ + strokeJoin?: StrokeJoin; + /** + * The miter limit at which to bevel a line join. + */ + strokeMiterLimit?: number; + /** + * The orientation of a non-stacked bar, tick, area, and line charts. + * The value is either horizontal (default) or vertical. + * - For bar, rule and tick, this determines whether the size of the bar and tick + * should be applied to x or y dimension. + * - For area, this property determines the orient property of the Vega output. + * - For line and trail marks, this property determines the sort order of the points in the line + * if `config.sortLineBy` is not specified. + * For stacked charts, this is always determined by the orientation of the stack; + * therefore explicitly specified value will be ignored. + */ + orient?: Orient; + /** + * The line interpolation method to use for line and area marks. One of the following: + * - `"linear"`: piecewise linear segments, as in a polyline. + * - `"linear-closed"`: close the linear segments to form a polygon. + * - `"step"`: alternate between horizontal and vertical segments, as in a step function. + * - `"step-before"`: alternate between vertical and horizontal segments, as in a step function. + * - `"step-after"`: alternate between horizontal and vertical segments, as in a step function. + * - `"basis"`: a B-spline, with control point duplication on the ends. + * - `"basis-open"`: an open B-spline; may not intersect the start or end. + * - `"basis-closed"`: a closed B-spline, as in a loop. + * - `"cardinal"`: a Cardinal spline, with control point duplication on the ends. + * - `"cardinal-open"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points. + * - `"cardinal-closed"`: a closed Cardinal spline, as in a loop. + * - `"bundle"`: equivalent to basis, except the tension parameter is used to straighten the spline. + * - `"monotone"`: cubic interpolation that preserves monotonicity in y. + */ + interpolate?: Interpolate; + /** + * Depending on the interpolation type, sets the tension parameter (for line and area marks). + * @minimum 0 + * @maximum 1 + */ + tension?: number; + /** + * The default symbol shape to use. One of: `"circle"` (default), `"square"`, `"cross"`, `"diamond"`, `"triangle-up"`, or `"triangle-down"`, or a custom SVG path. + * + * __Default value:__ `"circle"` + * + */ + shape?: string; + /** + * The pixel area each the point/circle/square. + * For example: in the case of circles, the radius is determined in part by the square root of the size value. + * + * __Default value:__ `30` + * + * @minimum 0 + */ + size?: number; + /** + * The horizontal alignment of the text. One of `"left"`, `"right"`, `"center"`. + */ + align?: HorizontalAlign; + /** + * The rotation angle of the text, in degrees. + * @minimum 0 + * @maximum 360 + */ + angle?: number; + /** + * The vertical alignment of the text. One of `"top"`, `"middle"`, `"bottom"`. + * + * __Default value:__ `"middle"` + * + */ + baseline?: VerticalAlign; + /** + * The direction of the text. One of `"ltr"` (left-to-right) or `"rtl"` (right-to-left). This property determines on which side is truncated in response to the limit parameter. + * + * __Default value:__ `"ltr"` + */ + dir?: Dir; + /** + * The horizontal offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property. + */ + dx?: number; + /** + * The vertical offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property. + */ + dy?: number; + /** + * Polar coordinate radial offset, in pixels, of the text label from the origin determined by the `x` and `y` properties. + * @minimum 0 + */ + radius?: number; + /** + * The maximum length of the text mark in pixels. The text value will be automatically truncated if the rendered size exceeds the limit. + * + * __Default value:__ `0`, indicating no limit + */ + limit?: number; + /** + * The ellipsis string for text truncated in response to the limit parameter. + * + * __Default value:__ `"…"` + */ + ellipsis?: string; + /** + * Polar coordinate angle, in radians, of the text label from the origin determined by the `x` and `y` properties. Values for `theta` follow the same convention of `arc` mark `startAngle` and `endAngle` properties: angles are measured in radians, with `0` indicating "north". + */ + theta?: number; + /** + * The typeface to set the text in (e.g., `"Helvetica Neue"`). + */ + font?: string; + /** + * The font size, in pixels. + * @minimum 0 + */ + fontSize?: number; + /** + * The font style (e.g., `"italic"`). + */ + fontStyle?: FontStyle; + /** + * The font weight. + * This can be either a string (e.g `"bold"`, `"normal"`) or a number (`100`, `200`, `300`, ..., `900` where `"normal"` = `400` and `"bold"` = `700`). + */ + fontWeight?: FontWeight; + /** + * Placeholder text if the `text` channel is not specified + */ + text?: string; + /** + * A URL to load upon mouse click. If defined, the mark acts as a hyperlink. + * + * @format uri + */ + href?: string; + /** + * The mouse cursor used over the mark. Any valid [CSS cursor type](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Values) can be used. + */ + cursor?: Cursor; + /** + * The tooltip text to show upon mouse hover. + */ + tooltip?: any; + /** + * The radius in pixels of rounded rectangle corners. + * + * __Default value:__ `0` + */ + cornerRadius?: number; +} +export declare const VG_MARK_CONFIGS: ("dir" | "font" | "text" | "shape" | "orient" | "fill" | "stroke" | "opacity" | "size" | "tooltip" | "href" | "interpolate" | "angle" | "baseline" | "fontSize" | "fontWeight" | "limit" | "strokeWidth" | "strokeDash" | "strokeDashOffset" | "strokeOpacity" | "strokeJoin" | "strokeMiterLimit" | "fillOpacity" | "strokeCap" | "tension" | "align" | "dx" | "dy" | "radius" | "ellipsis" | "theta" | "fontStyle" | "cursor" | "cornerRadius")[]; +export declare type Anchor = 'start' | 'middle' | 'end'; +export interface VgTitle { + /** + * The title text. + */ + text: string; + /** + * The orientation of the title relative to the chart. One of `"top"` (the default), `"bottom"`, `"left"`, or `"right"`. + */ + orient?: TitleOrient; + /** + * The anchor position for placing the title. One of `"start"`, `"middle"` (the default), or `"end"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title. + */ + anchor?: Anchor; + /** + * The orthogonal offset in pixels by which to displace the title from its position along the edge of the chart. + */ + offset?: number; + style?: string | string[]; +} +export declare type TitleOrient = 'top' | 'bottom' | 'left' | 'right'; +export interface VgTitleConfig { + /** + * The anchor position for placing the title. One of `"start"`, `"middle"`, or `"end"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title. + * + * __Default value:__ `"middle"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. + * `"start"` for other composite views. + * + * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `"start"`. + */ + anchor?: Anchor; + /** + * Angle in degrees of title text. + */ + angle?: number; + /** + * Vertical text baseline for title text. + */ + baseline?: VerticalAlign; + /** + * Text color for title text. + */ + color?: string; + /** + * Font name for title text. + */ + font?: string; + /** + * Font size in pixels for title text. + * + * __Default value:__ `10`. + * + * @minimum 0 + */ + fontSize?: number; + /** + * Font weight for title text. + * This can be either a string (e.g `"bold"`, `"normal"`) or a number (`100`, `200`, `300`, ..., `900` where `"normal"` = `400` and `"bold"` = `700`). + */ + fontWeight?: FontWeight; + /** + * The maximum allowed length in pixels of legend labels. + * + * @minimum 0 + */ + limit?: number; + /** + * Offset in pixels of the title from the chart body and axes. + */ + offset?: number; + /** + * Default title orientation ("top", "bottom", "left", or "right") + */ + orient?: TitleOrient; +} +export declare type VgComparatorOrder = 'ascending' | 'descending'; +export interface VgComparator { + field?: string | string[]; + order?: VgComparatorOrder | VgComparatorOrder[]; +} +export interface VgWindowTransform { + type: 'window'; + params?: Number[]; + as?: string[]; + ops?: (AggregateOp | WindowOnlyOp)[]; + fields?: string[]; + frame?: Number[]; + ignorePeers?: Boolean; + groupby?: string[]; + sort?: VgComparator; +} diff --git a/build/src/vega.schema.js b/build/src/vega.schema.js new file mode 100644 index 0000000000..5457c0b94f --- /dev/null +++ b/build/src/vega.schema.js @@ -0,0 +1,71 @@ +import { isArray } from 'vega-util'; +import { flagKeys } from './util'; +export function isVgSignalRef(o) { + return !!o['signal']; +} +export function isVgRangeStep(range) { + return !!range['step']; +} +export function isDataRefUnionedDomain(domain) { + if (!isArray(domain)) { + return 'fields' in domain && !('data' in domain); + } + return false; +} +export function isFieldRefUnionDomain(domain) { + if (!isArray(domain)) { + return 'fields' in domain && 'data' in domain; + } + return false; +} +export function isDataRefDomain(domain) { + if (!isArray(domain)) { + return 'field' in domain && 'data' in domain; + } + return false; +} +export function isSignalRefDomain(domain) { + if (!isArray(domain)) { + return 'signal' in domain; + } + return false; +} +var VG_MARK_CONFIG_INDEX = { + opacity: 1, + fill: 1, + fillOpacity: 1, + stroke: 1, + strokeCap: 1, + strokeWidth: 1, + strokeOpacity: 1, + strokeDash: 1, + strokeDashOffset: 1, + strokeJoin: 1, + strokeMiterLimit: 1, + size: 1, + shape: 1, + interpolate: 1, + tension: 1, + orient: 1, + align: 1, + baseline: 1, + text: 1, + dir: 1, + dx: 1, + dy: 1, + ellipsis: 1, + limit: 1, + radius: 1, + theta: 1, + angle: 1, + font: 1, + fontSize: 1, + fontWeight: 1, + fontStyle: 1, + cursor: 1, + href: 1, + tooltip: 1, + cornerRadius: 1, +}; +export var VG_MARK_CONFIGS = flagKeys(VG_MARK_CONFIG_INDEX); +//# sourceMappingURL=vega.schema.js.map \ No newline at end of file diff --git a/build/src/vega.schema.js.map b/build/src/vega.schema.js.map new file mode 100644 index 0000000000..ae12c90a74 --- /dev/null +++ b/build/src/vega.schema.js.map @@ -0,0 +1 @@ +{"version":3,"file":"vega.schema.js","sourceRoot":"","sources":["../../src/vega.schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAMlC,OAAO,EAAO,QAAQ,EAAC,MAAM,QAAQ,CAAC;AAgDtC,MAAM,wBAAwB,CAAM;IAClC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACvB,CAAC;AAmCD,MAAM,wBAAwB,KAAc;IAC1C,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC;AA6HD,MAAM,iCAAiC,MAAgB;IACrD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACpB,OAAO,QAAQ,IAAI,MAAM,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC;KAClD;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,gCAAgC,MAAgB;IACpD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACpB,OAAO,QAAQ,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,CAAC;KAC/C;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,0BAA0B,MAAgB;IAC9C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACnB,OAAO,OAAO,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,CAAC;KAC/C;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,4BAA4B,MAAgB;IAChD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACpB,OAAO,QAAQ,IAAI,MAAM,CAAC;KAC3B;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AA+9BD,IAAM,oBAAoB,GAA6B;IACrD,OAAO,EAAE,CAAC;IACV,IAAI,EAAE,CAAC;IACP,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,CAAC;IACZ,WAAW,EAAE,CAAC;IACd,aAAa,EAAE,CAAC;IAChB,UAAU,EAAE,CAAC;IACb,gBAAgB,EAAE,CAAC;IACnB,UAAU,EAAE,CAAC;IACb,gBAAgB,EAAE,CAAC;IACnB,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,WAAW,EAAE,CAAC;IACd,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,CAAC;IACN,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,QAAQ,EAAE,CAAC;IACX,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,CAAC;IACZ,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,OAAO,EAAE,CAAC;IACV,YAAY,EAAE,CAAC;CAUhB,CAAC;AAEF,MAAM,CAAC,IAAM,eAAe,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAC","sourcesContent":["import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {BaseBin} from './bin';\nimport {NiceTime, ScaleType} from './scale';\nimport {SortOrder} from './sort';\nimport {StackOffset} from './stack';\nimport {WindowOnlyOp} from './transform';\nimport {Flag, flagKeys} from './util';\n\nexport interface VgData {\n name: string;\n source?: string;\n values?: any;\n format?: {\n type?: string;\n parse?: string | object;\n property?: string;\n feature?: string;\n mesh?: string;\n };\n url?: string;\n transform?: VgTransform[];\n}\n\n\nexport interface VgParentRef {\n parent: string;\n}\n\nexport type VgFieldRef = string | VgParentRef | VgParentRef[];\n\nexport type VgSortField = true | {\n field?: VgFieldRef,\n op: AggregateOp,\n order?: SortOrder\n};\n\n/**\n * Unioned domains can only be sorted by count aggregate.\n */\nexport type VgUnionSortField = true | {\n op: 'count'\n order?: SortOrder\n};\n\nexport interface VgDataRef {\n data: string;\n field: VgFieldRef;\n sort?: VgSortField;\n}\n\nexport interface VgSignalRef {\n signal: string;\n}\n\nexport function isVgSignalRef(o: any): o is VgSignalRef {\n return !!o['signal'];\n}\n\nexport type VgEventStream = any;\n\n// TODO: add type of value (Make it VgValueRef {value?:T ...})\nexport interface VgValueRef {\n value?: number | string | boolean;\n field?: string | {\n datum?: string,\n group?: string,\n parent?: string\n };\n signal?: string;\n scale?: string; // TODO: object\n mult?: number;\n offset?: number | VgValueRef;\n band?: boolean | number | VgValueRef;\n}\n\n// TODO: add vg prefix\nexport interface DataRefUnionDomain {\n fields: (any[] | VgDataRef | VgSignalRef)[];\n sort?: VgUnionSortField;\n}\n\nexport interface VgFieldRefUnionDomain {\n data: string;\n fields: VgFieldRef[];\n sort?: VgUnionSortField;\n}\n\nexport type VgScheme = {scheme: string, extent?: number[], count?: number};\nexport type VgRange = string | VgDataRef | (number|string|VgDataRef|VgSignalRef)[] | VgScheme | VgRangeStep;\n\nexport type VgRangeStep = {step: number | VgSignalRef};\nexport function isVgRangeStep(range: VgRange): range is VgRangeStep {\n return !!range['step'];\n}\n\n// Domains that are not a union of domains\nexport type VgNonUnionDomain = any[] | VgDataRef | VgSignalRef;\nexport type VgDomain = VgNonUnionDomain | DataRefUnionDomain | VgFieldRefUnionDomain;\n\nexport type VgMarkGroup = any;\n\nexport type VgProjectionType = 'albers' | 'albersUsa' | 'azimuthalEqualArea' | 'azimuthalEquidistant' | 'conicConformal' | 'conicEqualArea' | 'conicEquidistant' | 'equirectangular' | 'gnomonic' | 'mercator' | 'orthographic' | 'stereographic' | 'transverseMercator';\n\n\nexport type VgProjection = {\n /*\n * The name of the projection.\n */\n name: string;\n /*\n * The type of the projection.\n */\n type?: VgProjectionType;\n /*\n * The clip angle of the projection.\n */\n clipAngle?: number;\n /*\n * Sets the projection’s viewport clip extent to the specified bounds in pixels\n */\n clipExtent?: number[][];\n /*\n * Sets the projection’s scale factor to the specified value\n */\n scale?: number;\n /*\n * The translation of the projection.\n */\n translate?: number[];\n /*\n * The center of the projection.\n */\n center?: number[];\n /**\n * The rotation of the projection.\n */\n rotate?: number[];\n /*\n * The desired precision of the projection.\n */\n precision?: String;\n /*\n * GeoJSON data to which the projection should attempt to automatically fit the translate and scale parameters..\n */\n fit?: VgSignalRef | Object | any[];\n /*\n * Used in conjunction with fit, provides the pixel area to which the projection should be automatically fit.\n */\n extent?: VgSignalRef | number[][];\n /*\n * Used in conjunction with fit, provides the width and height in pixels of the area to which the projection should be automatically fit.\n */\n size?: VgSignalRef | (number | VgSignalRef)[];\n\n /* The following properties are all supported for specific types of projections. Consult the d3-geo-projection library for more information: https://github.com/d3/d3-geo-projection */\n coefficient?: number;\n distance?: number;\n fraction?: number;\n lobes?: number;\n parallel?: number;\n radius?: number;\n ratio?: number;\n spacing?: number;\n tilt?: number;\n};\n\nexport interface VgScale {\n name: string;\n type: ScaleType;\n domain: VgDomain;\n domainRaw?: VgSignalRef;\n range: VgRange;\n\n clamp?: boolean;\n base?: number;\n exponent?: number;\n interpolate?: ScaleInterpolate | ScaleInterpolateParams;\n nice?: boolean | number | NiceTime | {interval: string, step: number};\n padding?: number;\n paddingInner?: number;\n paddingOuter?: number;\n reverse?: boolean;\n round?: boolean;\n zero?: boolean;\n}\n\nexport type ScaleInterpolate = 'rgb'| 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long';\n\nexport interface ScaleInterpolateParams {\n type: 'rgb' | 'cubehelix' | 'cubehelix-long';\n gamma?: number;\n}\n\nexport type VgLayoutAlign = 'none' | 'each' | 'all';\n\nexport type RowCol = {\n row?: T,\n column?: T\n};\n\nexport interface VgLayout {\n center?: boolean | RowCol;\n padding?: number | RowCol;\n headerBand?: number | RowCol;\n footerBand?: number | RowCol;\n offset?: number | {\n rowHeader?: number,\n rowFooter?: number,\n rowTitle?: number,\n columnHeader?: number,\n columnFooter?: number,\n columnTitle?: number\n };\n bounds?: 'full' | 'flush';\n columns?: number | {signal: string};\n align?: VgLayoutAlign | RowCol;\n}\n\nexport function isDataRefUnionedDomain(domain: VgDomain): domain is DataRefUnionDomain {\n if (!isArray(domain)) {\n return 'fields' in domain && !('data' in domain);\n }\n return false;\n}\n\nexport function isFieldRefUnionDomain(domain: VgDomain): domain is VgFieldRefUnionDomain {\n if (!isArray(domain)) {\n return 'fields' in domain && 'data' in domain;\n }\n return false;\n}\n\nexport function isDataRefDomain(domain: VgDomain): domain is VgDataRef {\n if (!isArray(domain)) {\n return 'field' in domain && 'data' in domain;\n }\n return false;\n}\n\nexport function isSignalRefDomain(domain: VgDomain): domain is VgSignalRef {\n if (!isArray(domain)) {\n return 'signal' in domain;\n }\n return false;\n}\n\nexport interface VgEventHandler {\n events: string[] | VgSignalRef;\n update?: string;\n encode?: string;\n force?: boolean;\n between?: any[];\n}\n\nexport interface VgSignal {\n name: string;\n bind?: string;\n description?: string;\n on?: VgEventHandler[];\n update?: string;\n react?: boolean;\n value?: string | number | boolean | {} | VgSignalRef;\n // only for nested signals\n push?: string;\n}\n\nexport type VgEncodeChannel = 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height'|'opacity'|'fill'|'fillOpacity'|'stroke'|'strokeWidth'|'strokeCap'|'strokeOpacity'|'strokeDash'|'strokeDashOffset'|'strokeMiterLimit'|'strokeJoin'|'cursor'|'clip'|'size'|'shape'|'path'|'innerRadius'|'outerRadius'|'startAngle'|'endAngle'|'interpolate'|'tension'|'orient'|'url'|'align'|'baseline'|'text'|'dir'|'ellipsis'|'limit'|'dx'|'dy'|'radius'|'theta'|'angle'|'font'|'fontSize'|'fontWeight'|'fontStyle'|'tooltip'|'href'|'cursor'|'defined'|'cornerRadius';\nexport type VgEncodeEntry = {\n [k in VgEncodeChannel]?: VgValueRef | (VgValueRef & {test?: string})[];\n};\n\n\n// TODO: make export interface VgEncodeEntry {\n// x?: VgValueRef\n// y?: VgValueRef\n// ...\n// color?: VgValueRef\n// ...\n// }\n\nexport type AxisOrient = 'top' | 'right' | 'left' | 'bottom';\n\nexport interface VgAxis {\n scale: string;\n domain?: boolean;\n format?: string;\n grid?: boolean;\n gridScale?: string;\n\n labels?: boolean;\n\n labelBound?: boolean | number;\n labelFlush?: boolean | number;\n labelPadding?: number;\n labelOverlap?: boolean | 'parity' | 'greedy';\n maxExtent?: number;\n minExtent?: number;\n offset?: number;\n orient?: AxisOrient;\n position?: number;\n\n ticks?: boolean;\n tickCount?: number;\n tickSize?: number;\n\n title?: string;\n titlePadding?: number;\n\n values?: any[] | VgSignalRef;\n zindex?: number;\n\n encode?: VgAxisEncode;\n}\n\nexport type LegendType = 'symbol' | 'gradient';\n\nexport interface VgLegend {\n fill?: string;\n stroke?: string;\n size?: string;\n shape?: string;\n opacity?: string;\n\n entryPadding?: number;\n format?: string;\n\n offset?: number;\n orient?: LegendOrient;\n padding?: number;\n\n tickCount?: number;\n title?: string;\n type?: LegendType;\n values?: any[] | VgSignalRef;\n zindex?: number;\n\n encode?: VgLegendEncode;\n}\n\nexport interface VgBinTransform extends BaseBin {\n type: 'bin';\n extent?: number[] | {signal: string};\n field: string;\n as: string[];\n signal?: string;\n}\n\nexport interface VgExtentTransform {\n type: 'extent';\n field: string;\n signal: string;\n}\n\nexport interface VgFormulaTransform {\n type: 'formula';\n as: string;\n expr: string;\n}\n\nexport interface VgFilterTransform {\n type: 'filter';\n expr: string;\n}\n\nexport interface VgAggregateTransform {\n type: 'aggregate';\n groupby?: VgFieldRef[];\n fields?: VgFieldRef[];\n ops?: AggregateOp[];\n as?: string[];\n cross?: boolean;\n drop?: boolean;\n}\n\nexport interface VgCollectTransform {\n type: 'collect';\n sort: VgSort;\n}\n\nexport interface VgLookupTransform {\n type: 'lookup';\n from: string;\n key: string;\n fields: string[];\n values?: string[];\n as?: string[];\n default?: string;\n}\n\nexport interface VgStackTransform {\n type: 'stack';\n offset?: StackOffset;\n groupby: string[];\n field: string;\n sort: VgSort;\n as: string[];\n}\n\nexport interface VgIdentifierTransform {\n type: 'identifier';\n as: string;\n}\n\nexport type VgTransform = VgBinTransform | VgExtentTransform | VgFormulaTransform | VgAggregateTransform | VgFilterTransform | VgImputeTransform | VgStackTransform | VgCollectTransform | VgLookupTransform | VgIdentifierTransform | VgGeoPointTransform | VgGeoJSONTransform | VgGeoJSONTransform | VgWindowTransform;\n\nexport interface VgGeoPointTransform {\n type: 'geopoint';\n projection: string; // projection name\n fields: VgFieldRef[];\n as?: string[];\n}\n\nexport interface VgGeoShapeTransform {\n type: 'geoshape';\n projection: string; // projection name\n field?: VgFieldRef;\n as?: string;\n}\n\nexport interface VgGeoJSONTransform {\n type: 'geojson';\n fields?: VgFieldRef[];\n geojson?: VgFieldRef;\n signal: string;\n}\n\nexport type VgPostEncodingTransform = VgGeoShapeTransform;\n\nexport interface VgAxisEncode {\n ticks?: VgGuideEncode;\n labels?: VgGuideEncode;\n title?: VgGuideEncode;\n grid?: VgGuideEncode;\n domain?: VgGuideEncode;\n}\n\nexport interface VgLegendEncode {\n title?: VgGuideEncode;\n labels?: VgGuideEncode;\n legend?: VgGuideEncode;\n symbols?: VgGuideEncode;\n gradient?: VgGuideEncode;\n}\n\nexport type VgGuideEncode = any; // TODO: replace this (See guideEncode in Vega Schema)\n\nexport type VgSort = {\n field: string;\n order?: VgComparatorOrder;\n} | {\n field: string[];\n order?: (VgComparatorOrder)[];\n};\n\nexport interface VgImputeTransform {\n type: 'impute';\n groupby?: string[];\n field: string;\n key: string;\n keyvals?: string[];\n method?: 'value' | 'median' | 'max' | 'min' | 'mean';\n value?: any;\n}\n\nexport type VgCheckboxBinding = {\n input: 'checkbox';\n element?: string;\n};\n\nexport type VgRadioBinding = {\n input: 'radio';\n options: string[];\n element?: string;\n};\n\nexport type VgSelectBinding = {\n input: 'select';\n options: string[];\n element?: string;\n};\n\nexport type VgRangeBinding = {\n input: 'range';\n min?: number;\n max?: number;\n step?: number;\n element?: string;\n};\n\nexport type VgGenericBinding = {\n input: string;\n element?: string;\n};\n\nexport type VgBinding = VgCheckboxBinding | VgRadioBinding |\n VgSelectBinding | VgRangeBinding | VgGenericBinding;\n\n\n/**\n * Base object for Vega's Axis and Axis Config.\n * All of these properties are both properties of Vega's Axis and Axis Config.\n */\nexport interface VgAxisBase {\n /**\n * A boolean flag indicating if the domain (the axis baseline) should be included as part of the axis.\n *\n * __Default value:__ `true`\n */\n domain?: boolean;\n\n /**\n * A boolean flag indicating if grid lines should be included as part of the axis\n *\n * __Default value:__ `true` for [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous) that are not binned; otherwise, `false`.\n */\n grid?: boolean;\n\n /**\n * A boolean flag indicating if labels should be included as part of the axis.\n *\n * __Default value:__ `true`.\n */\n labels?: boolean;\n\n /**\n * Indicates if labels should be hidden if they exceed the axis range. If `false `(the default) no bounds overlap analysis is performed. If `true`, labels will be hidden if they exceed the axis range by more than 1 pixel. If this property is a number, it specifies the pixel tolerance: the maximum amount by which a label bounding box may exceed the axis range.\n *\n * __Default value:__ `false`.\n */\n labelBound?: boolean | number;\n\n /**\n * Indicates if the first and last axis labels should be aligned flush with the scale range. Flush alignment for a horizontal axis will left-align the first label and right-align the last label. For vertical axes, bottom and top text baselines are applied instead. If this property is a number, it also indicates the number of pixels by which to offset the first and last labels; for example, a value of 2 will flush-align the first and last labels and also push them 2 pixels outward from the center of the axis. The additional adjustment can sometimes help the labels better visually group with corresponding axis ticks.\n *\n * __Default value:__ `true` for axis of a continuous x-scale. Otherwise, `false`.\n */\n labelFlush?: boolean | number;\n\n /**\n * The strategy to use for resolving overlap of axis labels. If `false` (the default), no overlap reduction is attempted. If set to `true` or `\"parity\"`, a strategy of removing every other label is used (this works well for standard linear axes). If set to `\"greedy\"`, a linear scan of the labels is performed, removing any labels that overlaps with the last visible label (this often works better for log-scaled axes).\n *\n * __Default value:__ `true` for non-nominal fields with non-log scales; `\"greedy\"` for log scales; otherwise `false`.\n */\n labelOverlap?: boolean | 'parity' | 'greedy';\n\n /**\n * The padding, in pixels, between axis and text labels.\n */\n labelPadding?: number;\n\n /**\n * Boolean value that determines whether the axis should include ticks.\n */\n ticks?: boolean;\n\n /**\n * The size in pixels of axis ticks.\n *\n * @minimum 0\n */\n tickSize?: number;\n\n /**\n * Max length for axis title if the title is automatically generated from the field's description.\n *\n * @minimum 0\n * __Default value:__ `undefined`.\n */\n titleMaxLength?: number;\n\n /**\n * The padding, in pixels, between title and axis.\n */\n titlePadding?: number;\n\n /**\n * The minimum extent in pixels that axis ticks and labels should use. This determines a minimum offset value for axis titles.\n *\n * __Default value:__ `30` for y-axis; `undefined` for x-axis.\n */\n minExtent?: number;\n\n /**\n * The maximum extent in pixels that axis ticks and labels should use. This determines a maximum offset value for axis titles.\n *\n * __Default value:__ `undefined`.\n */\n maxExtent?: number;\n}\n\nexport interface VgAxisConfig extends VgAxisBase {\n /**\n * An interpolation fraction indicating where, for `band` scales, axis ticks should be positioned. A value of `0` places ticks at the left edge of their bands. A value of `0.5` places ticks in the middle of their bands.\n */\n bandPosition?: number;\n /**\n * Stroke width of axis domain line\n *\n * __Default value:__ (none, using Vega default).\n */\n domainWidth?: number;\n\n /**\n * Color of axis domain line.\n *\n * __Default value:__ (none, using Vega default).\n */\n domainColor?: string;\n\n // ---------- Grid ----------\n /**\n * Color of gridlines.\n */\n gridColor?: string;\n\n /**\n * The offset (in pixels) into which to begin drawing with the grid dash array.\n */\n gridDash?: number[];\n\n /**\n * The stroke opacity of grid (value between [0,1])\n *\n * __Default value:__ (`1` by default)\n * @minimum 0\n * @maximum 1\n */\n gridOpacity?: number;\n\n /**\n * The grid width, in pixels.\n * @minimum 0\n */\n gridWidth?: number;\n\n // ---------- Ticks ----------\n /**\n * The color of the axis's tick.\n */\n tickColor?: string;\n\n\n /**\n * The rotation angle of the axis labels.\n *\n * __Default value:__ `-90` for nominal and ordinal fields; `0` otherwise.\n *\n * @minimum -360\n * @maximum 360\n */\n labelAngle?: number;\n\n /**\n * The color of the tick label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the tick label.\n */\n labelFont?: string;\n\n /**\n * The font size of the label, in pixels.\n *\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * Maximum allowed pixel width of axis tick labels.\n */\n labelLimit?: number;\n\n /**\n * Boolean flag indicating if pixel position values should be rounded to the nearest integer.\n */\n tickRound?: boolean;\n\n /**\n * The width, in pixels, of ticks.\n *\n * @minimum 0\n */\n tickWidth?: number;\n\n // ---------- Title ----------\n\n /**\n * Horizontal text alignment of axis titles.\n */\n titleAlign?: string;\n\n /**\n * Angle in degrees of axis titles.\n */\n titleAngle?: number;\n /**\n * Vertical text baseline for axis titles.\n */\n titleBaseline?: string;\n /**\n * Color of the title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * Font of the title. (e.g., `\"Helvetica Neue\"`).\n */\n titleFont?: string;\n\n /**\n * Font size of the title.\n *\n * @minimum 0\n */\n titleFontSize?: number;\n\n /**\n * Font weight of the title.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n titleFontWeight?: FontWeight;\n\n /**\n * Maximum allowed pixel width of axis titles.\n */\n titleLimit?: number;\n\n /**\n * X-coordinate of the axis title relative to the axis group.\n */\n titleX?: number;\n\n /**\n * Y-coordinate of the axis title relative to the axis group.\n */\n titleY?: number;\n}\n\nexport type LegendOrient = 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'none';\n\nexport interface VgLegendBase {\n /**\n * Padding (in pixels) between legend entries in a symbol legend.\n */\n entryPadding?: number;\n\n\n /**\n * The orientation of the legend, which determines how the legend is positioned within the scene. One of \"left\", \"right\", \"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\", \"none\".\n *\n * __Default value:__ `\"right\"`\n */\n orient?: LegendOrient;\n\n /**\n * The offset, in pixels, by which to displace the legend from the edge of the enclosing group or data rectangle.\n *\n * __Default value:__ `0`\n */\n offset?: number;\n\n /**\n * The padding, in pixels, between the legend and axis.\n */\n padding?: number;\n}\n\nexport interface VgLegendConfig extends VgLegendBase {\n\n /**\n * Corner radius for the full legend.\n */\n cornerRadius?: number;\n\n /**\n * Background fill color for the full legend.\n */\n fillColor?: string;\n\n /**\n * Border stroke color for the full legend.\n */\n strokeColor?: string;\n\n /**\n * Border stroke dash pattern for the full legend.\n */\n strokeDash?: number[];\n\n /**\n * Border stroke width for the full legend.\n */\n strokeWidth?: number;\n // ---------- Gradient ----------\n /**\n * The color of the gradient stroke, can be in hex color code or regular color name.\n */\n gradientStrokeColor?: string;\n\n /**\n * The width of the gradient stroke, in pixels.\n * @minimum 0\n */\n gradientStrokeWidth?: number;\n\n /**\n * The height of the gradient, in pixels.\n * @minimum 0\n */\n gradientHeight?: number;\n\n /**\n * Text baseline for color ramp gradient labels.\n */\n gradientLabelBaseline?: string;\n\n /**\n * The maximum allowed length in pixels of color ramp gradient labels.\n */\n gradientLabelLimit?: number;\n\n /**\n * Vertical offset in pixels for color ramp gradient labels.\n */\n gradientLabelOffset?: number;\n\n /**\n * The width of the gradient, in pixels.\n * @minimum 0\n */\n gradientWidth?: number;\n\n // ---------- Label ----------\n /**\n * The alignment of the legend label, can be left, middle or right.\n */\n labelAlign?: string;\n\n /**\n * The position of the baseline of legend label, can be top, middle or bottom.\n */\n labelBaseline?: string;\n\n /**\n * The color of the legend label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the legend label.\n */\n labelFont?: string;\n\n /**\n * The font size of legend label.\n *\n * __Default value:__ `10`.\n *\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * Maximum allowed pixel width of axis tick labels.\n */\n labelLimit?: number;\n\n /**\n * The offset of the legend label.\n * @minimum 0\n */\n labelOffset?: number;\n\n // ---------- Symbols ----------\n /**\n * The color of the legend symbol,\n */\n symbolColor?: string;\n\n /**\n * Default shape type (such as \"circle\") for legend symbols.\n */\n symbolType?: string;\n\n /**\n * The size of the legend symbol, in pixels.\n * @minimum 0\n */\n symbolSize?: number;\n\n /**\n * The width of the symbol's stroke.\n * @minimum 0\n */\n symbolStrokeWidth?: number;\n\n // ---------- Title ----------\n /**\n * Horizontal text alignment for legend titles.\n */\n titleAlign?: string;\n\n /**\n * Vertical text baseline for legend titles.\n */\n titleBaseline?: string;\n /**\n * The color of the legend title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * The font of the legend title.\n */\n titleFont?: string;\n\n /**\n * The font size of the legend title.\n */\n titleFontSize?: number;\n\n /**\n * The font weight of the legend title.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n titleFontWeight?: FontWeight;\n\n /**\n * Maximum allowed pixel width of axis titles.\n */\n titleLimit?: number;\n\n /**\n * The padding, in pixels, between title and legend.\n */\n titlePadding?: number;\n}\n\nexport type FontStyle = 'normal' | 'italic';\n\nexport type FontWeightString = 'normal' | 'bold';\n/**\n * @TJS-type integer\n * @minimum 100\n * @maximum 900\n */\nexport type FontWeightNumber = number;\nexport type FontWeight = FontWeightString | FontWeightNumber;\nexport type HorizontalAlign = 'left' | 'right' | 'center';\nexport type Interpolate = 'linear' | 'linear-closed' |\n 'step' | 'step-before' | 'step-after' |\n 'basis' | 'basis-open' | 'basis-closed' |\n 'cardinal' | 'cardinal-open' | 'cardinal-closed' |\n 'bundle' | 'monotone';\nexport type Orient = 'horizontal' | 'vertical';\nexport type VerticalAlign = 'top' | 'middle' | 'bottom';\nexport type Cursor = 'auto' | 'default' | 'none' |\n 'context-menu' | 'help' | 'pointer' |\n 'progress' | 'wait' | 'cell' |\n 'crosshair' | 'text' | 'vertical-text' |\n 'alias' | 'copy' | 'move' |\n 'no-drop' | 'not-allowed' | 'e-resize' |\n 'n-resize' | 'ne-resize' | 'nw-resize' |\n 's-resize' | 'se-resize' | 'sw-resize' |\n 'w-resize' | 'ew-resize' | 'ns-resize' |\n 'nesw-resize' | 'nwse-resize' | 'col-resize' |\n 'row-resize' | 'all-scroll' | 'zoom-in' |\n 'zoom-out' | 'grab' | 'grabbing';\nexport type StrokeCap = 'butt' | 'round' | 'square';\nexport type StrokeJoin = 'miter' | 'round' | 'bevel';\nexport type Dir = 'ltr' | 'rtl';\n\nexport interface VgMarkConfig {\n\n /**\n * Default Fill Color. This has higher precedence than `config.color`\n *\n * __Default value:__ (None)\n *\n */\n fill?: string;\n\n /**\n * Default Stroke Color. This has higher precedence than `config.color`\n *\n * __Default value:__ (None)\n *\n */\n stroke?: string;\n\n // ---------- Opacity ----------\n /**\n * The overall opacity (value between [0,1]).\n *\n * __Default value:__ `0.7` for non-aggregate plots with `point`, `tick`, `circle`, or `square` marks or layered `bar` charts and `1` otherwise.\n *\n * @minimum 0\n * @maximum 1\n */\n opacity?: number;\n\n\n /**\n * The fill opacity (value between [0,1]).\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n * @maximum 1\n */\n fillOpacity?: number;\n\n /**\n * The stroke opacity (value between [0,1]).\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n * @maximum 1\n */\n strokeOpacity?: number;\n\n // ---------- Stroke Style ----------\n /**\n * The stroke width, in pixels.\n *\n * @minimum 0\n */\n strokeWidth?: number;\n\n /**\n * The stroke cap for line ending style. One of `\"butt\"`, `\"round\"`, or `\"square\"`.\n *\n * __Default value:__ `\"square\"`\n */\n strokeCap?: StrokeCap;\n\n /**\n * An array of alternating stroke, space lengths for creating dashed or dotted lines.\n */\n strokeDash?: number[];\n\n /**\n * The offset (in pixels) into which to begin drawing with the stroke dash array.\n */\n strokeDashOffset?: number;\n\n /**\n * The stroke line join method. One of `\"miter\"`, `\"round\"` or `\"bevel\"`.\n *\n * __Default value:__ `\"miter\"`\n */\n strokeJoin?: StrokeJoin;\n\n /**\n * The miter limit at which to bevel a line join.\n */\n strokeMiterLimit?: number;\n\n // ---------- Orientation: Bar, Tick, Line, Area ----------\n /**\n * The orientation of a non-stacked bar, tick, area, and line charts.\n * The value is either horizontal (default) or vertical.\n * - For bar, rule and tick, this determines whether the size of the bar and tick\n * should be applied to x or y dimension.\n * - For area, this property determines the orient property of the Vega output.\n * - For line and trail marks, this property determines the sort order of the points in the line\n * if `config.sortLineBy` is not specified.\n * For stacked charts, this is always determined by the orientation of the stack;\n * therefore explicitly specified value will be ignored.\n */\n orient?: Orient;\n\n // ---------- Interpolation: Line / area ----------\n /**\n * The line interpolation method to use for line and area marks. One of the following:\n * - `\"linear\"`: piecewise linear segments, as in a polyline.\n * - `\"linear-closed\"`: close the linear segments to form a polygon.\n * - `\"step\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"step-before\"`: alternate between vertical and horizontal segments, as in a step function.\n * - `\"step-after\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"basis\"`: a B-spline, with control point duplication on the ends.\n * - `\"basis-open\"`: an open B-spline; may not intersect the start or end.\n * - `\"basis-closed\"`: a closed B-spline, as in a loop.\n * - `\"cardinal\"`: a Cardinal spline, with control point duplication on the ends.\n * - `\"cardinal-open\"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points.\n * - `\"cardinal-closed\"`: a closed Cardinal spline, as in a loop.\n * - `\"bundle\"`: equivalent to basis, except the tension parameter is used to straighten the spline.\n * - `\"monotone\"`: cubic interpolation that preserves monotonicity in y.\n */\n interpolate?: Interpolate;\n /**\n * Depending on the interpolation type, sets the tension parameter (for line and area marks).\n * @minimum 0\n * @maximum 1\n */\n tension?: number;\n\n /**\n * The default symbol shape to use. One of: `\"circle\"` (default), `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, or `\"triangle-down\"`, or a custom SVG path.\n *\n * __Default value:__ `\"circle\"`\n *\n */\n shape?: string;\n\n /**\n * The pixel area each the point/circle/square.\n * For example: in the case of circles, the radius is determined in part by the square root of the size value.\n *\n * __Default value:__ `30`\n *\n * @minimum 0\n */\n size?: number;\n\n // Text / Label Mark Config\n\n /**\n * The horizontal alignment of the text. One of `\"left\"`, `\"right\"`, `\"center\"`.\n */\n align?: HorizontalAlign;\n\n /**\n * The rotation angle of the text, in degrees.\n * @minimum 0\n * @maximum 360\n */\n angle?: number;\n\n /**\n * The vertical alignment of the text. One of `\"top\"`, `\"middle\"`, `\"bottom\"`.\n *\n * __Default value:__ `\"middle\"`\n *\n */\n baseline?: VerticalAlign;\n\n /**\n * The direction of the text. One of `\"ltr\"` (left-to-right) or `\"rtl\"` (right-to-left). This property determines on which side is truncated in response to the limit parameter.\n *\n * __Default value:__ `\"ltr\"`\n */\n dir?: Dir;\n\n /**\n * The horizontal offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property.\n */\n dx?: number;\n\n /**\n * The vertical offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property.\n */\n dy?: number;\n\n /**\n * Polar coordinate radial offset, in pixels, of the text label from the origin determined by the `x` and `y` properties.\n * @minimum 0\n */\n radius?: number;\n\n /**\n * The maximum length of the text mark in pixels. The text value will be automatically truncated if the rendered size exceeds the limit.\n *\n * __Default value:__ `0`, indicating no limit\n */\n limit?: number;\n\n /**\n * The ellipsis string for text truncated in response to the limit parameter.\n *\n * __Default value:__ `\"…\"`\n */\n ellipsis?: string;\n\n /**\n * Polar coordinate angle, in radians, of the text label from the origin determined by the `x` and `y` properties. Values for `theta` follow the same convention of `arc` mark `startAngle` and `endAngle` properties: angles are measured in radians, with `0` indicating \"north\".\n */\n theta?: number;\n\n /**\n * The typeface to set the text in (e.g., `\"Helvetica Neue\"`).\n */\n font?: string;\n\n /**\n * The font size, in pixels.\n * @minimum 0\n */\n fontSize?: number;\n\n /**\n * The font style (e.g., `\"italic\"`).\n */\n fontStyle?: FontStyle;\n /**\n * The font weight.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n fontWeight?: FontWeight;\n\n /**\n * Placeholder text if the `text` channel is not specified\n */\n text?: string;\n\n /**\n * A URL to load upon mouse click. If defined, the mark acts as a hyperlink.\n *\n * @format uri\n */\n href?: string;\n\n /**\n * The mouse cursor used over the mark. Any valid [CSS cursor type](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Values) can be used.\n */\n cursor?: Cursor;\n\n /**\n * The tooltip text to show upon mouse hover.\n */\n tooltip?: any;\n\n // ---------- Corner Radius: Bar, Tick, Rect ----------\n\n /**\n * The radius in pixels of rounded rectangle corners.\n *\n * __Default value:__ `0`\n */\n cornerRadius?: number;\n}\n\nconst VG_MARK_CONFIG_INDEX: Flag = {\n opacity: 1,\n fill: 1,\n fillOpacity: 1,\n stroke: 1,\n strokeCap: 1,\n strokeWidth: 1,\n strokeOpacity: 1,\n strokeDash: 1,\n strokeDashOffset: 1,\n strokeJoin: 1,\n strokeMiterLimit: 1,\n size: 1,\n shape: 1,\n interpolate: 1,\n tension: 1,\n orient: 1,\n align: 1,\n baseline: 1,\n text: 1,\n dir: 1,\n dx: 1,\n dy: 1,\n ellipsis: 1,\n limit: 1,\n radius: 1,\n theta: 1,\n angle: 1,\n font: 1,\n fontSize: 1,\n fontWeight: 1,\n fontStyle: 1,\n cursor: 1,\n href: 1,\n tooltip: 1,\n cornerRadius: 1,\n // commented below are vg channel that do not have mark config.\n // 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height'\n // clip: 1,\n // endAngle: 1,\n // innerRadius: 1,\n // outerRadius: 1,\n // path: 1,\n // startAngle: 1,\n // url: 1,\n};\n\nexport const VG_MARK_CONFIGS = flagKeys(VG_MARK_CONFIG_INDEX);\n\nexport type Anchor = 'start' | 'middle' | 'end';\n\nexport interface VgTitle {\n /**\n * The title text.\n */\n text: string;\n\n /**\n * The orientation of the title relative to the chart. One of `\"top\"` (the default), `\"bottom\"`, `\"left\"`, or `\"right\"`.\n */\n orient?: TitleOrient;\n\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"` (the default), or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n */\n anchor?: Anchor;\n\n /**\n * The orthogonal offset in pixels by which to displace the title from its position along the edge of the chart.\n */\n offset?: number;\n\n style?: string | string[];\n\n // TODO: name, encode, interactive, zindex\n}\n\nexport type TitleOrient = 'top' | 'bottom' | 'left' | 'right';\n\nexport interface VgTitleConfig {\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"`, or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n *\n * __Default value:__ `\"middle\"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views.\n * `\"start\"` for other composite views.\n *\n * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `\"start\"`.\n */\n anchor?: Anchor;\n /**\n * Angle in degrees of title text.\n */\n angle?:\tnumber;\n /**\n * Vertical text baseline for title text.\n */\n baseline?: VerticalAlign;\n /**\n * Text color for title text.\n */\n color?:\tstring;\n /**\n * Font name for title text.\n */\n font?:\tstring;\n /**\n * Font size in pixels for title text.\n *\n * __Default value:__ `10`.\n *\n * @minimum 0\n */\n fontSize?:\tnumber;\n /**\n * Font weight for title text.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n fontWeight?: FontWeight;\n /**\n * The maximum allowed length in pixels of legend labels.\n *\n * @minimum 0\n */\n limit?:\tnumber;\n /**\n * Offset in pixels of the title from the chart body and axes.\n */\n offset?:\tnumber;\n /**\n * Default title orientation (\"top\", \"bottom\", \"left\", or \"right\")\n */\n orient?: TitleOrient;\n}\n\nexport type VgComparatorOrder = 'ascending' | 'descending';\n\nexport interface VgComparator {\n field?: string | string[];\n order?: VgComparatorOrder | VgComparatorOrder[];\n}\n\nexport interface VgWindowTransform {\n type: 'window';\n params?: Number[];\n as?: string[];\n ops?: (AggregateOp | WindowOnlyOp)[];\n fields?: string[];\n frame?: Number[];\n ignorePeers?: Boolean;\n groupby?: string[];\n sort?: VgComparator;\n}\n"]} \ No newline at end of file diff --git a/build/test/axis.test.d.ts b/build/test/axis.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/axis.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/axis.test.js b/build/test/axis.test.js new file mode 100644 index 0000000000..9a79e5090f --- /dev/null +++ b/build/test/axis.test.js @@ -0,0 +1,11 @@ +import { assert } from 'chai'; +import { VG_AXIS_PROPERTIES } from '../src/axis'; +describe('axis', function () { + describe('VG_AXIS_PROPERTIES', function () { + it('should have scale and orient as the first two items', function () { + assert.equal(VG_AXIS_PROPERTIES[0], 'scale'); + assert.equal(VG_AXIS_PROPERTIES[1], 'orient'); + }); + }); +}); +//# sourceMappingURL=axis.test.js.map \ No newline at end of file diff --git a/build/test/axis.test.js.map b/build/test/axis.test.js.map new file mode 100644 index 0000000000..5a73157713 --- /dev/null +++ b/build/test/axis.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"axis.test.js","sourceRoot":"","sources":["../../test/axis.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,kBAAkB,EAAC,MAAM,aAAa,CAAC;AAE/C,QAAQ,CAAC,MAAM,EAAE;IACf,QAAQ,CAAC,oBAAoB,EAAE;QAC7B,EAAE,CAAC,qDAAqD,EAAE;YACxD,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC7C,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\nimport {VG_AXIS_PROPERTIES} from '../src/axis';\n\ndescribe('axis', () => {\n describe('VG_AXIS_PROPERTIES', () => {\n it('should have scale and orient as the first two items', () => {\n assert.equal(VG_AXIS_PROPERTIES[0], 'scale');\n assert.equal(VG_AXIS_PROPERTIES[1], 'orient');\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/bin.test.d.ts b/build/test/bin.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/bin.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/bin.test.js b/build/test/bin.test.js new file mode 100644 index 0000000000..91745dfe03 --- /dev/null +++ b/build/test/bin.test.js @@ -0,0 +1,23 @@ +import { assert } from 'chai'; +import { autoMaxBins, binToString, isBinParams } from '../src/bin'; +import { COLOR, COLUMN, OPACITY, ROW, SHAPE } from '../src/channel'; +describe('autoMaxBins', function () { + it('should assign generate correct defaults for different channels', function () { + // Not testing case for 10 because it's already tested + [COLOR, OPACITY, SHAPE, ROW, COLUMN].forEach(function (a) { return assert.deepEqual(autoMaxBins(a), 6); }); + }); +}); +describe('binToString', function () { + it('should generate the corrrect key for boolean', function () { + assert.deepEqual(binToString(true), 'bin'); + assert.deepEqual(binToString(false), 'bin'); + }); +}); +describe('isBinParams', function () { + it('should detect whether the input is BinParams or not', function () { + assert.deepEqual(isBinParams(true), false); + assert.deepEqual(isBinParams({}), true); + assert.deepEqual(isBinParams({ extent: [0, 1] }), true); + }); +}); +//# sourceMappingURL=bin.test.js.map \ No newline at end of file diff --git a/build/test/bin.test.js.map b/build/test/bin.test.js.map new file mode 100644 index 0000000000..9ddaf458c2 --- /dev/null +++ b/build/test/bin.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bin.test.js","sourceRoot":"","sources":["../../test/bin.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAC,MAAM,YAAY,CAAC;AACjE,OAAO,EAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAElE,QAAQ,CAAC,aAAa,EAAE;IACtB,EAAE,CAAC,gEAAgE,EAAE;QACnE,sDAAsD;QACtD,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,UAAC,CAAC,IAAK,OAAA,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAnC,CAAmC,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,aAAa,EAAE;IACtB,EAAE,CAAC,8CAA8C,EAAE;QAClD,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,aAAa,EAAE;IACtB,EAAE,CAAC,qDAAqD,EAAE;QACzD,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,EAAC,MAAM,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\nimport {autoMaxBins, binToString, isBinParams} from '../src/bin';\nimport {COLOR, COLUMN, OPACITY, ROW, SHAPE} from '../src/channel';\n\ndescribe('autoMaxBins', () => {\n it('should assign generate correct defaults for different channels', () => {\n // Not testing case for 10 because it's already tested\n [COLOR, OPACITY, SHAPE, ROW, COLUMN].forEach((a) => assert.deepEqual(autoMaxBins(a), 6));\n });\n});\n\ndescribe('binToString', () => {\n it('should generate the corrrect key for boolean', () => {\n assert.deepEqual(binToString(true), 'bin');\n assert.deepEqual(binToString(false), 'bin');\n });\n});\n\ndescribe('isBinParams', () => {\n it('should detect whether the input is BinParams or not', () => {\n assert.deepEqual(isBinParams(true), false);\n assert.deepEqual(isBinParams({}), true);\n assert.deepEqual(isBinParams({extent: [0,1]}), true);\n });\n});\n\n"]} \ No newline at end of file diff --git a/build/test/channel.test.d.ts b/build/test/channel.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/channel.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/channel.test.js b/build/test/channel.test.js new file mode 100644 index 0000000000..5dc05aad80 --- /dev/null +++ b/build/test/channel.test.js @@ -0,0 +1,48 @@ +import { assert } from 'chai'; +import { isScaleChannel, rangeType, SINGLE_DEF_CHANNELS } from '../src/channel'; +import { CHANNELS, NONPOSITION_SCALE_CHANNELS, SCALE_CHANNELS, UNIT_CHANNELS } from '../src/channel'; +import { without } from '../src/util'; +describe('channel', function () { + describe('UNIT_CHANNELS', function () { + it('should be CHANNELS without row and column', function () { + assert.deepEqual(UNIT_CHANNELS, without(CHANNELS, ['row', 'column'])); + }); + }); + describe('SINGLE_DEF_CHANNELS', function () { + it('should be CHANNELS without detail and order', function () { + assert.deepEqual(SINGLE_DEF_CHANNELS, without(CHANNELS, ['detail', 'order'])); + }); + }); + describe('SCALE_CHANNELS', function () { + it('should be UNIT_CHANNELS without X2, Y2, ORDER, DETAIL, TEXT, LABEL, TOOLTIP', function () { + assert.deepEqual(SCALE_CHANNELS, without(UNIT_CHANNELS, ['x2', 'y2', 'latitude', 'longitude', 'latitude2', 'longitude2', 'order', 'detail', 'key', 'text', 'label', 'tooltip', 'href'])); + }); + }); + describe('NONPOSITION_SCALE_CHANNELS', function () { + it('should be SCALE_CHANNELS without x, y, x2, y2', function () { + assert.deepEqual(NONPOSITION_SCALE_CHANNELS, without(SCALE_CHANNELS, ['x', 'y'])); + }); + }); + describe('isScaleChannel', function () { + it('should return true for all scale channel', function () { + for (var _i = 0, SCALE_CHANNELS_1 = SCALE_CHANNELS; _i < SCALE_CHANNELS_1.length; _i++) { + var channel = SCALE_CHANNELS_1[_i]; + assert(isScaleChannel(channel)); + } + }); + }); + describe('rangeType', function () { + it('should be defined for all channels (no error).', function () { + var _loop_1 = function (c) { + assert.doesNotThrow(function () { + rangeType(c); + }); + }; + for (var _i = 0, CHANNELS_1 = CHANNELS; _i < CHANNELS_1.length; _i++) { + var c = CHANNELS_1[_i]; + _loop_1(c); + } + }); + }); +}); +//# sourceMappingURL=channel.test.js.map \ No newline at end of file diff --git a/build/test/channel.test.js.map b/build/test/channel.test.js.map new file mode 100644 index 0000000000..9564bb9bbf --- /dev/null +++ b/build/test/channel.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"channel.test.js","sourceRoot":"","sources":["../../test/channel.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,cAAc,EAAE,SAAS,EAAE,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAC,QAAQ,EAAE,0BAA0B,EAAE,cAAc,EAAE,aAAa,EAAC,MAAM,gBAAgB,CAAC;AACnG,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAC;AAEpC,QAAQ,CAAC,SAAS,EAAE;IAClB,QAAQ,CAAC,eAAe,EAAE;QACxB,EAAE,CAAC,2CAA2C,EAAE;YAC9C,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qBAAqB,EAAE;QAC9B,EAAE,CAAC,6CAA6C,EAAE;YAChD,MAAM,CAAC,SAAS,CAAC,mBAAmB,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE;QACzB,EAAE,CAAC,6EAA6E,EAAE;YAChF,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3L,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,4BAA4B,EAAE;QACrC,EAAE,CAAC,+CAA+C,EAAE;YAClD,MAAM,CAAC,SAAS,CAAC,0BAA0B,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACpF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE;QACzB,EAAE,CAAC,0CAA0C,EAAE;YAC7C,KAAsB,UAAc,EAAd,iCAAc,EAAd,4BAAc,EAAd,IAAc,EAAE;gBAAjC,IAAM,OAAO,uBAAA;gBAChB,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;aACjC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,EAAE;QACpB,EAAE,CAAC,gDAAgD,EAAE;oCACxC,CAAC;gBACV,MAAM,CAAC,YAAY,CAAC;oBAClB,SAAS,CAAC,CAAC,CAAC,CAAC;gBACf,CAAC,CAAC,CAAC;YACL,CAAC;YAJD,KAAgB,UAAQ,EAAR,qBAAQ,EAAR,sBAAQ,EAAR,IAAQ;gBAAnB,IAAM,CAAC,iBAAA;wBAAD,CAAC;aAIX;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\nimport {isScaleChannel, rangeType, SINGLE_DEF_CHANNELS} from '../src/channel';\nimport {CHANNELS, NONPOSITION_SCALE_CHANNELS, SCALE_CHANNELS, UNIT_CHANNELS} from '../src/channel';\nimport {without} from '../src/util';\n\ndescribe('channel', () => {\n describe('UNIT_CHANNELS', () => {\n it('should be CHANNELS without row and column', () => {\n assert.deepEqual(UNIT_CHANNELS, without(CHANNELS, ['row', 'column']));\n });\n });\n\n describe('SINGLE_DEF_CHANNELS', () => {\n it('should be CHANNELS without detail and order', () => {\n assert.deepEqual(SINGLE_DEF_CHANNELS, without(CHANNELS, ['detail', 'order']));\n });\n });\n\n describe('SCALE_CHANNELS', () => {\n it('should be UNIT_CHANNELS without X2, Y2, ORDER, DETAIL, TEXT, LABEL, TOOLTIP', () => {\n assert.deepEqual(SCALE_CHANNELS, without(UNIT_CHANNELS, ['x2', 'y2', 'latitude', 'longitude', 'latitude2', 'longitude2', 'order', 'detail', 'key', 'text', 'label', 'tooltip', 'href']));\n });\n });\n\n describe('NONPOSITION_SCALE_CHANNELS', () => {\n it('should be SCALE_CHANNELS without x, y, x2, y2', () => {\n assert.deepEqual(NONPOSITION_SCALE_CHANNELS, without(SCALE_CHANNELS, ['x', 'y']));\n });\n });\n\n describe('isScaleChannel', () => {\n it('should return true for all scale channel', () => {\n for (const channel of SCALE_CHANNELS) {\n assert(isScaleChannel(channel));\n }\n });\n });\n\n describe('rangeType', () => {\n it('should be defined for all channels (no error).', () => {\n for (const c of CHANNELS) {\n assert.doesNotThrow(() => {\n rangeType(c);\n });\n }\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/axis/assemble.test.d.ts b/build/test/compile/axis/assemble.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/axis/assemble.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/axis/assemble.test.js b/build/test/compile/axis/assemble.test.js new file mode 100644 index 0000000000..7463c1da9c --- /dev/null +++ b/build/test/compile/axis/assemble.test.js @@ -0,0 +1,50 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { assembleAxis } from '../../../src/compile/axis/assemble'; +import { AxisComponent } from '../../../src/compile/axis/component'; +import { defaultConfig } from '../../../src/config'; +describe('compile/axis/assemble', function () { + describe('assembleAxis()', function () { + it('outputs grid axis with only grid encode blocks', function () { + var axisCmpt = new AxisComponent({ + orient: 'left', + grid: true, + encode: { + grid: { update: { stroke: { value: 'red' } } }, + labels: { update: { fill: { value: 'red' } } } + } + }); + var axis = assembleAxis(axisCmpt, 'grid', defaultConfig); + assert.isUndefined(axis.encode.labels); + }); + it('outputs grid axis with custom zindex', function () { + var axisCmpt = new AxisComponent({ + orient: 'left', + grid: true, + zindex: 3 + }); + var axis = assembleAxis(axisCmpt, 'grid', defaultConfig); + assert.equal(axis.zindex, 3); + }); + it('outputs main axis without grid encode blocks', function () { + var axisCmpt = new AxisComponent({ + orient: 'left', + encode: { + grid: { update: { stroke: { value: 'red' } } }, + labels: { update: { fill: { value: 'red' } } } + } + }); + var axis = assembleAxis(axisCmpt, 'main', defaultConfig); + assert.isUndefined(axis.encode.grid); + }); + it('correctly assemble title fieldDefs', function () { + var axisCmpt = new AxisComponent({ + orient: 'left', + title: [{ aggregate: 'max', field: 'a' }, { aggregate: 'min', field: 'b' }] + }); + var axis = assembleAxis(axisCmpt, 'main', defaultConfig); + assert.equal(axis.title, 'Max of a, Min of b'); + }); + }); +}); +//# sourceMappingURL=assemble.test.js.map \ No newline at end of file diff --git a/build/test/compile/axis/assemble.test.js.map b/build/test/compile/axis/assemble.test.js.map new file mode 100644 index 0000000000..1342c930e9 --- /dev/null +++ b/build/test/compile/axis/assemble.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.test.js","sourceRoot":"","sources":["../../../../test/compile/axis/assemble.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,YAAY,EAAC,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAC,aAAa,EAAC,MAAM,qCAAqC,CAAC;AAClE,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAIlD,QAAQ,CAAC,uBAAuB,EAAE;IAChC,QAAQ,CAAC,gBAAgB,EAAE;QACzB,EAAE,CAAC,gDAAgD,EAAE;YACnD,IAAM,QAAQ,GAAG,IAAI,aAAa,CAAC;gBACjC,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,EAAC,MAAM,EAAE,EAAC,MAAM,EAAE,EAAC,KAAK,EAAE,KAAK,EAAC,EAAC,EAAC;oBACxC,MAAM,EAAE,EAAC,MAAM,EAAE,EAAC,IAAI,EAAE,EAAC,KAAK,EAAE,KAAK,EAAC,EAAC,EAAC;iBACzC;aACF,CAAC,CAAC;YACH,IAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;YAC3D,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE;YACzC,IAAM,QAAQ,GAAG,IAAI,aAAa,CAAC;gBACjC,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,CAAC;aACV,CAAC,CAAC;YACH,IAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;YAC3D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE;YACjD,IAAM,QAAQ,GAAG,IAAI,aAAa,CAAC;gBACjC,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE;oBACN,IAAI,EAAE,EAAC,MAAM,EAAE,EAAC,MAAM,EAAE,EAAC,KAAK,EAAE,KAAK,EAAC,EAAC,EAAC;oBACxC,MAAM,EAAE,EAAC,MAAM,EAAE,EAAC,IAAI,EAAE,EAAC,KAAK,EAAE,KAAK,EAAC,EAAC,EAAC;iBACzC;aACF,CAAC,CAAC;YACH,IAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;YAC3D,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE;YACvC,IAAM,QAAQ,GAAG,IAAI,aAAa,CAAC;gBACjC,MAAM,EAAE,MAAM;gBACd,KAAK,EAAE,CAAC,EAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAC,EAAE,EAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAC,CAAC;aACxE,CAAC,CAAC;YACH,IAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;YAC3D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AAEL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {assembleAxis} from '../../../src/compile/axis/assemble';\nimport {AxisComponent} from '../../../src/compile/axis/component';\nimport {defaultConfig} from '../../../src/config';\n\n\n\ndescribe('compile/axis/assemble', () => {\n describe('assembleAxis()', () => {\n it('outputs grid axis with only grid encode blocks', () => {\n const axisCmpt = new AxisComponent({\n orient: 'left',\n grid: true,\n encode: {\n grid: {update: {stroke: {value: 'red'}}},\n labels: {update: {fill: {value: 'red'}}}\n }\n });\n const axis = assembleAxis(axisCmpt, 'grid', defaultConfig);\n assert.isUndefined(axis.encode.labels);\n });\n\n it('outputs grid axis with custom zindex', () => {\n const axisCmpt = new AxisComponent({\n orient: 'left',\n grid: true,\n zindex: 3\n });\n const axis = assembleAxis(axisCmpt, 'grid', defaultConfig);\n assert.equal(axis.zindex, 3);\n });\n\n it('outputs main axis without grid encode blocks', () => {\n const axisCmpt = new AxisComponent({\n orient: 'left',\n encode: {\n grid: {update: {stroke: {value: 'red'}}},\n labels: {update: {fill: {value: 'red'}}}\n }\n });\n const axis = assembleAxis(axisCmpt, 'main', defaultConfig);\n assert.isUndefined(axis.encode.grid);\n });\n\n it('correctly assemble title fieldDefs', () => {\n const axisCmpt = new AxisComponent({\n orient: 'left',\n title: [{aggregate: 'max', field: 'a'}, {aggregate: 'min', field: 'b'}]\n });\n const axis = assembleAxis(axisCmpt, 'main', defaultConfig);\n assert.equal(axis.title, 'Max of a, Min of b');\n });\n });\n\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/axis/encode.test.d.ts b/build/test/compile/axis/encode.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/axis/encode.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/axis/encode.test.js b/build/test/compile/axis/encode.test.js new file mode 100644 index 0000000000..378c2426f0 --- /dev/null +++ b/build/test/compile/axis/encode.test.js @@ -0,0 +1,139 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import * as encode from '../../../src/compile/axis/encode'; +import { labelAlign, labelBaseline } from '../../../src/compile/axis/encode'; +import { parseUnitModelWithScale } from '../../util'; +describe('compile/axis/encode', function () { + describe('encode.labels()', function () { + it('should not rotate label for temporal field by default', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal", timeUnit: "month" } + } + }); + var labels = encode.labels(model, 'x', {}, 'bottom'); + assert.isUndefined(labels.angle); + }); + it('should do not rotate label for temporal field if labelAngle is specified in axis config', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal", timeUnit: "month" } + }, + config: { axisX: { labelAngle: 90 } } + }); + var labels = encode.labels(model, 'x', {}, 'bottom'); + assert.isUndefined(labels.angle); + }); + it('should have correct text.signal for quarter timeUnits', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal", timeUnit: "quarter" } + } + }); + var labels = encode.labels(model, 'x', {}, 'bottom'); + var expected = "'Q' + quarter(datum.value)"; + assert.equal(labels.text.signal, expected); + }); + it('should have correct text.signal for yearquartermonth timeUnits', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal", timeUnit: "yearquartermonth" } + } + }); + var labels = encode.labels(model, 'x', {}, 'bottom'); + var expected = "'Q' + quarter(datum.value) + ' ' + timeFormat(datum.value, '%b %Y')"; + assert.equal(labels.text.signal, expected); + }); + }); + describe('labelAlign', function () { + describe('horizontal orients', function () { + it('360 degree check for horizonatal orients return to see if they orient properly', function () { + assert.equal(labelAlign(0, 'top'), 'center'); + assert.equal(labelAlign(15, 'top'), 'right'); + assert.equal(labelAlign(30, 'top'), 'right'); + assert.equal(labelAlign(45, 'top'), 'right'); + assert.equal(labelAlign(60, 'top'), 'right'); + assert.equal(labelAlign(75, 'top'), 'right'); + assert.equal(labelAlign(90, 'top'), 'right'); + assert.equal(labelAlign(105, 'top'), 'right'); + assert.equal(labelAlign(120, 'top'), 'right'); + assert.equal(labelAlign(135, 'top'), 'right'); + assert.equal(labelAlign(150, 'top'), 'right'); + assert.equal(labelAlign(165, 'top'), 'right'); + assert.equal(labelAlign(180, 'top'), 'center'); + assert.equal(labelAlign(195, 'bottom'), 'right'); + assert.equal(labelAlign(210, 'bottom'), 'right'); + assert.equal(labelAlign(225, 'bottom'), 'right'); + assert.equal(labelAlign(240, 'bottom'), 'right'); + assert.equal(labelAlign(255, 'bottom'), 'right'); + assert.equal(labelAlign(270, 'bottom'), 'right'); + assert.equal(labelAlign(285, 'bottom'), 'right'); + assert.equal(labelAlign(300, 'bottom'), 'right'); + assert.equal(labelAlign(315, 'bottom'), 'right'); + assert.equal(labelAlign(330, 'bottom'), 'right'); + assert.equal(labelAlign(345, 'bottom'), 'right'); + }); + it('360 degree check for vertical orients return to see if they orient properly', function () { + assert.equal(labelAlign(0, 'left'), 'right'); + assert.equal(labelAlign(15, 'left'), 'right'); + assert.equal(labelAlign(30, 'left'), 'right'); + assert.equal(labelAlign(45, 'left'), 'right'); + assert.equal(labelAlign(60, 'left'), 'right'); + assert.equal(labelAlign(75, 'left'), 'right'); + assert.equal(labelAlign(90, 'left'), 'center'); + assert.equal(labelAlign(105, 'left'), 'left'); + assert.equal(labelAlign(120, 'left'), 'left'); + assert.equal(labelAlign(135, 'left'), 'left'); + assert.equal(labelAlign(150, 'left'), 'left'); + assert.equal(labelAlign(165, 'left'), 'left'); + assert.equal(labelAlign(180, 'left'), 'left'); + assert.equal(labelAlign(195, 'right'), 'right'); + assert.equal(labelAlign(210, 'right'), 'right'); + assert.equal(labelAlign(225, 'right'), 'right'); + assert.equal(labelAlign(240, 'right'), 'right'); + assert.equal(labelAlign(255, 'right'), 'right'); + assert.equal(labelAlign(270, 'right'), 'center'); + assert.equal(labelAlign(285, 'right'), 'left'); + assert.equal(labelAlign(300, 'right'), 'left'); + assert.equal(labelAlign(315, 'right'), 'left'); + assert.equal(labelAlign(330, 'right'), 'left'); + assert.equal(labelAlign(345, 'right'), 'left'); + }); + }); + }); + describe('labelBaseline', function () { + it('is middle for perpendiculars horizontal orients', function () { + assert.deepEqual(labelBaseline(90, 'top'), { value: 'middle' }); + assert.deepEqual(labelBaseline(270, 'bottom'), { value: 'middle' }); + }); + it('is top for bottom orients for 1st and 4th quadrants', function () { + assert.deepEqual(labelBaseline(45, 'bottom'), { value: 'top' }); + assert.deepEqual(labelBaseline(180, 'top'), { value: 'top' }); + }); + it('is bottom for bottom orients for 2nd and 3rd quadrants', function () { + assert.deepEqual(labelBaseline(100, 'bottom'), { value: 'middle' }); + assert.deepEqual(labelBaseline(260, 'bottom'), { value: 'middle' }); + }); + it('is middle for 0 and 180 horizontal orients', function () { + assert.deepEqual(labelBaseline(0, 'left'), { value: 'middle' }); + assert.deepEqual(labelBaseline(180, 'right'), { value: 'middle' }); + }); + it('is top for bottom orients for 1st and 2nd quadrants', function () { + assert.deepEqual(labelBaseline(80, 'left'), { value: 'top' }); + assert.deepEqual(labelBaseline(100, 'left'), { value: 'top' }); + }); + it('is bottom for bottom orients for 3rd and 4th quadrants', function () { + assert.deepEqual(labelBaseline(280, 'left'), { value: 'bottom' }); + assert.deepEqual(labelBaseline(260, 'left'), { value: 'bottom' }); + }); + it('is bottom for bottom orients for 3rd and 4th quadrants', function () { + assert.deepEqual(labelBaseline(280, 'left'), { value: 'bottom' }); + assert.deepEqual(labelBaseline(260, 'left'), { value: 'bottom' }); + }); + }); +}); +//# sourceMappingURL=encode.test.js.map \ No newline at end of file diff --git a/build/test/compile/axis/encode.test.js.map b/build/test/compile/axis/encode.test.js.map new file mode 100644 index 0000000000..707ce78046 --- /dev/null +++ b/build/test/compile/axis/encode.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"encode.test.js","sourceRoot":"","sources":["../../../../test/compile/axis/encode.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\n\nimport * as encode from '../../../src/compile/axis/encode';\nimport {labelAlign, labelBaseline} from '../../../src/compile/axis/encode';\nimport {parseUnitModelWithScale} from '../../util';\n\n\ndescribe('compile/axis/encode', () => {\n describe('encode.labels()', function () {\n it('should not rotate label for temporal field by default', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"temporal\", timeUnit: \"month\"}\n }\n });\n const labels = encode.labels(model, 'x', {}, 'bottom');\n assert.isUndefined(labels.angle);\n });\n\n it('should do not rotate label for temporal field if labelAngle is specified in axis config', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"temporal\", timeUnit: \"month\"}\n },\n config: {axisX: {labelAngle: 90}}\n });\n const labels = encode.labels(model, 'x', {}, 'bottom');\n assert.isUndefined(labels.angle);\n });\n\n it('should have correct text.signal for quarter timeUnits', function () {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"temporal\", timeUnit: \"quarter\"}\n }\n });\n const labels = encode.labels(model, 'x', {}, 'bottom');\n const expected = \"'Q' + quarter(datum.value)\";\n assert.equal(labels.text.signal, expected);\n });\n\n it('should have correct text.signal for yearquartermonth timeUnits', function () {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"temporal\", timeUnit: \"yearquartermonth\"}\n }\n });\n const labels = encode.labels(model, 'x', {}, 'bottom');\n const expected = \"'Q' + quarter(datum.value) + ' ' + timeFormat(datum.value, '%b %Y')\";\n assert.equal(labels.text.signal, expected);\n });\n });\n\n describe('labelAlign', () => {\n describe('horizontal orients', () => {\n it('360 degree check for horizonatal orients return to see if they orient properly', () => {\n assert.equal(labelAlign(0, 'top'), 'center');\n assert.equal(labelAlign(15, 'top'), 'right');\n assert.equal(labelAlign(30, 'top'), 'right');\n assert.equal(labelAlign(45, 'top'), 'right');\n assert.equal(labelAlign(60, 'top'), 'right');\n assert.equal(labelAlign(75, 'top'), 'right');\n assert.equal(labelAlign(90, 'top'), 'right');\n assert.equal(labelAlign(105, 'top'), 'right');\n assert.equal(labelAlign(120, 'top'), 'right');\n assert.equal(labelAlign(135, 'top'), 'right');\n assert.equal(labelAlign(150, 'top'), 'right');\n assert.equal(labelAlign(165, 'top'), 'right');\n assert.equal(labelAlign(180, 'top'), 'center');\n assert.equal(labelAlign(195, 'bottom'), 'right');\n assert.equal(labelAlign(210, 'bottom'), 'right');\n assert.equal(labelAlign(225, 'bottom'), 'right');\n assert.equal(labelAlign(240, 'bottom'), 'right');\n assert.equal(labelAlign(255, 'bottom'), 'right');\n assert.equal(labelAlign(270, 'bottom'), 'right');\n assert.equal(labelAlign(285, 'bottom'), 'right');\n assert.equal(labelAlign(300, 'bottom'), 'right');\n assert.equal(labelAlign(315, 'bottom'), 'right');\n assert.equal(labelAlign(330, 'bottom'), 'right');\n assert.equal(labelAlign(345, 'bottom'), 'right');\n });\n it('360 degree check for vertical orients return to see if they orient properly', () => {\n assert.equal(labelAlign(0, 'left'), 'right');\n assert.equal(labelAlign(15, 'left'), 'right');\n assert.equal(labelAlign(30, 'left'), 'right');\n assert.equal(labelAlign(45, 'left'), 'right');\n assert.equal(labelAlign(60, 'left'), 'right');\n assert.equal(labelAlign(75, 'left'), 'right');\n assert.equal(labelAlign(90, 'left'), 'center');\n assert.equal(labelAlign(105, 'left'), 'left');\n assert.equal(labelAlign(120, 'left'), 'left');\n assert.equal(labelAlign(135, 'left'), 'left');\n assert.equal(labelAlign(150, 'left'), 'left');\n assert.equal(labelAlign(165, 'left'), 'left');\n assert.equal(labelAlign(180, 'left'), 'left');\n assert.equal(labelAlign(195, 'right'), 'right');\n assert.equal(labelAlign(210, 'right'), 'right');\n assert.equal(labelAlign(225, 'right'), 'right');\n assert.equal(labelAlign(240, 'right'), 'right');\n assert.equal(labelAlign(255, 'right'), 'right');\n assert.equal(labelAlign(270, 'right'), 'center');\n assert.equal(labelAlign(285, 'right'), 'left');\n assert.equal(labelAlign(300, 'right'), 'left');\n assert.equal(labelAlign(315, 'right'), 'left');\n assert.equal(labelAlign(330, 'right'), 'left');\n assert.equal(labelAlign(345, 'right'), 'left');\n });\n });\n });\n\n describe('labelBaseline', () => {\n it('is middle for perpendiculars horizontal orients', () => {\n assert.deepEqual(labelBaseline(90, 'top'), {value: 'middle'});\n assert.deepEqual(labelBaseline(270, 'bottom'), {value: 'middle'});\n });\n\n\n it('is top for bottom orients for 1st and 4th quadrants', () => {\n assert.deepEqual(labelBaseline(45, 'bottom'), {value: 'top'});\n assert.deepEqual(labelBaseline(180, 'top'), {value: 'top'});\n });\n\n it('is bottom for bottom orients for 2nd and 3rd quadrants', () => {\n assert.deepEqual(labelBaseline(100, 'bottom'), {value: 'middle'});\n assert.deepEqual(labelBaseline(260, 'bottom'), {value: 'middle'});\n });\n\n it('is middle for 0 and 180 horizontal orients', () => {\n assert.deepEqual(labelBaseline(0, 'left'), {value: 'middle'});\n assert.deepEqual(labelBaseline(180, 'right'), {value: 'middle'});\n });\n\n\n it('is top for bottom orients for 1st and 2nd quadrants', () => {\n assert.deepEqual(labelBaseline(80, 'left'), {value: 'top'});\n assert.deepEqual(labelBaseline(100, 'left'), {value: 'top'});\n });\n\n it('is bottom for bottom orients for 3rd and 4th quadrants', () => {\n assert.deepEqual(labelBaseline(280, 'left'), {value: 'bottom'});\n assert.deepEqual(labelBaseline(260, 'left'), {value: 'bottom'});\n });\n\n it('is bottom for bottom orients for 3rd and 4th quadrants', () => {\n assert.deepEqual(labelBaseline(280, 'left'), {value: 'bottom'});\n assert.deepEqual(labelBaseline(260, 'left'), {value: 'bottom'});\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/axis/parse.test.d.ts b/build/test/compile/axis/parse.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/axis/parse.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/axis/parse.test.js b/build/test/compile/axis/parse.test.js new file mode 100644 index 0000000000..ae3f506acd --- /dev/null +++ b/build/test/compile/axis/parse.test.js @@ -0,0 +1,304 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { Y } from '../../../src/channel'; +import { parseLayerAxis, parseUnitAxis } from '../../../src/compile/axis/parse'; +import { parseLayerModel, parseUnitModelWithScale } from '../../util'; +describe('Axis', function () { + // TODO: move this to model.test.ts + describe('= true', function () { + it('should produce default properties for axis', function () { + var model1 = parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" } + }, + "data": { "url": "data/movies.json" } + }); + var model2 = parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" } + }, + "data": { "url": "data/movies.json" } + }); + assert.deepEqual(model1.axis(Y), model2.axis(Y)); + }); + }); + describe('parseUnitAxis', function () { + it('should produce Vega grid', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative", + axis: { grid: true, gridColor: "blue", gridWidth: 20 } + } + } + }); + var axisComponent = parseUnitAxis(model); + assert.equal(axisComponent['x'].length, 1); + assert.equal(axisComponent['x'][0].explicit.grid, true); + }); + it('should produce Vega grid when axis config is specified.', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative" + } + }, + "config": { "axisX": { "grid": true } } + }); + var axisComponent = parseUnitAxis(model); + assert.equal(axisComponent['x'].length, 1); + assert.equal(axisComponent['x'][0].implicit.grid, true); + }); + it('should produce axis component with grid=false', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative", + axis: { grid: false, gridColor: "blue", gridWidth: 20 } + } + } + }); + var axisComponent = parseUnitAxis(model); + assert.equal(axisComponent['x'].length, 1); + assert.equal(axisComponent['x'][0].explicit.grid, false); + }); + it('should ignore null scales', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + longitude: { + field: "a", + type: "quantitative" + }, + latitude: { + field: "b", + type: "quantitative" + } + } + }); + var axisComponent = parseUnitAxis(model); + assert.isUndefined(axisComponent['x']); + assert.isUndefined(axisComponent['y']); + }); + it('should produce Vega grid axis = undefined axis if grid is disabled via config.axisX', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative" + } + }, + config: { axisX: { grid: false } } + }); + var axisComponent = parseUnitAxis(model); + assert.equal(axisComponent['x'].length, 1); + assert.equal(axisComponent['x'][0].explicit.grid, undefined); + }); + it('should produce Vega grid axis = undefined axis if grid is disabled via config.axis', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative" + } + }, + config: { axis: { grid: false } } + }); + var axisComponent = parseUnitAxis(model); + assert.equal(axisComponent['x'].length, 1); + assert.equal(axisComponent['x'][0].explicit.grid, undefined); + }); + it('should store the title value if title = null, "", or false', function () { + for (var _i = 0, _a = [null, '', false]; _i < _a.length; _i++) { + var val = _a[_i]; + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative", + axis: { title: val } // Need to cast as false is not valid, but we want to fall back gracefully + } + } + }); + var axisComponent = parseUnitAxis(model); + assert.equal(axisComponent['x'].length, 1); + assert.equal(axisComponent['x'][0].explicit.title, val); + } + }); + it('should store the fieldDef title value if title = null, "", or false', function () { + for (var _i = 0, _a = [null, '', false]; _i < _a.length; _i++) { + var val = _a[_i]; + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative", + title: val // Need to cast as false is not valid, but we want to fall back gracefully + } + } + }); + var axisComponent = parseUnitAxis(model); + assert.equal(axisComponent['x'].length, 1); + assert.equal(axisComponent['x'][0].explicit.title, val); + } + }); + it('should store fieldDef.title as explicit', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative", + title: 'foo' + } + } + }); + var axisComponent = parseUnitAxis(model); + assert.equal(axisComponent['x'].length, 1); + assert.equal(axisComponent['x'][0].explicit.title, 'foo'); + }); + it('should merge title of fieldDef and fieldDef2', function () { + var model = parseUnitModelWithScale({ + mark: "bar", + encoding: { + x: { + field: "a", + type: "quantitative", + title: 'foo' + }, + x2: { + field: "b", + type: "quantitative", + title: 'bar' + } + } + }); + var axisComponent = parseUnitAxis(model); + assert.equal(axisComponent['x'].length, 1); + assert.equal(axisComponent['x'][0].explicit.title, 'foo, bar'); + }); + it('should use title of fieldDef2', function () { + var model = parseUnitModelWithScale({ + mark: "bar", + encoding: { + x: { + field: "a", + type: "quantitative" + }, + x2: { + field: "b", + type: "quantitative", + title: 'bar' + } + } + }); + var axisComponent = parseUnitAxis(model); + assert.equal(axisComponent['x'].length, 1); + assert.equal(axisComponent['x'][0].explicit.title, 'bar'); + }); + it('should store both x and x2 for ranged mark', function () { + var model = parseUnitModelWithScale({ + mark: "rule", + encoding: { + x: { field: "a", type: "quantitative" }, + x2: { field: "a2", type: "quantitative" } + } + }); + var axisComponent = parseUnitAxis(model); + assert.equal(axisComponent['x'].length, 1); + assert.deepEqual(axisComponent['x'][0].get('title'), [{ field: "a" }, { field: "a2" }]); + }); + }); + describe('parseLayerAxis', function () { + var globalRuleOverlay = parseLayerModel({ + "layer": [ + { + "mark": "rule", + "encoding": { + "y": { + "aggregate": "mean", + "field": "a", + "type": "quantitative" + } + } + }, + { + "mark": "line", + "encoding": { + "y": { + "aggregate": "mean", + "field": "a", + "type": "quantitative" + }, + "x": { + "timeUnit": "month", + "type": "temporal", + "field": "date" + } + } + } + ] + }); + globalRuleOverlay.parseScale(); + globalRuleOverlay.parseLayoutSize(); + parseLayerAxis(globalRuleOverlay); + it('correctly merges gridScale if one layer does not have one of the axis', function () { + var axisComponents = globalRuleOverlay.component.axes; + assert.equal(axisComponents.y.length, 1); + assert.equal(axisComponents.y[0].get('gridScale'), 'x'); + }); + it('correctly merges similar title', function () { + var axisComponents = globalRuleOverlay.component.axes; + assert.deepEqual(axisComponents.y[0].get('title'), [{ aggregate: 'mean', field: 'a' }]); + }); + it('correctly combines different title', function () { + var model = parseLayerModel({ + "$schema": "https://vega.github.io/schema/vega-lite/v2.json", + "data": { "url": "data/cars.json" }, + "layer": [ + { + "mark": "line", + "encoding": { + "x": { "field": "Cylinders", "type": "ordinal" }, + "y": { + "aggregate": "max", + "field": "Horsepower", + "type": "quantitative" + }, + "color": { "value": "darkred" } + } + }, + { + "data": { "url": "data/cars.json" }, + "mark": "line", + "encoding": { + "x": { "field": "Cylinders", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "Horsepower", + "type": "quantitative" + } + } + } + ] + }); + model.parseScale(); + parseLayerAxis(model); + var axisComponents = model.component.axes; + assert.deepEqual(axisComponents.y[0].get('title'), [{ aggregate: 'max', field: 'Horsepower' }, { aggregate: 'min', field: 'Horsepower' }]); + }); + }); +}); +//# sourceMappingURL=parse.test.js.map \ No newline at end of file diff --git a/build/test/compile/axis/parse.test.js.map b/build/test/compile/axis/parse.test.js.map new file mode 100644 index 0000000000..83b4c22496 --- /dev/null +++ b/build/test/compile/axis/parse.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.test.js","sourceRoot":"","sources":["../../../../test/compile/axis/parse.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {Y} from '../../../src/channel';\nimport {parseLayerAxis, parseUnitAxis} from '../../../src/compile/axis/parse';\nimport {parseLayerModel, parseUnitModelWithScale} from '../../util';\n\ndescribe('Axis', function() {\n // TODO: move this to model.test.ts\n describe('= true', function() {\n it('should produce default properties for axis', function() {\n const model1 = parseUnitModelWithScale({\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": 'US_Gross', \"aggregate\": \"sum\"}\n },\n \"data\": {\"url\": \"data/movies.json\"}\n });\n\n const model2 = parseUnitModelWithScale({\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": 'US_Gross', \"aggregate\": \"sum\"}\n },\n \"data\": {\"url\": \"data/movies.json\"}\n });\n assert.deepEqual(model1.axis(Y), model2.axis(Y));\n });\n });\n describe('parseUnitAxis', function() {\n it('should produce Vega grid', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {\n field: \"a\",\n type: \"quantitative\",\n axis: {grid: true, gridColor: \"blue\", gridWidth: 20}\n }\n }\n });\n const axisComponent = parseUnitAxis(model);\n assert.equal(axisComponent['x'].length, 1);\n assert.equal(axisComponent['x'][0].explicit.grid, true);\n });\n\n it('should produce Vega grid when axis config is specified.', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {\n field: \"a\",\n type: \"quantitative\"\n }\n },\n \"config\": {\"axisX\": {\"grid\": true}}\n });\n const axisComponent = parseUnitAxis(model);\n assert.equal(axisComponent['x'].length, 1);\n assert.equal(axisComponent['x'][0].implicit.grid, true);\n });\n\n it('should produce axis component with grid=false', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {\n field: \"a\",\n type: \"quantitative\",\n axis: {grid: false, gridColor: \"blue\", gridWidth: 20}\n }\n }\n });\n const axisComponent = parseUnitAxis(model);\n assert.equal(axisComponent['x'].length, 1);\n assert.equal(axisComponent['x'][0].explicit.grid, false);\n });\n\n it('should ignore null scales', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n longitude: {\n field: \"a\",\n type: \"quantitative\"\n },\n latitude: {\n field: \"b\",\n type: \"quantitative\"\n }\n }\n });\n const axisComponent = parseUnitAxis(model);\n assert.isUndefined(axisComponent['x']);\n assert.isUndefined(axisComponent['y']);\n });\n\n it('should produce Vega grid axis = undefined axis if grid is disabled via config.axisX', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {\n field: \"a\",\n type: \"quantitative\"\n }\n },\n config: {axisX: {grid: false}}\n });\n const axisComponent = parseUnitAxis(model);\n assert.equal(axisComponent['x'].length, 1);\n assert.equal(axisComponent['x'][0].explicit.grid, undefined);\n });\n\n\n it('should produce Vega grid axis = undefined axis if grid is disabled via config.axis', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {\n field: \"a\",\n type: \"quantitative\"\n }\n },\n config: {axis: {grid: false}}\n });\n const axisComponent = parseUnitAxis(model);\n assert.equal(axisComponent['x'].length, 1);\n assert.equal(axisComponent['x'][0].explicit.grid, undefined);\n });\n\n it('should store the title value if title = null, \"\", or false', function () {\n for (const val of [null, '', false]) {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {\n field: \"a\",\n type: \"quantitative\",\n axis: {title: val as any} // Need to cast as false is not valid, but we want to fall back gracefully\n }\n }\n });\n const axisComponent = parseUnitAxis(model);\n assert.equal(axisComponent['x'].length, 1);\n assert.equal(axisComponent['x'][0].explicit.title, val as any);\n }\n });\n\n it('should store the fieldDef title value if title = null, \"\", or false', function () {\n for (const val of [null, '', false]) {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {\n field: \"a\",\n type: \"quantitative\",\n title: val as any // Need to cast as false is not valid, but we want to fall back gracefully\n }\n }\n });\n const axisComponent = parseUnitAxis(model);\n assert.equal(axisComponent['x'].length, 1);\n assert.equal(axisComponent['x'][0].explicit.title, val as any);\n }\n });\n\n it('should store fieldDef.title as explicit', function () {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {\n field: \"a\",\n type: \"quantitative\",\n title: 'foo'\n }\n }\n });\n const axisComponent = parseUnitAxis(model);\n assert.equal(axisComponent['x'].length, 1);\n assert.equal(axisComponent['x'][0].explicit.title, 'foo');\n });\n\n it('should merge title of fieldDef and fieldDef2', function () {\n const model = parseUnitModelWithScale({\n mark: \"bar\",\n encoding: {\n x: {\n field: \"a\",\n type: \"quantitative\",\n title: 'foo'\n },\n x2: {\n field: \"b\",\n type: \"quantitative\",\n title: 'bar'\n }\n }\n });\n const axisComponent = parseUnitAxis(model);\n assert.equal(axisComponent['x'].length, 1);\n assert.equal(axisComponent['x'][0].explicit.title, 'foo, bar');\n });\n\n it('should use title of fieldDef2', function () {\n const model = parseUnitModelWithScale({\n mark: \"bar\",\n encoding: {\n x: {\n field: \"a\",\n type: \"quantitative\"\n },\n x2: {\n field: \"b\",\n type: \"quantitative\",\n title: 'bar'\n }\n }\n });\n const axisComponent = parseUnitAxis(model);\n assert.equal(axisComponent['x'].length, 1);\n assert.equal(axisComponent['x'][0].explicit.title, 'bar');\n });\n\n it('should store both x and x2 for ranged mark', function () {\n const model = parseUnitModelWithScale({\n mark: \"rule\",\n encoding: {\n x: {field: \"a\", type: \"quantitative\"},\n x2: {field: \"a2\", type: \"quantitative\"}\n }\n });\n const axisComponent = parseUnitAxis(model);\n assert.equal(axisComponent['x'].length, 1);\n assert.deepEqual(axisComponent['x'][0].get('title'), [{field: \"a\"}, {field: \"a2\"}]);\n });\n });\n\n describe('parseLayerAxis', () => {\n const globalRuleOverlay = parseLayerModel({\n \"layer\": [\n {\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"a\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n \"mark\": \"line\",\n \"encoding\": {\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"a\",\n \"type\": \"quantitative\"\n },\n \"x\": {\n \"timeUnit\": \"month\",\n \"type\": \"temporal\",\n \"field\": \"date\"\n }\n }\n }\n ]\n });\n globalRuleOverlay.parseScale();\n globalRuleOverlay.parseLayoutSize();\n parseLayerAxis(globalRuleOverlay);\n\n\n it('correctly merges gridScale if one layer does not have one of the axis', () => {\n const axisComponents = globalRuleOverlay.component.axes;\n assert.equal(axisComponents.y.length, 1);\n assert.equal(axisComponents.y[0].get('gridScale'), 'x');\n });\n\n it('correctly merges similar title', () => {\n const axisComponents = globalRuleOverlay.component.axes;\n assert.deepEqual(axisComponents.y[0].get('title'), [{aggregate: 'mean', field: 'a'}]);\n });\n\n it('correctly combines different title', () => {\n const model = parseLayerModel({\n \"$schema\": \"https://vega.github.io/schema/vega-lite/v2.json\",\n \"data\": {\"url\": \"data/cars.json\"},\n \"layer\": [\n {\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"Cylinders\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"max\",\n \"field\": \"Horsepower\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"darkred\"}\n }\n },\n {\n \"data\": {\"url\": \"data/cars.json\"},\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"Cylinders\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"min\",\n \"field\": \"Horsepower\",\n \"type\": \"quantitative\"\n }\n }\n }\n ]\n });\n model.parseScale();\n parseLayerAxis(model);\n const axisComponents = model.component.axes;\n\n assert.deepEqual(\n axisComponents.y[0].get('title'),\n [{aggregate: 'max', field: 'Horsepower'}, {aggregate: 'min', field: 'Horsepower'}]\n );\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/axis/properties.test.d.ts b/build/test/compile/axis/properties.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/axis/properties.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/axis/properties.test.js b/build/test/compile/axis/properties.test.js new file mode 100644 index 0000000000..a30769a24b --- /dev/null +++ b/build/test/compile/axis/properties.test.js @@ -0,0 +1,102 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import * as properties from '../../../src/compile/axis/properties'; +import { parseUnitModelWithScale } from '../../util'; +describe('compile/axis', function () { + describe('grid()', function () { + it('should return true by default for continuous scale that is not binned', function () { + var grid = properties.grid('linear', { field: 'a', type: 'quantitative' }); + assert.deepEqual(grid, true); + }); + it('should return false by default for binned field', function () { + var grid = properties.grid('linear', { bin: true, field: 'a', type: 'quantitative' }); + assert.deepEqual(grid, false); + }); + it('should return false by default for a discrete scale', function () { + var grid = properties.grid('point', { field: 'a', type: 'quantitative' }); + assert.deepEqual(grid, false); + }); + }); + describe('orient()', function () { + it('should return bottom for x by default', function () { + var orient = properties.orient('x'); + assert.deepEqual(orient, 'bottom'); + }); + it('should return left for y by default', function () { + var orient = properties.orient('y'); + assert.deepEqual(orient, 'left'); + }); + }); + describe('tickCount', function () { + it('should return undefined by default for a binned field', function () { + var tickCount = properties.tickCount('x', { bin: { maxbins: 10 }, field: 'a', type: 'quantitative' }, 'linear', { signal: 'a' }); + assert.deepEqual(tickCount, { signal: 'ceil(a/20)' }); + }); + var _loop_1 = function (timeUnit) { + it("should return undefined by default for a temporal field with timeUnit=" + timeUnit, function () { + var tickCount = properties.tickCount('x', { timeUnit: timeUnit, field: 'a', type: 'temporal' }, 'linear', { signal: 'a' }); + assert.isUndefined(tickCount); + }); + }; + for (var _i = 0, _a = ['month', 'hours', 'day', 'quarter']; _i < _a.length; _i++) { + var timeUnit = _a[_i]; + _loop_1(timeUnit); + } + it('should return size/40 by default for linear scale', function () { + var tickCount = properties.tickCount('x', { field: 'a', type: 'quantitative' }, 'linear', { signal: 'a' }); + assert.deepEqual(tickCount, { signal: 'ceil(a/40)' }); + }); + it('should return undefined by default for log scale', function () { + var tickCount = properties.tickCount('x', { field: 'a', type: 'quantitative' }, 'log', undefined); + assert.deepEqual(tickCount, undefined); + }); + it('should return undefined by default for point scale', function () { + var tickCount = properties.tickCount('x', { field: 'a', type: 'quantitative' }, 'point', undefined); + assert.deepEqual(tickCount, undefined); + }); + }); + describe('title()', function () { + it('should add return fieldTitle by default', function () { + var title = properties.title(3, { field: 'a', type: "quantitative" }, {}); + assert.deepEqual(title, 'a'); + }); + it('should add return fieldTitle by default', function () { + var title = properties.title(10, { aggregate: 'sum', field: 'a', type: "quantitative" }, {}); + assert.deepEqual(title, 'Sum of a'); + }); + it('should add return fieldTitle by default and truncate', function () { + var title = properties.title(3, { aggregate: 'sum', field: 'a', type: "quantitative" }, {}); + assert.deepEqual(title, 'Su…'); + }); + }); + describe('values', function () { + it('should return correct timestamp values for DateTimes', function () { + var values = properties.values({ values: [{ year: 1970 }, { year: 1980 }] }, null, { field: 'a', type: 'temporal' }, "x"); + assert.deepEqual(values, [ + { "signal": "datetime(1970, 0, 1, 0, 0, 0, 0)" }, + { "signal": "datetime(1980, 0, 1, 0, 0, 0, 0)" } + ]); + }); + it('should simply return values for non-DateTime', function () { + var values = properties.values({ values: [1, 2, 3, 4] }, null, { field: 'a', type: 'quantitative' }, "x"); + assert.deepEqual(values, [1, 2, 3, 4]); + }); + it('should simply drop values when domain is specified', function () { + var model1 = parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "y": { + "type": "quantitative", + "field": 'US_Gross', + "scale": { "domain": [-1, 2] }, + "bin": { "extent": [0, 1] } + } + }, + "data": { "url": "data/movies.json" } + }); + var values = properties.values({}, model1, model1.fieldDef("y"), "y"); + assert.deepEqual(values, undefined); + }); + }); +}); +//# sourceMappingURL=properties.test.js.map \ No newline at end of file diff --git a/build/test/compile/axis/properties.test.js.map b/build/test/compile/axis/properties.test.js.map new file mode 100644 index 0000000000..96c375c551 --- /dev/null +++ b/build/test/compile/axis/properties.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"properties.test.js","sourceRoot":"","sources":["../../../../test/compile/axis/properties.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,UAAU,MAAM,sCAAsC,CAAC;AAEnE,OAAO,EAAC,uBAAuB,EAAC,MAAM,YAAY,CAAC;AAEnD,QAAQ,CAAC,cAAc,EAAE;IACvB,QAAQ,CAAC,QAAQ,EAAE;QACjB,EAAE,CAAC,uEAAuE,EAAE;YAC1E,IAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,CAAC,CAAC;YAC3E,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE;YACpD,IAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,CAAC,CAAC;YACtF,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE;YACxD,IAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,CAAC,CAAC;YAC1E,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,UAAU,EAAE;QACnB,EAAE,CAAC,uCAAuC,EAAE;YAC1C,IAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACtC,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE;YACxC,IAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACtC,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,EAAE;QACpB,EAAE,CAAC,uDAAuD,EAAE;YAC1D,IAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,EAAC,GAAG,EAAE,EAAC,OAAO,EAAE,EAAE,EAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,EAAE,QAAQ,EAAE,EAAC,MAAM,EAAG,GAAG,EAAC,CAAC,CAAC;YAC9H,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,EAAC,MAAM,EAAE,YAAY,EAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;gCAEQ,QAAQ;YACf,EAAE,CAAC,2EAAyE,QAAU,EAAE;gBACtF,IAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,EAAC,QAAQ,UAAA,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAC,EAAE,QAAQ,EAAE,EAAC,MAAM,EAAG,GAAG,EAAC,CAAC,CAAC;gBAChH,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC;QACP,CAAC;QALD,KAAuB,UAAkD,EAAlD,KAAA,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,CAAe,EAAlD,cAAkD,EAAlD,IAAkD;YAApE,IAAM,QAAQ,SAAA;oBAAR,QAAQ;SAKlB;QAED,EAAE,CAAC,mDAAmD,EAAE;YACtD,IAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,EAAE,QAAQ,EAAE,EAAC,MAAM,EAAG,GAAG,EAAC,CAAC,CAAC;YAC1G,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,EAAC,MAAM,EAAE,YAAY,EAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE;YACrD,IAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;YAClG,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE;YACvD,IAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;YACpG,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE;QAClB,EAAE,CAAC,yCAAyC,EAAE;YAC5C,IAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,EAAE,EAAE,CAAC,CAAC;YAC1E,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE;YAC5C,IAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,EAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,EAAE,EAAE,CAAC,CAAC;YAC7F,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE;YACzD,IAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,EAAE,EAAE,CAAC,CAAC;YAC5F,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE;QACjB,EAAE,CAAC,sDAAsD,EAAE;YACzD,IAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,EAAC,MAAM,EAAE,CAAC,EAAC,IAAI,EAAE,IAAI,EAAC,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,EAAC,EAAE,IAAI,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAC,EAAE,GAAG,CAAC,CAAC;YAEpH,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE;gBACvB,EAAC,QAAQ,EAAE,kCAAkC,EAAC;gBAC9C,EAAC,QAAQ,EAAE,kCAAkC,EAAC;aAC/C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE;YACjD,IAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,EAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAC,EAAE,IAAI,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,EAAE,GAAG,CAAC,CAAC;YAExG,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE;YACvD,IAAM,MAAM,GAAG,uBAAuB,CAAC;gBACrC,MAAM,EAAE,KAAK;gBACb,UAAU,EAAE;oBACV,GAAG,EAAE;wBACH,MAAM,EAAE,cAAc;wBACtB,OAAO,EAAE,UAAU;wBACnB,OAAO,EAAE,EAAC,QAAQ,EAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC;wBAC1B,KAAK,EAAE,EAAC,QAAQ,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC;qBACxB;iBACF;gBACD,MAAM,EAAE,EAAC,KAAK,EAAE,kBAAkB,EAAC;aACpC,CAAC,CAAC;YACH,IAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;YAExE,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport * as properties from '../../../src/compile/axis/properties';\nimport {TimeUnit} from '../../../src/timeunit';\nimport {parseUnitModelWithScale} from '../../util';\n\ndescribe('compile/axis', ()=> {\n describe('grid()', function () {\n it('should return true by default for continuous scale that is not binned', function () {\n const grid = properties.grid('linear', {field: 'a', type: 'quantitative'});\n assert.deepEqual(grid, true);\n });\n\n it('should return false by default for binned field', function () {\n const grid = properties.grid('linear', {bin: true, field: 'a', type: 'quantitative'});\n assert.deepEqual(grid, false);\n });\n\n it('should return false by default for a discrete scale', function () {\n const grid = properties.grid('point', {field: 'a', type: 'quantitative'});\n assert.deepEqual(grid, false);\n });\n });\n\n describe('orient()', function () {\n it('should return bottom for x by default', function () {\n const orient = properties.orient('x');\n assert.deepEqual(orient, 'bottom');\n });\n\n it('should return left for y by default', function () {\n const orient = properties.orient('y');\n assert.deepEqual(orient, 'left');\n });\n });\n\n describe('tickCount', function() {\n it('should return undefined by default for a binned field', () => {\n const tickCount = properties.tickCount('x', {bin: {maxbins: 10}, field: 'a', type: 'quantitative'}, 'linear', {signal : 'a'});\n assert.deepEqual(tickCount, {signal: 'ceil(a/20)'});\n });\n\n for (const timeUnit of ['month', 'hours', 'day', 'quarter'] as TimeUnit[]) {\n it(`should return undefined by default for a temporal field with timeUnit=${timeUnit}`, () => {\n const tickCount = properties.tickCount('x', {timeUnit, field: 'a', type: 'temporal'}, 'linear', {signal : 'a'});\n assert.isUndefined(tickCount);\n });\n }\n\n it('should return size/40 by default for linear scale', () => {\n const tickCount = properties.tickCount('x', {field: 'a', type: 'quantitative'}, 'linear', {signal : 'a'});\n assert.deepEqual(tickCount, {signal: 'ceil(a/40)'});\n });\n\n it('should return undefined by default for log scale', function () {\n const tickCount = properties.tickCount('x', {field: 'a', type: 'quantitative'}, 'log', undefined);\n assert.deepEqual(tickCount, undefined);\n });\n\n it('should return undefined by default for point scale', function () {\n const tickCount = properties.tickCount('x', {field: 'a', type: 'quantitative'}, 'point', undefined);\n assert.deepEqual(tickCount, undefined);\n });\n });\n\n describe('title()', function () {\n it('should add return fieldTitle by default', function () {\n const title = properties.title(3, {field: 'a', type: \"quantitative\"}, {});\n assert.deepEqual(title, 'a');\n });\n\n it('should add return fieldTitle by default', function () {\n const title = properties.title(10, {aggregate: 'sum', field: 'a', type: \"quantitative\"}, {});\n assert.deepEqual(title, 'Sum of a');\n });\n\n it('should add return fieldTitle by default and truncate', function () {\n const title = properties.title(3, {aggregate: 'sum', field: 'a', type: \"quantitative\"}, {});\n assert.deepEqual(title, 'Su…');\n });\n });\n\n describe('values', () => {\n it('should return correct timestamp values for DateTimes', () => {\n const values = properties.values({values: [{year: 1970}, {year: 1980}]}, null, {field: 'a', type: 'temporal'}, \"x\");\n\n assert.deepEqual(values, [\n {\"signal\": \"datetime(1970, 0, 1, 0, 0, 0, 0)\"},\n {\"signal\": \"datetime(1980, 0, 1, 0, 0, 0, 0)\"}\n ]);\n });\n\n it('should simply return values for non-DateTime', () => {\n const values = properties.values({values: [1, 2, 3, 4]}, null, {field: 'a', type: 'quantitative'}, \"x\");\n\n assert.deepEqual(values, [1,2,3,4]);\n });\n\n it('should simply drop values when domain is specified', () => {\n const model1 = parseUnitModelWithScale({\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\n \"type\": \"quantitative\",\n \"field\": 'US_Gross',\n \"scale\": {\"domain\":[-1,2]},\n \"bin\": {\"extent\":[0,1]}\n }\n },\n \"data\": {\"url\": \"data/movies.json\"}\n });\n const values = properties.values({}, model1, model1.fieldDef(\"y\"), \"y\");\n\n assert.deepEqual(values, undefined);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/common.test.d.ts b/build/test/compile/common.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/common.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/common.test.js b/build/test/compile/common.test.js new file mode 100644 index 0000000000..a9890c2044 --- /dev/null +++ b/build/test/compile/common.test.js @@ -0,0 +1,61 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { numberFormat, timeFormatExpression } from '../../src/compile/common'; +import { defaultConfig } from '../../src/config'; +import { vgField } from '../../src/fielddef'; +import { TimeUnit } from '../../src/timeunit'; +import { NOMINAL, ORDINAL, QUANTITATIVE, TEMPORAL } from '../../src/type'; +describe('Common', function () { + describe('timeFormat()', function () { + it('should get the right time expression for month with shortTimeLabels=true', function () { + var fieldDef = { timeUnit: TimeUnit.MONTH, field: 'a', type: TEMPORAL }; + var expression = timeFormatExpression(vgField(fieldDef, { expr: 'datum' }), TimeUnit.MONTH, undefined, true, defaultConfig.timeFormat, false); + assert.equal(expression, "timeFormat(datum[\"month_a\"], '%b')"); + }); + it('should get the right time expression for month with shortTimeLabels=false', function () { + var fieldDef = { timeUnit: TimeUnit.MONTH, field: 'a', type: TEMPORAL }; + var expression = timeFormatExpression(vgField(fieldDef, { expr: 'datum' }), TimeUnit.MONTH, undefined, false, defaultConfig.timeFormat, false); + assert.equal(expression, "timeFormat(datum[\"month_a\"], '%B')"); + }); + it('should get the right time expression for yearmonth with custom format', function () { + var fieldDef = { timeUnit: TimeUnit.YEARMONTH, field: 'a', type: TEMPORAL }; + var expression = timeFormatExpression(vgField(fieldDef, { expr: 'datum' }), TimeUnit.MONTH, '%Y', true, defaultConfig.timeFormat, false); + assert.equal(expression, "timeFormat(datum[\"yearmonth_a\"], '%Y')"); + }); + it('should get the right time expression for quarter', function () { + var fieldDef = { timeUnit: TimeUnit.QUARTER, field: 'a', type: TEMPORAL }; + var expression = timeFormatExpression(vgField(fieldDef, { expr: 'datum' }), TimeUnit.QUARTER, undefined, true, defaultConfig.timeFormat, false); + assert.equal(expression, "'Q' + quarter(datum[\"quarter_a\"])"); + }); + it('should get the right time expression for yearquarter', function () { + var expression = timeFormatExpression('datum["data"]', TimeUnit.YEARQUARTER, undefined, true, defaultConfig.timeFormat, false); + assert.equal(expression, "'Q' + quarter(datum[\"data\"]) + ' ' + timeFormat(datum[\"data\"], '%y')"); + }); + it('should get the right time expression for yearmonth with custom format and utc scale type', function () { + var fieldDef = { timeUnit: TimeUnit.YEARMONTH, field: 'a', type: TEMPORAL }; + var expression = timeFormatExpression(vgField(fieldDef, { expr: 'datum' }), TimeUnit.MONTH, '%Y', true, defaultConfig.timeFormat, true); + assert.equal(expression, "utcFormat(datum[\"yearmonth_a\"], '%Y')"); + }); + }); + describe('numberFormat()', function () { + it('should use number format for quantitative scale', function () { + assert.equal(numberFormat({ field: 'a', type: QUANTITATIVE }, undefined, { numberFormat: 'd' }), 'd'); + }); + it('should support empty number format', function () { + assert.equal(numberFormat({ field: 'a', type: QUANTITATIVE }, undefined, { numberFormat: '' }), ''); + }); + it('should use format if provided', function () { + assert.equal(numberFormat({ field: 'a', type: QUANTITATIVE }, 'a', {}), 'a'); + }); + it('should not use number format for binned quantitative scale', function () { + assert.equal(numberFormat({ bin: true, field: 'a', type: QUANTITATIVE }, undefined, {}), undefined); + }); + it('should not use number format for non-quantitative scale', function () { + for (var _i = 0, _a = [TEMPORAL, NOMINAL, ORDINAL]; _i < _a.length; _i++) { + var type = _a[_i]; + assert.equal(numberFormat({ bin: true, field: 'a', type: type }, undefined, {}), undefined); + } + }); + }); +}); +//# sourceMappingURL=common.test.js.map \ No newline at end of file diff --git a/build/test/compile/common.test.js.map b/build/test/compile/common.test.js.map new file mode 100644 index 0000000000..54057e24fd --- /dev/null +++ b/build/test/compile/common.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"common.test.js","sourceRoot":"","sources":["../../../test/compile/common.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {numberFormat, timeFormatExpression} from '../../src/compile/common';\nimport {defaultConfig} from '../../src/config';\nimport {vgField} from '../../src/fielddef';\nimport {TimeUnit} from '../../src/timeunit';\nimport {NOMINAL, ORDINAL, QUANTITATIVE, TEMPORAL} from '../../src/type';\n\ndescribe('Common', function() {\n describe('timeFormat()', function() {\n it('should get the right time expression for month with shortTimeLabels=true', function() {\n const fieldDef = {timeUnit: TimeUnit.MONTH, field: 'a', type: TEMPORAL};\n const expression = timeFormatExpression(vgField(fieldDef, {expr: 'datum'}), TimeUnit.MONTH, undefined, true, defaultConfig.timeFormat, false);\n assert.equal(expression, `timeFormat(datum[\"month_a\"], '%b')`);\n });\n\n it('should get the right time expression for month with shortTimeLabels=false', function() {\n const fieldDef = {timeUnit: TimeUnit.MONTH, field: 'a', type: TEMPORAL};\n const expression = timeFormatExpression(vgField(fieldDef, {expr: 'datum'}), TimeUnit.MONTH, undefined, false, defaultConfig.timeFormat, false);\n assert.equal(expression, `timeFormat(datum[\"month_a\"], '%B')`);\n });\n\n it('should get the right time expression for yearmonth with custom format', function() {\n const fieldDef = {timeUnit: TimeUnit.YEARMONTH, field: 'a', type: TEMPORAL};\n const expression = timeFormatExpression(vgField(fieldDef, {expr: 'datum'}), TimeUnit.MONTH, '%Y', true, defaultConfig.timeFormat, false);\n assert.equal(expression, `timeFormat(datum[\"yearmonth_a\"], '%Y')`);\n });\n\n it('should get the right time expression for quarter', function() {\n const fieldDef = {timeUnit: TimeUnit.QUARTER, field: 'a', type: TEMPORAL};\n const expression = timeFormatExpression(vgField(fieldDef, {expr: 'datum'}), TimeUnit.QUARTER, undefined, true, defaultConfig.timeFormat, false);\n assert.equal(expression, `'Q' + quarter(datum[\"quarter_a\"])`);\n });\n\n it('should get the right time expression for yearquarter', function() {\n const expression = timeFormatExpression('datum[\"data\"]', TimeUnit.YEARQUARTER, undefined, true, defaultConfig.timeFormat, false);\n assert.equal(expression, `'Q' + quarter(datum[\"data\"]) + ' ' + timeFormat(datum[\"data\"], '%y')`);\n });\n\n it('should get the right time expression for yearmonth with custom format and utc scale type', function() {\n const fieldDef = {timeUnit: TimeUnit.YEARMONTH, field: 'a', type: TEMPORAL};\n const expression = timeFormatExpression(vgField(fieldDef, {expr: 'datum'}), TimeUnit.MONTH, '%Y', true, defaultConfig.timeFormat, true);\n assert.equal(expression, `utcFormat(datum[\"yearmonth_a\"], '%Y')`);\n });\n });\n\n describe('numberFormat()', function() {\n it('should use number format for quantitative scale', function() {\n assert.equal(numberFormat({field: 'a', type: QUANTITATIVE}, undefined, {numberFormat: 'd'}), 'd');\n });\n\n it('should support empty number format', function() {\n assert.equal(numberFormat({field: 'a', type: QUANTITATIVE}, undefined, {numberFormat: ''}), '');\n });\n\n it('should use format if provided', function() {\n assert.equal(numberFormat({field: 'a', type: QUANTITATIVE}, 'a', {}), 'a');\n });\n\n it('should not use number format for binned quantitative scale', function() {\n assert.equal(numberFormat({bin: true, field: 'a', type: QUANTITATIVE}, undefined, {}), undefined);\n });\n\n it('should not use number format for non-quantitative scale', function() {\n for (const type of [TEMPORAL, NOMINAL, ORDINAL]) {\n assert.equal(numberFormat({bin: true, field: 'a', type: type}, undefined, {}), undefined);\n }\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/compile.test.d.ts b/build/test/compile/compile.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/compile.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/compile.test.js b/build/test/compile/compile.test.js new file mode 100644 index 0000000000..21eb7f4954 --- /dev/null +++ b/build/test/compile/compile.test.js @@ -0,0 +1,263 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import * as log from '../../src/log'; +import { compile } from '../../src/compile/compile'; +describe('compile/compile', function () { + it('should throw error for invalid spec', function () { + assert.throws(function () { + compile({}); + }, Error, log.message.INVALID_SPEC); + }); + it('should return a spec with default top-level properties, size signals, data, marks, and title', function () { + var spec = compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "title": { "text": "test" }, + "mark": "point", + "encoding": {} + }).spec; + assert.equal(spec.padding, 5); + assert.equal(spec.autosize, 'pad'); + assert.equal(spec.width, 21); + assert.equal(spec.height, 21); + assert.deepEqual(spec.title, { text: 'test' }); + assert.equal(spec.data.length, 1); // just source + assert.equal(spec.marks.length, 1); // just the root group + }); + it('should return a spec with specified top-level properties, size signals, data and marks', function () { + var spec = compile({ + "padding": 123, + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "mark": "point", + "encoding": {} + }).spec; + assert.equal(spec.padding, 123); + assert.equal(spec.autosize, 'pad'); + assert.equal(spec.width, 21); + assert.equal(spec.height, 21); + assert.equal(spec.data.length, 1); // just source. + assert.equal(spec.marks.length, 1); // just the root group + }); + it('should use size signal for bar chart width', function () { + var spec = compile({ + "data": { "values": [{ "a": "A", "b": 28 }] }, + "mark": "bar", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" } + } + }).spec; + assert.deepEqual(spec.signals, [{ + name: 'x_step', + value: 21 + }, { + name: 'width', + update: "bandspace(domain('x').length, 0.1, 0.05) * x_step" + }]); + assert.equal(spec.height, 200); + }); + it('should set resize to true if requested', function () { + var spec = compile({ + "autosize": { + "resize": true + }, + "data": { "url": "foo.csv" }, + "mark": "point", + "encoding": {} + }).spec; + assert(spec.autosize.resize); + }); + it('should set autosize to fit and containment if requested', function () { + var spec = compile({ + "autosize": { + "type": "fit", + "contains": "content" + }, + "data": { "url": "foo.csv" }, + "mark": "point", + "encoding": {} + }).spec; + assert.deepEqual(spec.autosize, { type: 'fit', contains: 'content' }); + }); + it('should set autosize to fit if requested', function () { + var spec = compile({ + "autosize": "fit", + "data": { "url": "foo.csv" }, + "mark": "point", + "encoding": {} + }).spec; + assert.equal(spec.autosize, "fit"); + }); + it('warn if size is data driven and autosize is fit', log.wrap(function (localLogger) { + var spec = compile({ + "data": { "values": [{ "a": "A", "b": 28 }] }, + "mark": "bar", + "autosize": "fit", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" } + } + }).spec; + assert.equal(localLogger.warns[0], log.message.CANNOT_FIX_RANGE_STEP_WITH_FIT); + assert.equal(spec.width, 200); + assert.equal(spec.height, 200); + })); + it('warn if trying to fit composed spec', log.wrap(function (localLogger) { + var spec = compile({ + "data": { "values": [{ "a": "A", "b": 28 }] }, + "autosize": "fit", + "vconcat": [{ + "mark": "point", + "encoding": {} + }] + }).spec; + assert.equal(localLogger.warns[0], log.message.FIT_NON_SINGLE); + assert.equal(spec.autosize, 'pad'); + })); + it('should return title for a layered spec.', function () { + var spec = compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "title": { "text": "test" }, + "layer": [{ + "mark": "point", + "encoding": {} + }] + }).spec; + assert.deepEqual(spec.title, { text: 'test' }); + }); + it('should return title (string) for a layered spec.', function () { + var spec = compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "title": "test", + "layer": [{ + "mark": "point", + "encoding": {} + }] + }).spec; + assert.deepEqual(spec.title, { text: 'test' }); + }); + it('should return title from a child of a layer spec if parent has no title.', function () { + var spec = compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "layer": [{ + "title": { "text": "test" }, + "mark": "point", + "encoding": {} + }] + }).spec; + assert.deepEqual(spec.title, { text: 'test' }); + }); + it('should return a title for a concat spec, throw warning if anchor is set to other values than "start" and automatically set anchor to "start".', log.wrap(function (localLogger) { + var spec = compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "title": { "text": "test" }, + "hconcat": [{ + "mark": "point", + "encoding": {} + }], + "config": { "title": { "anchor": "middle" } } + }).spec; + assert.deepEqual(spec.title, { + text: 'test', + anchor: 'start' // We only support anchor as start for concat + }); + assert.equal(localLogger.warns[0], log.message.cannotSetTitleAnchor('concat')); + })); + it('should return a title for a concat spec, automatically set anchor to "start", and augment the title with non-mark title config (e.g., offset).', function () { + var spec = compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "title": { "text": "test" }, + "hconcat": [{ + "mark": "point", + "encoding": {} + }], + "config": { "title": { "offset": 5 } } + }).spec; + assert.deepEqual(spec.title, { + text: 'test', + anchor: 'start', + offset: 5 + }); + }); + it('should not have title if there is no title.', function () { + var spec = compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "hconcat": [{ + "mark": "point", + "encoding": {} + }], + "config": { "title": { "offset": 5 } } + }).spec; + assert.isUndefined(spec.title); + }); + it('should use provided config.', function () { + var spec = compile({ + mark: "point", + data: { url: "foo.csv" }, + encoding: {} + }, { config: { + background: "blue" + } }).spec; + assert.equal(spec.config.background, "blue"); + }); + it('should merge spec and provided config.', function () { + var spec = compile({ + mark: "point", + data: { url: "foo.csv" }, + encoding: {}, + config: { + background: "red" + } + }, { config: { + background: "blue" + } }).spec; + assert.equal(spec.config.background, "red"); + }); + it('should return a spec with projections (implicit)', function () { + var spec = compile({ + "mark": "geoshape", + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {} + }).spec; + assert.isDefined(spec.projections); + }); + it('should return a spec with projections (explicit)', function () { + var spec = compile({ + "mark": "geoshape", + "projection": { + "type": "albersUsa" + }, + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {} + }).spec; + assert.isDefined(spec.projections); + }); +}); +//# sourceMappingURL=compile.test.js.map \ No newline at end of file diff --git a/build/test/compile/compile.test.js.map b/build/test/compile/compile.test.js.map new file mode 100644 index 0000000000..0e659dd3e1 --- /dev/null +++ b/build/test/compile/compile.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"compile.test.js","sourceRoot":"","sources":["../../../test/compile/compile.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\n\nimport * as log from '../../src/log';\n\nimport {compile} from '../../src/compile/compile';\n\n\ndescribe('compile/compile', function() {\n it('should throw error for invalid spec', () => {\n assert.throws(() => {\n compile({} as any);\n }, Error, log.message.INVALID_SPEC);\n });\n\n it('should return a spec with default top-level properties, size signals, data, marks, and title', () => {\n const spec = compile({\n \"data\": {\n \"values\": [{\"a\": \"A\",\"b\": 28}]\n },\n \"title\": {\"text\": \"test\"},\n \"mark\": \"point\",\n \"encoding\": {}\n }).spec;\n\n assert.equal(spec.padding, 5);\n assert.equal(spec.autosize, 'pad');\n assert.equal(spec.width, 21);\n assert.equal(spec.height, 21);\n assert.deepEqual(spec.title, {text: 'test'});\n\n assert.equal(spec.data.length, 1); // just source\n assert.equal(spec.marks.length, 1); // just the root group\n });\n\n it('should return a spec with specified top-level properties, size signals, data and marks', () => {\n const spec = compile({\n \"padding\": 123,\n \"data\": {\n \"values\": [{\"a\": \"A\",\"b\": 28}]\n },\n \"mark\": \"point\",\n \"encoding\": {}\n }).spec;\n\n assert.equal(spec.padding, 123);\n assert.equal(spec.autosize, 'pad');\n assert.equal(spec.width, 21);\n assert.equal(spec.height, 21);\n\n assert.equal(spec.data.length, 1); // just source.\n assert.equal(spec.marks.length, 1); // just the root group\n });\n\n it('should use size signal for bar chart width', () => {\n const spec = compile({\n \"data\": {\"values\": [{\"a\": \"A\",\"b\": 28}]},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"b\", \"type\": \"quantitative\"}\n }\n }).spec;\n\n assert.deepEqual(spec.signals, [{\n name: 'x_step',\n value: 21\n }, {\n name: 'width',\n update: `bandspace(domain('x').length, 0.1, 0.05) * x_step`\n }]);\n assert.equal(spec.height, 200);\n });\n\n it('should set resize to true if requested', () => {\n const spec = compile({\n \"autosize\": {\n \"resize\": true\n },\n \"data\": {\"url\": \"foo.csv\"},\n \"mark\": \"point\",\n \"encoding\": {}\n }).spec;\n\n assert(spec.autosize.resize);\n });\n\n it('should set autosize to fit and containment if requested', () => {\n const spec = compile({\n \"autosize\": {\n \"type\": \"fit\",\n \"contains\": \"content\"\n },\n \"data\": {\"url\": \"foo.csv\"},\n \"mark\": \"point\",\n \"encoding\": {}\n }).spec;\n\n assert.deepEqual(spec.autosize, {type: 'fit', contains: 'content'});\n });\n\n it('should set autosize to fit if requested', () => {\n const spec = compile({\n \"autosize\": \"fit\",\n \"data\": {\"url\": \"foo.csv\"},\n \"mark\": \"point\",\n \"encoding\": {}\n }).spec;\n\n assert.equal(spec.autosize, \"fit\");\n });\n\n it('warn if size is data driven and autosize is fit', log.wrap((localLogger) => {\n const spec = compile({\n \"data\": {\"values\": [{\"a\": \"A\",\"b\": 28}]},\n \"mark\": \"bar\",\n \"autosize\": \"fit\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"b\", \"type\": \"quantitative\"}\n }\n }).spec;\n assert.equal(localLogger.warns[0], log.message.CANNOT_FIX_RANGE_STEP_WITH_FIT);\n assert.equal(spec.width, 200);\n assert.equal(spec.height, 200);\n }));\n\n it('warn if trying to fit composed spec', log.wrap((localLogger) => {\n const spec = compile({\n \"data\": {\"values\": [{\"a\": \"A\",\"b\": 28}]},\n \"autosize\": \"fit\",\n \"vconcat\": [{\n \"mark\": \"point\",\n \"encoding\": {}\n }]\n }).spec;\n assert.equal(localLogger.warns[0], log.message.FIT_NON_SINGLE);\n assert.equal(spec.autosize, 'pad');\n }));\n\n it('should return title for a layered spec.', () => {\n const spec = compile({\n \"data\": {\n \"values\": [{\"a\": \"A\",\"b\": 28}]\n },\n \"title\": {\"text\": \"test\"},\n \"layer\": [{\n \"mark\": \"point\",\n \"encoding\": {}\n }]\n }).spec;\n assert.deepEqual(spec.title, {text: 'test'});\n });\n\n it('should return title (string) for a layered spec.', () => {\n const spec = compile({\n \"data\": {\n \"values\": [{\"a\": \"A\",\"b\": 28}]\n },\n \"title\": \"test\",\n \"layer\": [{\n \"mark\": \"point\",\n \"encoding\": {}\n }]\n }).spec;\n assert.deepEqual(spec.title, {text: 'test'});\n });\n\n it('should return title from a child of a layer spec if parent has no title.', () => {\n const spec = compile({\n \"data\": {\n \"values\": [{\"a\": \"A\",\"b\": 28}]\n },\n \"layer\": [{\n \"title\": {\"text\": \"test\"},\n \"mark\": \"point\",\n \"encoding\": {}\n }]\n }).spec;\n assert.deepEqual(spec.title, {text: 'test'});\n });\n\n it('should return a title for a concat spec, throw warning if anchor is set to other values than \"start\" and automatically set anchor to \"start\".', log.wrap((localLogger) => {\n const spec = compile({\n \"data\": {\n \"values\": [{\"a\": \"A\",\"b\": 28}]\n },\n \"title\": {\"text\": \"test\"},\n \"hconcat\": [{\n \"mark\": \"point\",\n \"encoding\": {}\n }],\n \"config\": {\"title\": {\"anchor\": \"middle\"}}\n }).spec;\n assert.deepEqual(spec.title, {\n text: 'test',\n anchor: 'start' // We only support anchor as start for concat\n });\n assert.equal(localLogger.warns[0], log.message.cannotSetTitleAnchor('concat'));\n }));\n\n it('should return a title for a concat spec, automatically set anchor to \"start\", and augment the title with non-mark title config (e.g., offset).', () => {\n const spec = compile({\n \"data\": {\n \"values\": [{\"a\": \"A\",\"b\": 28}]\n },\n \"title\": {\"text\": \"test\"},\n \"hconcat\": [{\n \"mark\": \"point\",\n \"encoding\": {}\n }],\n \"config\": {\"title\": {\"offset\": 5}}\n }).spec;\n assert.deepEqual(spec.title, {\n text: 'test',\n anchor: 'start',\n offset: 5\n });\n });\n\n it('should not have title if there is no title.', () => {\n const spec = compile({\n \"data\": {\n \"values\": [{\"a\": \"A\",\"b\": 28}]\n },\n \"hconcat\": [{\n \"mark\": \"point\",\n \"encoding\": {}\n }],\n \"config\": {\"title\": {\"offset\": 5}}\n }).spec;\n assert.isUndefined(spec.title);\n });\n\n it('should use provided config.', () => {\n const spec = compile({\n mark: \"point\",\n data: {url: \"foo.csv\"},\n encoding: {}\n }, {config: {\n background: \"blue\"\n }}).spec;\n assert.equal(spec.config.background, \"blue\");\n });\n\n it('should merge spec and provided config.', () => {\n const spec = compile({\n mark: \"point\",\n data: {url: \"foo.csv\"},\n encoding: {},\n config: {\n background: \"red\"\n }\n }, {config: {\n background: \"blue\"\n }}).spec;\n assert.equal(spec.config.background, \"red\");\n });\n\n it('should return a spec with projections (implicit)', () => {\n const spec = compile({\n \"mark\": \"geoshape\",\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {}\n }).spec;\n assert.isDefined(spec.projections);\n });\n\n it('should return a spec with projections (explicit)', () => {\n const spec = compile({\n \"mark\": \"geoshape\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {}\n }).spec;\n assert.isDefined(spec.projections);\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/concat.test.d.ts b/build/test/compile/concat.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/concat.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/concat.test.js b/build/test/compile/concat.test.js new file mode 100644 index 0000000000..5ae6c47e8e --- /dev/null +++ b/build/test/compile/concat.test.js @@ -0,0 +1,90 @@ +import { assert } from 'chai'; +import * as log from '../../src/log'; +import { parseConcatModel } from '../util'; +describe('Concat', function () { + describe('merge scale domains', function () { + it('should instantiate all children in vconcat', function () { + var model = parseConcatModel({ + vconcat: [{ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }, { + mark: 'bar', + encoding: { + x: { field: 'b', type: 'ordinal' }, + y: { field: 'c', type: 'quantitative' } + } + }] + }); + assert.equal(model.children.length, 2); + assert(model.isVConcat); + }); + it('should instantiate all children in hconcat', function () { + var model = parseConcatModel({ + hconcat: [{ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }, { + mark: 'bar', + encoding: { + x: { field: 'b', type: 'ordinal' }, + y: { field: 'c', type: 'quantitative' } + } + }] + }); + assert.equal(model.children.length, 2); + assert(!model.isVConcat); + }); + it('should create correct layout for vconcat', function () { + var model = parseConcatModel({ + vconcat: [{ + mark: 'point', + encoding: {} + }, { + mark: 'bar', + encoding: {} + }] + }); + assert.deepEqual(model.assembleLayout(), { + padding: { row: 10, column: 10 }, + columns: 1, + bounds: 'full', + align: 'each' + }); + }); + it('should create correct layout for hconcat', function () { + var model = parseConcatModel({ + hconcat: [{ + mark: 'point', + encoding: {} + }, { + mark: 'bar', + encoding: {} + }] + }); + assert.deepEqual(model.assembleLayout(), { + padding: { row: 10, column: 10 }, + bounds: 'full', + align: 'each' + }); + }); + }); + describe('resolve', function () { + it('cannot share axes', log.wrap(function (localLogger) { + parseConcatModel({ + hconcat: [], + resolve: { + axis: { + x: 'shared' + } + } + }); + assert.equal(localLogger.warns[0], log.message.CONCAT_CANNOT_SHARE_AXIS); + })); + }); +}); +//# sourceMappingURL=concat.test.js.map \ No newline at end of file diff --git a/build/test/compile/concat.test.js.map b/build/test/compile/concat.test.js.map new file mode 100644 index 0000000000..0039809ed4 --- /dev/null +++ b/build/test/compile/concat.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"concat.test.js","sourceRoot":"","sources":["../../../test/compile/concat.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport * as log from '../../src/log';\nimport {VgLayout} from '../../src/vega.schema';\nimport {parseConcatModel} from '../util';\n\ndescribe('Concat', () => {\n describe('merge scale domains', () => {\n it('should instantiate all children in vconcat', () => {\n const model = parseConcatModel({\n vconcat: [{\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal'}\n }\n },{\n mark: 'bar',\n encoding: {\n x: {field: 'b', type: 'ordinal'},\n y: {field: 'c', type: 'quantitative'}\n }\n }]\n });\n\n assert.equal(model.children.length, 2);\n assert(model.isVConcat);\n });\n\n it('should instantiate all children in hconcat', () => {\n const model = parseConcatModel({\n hconcat: [{\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal'}\n }\n },{\n mark: 'bar',\n encoding: {\n x: {field: 'b', type: 'ordinal'},\n y: {field: 'c', type: 'quantitative'}\n }\n }]\n });\n\n assert.equal(model.children.length, 2);\n assert(!model.isVConcat);\n });\n\n it('should create correct layout for vconcat', () => {\n const model = parseConcatModel({\n vconcat: [{\n mark: 'point',\n encoding: {\n }\n },{\n mark: 'bar',\n encoding: {\n }\n }]\n });\n\n assert.deepEqual(model.assembleLayout(), {\n padding: {row: 10, column: 10},\n columns: 1,\n bounds: 'full',\n align: 'each'\n });\n });\n\n it('should create correct layout for hconcat', () => {\n const model = parseConcatModel({\n hconcat: [{\n mark: 'point',\n encoding: {\n }\n },{\n mark: 'bar',\n encoding: {\n }\n }]\n });\n\n assert.deepEqual(model.assembleLayout(), {\n padding: {row: 10, column: 10},\n bounds: 'full',\n align: 'each'\n });\n });\n });\n\n describe('resolve', () => {\n it('cannot share axes', log.wrap((localLogger) => {\n parseConcatModel({\n hconcat: [],\n resolve: {\n axis: {\n x: 'shared'\n }\n }\n });\n assert.equal(localLogger.warns[0], log.message.CONCAT_CANNOT_SHARE_AXIS);\n }));\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/aggregate.test.d.ts b/build/test/compile/data/aggregate.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/aggregate.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/aggregate.test.js b/build/test/compile/data/aggregate.test.js new file mode 100644 index 0000000000..880587b6ab --- /dev/null +++ b/build/test/compile/data/aggregate.test.js @@ -0,0 +1,169 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { AggregateNode } from '../../../src/compile/data/aggregate'; +import { parseUnitModel } from '../../util'; +describe('compile/data/summary', function () { + describe('clone', function () { + it('should have correct type', function () { + var agg = new AggregateNode(null, {}, {}); + assert(agg instanceof AggregateNode); + var clone = agg.clone(); + assert(clone instanceof AggregateNode); + }); + it('should have make a deep copy', function () { + var agg = new AggregateNode(null, { foo: true }, {}); + var clone = agg.clone(); + clone.addDimensions(['bar']); + assert.deepEqual(clone.dependentFields(), { 'foo': true, 'bar': true }); + assert.deepEqual(agg.dependentFields(), { 'foo': true }); + }); + }); + describe('parseUnit', function () { + it('should produce the correct summary component for sum(Acceleration) and count(*)', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + 'y': { + 'aggregate': 'sum', + 'field': 'Acceleration', + 'type': "quantitative" + }, + 'x': { + 'field': 'Origin', + 'type': "ordinal" + }, + color: { type: "quantitative", aggregate: 'count' } + } + }); + var agg = AggregateNode.makeFromEncoding(null, model); + assert.deepEqual(agg.assemble(), { + type: 'aggregate', + groupby: ['Origin'], + ops: ['sum', 'count'], + fields: ['Acceleration', '*'], + as: [ + "sum_Acceleration", + "count_*" + ] + }); + }); + it('should produce the correct summary component for aggregated plot with detail arrays', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + 'x': { 'aggregate': 'mean', 'field': 'Displacement', 'type': "quantitative" }, + 'detail': [ + { 'field': 'Origin', 'type': "ordinal" }, + { 'field': 'Cylinders', 'type': "quantitative" } + ] + } + }); + var agg = AggregateNode.makeFromEncoding(null, model); + assert.deepEqual(agg.assemble(), { + type: 'aggregate', + groupby: ['Origin', 'Cylinders'], + ops: ['mean'], + fields: ['Displacement'], + as: ['mean_Displacement'] + }); + }); + it('should include conditional field in the summary component', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + 'x': { 'aggregate': 'mean', 'field': 'Displacement', 'type': "quantitative" }, + color: { + condition: { selection: 'a', field: 'Origin', 'type': "ordinal" }, + value: 'red' + } + } + }); + var agg = AggregateNode.makeFromEncoding(null, model); + assert.deepEqual(agg.assemble(), { + type: 'aggregate', + groupby: ['Origin'], + ops: ['mean'], + fields: ['Displacement'], + as: ['mean_Displacement'] + }); + }); + it('should add min and max if needed for unaggregated scale domain', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + 'x': { 'aggregate': 'mean', 'field': 'Displacement', 'type': "quantitative", scale: { domain: 'unaggregated' } }, + } + }); + var agg = AggregateNode.makeFromEncoding(null, model); + assert.deepEqual(agg.assemble(), { + type: 'aggregate', + groupby: [], + ops: ['mean', 'min', 'max'], + fields: ['Displacement', 'Displacement', 'Displacement'], + as: [ + "mean_Displacement", + "min_Displacement", + "max_Displacement" + ] + }); + }); + it('should add correct dimensions when binning', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + 'x': { 'bin': true, 'field': 'Displacement', 'type': "quantitative" }, + 'y': { 'bin': true, 'field': 'Acceleration', 'type': "ordinal" }, + 'color': { 'aggregate': 'count', 'type': "quantitative" } + } + }); + var agg = AggregateNode.makeFromEncoding(null, model); + assert.deepEqual(agg.assemble(), { + type: 'aggregate', + groupby: [ + 'bin_maxbins_10_Displacement', + 'bin_maxbins_10_Displacement_end', + 'bin_maxbins_10_Acceleration', + 'bin_maxbins_10_Acceleration_end', + 'bin_maxbins_10_Acceleration_range' + ], + ops: ['count'], + fields: ['*'], + as: ['count_*'] + }); + }); + it('should produce the correct summary component from transform array', function () { + var t = { + aggregate: [ + { op: 'mean', field: 'Displacement', as: 'Displacement_mean' }, + { op: 'sum', field: 'Acceleration', as: 'Acceleration_sum' } + ], + groupby: ['Displacement_mean', 'Acceleration_sum'] + }; + var agg = AggregateNode.makeFromTransform(null, t); + assert.deepEqual(agg.assemble(), { + type: 'aggregate', + groupby: ['Displacement_mean', 'Acceleration_sum'], + ops: ['mean', 'sum'], + fields: ['Displacement', 'Acceleration'], + as: ['Displacement_mean', 'Acceleration_sum'] + }); + }); + it('should produce the correct summary component from transform array with different aggregrations for the same field', function () { + var t = { aggregate: [ + { op: 'mean', field: 'Displacement', as: 'Displacement_mean' }, + { op: 'max', field: 'Displacement', as: 'Displacement_max' }, + { op: 'sum', field: 'Acceleration', as: 'Acceleration_sum' } + ], + groupby: ['Displacement_mean', 'Acceleration_sum'] }; + var agg = AggregateNode.makeFromTransform(null, t); + assert.deepEqual(agg.assemble(), { + type: 'aggregate', + groupby: ['Displacement_mean', 'Acceleration_sum'], + ops: ['mean', 'max', 'sum'], + fields: ['Displacement', 'Displacement', 'Acceleration'], + as: ['Displacement_mean', 'Displacement_max', 'Acceleration_sum'] + }); + }); + }); +}); +//# sourceMappingURL=aggregate.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/aggregate.test.js.map b/build/test/compile/data/aggregate.test.js.map new file mode 100644 index 0000000000..0029d0d5d2 --- /dev/null +++ b/build/test/compile/data/aggregate.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"aggregate.test.js","sourceRoot":"","sources":["../../../../test/compile/data/aggregate.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\n\nimport {AggregateNode} from '../../../src/compile/data/aggregate';\nimport {AggregateTransform} from '../../../src/transform';\nimport {StringSet} from '../../../src/util';\nimport {VgAggregateTransform} from '../../../src/vega.schema';\nimport {parseUnitModel} from '../../util';\n\ndescribe('compile/data/summary', function () {\n describe('clone', function() {\n it('should have correct type', function() {\n const agg = new AggregateNode(null, {}, {});\n assert(agg instanceof AggregateNode);\n const clone = agg.clone();\n assert(clone instanceof AggregateNode);\n });\n\n it('should have make a deep copy', function() {\n const agg = new AggregateNode(null, {foo: true}, {});\n const clone = agg.clone();\n clone.addDimensions(['bar']);\n assert.deepEqual(clone.dependentFields(), {'foo': true, 'bar': true});\n assert.deepEqual(agg.dependentFields(), {'foo': true});\n });\n });\n\n describe('parseUnit', function() {\n it('should produce the correct summary component for sum(Acceleration) and count(*)' , () => {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n 'y': {\n 'aggregate': 'sum',\n 'field': 'Acceleration',\n 'type': \"quantitative\"\n },\n 'x': {\n 'field': 'Origin',\n 'type': \"ordinal\"\n },\n color: {type: \"quantitative\", aggregate: 'count'}\n }\n });\n\n const agg = AggregateNode.makeFromEncoding(null, model);\n assert.deepEqual(agg.assemble(), {\n type: 'aggregate',\n groupby: ['Origin'],\n ops: ['sum', 'count'],\n fields: ['Acceleration', '*'],\n as: [\n \"sum_Acceleration\",\n \"count_*\"\n ]\n });\n });\n\n it('should produce the correct summary component for aggregated plot with detail arrays', function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n 'x': {'aggregate': 'mean', 'field': 'Displacement', 'type': \"quantitative\"},\n 'detail': [\n {'field': 'Origin', 'type': \"ordinal\"},\n {'field': 'Cylinders', 'type': \"quantitative\"}\n ]\n }\n });\n\n const agg = AggregateNode.makeFromEncoding(null, model);\n assert.deepEqual(agg.assemble(), {\n type: 'aggregate',\n groupby: ['Origin', 'Cylinders'],\n ops: ['mean'],\n fields: ['Displacement'],\n as: ['mean_Displacement']\n });\n });\n\n it('should include conditional field in the summary component', function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n 'x': {'aggregate': 'mean', 'field': 'Displacement', 'type': \"quantitative\"},\n color: {\n condition: {selection: 'a', field: 'Origin', 'type': \"ordinal\"},\n value: 'red'\n }\n }\n });\n\n const agg = AggregateNode.makeFromEncoding(null, model);\n assert.deepEqual(agg.assemble(), {\n type: 'aggregate',\n groupby: ['Origin'],\n ops: ['mean'],\n fields: ['Displacement'],\n as: ['mean_Displacement']\n });\n });\n\n it('should add min and max if needed for unaggregated scale domain', function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n 'x': {'aggregate': 'mean', 'field': 'Displacement', 'type': \"quantitative\", scale: {domain: 'unaggregated'}},\n }\n });\n\n const agg = AggregateNode.makeFromEncoding(null, model);\n assert.deepEqual(agg.assemble(), {\n type: 'aggregate',\n groupby: [],\n ops: ['mean', 'min', 'max'],\n fields: ['Displacement', 'Displacement', 'Displacement'],\n as: [\n \"mean_Displacement\",\n \"min_Displacement\",\n \"max_Displacement\"\n ]\n });\n });\n\n it('should add correct dimensions when binning', function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n 'x': {'bin': true, 'field': 'Displacement', 'type': \"quantitative\"},\n 'y': {'bin': true, 'field': 'Acceleration', 'type': \"ordinal\"},\n 'color': {'aggregate': 'count', 'type': \"quantitative\"}\n }\n });\n\n const agg = AggregateNode.makeFromEncoding(null, model);\n assert.deepEqual(agg.assemble(), {\n type: 'aggregate',\n groupby: [\n 'bin_maxbins_10_Displacement',\n 'bin_maxbins_10_Displacement_end',\n 'bin_maxbins_10_Acceleration',\n 'bin_maxbins_10_Acceleration_end',\n 'bin_maxbins_10_Acceleration_range'\n ],\n ops: ['count'],\n fields: ['*'],\n as: ['count_*']\n });\n });\n\n it('should produce the correct summary component from transform array', function() {\n const t: AggregateTransform = {\n aggregate: [\n {op: 'mean', field: 'Displacement', as: 'Displacement_mean'},\n {op: 'sum', field: 'Acceleration', as: 'Acceleration_sum'}\n ],\n groupby: ['Displacement_mean', 'Acceleration_sum']};\n\n const agg = AggregateNode.makeFromTransform(null, t);\n assert.deepEqual(agg.assemble(), {\n type: 'aggregate',\n groupby: ['Displacement_mean', 'Acceleration_sum'],\n ops: ['mean', 'sum'],\n fields: ['Displacement', 'Acceleration'],\n as: ['Displacement_mean', 'Acceleration_sum']\n });\n });\n\n it('should produce the correct summary component from transform array with different aggregrations for the same field', function() {\n const t: AggregateTransform = {aggregate: [\n {op: 'mean', field: 'Displacement', as: 'Displacement_mean'},\n {op: 'max', field: 'Displacement', as: 'Displacement_max'},\n {op: 'sum', field: 'Acceleration', as: 'Acceleration_sum'}],\n groupby: ['Displacement_mean', 'Acceleration_sum']};\n\n const agg = AggregateNode.makeFromTransform(null, t);\n assert.deepEqual(agg.assemble(), {\n type: 'aggregate',\n groupby: ['Displacement_mean', 'Acceleration_sum'],\n ops: ['mean', 'max', 'sum'],\n fields: ['Displacement', 'Displacement', 'Acceleration'],\n as: ['Displacement_mean', 'Displacement_max', 'Acceleration_sum']\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/assemble.test.d.ts b/build/test/compile/data/assemble.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/assemble.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/assemble.test.js b/build/test/compile/data/assemble.test.js new file mode 100644 index 0000000000..953bc648e4 --- /dev/null +++ b/build/test/compile/data/assemble.test.js @@ -0,0 +1,137 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { AggregateNode } from '../../../src/compile/data/aggregate'; +import { assembleRootData } from '../../../src/compile/data/assemble'; +import { OutputNode } from '../../../src/compile/data/dataflow'; +import { SourceNode } from '../../../src/compile/data/source'; +import { WindowTransformNode } from '../../../src/compile/data/window'; +describe('compile/data/assemble', function () { + describe('assembleData', function () { + it('should assemble named data source', function () { + var src = new SourceNode({ name: 'foo' }); + var outputNodeRefCounts = {}; + var main = new OutputNode(null, 'mainOut', 'main', outputNodeRefCounts); + main.parent = src; + assert.equal(main.getSource(), 'mainOut'); + var data = assembleRootData({ + sources: { named: src }, + outputNodes: { out: main }, + outputNodeRefCounts: outputNodeRefCounts, + isFaceted: false + }, {}); + assert.equal(data.length, 1); + assert.equal(data[0].name, "foo"); + }); + it('should assemble raw and main output', function () { + var src = new SourceNode({ url: 'foo.csv' }); + var outputNodeRefCounts = {}; + var raw = new OutputNode(null, 'rawOut', 'raw', outputNodeRefCounts); + raw.parent = src; + var agg = new AggregateNode(null, { a: true }, { b: { count: 'count_*' } }); + agg.parent = raw; + var main = new OutputNode(null, 'mainOut', 'main', outputNodeRefCounts); + main.parent = agg; + assert.equal(raw.getSource(), 'rawOut'); + assert.equal(main.getSource(), 'mainOut'); + var data = assembleRootData({ + sources: { named: src }, + outputNodes: { out: main }, + outputNodeRefCounts: outputNodeRefCounts, + isFaceted: false + }, {}); + assert.deepEqual(data, [{ + name: 'source_0', + url: 'foo.csv', + format: { type: 'csv' } + }, { + name: 'data_0', + source: 'source_0', + transform: [{ + type: 'aggregate', + groupby: ['a'], + ops: ['count'], + fields: ['b'], + as: ['count_*'] + }] + } + ]); + }); + it('should assemble window transform node', function () { + var src = new SourceNode({ url: 'foo.csv' }); + var outputNodeRefCounts = {}; + var raw = new OutputNode(null, 'rawOut', 'raw', outputNodeRefCounts); + raw.parent = src; + var transform = { + window: [ + { + op: 'row_number', + as: 'ordered_row_number', + }, + ], + ignorePeers: false, + sort: [ + { + field: 'f', + order: 'ascending' + } + ], + groupby: ['f'], + frame: [null, 0] + }; + var agg = new WindowTransformNode(null, transform); + agg.parent = raw; + var main = new OutputNode(null, 'mainOut', 'main', outputNodeRefCounts); + main.parent = agg; + assert.equal(raw.getSource(), 'rawOut'); + assert.equal(main.getSource(), 'mainOut'); + var data = assembleRootData({ + sources: { named: src }, + outputNodes: { out: main }, + outputNodeRefCounts: outputNodeRefCounts, + isFaceted: false + }, {}); + assert.deepEqual(data, [{ + name: 'source_0', + url: 'foo.csv', + format: { type: 'csv' } + }, { + name: 'data_0', + source: 'source_0', + transform: [{ + type: 'window', + ops: ['row_number'], + fields: [null], + params: [null], + sort: { + field: ["f"], + order: ["ascending"], + }, + ignorePeers: false, + as: ['ordered_row_number'], + frame: [null, 0], + groupby: ['f'] + }] + } + ]); + }); + it('should assemble named datasets with datastore', function () { + var src = new SourceNode({ name: 'foo' }); + var outputNodeRefCounts = {}; + var main = new OutputNode(null, 'mainOut', 'main', outputNodeRefCounts); + main.parent = src; + var data = assembleRootData({ + sources: { named: src }, + outputNodes: { out: main }, + outputNodeRefCounts: outputNodeRefCounts, + isFaceted: false + }, { + foo: [1, 2, 3] + }); + assert.deepEqual(data, [{ + name: 'foo', + values: [1, 2, 3] + }]); + }); + }); +}); +//# sourceMappingURL=assemble.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/assemble.test.js.map b/build/test/compile/data/assemble.test.js.map new file mode 100644 index 0000000000..39f3c48ddf --- /dev/null +++ b/build/test/compile/data/assemble.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.test.js","sourceRoot":"","sources":["../../../../test/compile/data/assemble.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {AggregateNode} from '../../../src/compile/data/aggregate';\nimport {assembleRootData} from '../../../src/compile/data/assemble';\nimport {OutputNode} from '../../../src/compile/data/dataflow';\nimport {SourceNode} from '../../../src/compile/data/source';\nimport {WindowTransformNode} from '../../../src/compile/data/window';\nimport {Transform} from '../../../src/transform';\nimport {VgData} from '../../../src/vega.schema';\n\ndescribe('compile/data/assemble', () => {\n describe('assembleData', () => {\n it('should assemble named data source', () => {\n const src = new SourceNode({name: 'foo'});\n const outputNodeRefCounts = {};\n const main = new OutputNode(null, 'mainOut', 'main', outputNodeRefCounts);\n main.parent = src;\n\n assert.equal(main.getSource(), 'mainOut');\n\n const data = assembleRootData({\n sources: {named: src},\n outputNodes: {out: main},\n outputNodeRefCounts,\n isFaceted: false\n }, {});\n\n assert.equal(data.length, 1);\n assert.equal(data[0].name, \"foo\");\n });\n\n it('should assemble raw and main output', () => {\n const src = new SourceNode({url: 'foo.csv'});\n const outputNodeRefCounts = {};\n const raw = new OutputNode(null, 'rawOut', 'raw', outputNodeRefCounts);\n raw.parent = src;\n const agg = new AggregateNode(null, {a: true}, {b: {count: 'count_*'}});\n agg.parent = raw;\n const main = new OutputNode(null, 'mainOut', 'main', outputNodeRefCounts);\n main.parent = agg;\n\n assert.equal(raw.getSource(), 'rawOut');\n assert.equal(main.getSource(), 'mainOut');\n\n const data = assembleRootData({\n sources: {named: src},\n outputNodes: {out: main},\n outputNodeRefCounts,\n isFaceted: false\n }, {});\n\n assert.deepEqual(data, [{\n name: 'source_0',\n url: 'foo.csv',\n format: {type: 'csv'}\n }, {\n name: 'data_0',\n source: 'source_0',\n transform: [{\n type: 'aggregate',\n groupby: ['a'],\n ops: ['count'],\n fields: ['b'],\n as: ['count_*']\n }]}\n ]);\n });\n\n it('should assemble window transform node', () => {\n const src = new SourceNode({url: 'foo.csv'});\n const outputNodeRefCounts = {};\n const raw = new OutputNode(null, 'rawOut', 'raw', outputNodeRefCounts);\n raw.parent = src;\n const transform: Transform = {\n window: [\n {\n op: 'row_number',\n as: 'ordered_row_number',\n },\n ],\n ignorePeers: false,\n sort:\n [\n {\n field:'f',\n order:'ascending'\n }\n ],\n groupby: ['f'],\n frame: [null, 0]\n };\n const agg = new WindowTransformNode(null, transform);\n agg.parent = raw;\n const main = new OutputNode(null, 'mainOut', 'main', outputNodeRefCounts);\n main.parent = agg;\n\n assert.equal(raw.getSource(), 'rawOut');\n assert.equal(main.getSource(), 'mainOut');\n\n const data = assembleRootData({\n sources: {named: src},\n outputNodes: {out: main},\n outputNodeRefCounts,\n isFaceted: false\n }, {});\n\n assert.deepEqual(data, [{\n name: 'source_0',\n url: 'foo.csv',\n format: {type: 'csv'}\n }, {\n name: 'data_0',\n source: 'source_0',\n transform: [{\n type: 'window',\n ops: ['row_number'],\n fields: [null],\n params: [null],\n sort : {\n field: [\"f\"],\n order: [\"ascending\"],\n },\n ignorePeers: false,\n as: ['ordered_row_number'],\n frame: [null, 0],\n groupby: ['f']\n }]}\n ]);\n });\n\n it('should assemble named datasets with datastore', () => {\n const src = new SourceNode({name: 'foo'});\n const outputNodeRefCounts = {};\n const main = new OutputNode(null, 'mainOut', 'main', outputNodeRefCounts);\n main.parent = src;\n\n const data = assembleRootData({\n sources: {named: src},\n outputNodes: {out: main},\n outputNodeRefCounts,\n isFaceted: false\n }, {\n foo: [1,2,3]\n });\n\n assert.deepEqual(data, [{\n name: 'foo',\n values: [1,2,3]\n }]);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/bin.test.d.ts b/build/test/compile/data/bin.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/bin.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/bin.test.js b/build/test/compile/data/bin.test.js new file mode 100644 index 0000000000..62946af4bd --- /dev/null +++ b/build/test/compile/data/bin.test.js @@ -0,0 +1,221 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { BinNode } from '../../../src/compile/data/bin'; +import { parseUnitModelWithScale } from '../../util'; +function assembleFromEncoding(model) { + return BinNode.makeFromEncoding(null, model).assemble(); +} +function assembleFromTransform(model, t) { + return BinNode.makeFromTransform(null, t, model).assemble(); +} +describe('compile/data/bin', function () { + it('should add bin transform and correctly apply bin with custom extent', function () { + var model = parseUnitModelWithScale({ + mark: 'point', + encoding: { + y: { + bin: { extent: [0, 100] }, + 'field': 'Acceleration', + 'type': 'quantitative' + } + } + }); + assert.deepEqual(assembleFromEncoding(model)[0], { + type: 'bin', + field: 'Acceleration', + as: ['bin_extent_0_100_maxbins_10_Acceleration', 'bin_extent_0_100_maxbins_10_Acceleration_end'], + maxbins: 10, + extent: [0, 100], + signal: "bin_extent_0_100_maxbins_10_Acceleration_bins", + }); + }); + it('should add bin transform and correctly apply bin for binned field without custom extent', function () { + var model = parseUnitModelWithScale({ + mark: 'point', + encoding: { + y: { + bin: true, + 'field': 'Acceleration', + 'type': 'quantitative' + } + } + }); + var transform = assembleFromEncoding(model); + assert.deepEqual(transform.length, 2); + assert.deepEqual(transform[0], { + type: 'extent', + field: 'Acceleration', + signal: 'bin_maxbins_10_Acceleration_extent' + }); + assert.deepEqual(transform[1], { + type: 'bin', + field: 'Acceleration', + as: ['bin_maxbins_10_Acceleration', 'bin_maxbins_10_Acceleration_end'], + maxbins: 10, + signal: 'bin_maxbins_10_Acceleration_bins', + extent: { signal: 'bin_maxbins_10_Acceleration_extent' } + }); + }); + it('should apply the bin transform only once for a binned field encoded in multiple channels', function () { + var model = parseUnitModelWithScale({ + data: { url: "data/movies.json" }, + mark: "circle", + encoding: { + x: { + bin: true, + field: "Rotten_Tomatoes_Rating", + type: "quantitative" + }, + color: { + bin: { "maxbins": 10 }, + field: "Rotten_Tomatoes_Rating", + type: "ordinal" + } + } + }); + var transform = assembleFromEncoding(model); + assert.deepEqual(transform.length, 3); + assert.deepEqual(transform[0], { + type: 'extent', + field: 'Rotten_Tomatoes_Rating', + signal: 'bin_maxbins_10_Rotten_Tomatoes_Rating_extent' + }); + assert.deepEqual(transform[1], { + type: 'bin', + field: 'Rotten_Tomatoes_Rating', + as: ['bin_maxbins_10_Rotten_Tomatoes_Rating', + 'bin_maxbins_10_Rotten_Tomatoes_Rating_end'], + signal: 'bin_maxbins_10_Rotten_Tomatoes_Rating_bins', + maxbins: 10, + extent: { signal: 'bin_maxbins_10_Rotten_Tomatoes_Rating_extent' } + }); + assert.deepEqual(transform[2], { + type: 'formula', + as: 'bin_maxbins_10_Rotten_Tomatoes_Rating_range', + expr: "datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"] === null || isNaN(datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"]) ? \"null\" : format(datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"], \"\") + \" - \" + format(datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating_end\"], \"\")" + }); + }); + it('should add bin transform from transform array and correctly apply bin with custom extent', function () { + var t = { + bin: { extent: [0, 100] }, + field: 'Acceleration', + as: 'binned_acceleration' + }; + var model = parseUnitModelWithScale({ + data: { url: "data/movies.json" }, + mark: "circle", + transform: [t], + encoding: { + x: { + field: "Rotten_Tomatoes_Rating", + type: "quantitative" + }, + color: { + field: "Rotten_Tomatoes_Rating", + type: "quantitative" + } + } + }); + assert.deepEqual(assembleFromTransform(model, t)[0], { + type: 'bin', + field: 'Acceleration', + "maxbins": 10, + as: ['binned_acceleration', 'binned_acceleration_end'], + extent: [0, 100], + signal: "bin_extent_0_100_maxbins_10_Acceleration_bins", + }); + }); + it('should add bin transform from transform array and correctly apply bin with custom extent', function () { + var t = { + bin: { extent: [0, 100], maxbins: 20 }, + field: 'Acceleration', + as: 'binned_acceleration' + }; + var model = parseUnitModelWithScale({ + data: { url: "data/movies.json" }, + mark: "circle", + transform: [t], + encoding: { + x: { + field: "Rotten_Tomatoes_Rating", + type: "quantitative" + }, + color: { + field: "Rotten_Tomatoes_Rating", + type: "quantitative" + } + } + }); + assert.deepEqual(assembleFromTransform(model, t)[0], { + type: 'bin', + field: 'Acceleration', + "maxbins": 20, + as: ['binned_acceleration', 'binned_acceleration_end'], + extent: [0, 100], + signal: "bin_extent_0_100_maxbins_20_Acceleration_bins", + }); + }); + it('should add bin transform from transform array with anchor property', function () { + var t = { + bin: { extent: [0, 100], anchor: 6 }, + field: 'Acceleration', + as: 'binned_acceleration' + }; + var model = parseUnitModelWithScale({ + data: { url: "data/movies.json" }, + mark: "circle", + transform: [t], + encoding: { + x: { + field: "Rotten_Tomatoes_Rating", + type: "quantitative" + }, + color: { + field: "Rotten_Tomatoes_Rating", + type: "quantitative" + } + } + }); + assert.deepEqual(assembleFromTransform(model, t)[0], { + type: 'bin', + field: 'Acceleration', + anchor: 6, + maxbins: 10, + as: ['binned_acceleration', 'binned_acceleration_end'], + extent: [0, 100], + signal: 'bin_extent_0_100_anchor_6_maxbins_10_Acceleration_bins', + }); + }); + it('should add bin transform from transform array with array as', function () { + var t = { + bin: { extent: [0, 100], anchor: 6 }, + field: 'Acceleration', + as: ['binned_acceleration_start', 'binned_acceleration_stop'] + }; + var model = parseUnitModelWithScale({ + data: { url: "data/movies.json" }, + mark: "circle", + transform: [t], + encoding: { + x: { + field: "Rotten_Tomatoes_Rating", + type: "quantitative" + }, + color: { + field: "Rotten_Tomatoes_Rating", + type: "quantitative" + } + } + }); + assert.deepEqual(assembleFromTransform(model, t)[0], { + type: 'bin', + field: 'Acceleration', + anchor: 6, + maxbins: 10, + as: ['binned_acceleration_start', 'binned_acceleration_stop'], + extent: [0, 100], + signal: 'bin_extent_0_100_anchor_6_maxbins_10_Acceleration_bins', + }); + }); +}); +//# sourceMappingURL=bin.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/bin.test.js.map b/build/test/compile/data/bin.test.js.map new file mode 100644 index 0000000000..1ad680a731 --- /dev/null +++ b/build/test/compile/data/bin.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bin.test.js","sourceRoot":"","sources":["../../../../test/compile/data/bin.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\n\nimport {BinNode} from '../../../src/compile/data/bin';\nimport {Model, ModelWithField} from '../../../src/compile/model';\nimport {BinTransform} from '../../../src/transform';\nimport {VgTransform} from '../../../src/vega.schema';\nimport {parseUnitModelWithScale} from '../../util';\n\nfunction assembleFromEncoding(model: ModelWithField) {\n return BinNode.makeFromEncoding(null, model).assemble();\n}\n\nfunction assembleFromTransform(model: Model, t: BinTransform) {\n return BinNode.makeFromTransform(null, t, model).assemble();\n}\n\ndescribe('compile/data/bin', function() {\n it('should add bin transform and correctly apply bin with custom extent', function() {\n const model = parseUnitModelWithScale({\n mark: 'point',\n encoding: {\n y: {\n bin: {extent: [0, 100]},\n 'field': 'Acceleration',\n 'type': 'quantitative'\n }\n }\n });\n\n assert.deepEqual(assembleFromEncoding(model)[0], {\n type: 'bin',\n field: 'Acceleration',\n as: ['bin_extent_0_100_maxbins_10_Acceleration', 'bin_extent_0_100_maxbins_10_Acceleration_end'],\n maxbins: 10,\n extent: [0, 100],\n signal: \"bin_extent_0_100_maxbins_10_Acceleration_bins\",\n });\n });\n\n it ('should add bin transform and correctly apply bin for binned field without custom extent', () => {\n const model = parseUnitModelWithScale({\n mark: 'point',\n encoding: {\n y: {\n bin: true,\n 'field': 'Acceleration',\n 'type': 'quantitative'\n }\n }\n });\n const transform = assembleFromEncoding(model);\n assert.deepEqual(transform.length, 2);\n assert.deepEqual(transform[0], {\n type: 'extent',\n field: 'Acceleration',\n signal: 'bin_maxbins_10_Acceleration_extent'\n });\n assert.deepEqual(transform[1], {\n type: 'bin',\n field: 'Acceleration',\n as: ['bin_maxbins_10_Acceleration', 'bin_maxbins_10_Acceleration_end'],\n maxbins: 10,\n signal: 'bin_maxbins_10_Acceleration_bins',\n extent: {signal: 'bin_maxbins_10_Acceleration_extent'}\n });\n });\n\n it('should apply the bin transform only once for a binned field encoded in multiple channels', () => {\n const model = parseUnitModelWithScale({\n data: {url: \"data/movies.json\"},\n mark: \"circle\",\n encoding: {\n x: {\n bin: true,\n field: \"Rotten_Tomatoes_Rating\",\n type: \"quantitative\"\n },\n color: {\n bin: {\"maxbins\": 10},\n field: \"Rotten_Tomatoes_Rating\",\n type: \"ordinal\"\n }\n }\n });\n const transform = assembleFromEncoding(model);\n assert.deepEqual(transform.length, 3);\n assert.deepEqual(transform[0], {\n type: 'extent',\n field: 'Rotten_Tomatoes_Rating',\n signal: 'bin_maxbins_10_Rotten_Tomatoes_Rating_extent'\n });\n assert.deepEqual(transform[1], {\n type: 'bin',\n field: 'Rotten_Tomatoes_Rating',\n as:\n [ 'bin_maxbins_10_Rotten_Tomatoes_Rating',\n 'bin_maxbins_10_Rotten_Tomatoes_Rating_end' ],\n signal: 'bin_maxbins_10_Rotten_Tomatoes_Rating_bins',\n maxbins: 10,\n extent: {signal: 'bin_maxbins_10_Rotten_Tomatoes_Rating_extent'}\n });\n assert.deepEqual(transform[2], {\n type: 'formula',\n as: 'bin_maxbins_10_Rotten_Tomatoes_Rating_range',\n expr: `datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"] === null || isNaN(datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"]) ? \"null\" : format(datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"], \"\") + \" - \" + format(datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating_end\"], \"\")`\n });\n });\n\n it('should add bin transform from transform array and correctly apply bin with custom extent', function() {\n const t: BinTransform = {\n bin: {extent: [0, 100]},\n field: 'Acceleration',\n as: 'binned_acceleration'\n };\n\n const model = parseUnitModelWithScale({\n data: {url: \"data/movies.json\"},\n mark: \"circle\",\n transform: [t],\n encoding: {\n x: {\n field: \"Rotten_Tomatoes_Rating\",\n type: \"quantitative\"\n },\n color: {\n field: \"Rotten_Tomatoes_Rating\",\n type: \"quantitative\"\n }\n }\n });\n\n assert.deepEqual(assembleFromTransform(model, t)[0], {\n type: 'bin',\n field: 'Acceleration',\n \"maxbins\": 10,\n as: ['binned_acceleration', 'binned_acceleration_end'],\n extent: [0, 100],\n signal: \"bin_extent_0_100_maxbins_10_Acceleration_bins\",\n });\n });\n\n it('should add bin transform from transform array and correctly apply bin with custom extent', function() {\n const t: BinTransform = {\n bin: {extent: [0, 100], maxbins: 20},\n field: 'Acceleration',\n as: 'binned_acceleration'\n };\n\n const model = parseUnitModelWithScale({\n data: {url: \"data/movies.json\"},\n mark: \"circle\",\n transform: [t],\n encoding: {\n x: {\n field: \"Rotten_Tomatoes_Rating\",\n type: \"quantitative\"\n },\n color: {\n field: \"Rotten_Tomatoes_Rating\",\n type: \"quantitative\"\n }\n }\n });\n\n assert.deepEqual(assembleFromTransform(model, t)[0], {\n type: 'bin',\n field: 'Acceleration',\n \"maxbins\": 20,\n as: ['binned_acceleration', 'binned_acceleration_end'],\n extent: [0, 100],\n signal: \"bin_extent_0_100_maxbins_20_Acceleration_bins\",\n });\n });\n\n it('should add bin transform from transform array with anchor property', function() {\n const t: BinTransform = {\n bin: {extent: [0, 100], anchor: 6},\n field: 'Acceleration',\n as: 'binned_acceleration'\n };\n\n const model = parseUnitModelWithScale({\n data: {url: \"data/movies.json\"},\n mark: \"circle\",\n transform: [t],\n encoding: {\n x: {\n field: \"Rotten_Tomatoes_Rating\",\n type: \"quantitative\"\n },\n color: {\n field: \"Rotten_Tomatoes_Rating\",\n type: \"quantitative\"\n }\n }\n });\n\n assert.deepEqual(assembleFromTransform(model, t)[0], {\n type: 'bin',\n field: 'Acceleration',\n anchor: 6,\n maxbins: 10,\n as: ['binned_acceleration', 'binned_acceleration_end'],\n extent: [0, 100],\n signal: 'bin_extent_0_100_anchor_6_maxbins_10_Acceleration_bins',\n });\n });\n\n it('should add bin transform from transform array with array as', function() {\n const t: BinTransform = {\n bin: {extent: [0, 100], anchor: 6},\n field: 'Acceleration',\n as: ['binned_acceleration_start', 'binned_acceleration_stop']\n };\n\n const model = parseUnitModelWithScale({\n data: {url: \"data/movies.json\"},\n mark: \"circle\",\n transform: [t],\n encoding: {\n x: {\n field: \"Rotten_Tomatoes_Rating\",\n type: \"quantitative\"\n },\n color: {\n field: \"Rotten_Tomatoes_Rating\",\n type: \"quantitative\"\n }\n }\n });\n\n assert.deepEqual(assembleFromTransform(model, t)[0], {\n type: 'bin',\n field: 'Acceleration',\n anchor: 6,\n maxbins: 10,\n as: ['binned_acceleration_start', 'binned_acceleration_stop'],\n extent: [0, 100],\n signal: 'bin_extent_0_100_anchor_6_maxbins_10_Acceleration_bins',\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/calculate.test.d.ts b/build/test/compile/data/calculate.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/calculate.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/calculate.test.js b/build/test/compile/data/calculate.test.js new file mode 100644 index 0000000000..1c29f94e60 --- /dev/null +++ b/build/test/compile/data/calculate.test.js @@ -0,0 +1,32 @@ +/* tslint:disable:quotemark */ +import { CalculateNode } from '../../../src/compile/data/calculate'; +import { parseUnitModel } from '../../util'; +function assembleFromSortArray(model) { + var node = CalculateNode.parseAllForSortIndex(null, model); + return node.assemble(); +} +describe('compile/data/calculate', function () { + describe('makeAllForSortIndex', function () { + it('produces correct formula transform', function () { + var model = parseUnitModel({ + data: { + values: [ + { a: 'A', b: 28 }, { a: 'B', b: 55 }, { a: 'C', b: 43 } + ] + }, + mark: 'bar', + encoding: { + x: { field: 'a', type: 'ordinal', sort: ['B', 'A', 'C'] }, + y: { field: 'b', type: 'quantitative' } + } + }); + var nodes = assembleFromSortArray(model); + expect(nodes).toEqual({ + type: 'formula', + expr: 'datum["a"]==="B" ? 0 : datum["a"]==="A" ? 1 : datum["a"]==="C" ? 2 : 3', + as: 'x_a_sort_index' + }); + }); + }); +}); +//# sourceMappingURL=calculate.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/calculate.test.js.map b/build/test/compile/data/calculate.test.js.map new file mode 100644 index 0000000000..24f10f03b1 --- /dev/null +++ b/build/test/compile/data/calculate.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"calculate.test.js","sourceRoot":"","sources":["../../../../test/compile/data/calculate.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,OAAO,EAAC,aAAa,EAAC,MAAM,qCAAqC,CAAC;AAElE,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAI1C,+BAA+B,KAAqB;IAClD,IAAM,IAAI,GAAG,aAAa,CAAC,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAkB,CAAC;IAC9E,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;AACzB,CAAC;AAED,QAAQ,CAAC,wBAAwB,EAAE;IACjC,QAAQ,CAAC,qBAAqB,EAAE;QAC9B,EAAE,CAAC,oCAAoC,EAAE;YACvC,IAAM,KAAK,GAAG,cAAc,CAAC;gBAC3B,IAAI,EAAE;oBACJ,MAAM,EAAE;wBACN,EAAC,CAAC,EAAE,GAAG,EAAC,CAAC,EAAE,EAAE,EAAC,EAAE,EAAC,CAAC,EAAE,GAAG,EAAC,CAAC,EAAE,EAAE,EAAC,EAAE,EAAC,CAAC,EAAE,GAAG,EAAC,CAAC,EAAE,EAAE,EAAC;qBAC/C;iBACF;gBACD,IAAI,EAAE,KAAK;gBACT,QAAQ,EAAE;oBACR,CAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAC;oBACvD,CAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC;iBACtC;aACJ,CAAC,CAAC;YACH,IAAM,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;YAC3C,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC;gBACpB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,wEAAwE;gBAC9E,EAAE,EAAE,gBAAgB;aACrB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:quotemark */\nimport {CalculateNode} from '../../../src/compile/data/calculate';\nimport {ModelWithField} from '../../../src/compile/model';\nimport {parseUnitModel} from '../../util';\n\n\n\nfunction assembleFromSortArray(model: ModelWithField) {\n const node = CalculateNode.parseAllForSortIndex(null, model) as CalculateNode;\n return node.assemble();\n}\n\ndescribe('compile/data/calculate', () => {\n describe('makeAllForSortIndex', () => {\n it('produces correct formula transform', () => {\n const model = parseUnitModel({\n data: {\n values: [\n {a: 'A',b: 28}, {a: 'B',b: 55}, {a: 'C',b: 43}\n ]\n },\n mark: 'bar',\n encoding: {\n x: {field: 'a', type: 'ordinal', sort: ['B', 'A', 'C']},\n y: {field: 'b', type: 'quantitative'}\n }\n });\n const nodes = assembleFromSortArray(model);\n expect(nodes).toEqual({\n type: 'formula',\n expr: 'datum[\"a\"]===\"B\" ? 0 : datum[\"a\"]===\"A\" ? 1 : datum[\"a\"]===\"C\" ? 2 : 3',\n as: 'x_a_sort_index'\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/dataflow.test.d.ts b/build/test/compile/data/dataflow.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/dataflow.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/dataflow.test.js b/build/test/compile/data/dataflow.test.js new file mode 100644 index 0000000000..e06208bac8 --- /dev/null +++ b/build/test/compile/data/dataflow.test.js @@ -0,0 +1,75 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { DataFlowNode } from '../../../src/compile/data/dataflow'; +describe('compile/data/dataflow', function () { + describe('DataFlowNode', function () { + describe('swap', function () { + it('should correctly swap two nodes in a simple chain', function () { + var a = new DataFlowNode(null, 'a'); + var b = new DataFlowNode(a, 'b'); + var c = new DataFlowNode(b, 'c'); + var d = new DataFlowNode(c, 'd'); + c.swapWithParent(); + assert.equal(a.numChildren(), 1); + assert.equal(a.children[0].debugName, 'c'); + assert.equal(b.numChildren(), 1); + assert.equal(b.children[0].debugName, 'd'); + assert.equal(c.numChildren(), 1); + assert.equal(c.children[0].debugName, 'b'); + assert.equal(d.numChildren(), 0); + }); + it('should correctly swap two nodes', function () { + var root = new DataFlowNode(null, 'root'); + var parent = new DataFlowNode(root, 'parent'); + var node = new DataFlowNode(parent, 'node'); + var child1 = new DataFlowNode(node, 'child1'); + var child2 = new DataFlowNode(node, 'child2'); + var parentChild1 = new DataFlowNode(parent, 'parentChild1'); + var parentChild2 = new DataFlowNode(parent, 'parentChild2'); + node.swapWithParent(); + assert.equal(root.numChildren(), 1); + assert.equal(root.children[0].debugName, 'node'); + assert.equal(node.parent.debugName, 'root'); + assert.equal(node.numChildren(), 1); + assert.equal(node.children[0].debugName, 'parent'); + assert.equal(parent.parent.debugName, 'node'); + assert.equal(parent.numChildren(), 4); + parent.children.forEach(function (c) { + assert.equal(c.numChildren(), 0); + assert.equal(c.parent.debugName, 'parent'); + }); + assert.equal(child1.debugName, 'child1'); + assert.equal(child2.debugName, 'child2'); + assert.equal(parentChild1.debugName, 'parentChild1'); + assert.equal(parentChild2.debugName, 'parentChild2'); + }); + }); + describe('remove', function () { + it('should remove node from dataflow', function () { + var a = new DataFlowNode(null, 'a'); + var b = new DataFlowNode(a, 'b'); + var c = new DataFlowNode(b, 'c'); + assert.deepEqual(a.children, [b]); + assert.equal(b.parent, a); + assert.equal(c.parent, b); + b.remove(); + assert.deepEqual(a.children, [c]); + assert.equal(c.parent, a); + }); + }); + describe('insertAsParentOf', function () { + it('should insert node into dataflow', function () { + var a = new DataFlowNode(null, 'a'); + var anotherChild = new DataFlowNode(a, 'a'); + var b = new DataFlowNode(null, 'b'); + var c = new DataFlowNode(a, 'c'); + b.insertAsParentOf(c); + assert.sameDeepMembers(a.children, [anotherChild, b]); + assert.equal(b.parent, a); + assert.equal(c.parent, b); + assert.equal(anotherChild.parent, a); + }); + }); + }); +}); +//# sourceMappingURL=dataflow.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/dataflow.test.js.map b/build/test/compile/data/dataflow.test.js.map new file mode 100644 index 0000000000..6fb58a2652 --- /dev/null +++ b/build/test/compile/data/dataflow.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dataflow.test.js","sourceRoot":"","sources":["../../../../test/compile/data/dataflow.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {DataFlowNode} from '../../../src/compile/data/dataflow';\n\ndescribe('compile/data/dataflow', function() {\n describe('DataFlowNode', function() {\n describe('swap', () => {\n it('should correctly swap two nodes in a simple chain', function() {\n const a = new DataFlowNode(null, 'a');\n const b = new DataFlowNode(a, 'b');\n\n const c = new DataFlowNode(b, 'c');\n\n const d = new DataFlowNode(c, 'd');\n\n c.swapWithParent();\n\n assert.equal(a.numChildren(), 1);\n assert.equal(a.children[0].debugName, 'c');\n\n assert.equal(b.numChildren(), 1);\n assert.equal(b.children[0].debugName, 'd');\n\n assert.equal(c.numChildren(), 1);\n assert.equal(c.children[0].debugName, 'b');\n\n assert.equal(d.numChildren(), 0);\n });\n\n it('should correctly swap two nodes', function() {\n const root = new DataFlowNode(null, 'root');\n const parent = new DataFlowNode(root, 'parent');\n\n const node = new DataFlowNode(parent, 'node');\n\n const child1 = new DataFlowNode(node, 'child1');\n const child2 = new DataFlowNode(node, 'child2');\n\n const parentChild1 = new DataFlowNode(parent, 'parentChild1');\n const parentChild2 = new DataFlowNode(parent, 'parentChild2');\n\n node.swapWithParent();\n\n assert.equal(root.numChildren(), 1);\n assert.equal(root.children[0].debugName, 'node');\n assert.equal(node.parent.debugName, 'root');\n\n assert.equal(node.numChildren(), 1);\n assert.equal(node.children[0].debugName, 'parent');\n assert.equal(parent.parent.debugName, 'node');\n\n assert.equal(parent.numChildren(), 4);\n parent.children.forEach(c => {\n assert.equal(c.numChildren(), 0);\n assert.equal(c.parent.debugName, 'parent');\n });\n\n assert.equal(child1.debugName, 'child1');\n assert.equal(child2.debugName, 'child2');\n assert.equal(parentChild1.debugName, 'parentChild1');\n assert.equal(parentChild2.debugName, 'parentChild2');\n });\n });\n\n describe('remove', function() {\n it('should remove node from dataflow', function() {\n const a = new DataFlowNode(null, 'a');\n const b = new DataFlowNode(a, 'b');\n\n const c = new DataFlowNode(b, 'c');\n\n assert.deepEqual(a.children, [b]);\n assert.equal(b.parent, a);\n assert.equal(c.parent, b);\n\n b.remove();\n\n assert.deepEqual(a.children, [c]);\n assert.equal(c.parent, a);\n });\n });\n\n describe('insertAsParentOf', function() {\n it('should insert node into dataflow', function() {\n const a = new DataFlowNode(null, 'a');\n const anotherChild = new DataFlowNode(a, 'a');\n const b = new DataFlowNode(null, 'b');\n const c = new DataFlowNode(a, 'c');\n\n b.insertAsParentOf(c);\n\n assert.sameDeepMembers(a.children, [anotherChild, b]);\n assert.equal(b.parent, a);\n assert.equal(c.parent, b);\n assert.equal(anotherChild.parent, a);\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/facet.test.d.ts b/build/test/compile/data/facet.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/facet.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/facet.test.js b/build/test/compile/data/facet.test.js new file mode 100644 index 0000000000..eb2c60bd1d --- /dev/null +++ b/build/test/compile/data/facet.test.js @@ -0,0 +1,201 @@ +import { assert } from 'chai'; +import { FacetNode } from '../../../src/compile/data/facet'; +import { parseFacetModelWithScale } from '../../util'; +describe('compile/data/facet', function () { + describe('assemble', function () { + it('should calculate column distinct if child has an independent discrete scale with step', function () { + var model = parseFacetModelWithScale({ + '$schema': 'https://vega.github.io/schema/vega-lite/v2.json', + 'description': 'A trellis bar chart showing the US population distribution of age groups and gender in 2000.', + 'data': { 'url': 'data/population.json' }, + 'facet': { 'column': { 'field': 'gender', 'type': 'nominal' } }, + 'spec': { + 'mark': 'bar', + 'encoding': { + 'y': { + 'aggregate': 'sum', 'field': 'people', 'type': 'quantitative', + 'axis': { 'title': 'population' } + }, + 'x': { + 'field': 'age', 'type': 'ordinal', + 'scale': { 'rangeStep': 17 } + }, + 'color': { + 'field': 'gender', 'type': 'nominal', + 'scale': { 'range': ['#EA98D2', '#659CCA'] } + } + } + }, + 'resolve': { + 'scale': { 'x': 'independent' } + }, + 'config': { 'view': { 'fill': 'yellow' } } + }); + var node = new FacetNode(null, model, 'facetName', 'dataName'); + var data = node.assemble(); + assert.deepEqual(data[0], { + name: 'column_domain', + source: 'dataName', + transform: [{ + type: 'aggregate', + groupby: ['gender'], + fields: ['age'], + ops: ['distinct'], + as: ['distinct_age'] + }] + }); + }); + it('should calculate column and row distinct if child has an independent discrete scale with step and the facet has both row and column', function () { + var model = parseFacetModelWithScale({ + '$schema': 'https://vega.github.io/schema/vega-lite/v2.json', + 'data': { + 'values': [ + { 'r': 'r1', 'c': 'c1', 'a': 'a1', 'b': 'b1' }, + { 'r': 'r1', 'c': 'c1', 'a': 'a2', 'b': 'b2' }, + { 'r': 'r2', 'c': 'c2', 'a': 'a1', 'b': 'b1' }, + { 'r': 'r3', 'c': 'c2', 'a': 'a3', 'b': 'b2' } + ] + }, + 'facet': { + 'row': { 'field': 'r', 'type': 'nominal' }, + 'column': { 'field': 'c', 'type': 'nominal' } + }, + 'spec': { + 'mark': 'rect', + 'encoding': { + 'y': { 'field': 'b', 'type': 'nominal' }, + 'x': { 'field': 'a', 'type': 'nominal' } + } + }, + 'resolve': { + 'scale': { + 'x': 'independent', + 'y': 'independent' + } + } + }); + var node = new FacetNode(null, model, 'facetName', 'dataName'); + var data = node.assemble(); + // crossed data + assert.deepEqual(data[0], { + name: 'cross_column_domain_row_domain', + source: 'dataName', + transform: [{ + type: 'aggregate', + groupby: ['c', 'r'], + fields: ['a', 'b'], + ops: ['distinct', 'distinct'] + }] + }); + assert.deepEqual(data[1], { + name: 'column_domain', + source: 'cross_column_domain_row_domain', + transform: [{ + type: 'aggregate', + groupby: ['c'], + fields: ['distinct_a'], + ops: ['max'], + as: ['distinct_a'] + }] + }); + assert.deepEqual(data[2], { + name: 'row_domain', + source: 'cross_column_domain_row_domain', + transform: [{ + type: 'aggregate', + groupby: ['r'], + fields: ['distinct_b'], + ops: ['max'], + as: ['distinct_b'] + }] + }); + }); + it('should calculate column and row sort array', function () { + var model = parseFacetModelWithScale({ + '$schema': 'https://vega.github.io/schema/vega-lite/v2.json', + 'data': { + 'name': 'a' + }, + 'facet': { + 'row': { 'field': 'r', 'type': 'nominal', sort: ['r1', 'r2'] }, + 'column': { 'field': 'c', 'type': 'nominal', sort: ['c1', 'c2'] } + }, + 'spec': { + 'mark': 'rect', + 'encoding': { + 'y': { 'field': 'b', 'type': 'quantitative' }, + 'x': { 'field': 'a', 'type': 'quantitative' } + } + } + }); + var node = new FacetNode(null, model, 'facetName', 'dataName'); + var data = node.assemble(); + assert.deepEqual(data[0], { + name: 'column_domain', + source: 'dataName', + transform: [{ + type: 'aggregate', + groupby: ['c'], + fields: ['column_c_sort_index'], + ops: ['max'], + as: ['column_c_sort_index'] + }] + }); + assert.deepEqual(data[1], { + name: 'row_domain', + source: 'dataName', + transform: [{ + type: 'aggregate', + groupby: ['r'], + fields: ['row_r_sort_index'], + ops: ['max'], + as: ['row_r_sort_index'] + }] + }); + }); + it('should calculate column and row sort field', function () { + var model = parseFacetModelWithScale({ + '$schema': 'https://vega.github.io/schema/vega-lite/v2.json', + 'data': { + 'name': 'a' + }, + 'facet': { + 'row': { 'field': 'r', 'type': 'nominal', sort: { op: 'median', field: 'b' } }, + 'column': { 'field': 'c', 'type': 'nominal', sort: { op: 'median', field: 'a' } } + }, + 'spec': { + 'mark': 'rect', + 'encoding': { + 'y': { 'field': 'b', 'type': 'quantitative' }, + 'x': { 'field': 'a', 'type': 'quantitative' } + } + } + }); + var node = new FacetNode(null, model, 'facetName', 'dataName'); + var data = node.assemble(); + assert.deepEqual(data[0], { + name: 'column_domain', + source: 'dataName', + transform: [{ + type: 'aggregate', + groupby: ['c'], + fields: ['a'], + ops: ['median'], + as: ['median_a'] + }] + }); + assert.deepEqual(data[1], { + name: 'row_domain', + source: 'dataName', + transform: [{ + type: 'aggregate', + groupby: ['r'], + fields: ['b'], + ops: ['median'], + as: ['median_b'] + }] + }); + }); + }); +}); +//# sourceMappingURL=facet.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/facet.test.js.map b/build/test/compile/data/facet.test.js.map new file mode 100644 index 0000000000..09aba9c442 --- /dev/null +++ b/build/test/compile/data/facet.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"facet.test.js","sourceRoot":"","sources":["../../../../test/compile/data/facet.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {FacetNode} from '../../../src/compile/data/facet';\nimport {parseFacetModelWithScale} from '../../util';\n\ndescribe('compile/data/facet', function() {\n describe('assemble', () => {\n it('should calculate column distinct if child has an independent discrete scale with step', () => {\n const model = parseFacetModelWithScale({\n '$schema': 'https://vega.github.io/schema/vega-lite/v2.json',\n 'description': 'A trellis bar chart showing the US population distribution of age groups and gender in 2000.',\n 'data': {'url': 'data/population.json'},\n 'facet': {'column': {'field': 'gender', 'type': 'nominal'}},\n 'spec': {\n 'mark': 'bar',\n 'encoding': {\n 'y': {\n 'aggregate': 'sum', 'field': 'people', 'type': 'quantitative',\n 'axis': {'title': 'population'}\n },\n 'x': {\n 'field': 'age', 'type': 'ordinal',\n 'scale': {'rangeStep': 17}\n },\n 'color': {\n 'field': 'gender', 'type': 'nominal',\n 'scale': {'range': ['#EA98D2','#659CCA']}\n }\n }\n },\n 'resolve': {\n 'scale': {'x': 'independent'}\n },\n 'config': {'view': {'fill': 'yellow'}}\n });\n\n const node = new FacetNode(null, model, 'facetName', 'dataName');\n const data = node.assemble();\n\n assert.deepEqual(data[0], {\n name: 'column_domain',\n source: 'dataName',\n transform:[{\n type: 'aggregate',\n groupby: ['gender'],\n fields: ['age'],\n ops: ['distinct'],\n as:['distinct_age']\n }]\n });\n });\n\n it('should calculate column and row distinct if child has an independent discrete scale with step and the facet has both row and column', () => {\n const model = parseFacetModelWithScale({\n '$schema': 'https://vega.github.io/schema/vega-lite/v2.json',\n 'data': {\n 'values': [\n {'r': 'r1', 'c': 'c1', 'a': 'a1', 'b': 'b1'},\n {'r': 'r1', 'c': 'c1', 'a': 'a2', 'b': 'b2'},\n {'r': 'r2', 'c': 'c2', 'a': 'a1', 'b': 'b1'},\n {'r': 'r3', 'c': 'c2', 'a': 'a3', 'b': 'b2'}\n ]\n },\n 'facet': {\n 'row': {'field': 'r', 'type': 'nominal'},\n 'column': {'field': 'c', 'type': 'nominal'}\n },\n 'spec': {\n 'mark': 'rect',\n 'encoding': {\n 'y': {'field': 'b', 'type': 'nominal'},\n 'x': {'field': 'a', 'type': 'nominal'}\n }\n },\n 'resolve': {\n 'scale': {\n 'x': 'independent',\n 'y': 'independent'\n }\n }\n });\n\n const node = new FacetNode(null, model, 'facetName', 'dataName');\n const data = node.assemble();\n\n // crossed data\n assert.deepEqual(data[0], {\n name: 'cross_column_domain_row_domain',\n source: 'dataName',\n transform: [{\n type: 'aggregate',\n groupby: ['c', 'r'],\n fields: ['a', 'b'],\n ops: ['distinct', 'distinct']\n }]\n });\n\n assert.deepEqual(data[1], {\n name: 'column_domain',\n source: 'cross_column_domain_row_domain',\n transform: [{\n type: 'aggregate',\n groupby: ['c'],\n fields: ['distinct_a'],\n ops: ['max'],\n as: ['distinct_a']\n }]\n });\n\n assert.deepEqual(data[2], {\n name: 'row_domain',\n source: 'cross_column_domain_row_domain',\n transform: [{\n type: 'aggregate',\n groupby: ['r'],\n fields: ['distinct_b'],\n ops: ['max'],\n as: ['distinct_b']\n }]\n });\n });\n\n\n it('should calculate column and row sort array', () => {\n const model = parseFacetModelWithScale({\n '$schema': 'https://vega.github.io/schema/vega-lite/v2.json',\n 'data': {\n 'name': 'a'\n },\n 'facet': {\n 'row': {'field': 'r', 'type': 'nominal', sort: ['r1', 'r2']},\n 'column': {'field': 'c', 'type': 'nominal', sort: ['c1', 'c2']}\n },\n 'spec': {\n 'mark': 'rect',\n 'encoding': {\n 'y': {'field': 'b', 'type': 'quantitative'},\n 'x': {'field': 'a', 'type': 'quantitative'}\n }\n }\n });\n\n const node = new FacetNode(null, model, 'facetName', 'dataName');\n const data = node.assemble();\n\n assert.deepEqual(data[0], {\n name: 'column_domain',\n source: 'dataName',\n transform: [{\n type: 'aggregate',\n groupby: ['c'],\n fields: ['column_c_sort_index'],\n ops: ['max'],\n as: ['column_c_sort_index']\n }]\n });\n\n assert.deepEqual(data[1], {\n name: 'row_domain',\n source: 'dataName',\n transform: [{\n type: 'aggregate',\n groupby: ['r'],\n fields: ['row_r_sort_index'],\n ops: ['max'],\n as: ['row_r_sort_index']\n }]\n });\n });\n\n it('should calculate column and row sort field', () => {\n const model = parseFacetModelWithScale({\n '$schema': 'https://vega.github.io/schema/vega-lite/v2.json',\n 'data': {\n 'name': 'a'\n },\n 'facet': {\n 'row': {'field': 'r', 'type': 'nominal', sort: {op: 'median', field: 'b'}},\n 'column': {'field': 'c', 'type': 'nominal', sort: {op: 'median', field: 'a'}}\n },\n 'spec': {\n 'mark': 'rect',\n 'encoding': {\n 'y': {'field': 'b', 'type': 'quantitative'},\n 'x': {'field': 'a', 'type': 'quantitative'}\n }\n }\n });\n\n const node = new FacetNode(null, model, 'facetName', 'dataName');\n const data = node.assemble();\n\n assert.deepEqual(data[0], {\n name: 'column_domain',\n source: 'dataName',\n transform: [{\n type: 'aggregate',\n groupby: ['c'],\n fields: ['a'],\n ops: ['median'],\n as: ['median_a']\n }]\n });\n\n assert.deepEqual(data[1], {\n name: 'row_domain',\n source: 'dataName',\n transform: [{\n type: 'aggregate',\n groupby: ['r'],\n fields: ['b'],\n ops: ['median'],\n as: ['median_b']\n }]\n });\n });\n\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/filter.test.d.ts b/build/test/compile/data/filter.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/filter.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/filter.test.js b/build/test/compile/data/filter.test.js new file mode 100644 index 0000000000..f3bed28a69 --- /dev/null +++ b/build/test/compile/data/filter.test.js @@ -0,0 +1,41 @@ +import * as tslib_1 from "tslib"; +import { assert } from 'chai'; +import { AncestorParse } from '../../../src/compile/data'; +import { DataFlowNode } from '../../../src/compile/data/dataflow'; +import { ParseNode } from '../../../src/compile/data/formatparse'; +import { parseTransformArray } from '../../../src/compile/data/parse'; +import { parseUnitModel } from '../../util'; +describe('compile/data/filter', function () { + it('should create parse for filtered fields', function () { + var model = parseUnitModel({ + 'data': { 'url': 'a.json' }, + 'transform': [ + { 'filter': { 'field': 'a', 'equal': { year: 2000 } } }, + { 'filter': { 'field': 'b', 'oneOf': ['a', 'b'] } }, + { 'filter': { 'field': 'c', 'range': [{ year: 2000 }, { year: 2001 }] } }, + { 'filter': { 'field': 'd', 'range': [1, 2] } } + ], + 'mark': 'point', + encoding: {} + }); + var parse = {}; + // extract the parse from the parse nodes that were generated along with the filter nodes + var root = new DataFlowNode(null); + parseTransformArray(root, model, new AncestorParse()); + var node = root.children[0]; + while (node.numChildren() > 0) { + if (node instanceof ParseNode) { + parse = tslib_1.__assign({}, parse, node.parse); + } + assert.equal(node.numChildren(), 1); + node = node.children[0]; + } + assert.deepEqual(parse, { + a: 'date', + b: 'string', + c: 'date', + d: 'number' + }); + }); +}); +//# sourceMappingURL=filter.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/filter.test.js.map b/build/test/compile/data/filter.test.js.map new file mode 100644 index 0000000000..57ab805931 --- /dev/null +++ b/build/test/compile/data/filter.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"filter.test.js","sourceRoot":"","sources":["../../../../test/compile/data/filter.test.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,aAAa,EAAC,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAC,YAAY,EAAC,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAC,SAAS,EAAC,MAAM,uCAAuC,CAAC;AAChE,OAAO,EAAC,mBAAmB,EAAC,MAAM,iCAAiC,CAAC;AAEpE,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAE1C,QAAQ,CAAC,qBAAqB,EAAE;IAC9B,EAAE,CAAC,yCAAyC,EAAE;QAC5C,IAAM,KAAK,GAAG,cAAc,CAAC;YAC3B,MAAM,EAAE,EAAC,KAAK,EAAE,QAAQ,EAAC;YACzB,WAAW,EAAE;gBACX,EAAC,QAAQ,EAAE,EAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,EAAC,EAAC;gBACjD,EAAC,QAAQ,EAAE,EAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAC,EAAC;gBAC/C,EAAC,QAAQ,EAAE,EAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAC,IAAI,EAAE,IAAI,EAAC,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,EAAC,EAAC;gBACjE,EAAC,QAAQ,EAAE,EAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAC,EAAC;aAC5C;YACD,MAAM,EAAE,OAAO;YACf,QAAQ,EAAE,EAAE;SACb,CAAC,CAAC;QAEH,IAAI,KAAK,GAAiB,EAAE,CAAC;QAE7B,yFAAyF;QACzF,IAAM,IAAI,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;QACpC,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,aAAa,EAAE,CAAC,CAAC;QACtD,IAAI,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAE5B,OAAO,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE;YAC7B,IAAI,IAAI,YAAY,SAAS,EAAE;gBAC7B,KAAK,wBAAO,KAAK,EAAK,IAAI,CAAC,KAAK,CAAC,CAAC;aACnC;YACD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;YACpC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;SACzB;QAED,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE;YACtB,CAAC,EAAE,MAAM;YACT,CAAC,EAAE,QAAQ;YACX,CAAC,EAAE,MAAM;YACT,CAAC,EAAE,QAAQ;SACZ,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\nimport {AncestorParse} from '../../../src/compile/data';\nimport {DataFlowNode} from '../../../src/compile/data/dataflow';\nimport {ParseNode} from '../../../src/compile/data/formatparse';\nimport {parseTransformArray} from '../../../src/compile/data/parse';\nimport {Dict} from '../../../src/util';\nimport {parseUnitModel} from '../../util';\n\ndescribe('compile/data/filter', () => {\n it('should create parse for filtered fields', () => {\n const model = parseUnitModel({\n 'data': {'url': 'a.json'},\n 'transform': [\n {'filter': {'field': 'a', 'equal': {year: 2000}}},\n {'filter': {'field': 'b', 'oneOf': ['a', 'b']}},\n {'filter': {'field': 'c', 'range': [{year: 2000}, {year: 2001}]}},\n {'filter': {'field': 'd', 'range': [1, 2]}}\n ],\n 'mark': 'point',\n encoding: {}\n });\n\n let parse: Dict = {};\n\n // extract the parse from the parse nodes that were generated along with the filter nodes\n const root = new DataFlowNode(null);\n parseTransformArray(root, model, new AncestorParse());\n let node = root.children[0];\n\n while (node.numChildren() > 0) {\n if (node instanceof ParseNode) {\n parse = {...parse, ...node.parse};\n }\n assert.equal(node.numChildren(), 1);\n node = node.children[0];\n }\n\n assert.deepEqual(parse, {\n a: 'date',\n b: 'string',\n c: 'date',\n d: 'number'\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/filterinvalid.test.d.ts b/build/test/compile/data/filterinvalid.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/filterinvalid.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/filterinvalid.test.js b/build/test/compile/data/filterinvalid.test.js new file mode 100644 index 0000000000..8d88b1d0d9 --- /dev/null +++ b/build/test/compile/data/filterinvalid.test.js @@ -0,0 +1,83 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { FilterInvalidNode } from '../../../src/compile/data/filterinvalid'; +import { mergeDeep } from '../../../src/util'; +import { parseUnitModelWithScale } from '../../util'; +function parse(model) { + return FilterInvalidNode.make(null, model); +} +describe('compile/data/nullfilter', function () { + describe('compileUnit', function () { + var spec = { + mark: "point", + encoding: { + y: { field: 'qq', type: "quantitative" }, + x: { field: 'tt', type: "temporal" }, + color: { field: 'oo', type: "ordinal" }, + shape: { field: 'nn', type: "nominal" } + } + }; + it('should add filterNull for Q and T by default', function () { + var model = parseUnitModelWithScale(spec); + assert.deepEqual(parse(model).filter, { + qq: { field: 'qq', type: "quantitative" }, + tt: { field: 'tt', type: "temporal" } + }); + }); + it('should add filterNull for Q and T when invalidValues is "filter".', function () { + var model = parseUnitModelWithScale(mergeDeep(spec, { + config: { + invalidValues: 'filter' + } + })); + assert.deepEqual(parse(model).filter, { + qq: { field: 'qq', type: "quantitative" }, + tt: { field: 'tt', type: "temporal" } + }); + }); + it('should add no null filter if when invalidValues is null', function () { + var model = parseUnitModelWithScale(mergeDeep(spec, { + config: { + invalidValues: null + } + })); + assert.deepEqual(parse(model), null); + }); + it('should add no null filter for count field', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + y: { aggregate: 'count', type: "quantitative" } + } + }); + assert.deepEqual(parse(model), null); + }); + }); + describe('assemble', function () { + it('should assemble simple filter', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + y: { field: 'foo', type: "quantitative" } + } + }); + assert.deepEqual(parse(model).assemble(), { + type: 'filter', + expr: 'datum["foo"] !== null && !isNaN(datum["foo"])' + }); + }); + it('should assemble filter for nested data', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + y: { field: 'foo.bar', type: "quantitative" } + } + }); + assert.deepEqual(parse(model).assemble(), { + type: 'filter', + expr: 'datum["foo.bar"] !== null && !isNaN(datum["foo.bar"])' + }); + }); + }); +}); +//# sourceMappingURL=filterinvalid.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/filterinvalid.test.js.map b/build/test/compile/data/filterinvalid.test.js.map new file mode 100644 index 0000000000..f593e1d7c0 --- /dev/null +++ b/build/test/compile/data/filterinvalid.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"filterinvalid.test.js","sourceRoot":"","sources":["../../../../test/compile/data/filterinvalid.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {FilterInvalidNode} from '../../../src/compile/data/filterinvalid';\nimport {UnitModel} from '../../../src/compile/unit';\nimport {NormalizedUnitSpec, TopLevel} from '../../../src/spec';\nimport {mergeDeep} from '../../../src/util';\nimport {parseUnitModelWithScale} from '../../util';\n\n\nfunction parse(model: UnitModel) {\n return FilterInvalidNode.make(null, model);\n}\n\ndescribe('compile/data/nullfilter', function() {\n describe('compileUnit', function() {\n const spec: NormalizedUnitSpec = {\n mark: \"point\",\n encoding: {\n y: {field: 'qq', type: \"quantitative\"},\n x: {field: 'tt', type: \"temporal\"},\n color: {field: 'oo', type: \"ordinal\"},\n shape: {field: 'nn', type: \"nominal\"}\n }\n };\n\n it('should add filterNull for Q and T by default', function () {\n const model = parseUnitModelWithScale(spec);\n assert.deepEqual(parse(model).filter, {\n qq: {field: 'qq', type: \"quantitative\"},\n tt: {field: 'tt', type: \"temporal\"}\n });\n });\n\n it('should add filterNull for Q and T when invalidValues is \"filter\".', function () {\n const model = parseUnitModelWithScale(mergeDeep>(spec, {\n config: {\n invalidValues: 'filter'\n }\n }));\n assert.deepEqual(parse(model).filter, {\n qq: {field: 'qq', type: \"quantitative\"},\n tt: {field: 'tt', type: \"temporal\"}\n });\n });\n\n it('should add no null filter if when invalidValues is null', function () {\n const model = parseUnitModelWithScale(mergeDeep>(spec, {\n config: {\n invalidValues: null\n }\n }));\n assert.deepEqual(parse(model), null);\n });\n\n it ('should add no null filter for count field', () => {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n y: {aggregate: 'count', type: \"quantitative\"}\n }\n });\n\n assert.deepEqual(parse(model), null);\n });\n });\n\n describe('assemble', function() {\n it ('should assemble simple filter', () => {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n y: {field: 'foo', type: \"quantitative\"}\n }\n });\n\n assert.deepEqual(parse(model).assemble(), {\n type: 'filter',\n expr: 'datum[\"foo\"] !== null && !isNaN(datum[\"foo\"])'\n });\n });\n\n it ('should assemble filter for nested data', () => {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n y: {field: 'foo.bar', type: \"quantitative\"}\n }\n });\n\n assert.deepEqual(parse(model).assemble(), {\n type: 'filter',\n expr: 'datum[\"foo.bar\"] !== null && !isNaN(datum[\"foo.bar\"])'\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/formatparse.test.d.ts b/build/test/compile/data/formatparse.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/formatparse.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/formatparse.test.js b/build/test/compile/data/formatparse.test.js new file mode 100644 index 0000000000..a9332cf829 --- /dev/null +++ b/build/test/compile/data/formatparse.test.js @@ -0,0 +1,273 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { AncestorParse } from '../../../src/compile/data'; +import { DataFlowNode } from '../../../src/compile/data/dataflow'; +import { ParseNode } from '../../../src/compile/data/formatparse'; +import { parseTransformArray } from '../../../src/compile/data/parse'; +import * as log from '../../../src/log'; +import { parseFacetModel, parseUnitModel } from '../../util'; +describe('compile/data/formatparse', function () { + describe('parseUnit', function () { + it('should parse binned fields as numbers', function () { + var model = parseUnitModel({ + "mark": "point", + "encoding": { + "x": { "field": "a", "type": "ordinal", "bin": true }, + "y": { "field": "b", "type": "ordinal" } + } + }); + assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, new AncestorParse()).parse, { + a: 'number' + }); + }); + it('should flatten nested fields that are used to sort domains', function () { + var model = parseUnitModel({ + "mark": "point", + "encoding": { + x: { field: 'a', type: 'ordinal', sort: { field: 'foo.bar', op: 'mean' } }, + } + }); + assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, new AncestorParse()).parse, { + 'foo.bar': 'flatten' + }); + }); + it('should return a correct customized parse.', function () { + var model = parseUnitModel({ + "data": { "url": "a.json", "format": { "parse": { "c": "number", "d": "date" } } }, + "mark": "point", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "temporal" }, + "color": { "field": "c", "type": "ordinal" }, + "shape": { "field": "c", "type": "nominal" } + } + }); + var ancestorParese = new AncestorParse(); + assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, ancestorParese).parse, { + a: 'number', + b: 'date' + }); + assert.deepEqual(ParseNode.makeExplicit(null, model, ancestorParese).parse, { + c: 'number', + d: 'date' + }); + }); + it('should include parse for all applicable fields, and exclude calculated fields', function () { + var model = parseUnitModel({ + transform: [{ calculate: 'datum["b"] * 2', as: 'b2' }], + mark: "point", + encoding: { + x: { field: 'a', type: "temporal" }, + y: { field: 'b', type: "quantitative" }, + color: { type: "quantitative", aggregate: 'count' }, + size: { field: 'b2', type: "quantitative" }, + } + }); + var ancestorParse = new AncestorParse(); + var parent = new DataFlowNode(null); + parseTransformArray(parent, model, ancestorParse); + assert.deepEqual(ancestorParse.combine(), { 'b2': 'derived' }); + assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, ancestorParse).parse, { + 'a': 'date', + 'b': 'number' + }); + }); + it('should not parse fields with aggregate=missing/valid/distinct', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + x: { aggregate: 'missing', field: 'b', type: "quantitative" }, + y: { aggregate: 'valid', field: 'b', type: "quantitative" }, + color: { aggregate: 'distinct', field: 'b', type: "quantitative" } + } + }); + assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, new AncestorParse()), null); + }); + it('should not parse the same field twice', function () { + var model = parseFacetModel({ + data: { + values: [], + format: { + parse: { + a: 'number' + } + } + }, + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: "point", + encoding: { + x: { field: 'a', type: "quantitative" }, + y: { field: 'b', type: "temporal" } + } + } + }); + assert.deepEqual(ParseNode.makeExplicit(null, model, new AncestorParse()).parse, { + 'a': 'number' + }); + model.parseScale(); + model.parseData(); + assert.deepEqual(model.child.component.data.ancestorParse.combine(), { + 'a': 'number', + 'b': 'date' + }); + // set the ancestor parse to see whether fields from it are not parsed + model.child.component.data.ancestorParse = new AncestorParse({ a: 'number' }); + assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model.child, model.child.component.data.ancestorParse).parse, { + 'b': 'date' + }); + }); + it('should not parse the same field twice in explicit', function () { + var model = parseUnitModel({ + data: { + values: [], + format: { + parse: { + a: 'number' + } + } + }, + mark: "point", + encoding: {} + }); + assert.isNull(ParseNode.makeExplicit(null, model, new AncestorParse({ a: 'number' }, {}))); + }); + it('should not parse the same field twice in implicit', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + x: { field: 'a', type: 'quantitative' } + } + }); + assert.isNull(ParseNode.makeExplicit(null, model, new AncestorParse({ a: 'number' }, {}))); + }); + it('should not parse counts', function () { + var model = parseUnitModel({ + "mark": "point", + "encoding": { + "x": { "aggregate": "sum", "field": "foo", "type": "quantitative" }, + "y": { "aggregate": "count", "type": "quantitative" } + } + }); + assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, new AncestorParse()).parse, { + "foo": "number" + }); + }); + it('should add flatten for nested fields', function () { + var model = parseUnitModel({ + "mark": "point", + "encoding": { + "x": { "field": "foo.bar", "type": "quantitative" }, + "y": { "field": "foo.baz", "type": "ordinal" } + } + }); + assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, new AncestorParse()).parse, { + "foo.bar": "number", + "foo.baz": "flatten" + }); + }); + it('should not parse if parse is disabled for a field', function () { + var model = parseUnitModel({ + "mark": "point", + "data": { + "values": [], + "format": { + "parse": { + "b": null + } + } + }, + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "quantitative" } + } + }); + var ancestorParse = new AncestorParse(); + assert.isNull(ParseNode.makeExplicit(null, model, ancestorParse), null); + assert.deepEqual(ancestorParse.combine(), { + b: null + }); + assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, ancestorParse).parse, { + a: 'number' + }); + }); + it('should not parse if parse is disabled', function () { + var model = parseUnitModel({ + "mark": "point", + "data": { + "values": [], + "format": { + "parse": null // implies AncestorParse.makeExplicit = true + } + }, + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "quantitative" } + } + }); + assert.isNull(ParseNode.makeExplicit(null, model, new AncestorParse({}, {}, true))); + }); + }); + describe('assembleTransforms', function () { + it('should assemble correct parse expressions', function () { + var p = new ParseNode(null, { + n: 'number', + b: 'boolean', + s: 'string', + d1: 'date', + d2: 'date:"%y"', + d3: 'utc:"%y"' + }); + assert.deepEqual(p.assembleTransforms(), [ + { type: 'formula', expr: 'toNumber(datum["n"])', as: 'n' }, + { type: 'formula', expr: 'toBoolean(datum["b"])', as: 'b' }, + { type: 'formula', expr: 'toString(datum["s"])', as: 's' }, + { type: 'formula', expr: 'toDate(datum["d1"])', as: 'd1' }, + { type: 'formula', expr: 'timeParse(datum["d2"],"%y")', as: 'd2' }, + { type: 'formula', expr: 'utcParse(datum["d3"],"%y")', as: 'd3' } + ]); + }); + it('should assemble flatten for nested fields', function () { + var p = new ParseNode(null, { + flat: 'number', + 'nested.field': 'flatten' + }); + assert.deepEqual(p.assembleTransforms(true), [ + { type: 'formula', expr: 'datum["nested"] && datum["nested"]["field"]', as: 'nested.field' } + ]); + }); + it('should show warning for unrecognized types', log.wrap(function (localLogger) { + var p = new ParseNode(null, { + x: 'foo', + }); + assert.deepEqual(p.assembleTransforms(), []); + assert.equal(localLogger.warns[0], log.message.unrecognizedParse('foo')); + })); + }); + describe('assembleFormatParse', function () { + it('should assemble correct parse', function () { + var p = new ParseNode(null, { + n: 'number', + b: 'boolean', + 'nested.field': 'flatten' + }); + assert.deepEqual(p.assembleFormatParse(), { + n: 'number', + b: 'boolean' + }); + }); + }); + describe('producedFields', function () { + it('should produce the correct fields', function () { + var p = new ParseNode(null, { + n: 'number', + b: 'boolean', + 'nested.field': 'flatten' + }); + assert.deepEqual(p.producedFields(), { n: true, b: true, 'nested.field': true }); + }); + }); +}); +//# sourceMappingURL=formatparse.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/formatparse.test.js.map b/build/test/compile/data/formatparse.test.js.map new file mode 100644 index 0000000000..c7fadc03ed --- /dev/null +++ b/build/test/compile/data/formatparse.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"formatparse.test.js","sourceRoot":"","sources":["../../../../test/compile/data/formatparse.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\nimport {assert} from 'chai';\nimport {AncestorParse} from '../../../src/compile/data';\nimport {DataFlowNode} from '../../../src/compile/data/dataflow';\nimport {ParseNode} from '../../../src/compile/data/formatparse';\nimport {parseTransformArray} from '../../../src/compile/data/parse';\nimport {ModelWithField} from '../../../src/compile/model';\nimport * as log from '../../../src/log';\nimport {parseFacetModel, parseUnitModel} from '../../util';\n\ndescribe('compile/data/formatparse', () => {\n describe('parseUnit', () => {\n it('should parse binned fields as numbers', () => {\n const model = parseUnitModel({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"ordinal\", \"bin\": true},\n \"y\": {\"field\": \"b\", \"type\": \"ordinal\"}\n }\n });\n\n assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, new AncestorParse()).parse, {\n a: 'number'\n });\n });\n\n it('should flatten nested fields that are used to sort domains', () => {\n const model = parseUnitModel({\n \"mark\": \"point\",\n \"encoding\": {\n x: {field: 'a', type: 'ordinal', sort: {field: 'foo.bar', op: 'mean'}},\n }\n });\n\n assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, new AncestorParse()).parse, {\n 'foo.bar': 'flatten'\n });\n });\n\n it('should return a correct customized parse.', () => {\n const model = parseUnitModel({\n \"data\": {\"url\": \"a.json\", \"format\": {\"parse\": {\"c\": \"number\", \"d\": \"date\"}}},\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"b\", \"type\": \"temporal\"},\n \"color\": {\"field\": \"c\", \"type\": \"ordinal\"},\n \"shape\": {\"field\": \"c\", \"type\": \"nominal\"}\n }\n });\n\n const ancestorParese = new AncestorParse();\n assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, ancestorParese).parse, {\n a: 'number',\n b: 'date'\n });\n\n assert.deepEqual(ParseNode.makeExplicit(null, model, ancestorParese).parse, {\n c: 'number',\n d: 'date'\n });\n });\n\n it('should include parse for all applicable fields, and exclude calculated fields', function() {\n const model = parseUnitModel({\n transform: [{calculate: 'datum[\"b\"] * 2', as: 'b2'}],\n mark: \"point\",\n encoding: {\n x: {field: 'a', type: \"temporal\"},\n y: {field: 'b', type: \"quantitative\"},\n color: {type: \"quantitative\", aggregate: 'count'},\n size: {field: 'b2', type: \"quantitative\"},\n }\n });\n\n const ancestorParse = new AncestorParse();\n const parent = new DataFlowNode(null);\n parseTransformArray(parent, model, ancestorParse);\n assert.deepEqual(ancestorParse.combine(), {'b2': 'derived'});\n assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, ancestorParse).parse, {\n 'a': 'date',\n 'b': 'number'\n });\n });\n\n it('should not parse fields with aggregate=missing/valid/distinct', function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n x: {aggregate: 'missing', field: 'b', type: \"quantitative\"},\n y: {aggregate: 'valid', field: 'b', type: \"quantitative\"},\n color: {aggregate: 'distinct', field: 'b', type: \"quantitative\"}\n }\n });\n\n assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, new AncestorParse()), null);\n });\n\n it('should not parse the same field twice', function() {\n const model = parseFacetModel({\n data: {\n values: [],\n format: {\n parse: {\n a: 'number'\n }\n }\n },\n facet: {\n row: {field: 'a', type: 'ordinal'}\n },\n spec: {\n mark: \"point\",\n encoding: {\n x: {field: 'a', type: \"quantitative\"},\n y: {field: 'b', type: \"temporal\"}\n }\n }\n });\n\n assert.deepEqual(ParseNode.makeExplicit(null, model, new AncestorParse()).parse, {\n 'a': 'number'\n });\n model.parseScale();\n model.parseData();\n\n assert.deepEqual(model.child.component.data.ancestorParse.combine(), {\n 'a': 'number',\n 'b': 'date'\n });\n\n // set the ancestor parse to see whether fields from it are not parsed\n model.child.component.data.ancestorParse = new AncestorParse({a: 'number'});\n assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model.child as ModelWithField, model.child.component.data.ancestorParse).parse, {\n 'b': 'date'\n });\n });\n\n it('should not parse the same field twice in explicit', function() {\n const model = parseUnitModel({\n data: {\n values: [],\n format: {\n parse: {\n a: 'number'\n }\n }\n },\n mark: \"point\",\n encoding: {}\n });\n\n assert.isNull(ParseNode.makeExplicit(null, model, new AncestorParse({a: 'number'}, {})));\n });\n\n it('should not parse the same field twice in implicit', function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n x: {field: 'a', type: 'quantitative'}\n }\n });\n\n assert.isNull(ParseNode.makeExplicit(null, model, new AncestorParse({a: 'number'}, {})));\n });\n\n it('should not parse counts', () => {\n const model = parseUnitModel({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"foo\", \"type\": \"quantitative\"},\n \"y\": {\"aggregate\": \"count\", \"type\": \"quantitative\"}\n }\n });\n\n assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, new AncestorParse()).parse, {\n \"foo\": \"number\"\n });\n });\n\n it('should add flatten for nested fields', () => {\n const model = parseUnitModel({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"foo.bar\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"foo.baz\", \"type\": \"ordinal\"}\n }\n });\n\n assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, new AncestorParse()).parse, {\n \"foo.bar\": \"number\",\n \"foo.baz\": \"flatten\"\n });\n });\n\n it('should not parse if parse is disabled for a field', () => {\n const model = parseUnitModel({\n \"mark\": \"point\",\n \"data\": {\n \"values\": [],\n \"format\": {\n \"parse\": {\n \"b\": null\n }\n }\n },\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"b\", \"type\": \"quantitative\"}\n }\n });\n\n const ancestorParse = new AncestorParse();\n assert.isNull(ParseNode.makeExplicit(null, model, ancestorParse), null);\n assert.deepEqual(ancestorParse.combine(), {\n b: null\n });\n assert.deepEqual(ParseNode.makeImplicitFromEncoding(null, model, ancestorParse).parse, {\n a: 'number'\n });\n });\n\n it('should not parse if parse is disabled', () => {\n const model = parseUnitModel({\n \"mark\": \"point\",\n \"data\": {\n \"values\": [],\n \"format\": {\n \"parse\": null // implies AncestorParse.makeExplicit = true\n }\n },\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"b\", \"type\": \"quantitative\"}\n }\n });\n\n assert.isNull(ParseNode.makeExplicit(null, model, new AncestorParse({}, {}, true)));\n });\n });\n\n describe('assembleTransforms', function() {\n it('should assemble correct parse expressions', function() {\n const p = new ParseNode(null, {\n n: 'number',\n b: 'boolean',\n s: 'string',\n d1: 'date',\n d2: 'date:\"%y\"',\n d3: 'utc:\"%y\"'\n });\n\n assert.deepEqual(p.assembleTransforms(), [\n {type: 'formula', expr: 'toNumber(datum[\"n\"])', as: 'n'},\n {type: 'formula', expr: 'toBoolean(datum[\"b\"])', as: 'b'},\n {type: 'formula', expr: 'toString(datum[\"s\"])', as: 's'},\n {type: 'formula', expr: 'toDate(datum[\"d1\"])', as: 'd1'},\n {type: 'formula', expr: 'timeParse(datum[\"d2\"],\"%y\")', as: 'd2'},\n {type: 'formula', expr: 'utcParse(datum[\"d3\"],\"%y\")', as: 'd3'}\n ]);\n });\n\n it('should assemble flatten for nested fields', function() {\n const p = new ParseNode(null, {\n flat: 'number',\n 'nested.field': 'flatten'\n });\n\n assert.deepEqual(p.assembleTransforms(true), [\n {type: 'formula', expr: 'datum[\"nested\"] && datum[\"nested\"][\"field\"]', as: 'nested.field'}\n ]);\n });\n\n it('should show warning for unrecognized types', log.wrap((localLogger) => {\n const p = new ParseNode(null, {\n x: 'foo',\n });\n\n assert.deepEqual(p.assembleTransforms(), []);\n assert.equal(localLogger.warns[0], log.message.unrecognizedParse('foo'));\n }));\n });\n\n describe('assembleFormatParse', function() {\n it('should assemble correct parse', function() {\n const p = new ParseNode(null, {\n n: 'number',\n b: 'boolean',\n 'nested.field': 'flatten'\n });\n\n assert.deepEqual(p.assembleFormatParse(), {\n n: 'number',\n b: 'boolean'\n });\n });\n });\n\n describe('producedFields', function() {\n it('should produce the correct fields', function() {\n const p = new ParseNode(null, {\n n: 'number',\n b: 'boolean',\n 'nested.field': 'flatten'\n });\n\n assert.deepEqual(p.producedFields(), {n: true, b: true, 'nested.field': true});\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/geojson.test.d.ts b/build/test/compile/data/geojson.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/geojson.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/geojson.test.js b/build/test/compile/data/geojson.test.js new file mode 100644 index 0000000000..c588ae4fcc --- /dev/null +++ b/build/test/compile/data/geojson.test.js @@ -0,0 +1,45 @@ +import { assert } from 'chai'; +import { DataFlowNode } from '../../../src/compile/data/dataflow'; +import { GeoJSONNode } from '../../../src/compile/data/geojson'; +import { contains, every } from '../../../src/util'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +/* tslint:disable:quotemark */ +describe('compile/data/geojson', function () { + it('should make transform and assemble correctly', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { + "url": "data/zipcodes.csv", + "format": { + "type": "csv" + } + }, + "mark": "circle", + "encoding": { + "longitude": { + "field": "longitude", + "type": "quantitative" + }, + "latitude": { + "field": "latitude", + "type": "quantitative" + } + } + }); + var root = new DataFlowNode(null); + GeoJSONNode.parseAll(root, model); + var node = root.children[0]; + var _loop_1 = function () { + assert.instanceOf(node, GeoJSONNode); + var transform = node.assemble(); + assert.equal(transform.type, 'geojson'); + assert.isTrue(every(['longitude', 'latitude'], function (field) { return contains(transform.fields, field); })); + assert.isUndefined(transform.geojson); + assert.isAtMost(node.children.length, 1); + node = node.children[0]; + }; + while (node != null) { + _loop_1(); + } + }); +}); +//# sourceMappingURL=geojson.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/geojson.test.js.map b/build/test/compile/data/geojson.test.js.map new file mode 100644 index 0000000000..eb8cd5441f --- /dev/null +++ b/build/test/compile/data/geojson.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"geojson.test.js","sourceRoot":"","sources":["../../../../test/compile/data/geojson.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,YAAY,EAAC,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAC,WAAW,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,oCAAoC,EAAC,MAAM,YAAY,CAAC;AAChE,8BAA8B;AAE9B,QAAQ,CAAC,sBAAsB,EAAE;IAC/B,EAAE,CAAC,8CAA8C,EAAE;QACjD,IAAM,KAAK,GAAG,oCAAoC,CAAC;YACjD,MAAM,EAAE;gBACN,KAAK,EAAE,mBAAmB;gBAC1B,QAAQ,EAAE;oBACR,MAAM,EAAE,KAAK;iBACd;aACF;YACD,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE;gBACV,WAAW,EAAE;oBACX,OAAO,EAAE,WAAW;oBACpB,MAAM,EAAE,cAAc;iBACvB;gBACD,UAAU,EAAE;oBACV,OAAO,EAAE,UAAU;oBACnB,MAAM,EAAE,cAAc;iBACvB;aACF;SACF,CAAC,CAAC;QAEH,IAAM,IAAI,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;QACpC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAElC,IAAI,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;;YAG1B,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YACrC,IAAM,SAAS,GAAiB,IAAK,CAAC,QAAQ,EAAE,CAAC;YACjD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,UAAC,KAAK,IAAK,OAAA,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,EAAjC,CAAiC,CAAC,CAAC,CAAC;YAC9F,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAEtC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YACzC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;QATD,OAAO,IAAI,IAAI,IAAI;;SASlB;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\nimport {DataFlowNode} from '../../../src/compile/data/dataflow';\nimport {GeoJSONNode} from '../../../src/compile/data/geojson';\nimport {contains, every} from '../../../src/util';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n/* tslint:disable:quotemark */\n\ndescribe('compile/data/geojson', () => {\n it('should make transform and assemble correctly', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\n \"url\": \"data/zipcodes.csv\",\n \"format\": {\n \"type\": \"csv\"\n }\n },\n \"mark\": \"circle\",\n \"encoding\": {\n \"longitude\": {\n \"field\": \"longitude\",\n \"type\": \"quantitative\"\n },\n \"latitude\": {\n \"field\": \"latitude\",\n \"type\": \"quantitative\"\n }\n }\n });\n\n const root = new DataFlowNode(null);\n GeoJSONNode.parseAll(root, model);\n\n let node = root.children[0];\n\n while (node != null) {\n assert.instanceOf(node, GeoJSONNode);\n const transform = (node).assemble();\n assert.equal(transform.type, 'geojson');\n assert.isTrue(every(['longitude', 'latitude'], (field) => contains(transform.fields, field)));\n assert.isUndefined(transform.geojson);\n\n assert.isAtMost(node.children.length, 1);\n node = node.children[0];\n }\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/geopoint.test.d.ts b/build/test/compile/data/geopoint.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/geopoint.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/geopoint.test.js b/build/test/compile/data/geopoint.test.js new file mode 100644 index 0000000000..3e28808b4d --- /dev/null +++ b/build/test/compile/data/geopoint.test.js @@ -0,0 +1,48 @@ +import { assert } from 'chai'; +import { DataFlowNode } from '../../../src/compile/data/dataflow'; +import { GeoPointNode } from '../../../src/compile/data/geopoint'; +import { contains, every } from '../../../src/util'; +import { parseUnitModel } from '../../util'; +describe('compile/data/geopoint', function () { + describe('geojson', function () { + it('should make transform and assemble correctly', function () { + var model = parseUnitModel({ + 'data': { + 'url': 'data/zipcodes.csv', + 'format': { + 'type': 'csv' + } + }, + 'mark': 'circle', + 'encoding': { + 'longitude': { + 'field': 'longitude', + 'type': 'quantitative' + }, + 'latitude': { + 'field': 'latitude', + 'type': 'quantitative' + } + } + }); + model.parse(); + var root = new DataFlowNode(null); + GeoPointNode.parseAll(root, model); + var node = root.children[0]; + var _loop_1 = function () { + assert.instanceOf(node, GeoPointNode); + var transform = node.assemble(); + assert.equal(transform.type, 'geopoint'); + assert.isTrue(every(['longitude', 'latitude'], function (field) { return contains(transform.fields, field); })); + assert.isTrue(every([model.getName('x'), model.getName('y')], function (a) { return contains(transform.as, a); })); + assert.isDefined(transform.projection); + assert.isAtMost(node.children.length, 1); + node = node.children[0]; + }; + while (node != null) { + _loop_1(); + } + }); + }); +}); +//# sourceMappingURL=geopoint.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/geopoint.test.js.map b/build/test/compile/data/geopoint.test.js.map new file mode 100644 index 0000000000..b44ecef6c2 --- /dev/null +++ b/build/test/compile/data/geopoint.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"geopoint.test.js","sourceRoot":"","sources":["../../../../test/compile/data/geopoint.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,YAAY,EAAC,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAC,YAAY,EAAC,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAE1C,QAAQ,CAAC,uBAAuB,EAAE;IAChC,QAAQ,CAAC,SAAS,EAAE;QAClB,EAAE,CAAC,8CAA8C,EAAE;YACjD,IAAM,KAAK,GAAG,cAAc,CAAC;gBAC3B,MAAM,EAAE;oBACN,KAAK,EAAE,mBAAmB;oBAC1B,QAAQ,EAAE;wBACR,MAAM,EAAE,KAAK;qBACd;iBACF;gBACD,MAAM,EAAE,QAAQ;gBAChB,UAAU,EAAE;oBACV,WAAW,EAAE;wBACX,OAAO,EAAE,WAAW;wBACpB,MAAM,EAAE,cAAc;qBACvB;oBACD,UAAU,EAAE;wBACV,OAAO,EAAE,UAAU;wBACnB,MAAM,EAAE,cAAc;qBACvB;iBACF;aACF,CAAC,CAAC;YACH,KAAK,CAAC,KAAK,EAAE,CAAC;YAEd,IAAM,IAAI,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;YACpC,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAEnC,IAAI,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;;gBAG1B,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;gBAEtC,IAAM,SAAS,GAAuC,IAAK,CAAC,QAAQ,EAAE,CAAC;gBACvE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBACzC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,UAAC,KAAK,IAAK,OAAA,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,EAAjC,CAAiC,CAAC,CAAC,CAAC;gBAC9F,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,UAAC,CAAC,IAAK,OAAA,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAzB,CAAyB,CAAC,CAAC,CAAC;gBACjG,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;gBACvC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBACzC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC1B,CAAC;YAVD,OAAO,IAAI,IAAI,IAAI;;aAUlB;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\nimport {DataFlowNode} from '../../../src/compile/data/dataflow';\nimport {GeoPointNode} from '../../../src/compile/data/geopoint';\nimport {contains, every} from '../../../src/util';\nimport {VgGeoPointTransform} from '../../../src/vega.schema';\nimport {parseUnitModel} from '../../util';\n\ndescribe('compile/data/geopoint', () => {\n describe('geojson', function () {\n it('should make transform and assemble correctly', () => {\n const model = parseUnitModel({\n 'data': {\n 'url': 'data/zipcodes.csv',\n 'format': {\n 'type': 'csv'\n }\n },\n 'mark': 'circle',\n 'encoding': {\n 'longitude': {\n 'field': 'longitude',\n 'type': 'quantitative'\n },\n 'latitude': {\n 'field': 'latitude',\n 'type': 'quantitative'\n }\n }\n });\n model.parse();\n\n const root = new DataFlowNode(null);\n GeoPointNode.parseAll(root, model);\n\n let node = root.children[0];\n\n while (node != null) {\n assert.instanceOf(node, GeoPointNode);\n\n const transform: VgGeoPointTransform = (node).assemble();\n assert.equal(transform.type, 'geopoint');\n assert.isTrue(every(['longitude', 'latitude'], (field) => contains(transform.fields, field)));\n assert.isTrue(every([model.getName('x'), model.getName('y')], (a) => contains(transform.as, a)));\n assert.isDefined(transform.projection);\n assert.isAtMost(node.children.length, 1);\n node = node.children[0];\n }\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/lookup.test.d.ts b/build/test/compile/data/lookup.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/lookup.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/lookup.test.js b/build/test/compile/data/lookup.test.js new file mode 100644 index 0000000000..14c8a44fb0 --- /dev/null +++ b/build/test/compile/data/lookup.test.js @@ -0,0 +1,77 @@ +import { assert } from 'chai'; +import { AncestorParse } from '../../../src/compile/data'; +import { LookupNode } from '../../../src/compile/data/lookup'; +import { parseTransformArray } from '../../../src/compile/data/parse'; +import * as log from '../../../src/log'; +import { parseUnitModel } from '../../util'; +describe('compile/data/lookup', function () { + it('should parse lookup from array', function () { + var model = parseUnitModel({ + 'data': { 'url': 'data/lookup_groups.csv' }, + 'transform': [{ + 'lookup': 'person', + 'from': { + 'data': { 'url': 'data/lookup_people.csv' }, + 'key': 'name', + 'fields': ['age', 'height'] + } + }], + 'mark': 'bar', + 'encoding': {} + }); + var t = parseTransformArray(null, model, new AncestorParse); + assert.deepEqual(t.assemble(), { + type: 'lookup', + from: 'lookup_0', + key: 'name', + fields: ['person'], + values: ['age', 'height'] + }); + }); + it('should create node for flat lookup', function () { + var lookup = new LookupNode(null, { + 'lookup': 'person', + 'from': { + 'data': { 'url': 'data/lookup_people.csv' }, + 'key': 'name', + 'fields': ['age', 'height'] + } + }, 'lookup_0'); + assert.deepEqual(lookup.assemble(), { + type: 'lookup', + from: 'lookup_0', + key: 'name', + fields: ['person'], + values: ['age', 'height'] + }); + }); + it('should create node for nested lookup', function () { + var lookup = new LookupNode(null, { + 'lookup': 'person', + 'from': { + 'data': { 'url': 'data/lookup_people.csv' }, + 'key': 'name' + }, + 'as': 'foo' + }, 'lookup_0'); + assert.deepEqual(lookup.assemble(), { + type: 'lookup', + from: 'lookup_0', + key: 'name', + fields: ['person'], + as: ['foo'] + }); + }); + it('should warn if fields are not specified and as is missing', log.wrap(function (localLogger) { + var lookup = new LookupNode(null, { + 'lookup': 'person', + 'from': { + 'data': { 'url': 'data/lookup_people.csv' }, + 'key': 'name' + } + }, 'lookup_0'); + lookup.assemble(); + assert.equal(localLogger.warns[0], log.message.NO_FIELDS_NEEDS_AS); + })); +}); +//# sourceMappingURL=lookup.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/lookup.test.js.map b/build/test/compile/data/lookup.test.js.map new file mode 100644 index 0000000000..4c1eab7b06 --- /dev/null +++ b/build/test/compile/data/lookup.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"lookup.test.js","sourceRoot":"","sources":["../../../../test/compile/data/lookup.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {AncestorParse} from '../../../src/compile/data';\nimport {LookupNode} from '../../../src/compile/data/lookup';\nimport {parseTransformArray} from '../../../src/compile/data/parse';\nimport * as log from '../../../src/log';\nimport {VgLookupTransform} from '../../../src/vega.schema';\nimport {parseUnitModel} from '../../util';\n\ndescribe('compile/data/lookup', function() {\n it('should parse lookup from array', function () {\n const model = parseUnitModel({\n 'data': {'url': 'data/lookup_groups.csv'},\n 'transform': [{\n 'lookup': 'person',\n 'from': {\n 'data': {'url': 'data/lookup_people.csv'},\n 'key': 'name',\n 'fields': ['age', 'height']\n }\n }],\n 'mark': 'bar',\n 'encoding': {}\n });\n\n const t = parseTransformArray(null, model, new AncestorParse);\n assert.deepEqual((t as LookupNode).assemble(), {\n type: 'lookup',\n from: 'lookup_0',\n key: 'name',\n fields: ['person'],\n values: ['age', 'height']\n });\n });\n\n it('should create node for flat lookup', function () {\n const lookup = new LookupNode(null, {\n 'lookup': 'person',\n 'from': {\n 'data': {'url': 'data/lookup_people.csv'},\n 'key': 'name',\n 'fields': ['age', 'height']\n }\n }, 'lookup_0');\n\n assert.deepEqual(lookup.assemble(), {\n type: 'lookup',\n from: 'lookup_0',\n key: 'name',\n fields: ['person'],\n values: ['age', 'height']\n });\n });\n\n it('should create node for nested lookup', function () {\n const lookup = new LookupNode(null, {\n 'lookup': 'person',\n 'from': {\n 'data': {'url': 'data/lookup_people.csv'},\n 'key': 'name'\n },\n 'as': 'foo'\n }, 'lookup_0');\n\n assert.deepEqual(lookup.assemble(), {\n type: 'lookup',\n from: 'lookup_0',\n key: 'name',\n fields: ['person'],\n as: ['foo']\n });\n });\n\n it('should warn if fields are not specified and as is missing', log.wrap((localLogger) => {\n const lookup = new LookupNode(null, {\n 'lookup': 'person',\n 'from': {\n 'data': {'url': 'data/lookup_people.csv'},\n 'key': 'name'\n }\n }, 'lookup_0');\n lookup.assemble();\n\n assert.equal(localLogger.warns[0], log.message.NO_FIELDS_NEEDS_AS);\n }));\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/parse.test.d.ts b/build/test/compile/data/parse.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/parse.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/parse.test.js b/build/test/compile/data/parse.test.js new file mode 100644 index 0000000000..a0d4ff5e86 --- /dev/null +++ b/build/test/compile/data/parse.test.js @@ -0,0 +1,207 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { AncestorParse } from '../../../src/compile/data'; +import { AggregateNode } from '../../../src/compile/data/aggregate'; +import { BinNode } from '../../../src/compile/data/bin'; +import { CalculateNode } from '../../../src/compile/data/calculate'; +import { DataFlowNode } from '../../../src/compile/data/dataflow'; +import { FilterNode } from '../../../src/compile/data/filter'; +import { ParseNode } from '../../../src/compile/data/formatparse'; +import { parseTransformArray } from '../../../src/compile/data/parse'; +import { TimeUnitNode } from '../../../src/compile/data/timeunit'; +import { WindowTransformNode } from '../../../src/compile/data/window'; +import { parseUnitModel } from '../../util'; +describe('compile/data/parse', function () { + describe('parseTransformArray()', function () { + it('should return a CalculateNode and a FilterNode', function () { + var model = parseUnitModel({ + data: { values: [] }, + mark: 'point', + transform: [{ calculate: 'calculate', as: 'as' }, { filter: 'filter' }], + encoding: { + x: { field: 'a', type: 'temporal', timeUnit: 'month' } + } + }); + var root = new DataFlowNode(null); + var result = parseTransformArray(root, model, new AncestorParse()); + assert.isTrue(root.children[0] instanceof CalculateNode); + assert.isTrue(result instanceof FilterNode); + }); + it('should add a parse node for filter transforms with time unit', function () { + var model = parseUnitModel({ + "data": { "url": "a.json" }, + "transform": [{ + "filter": { + "not": { + "and": [{ + "or": [ + { + "timeUnit": "year", + "field": "date", + "equal": 2005 + }, + "datum.a > 5" + ] + }] + } + } + }], + "mark": "point", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "temporal" }, + "color": { "field": "c", "type": "ordinal" }, + "shape": { "field": "d", "type": "nominal" } + } + }); + var root = new DataFlowNode(null); + var parse = new AncestorParse(); + var result = parseTransformArray(root, model, parse); + assert.isTrue(root.children[0] instanceof ParseNode); + assert.isTrue(result instanceof FilterNode); + assert.deepEqual(root.children[0].parse, { + date: 'date' + }); + assert.deepEqual(parse.combine(), { date: 'date' }); + }); + it('should return a BinNode node and a TimeUnitNode', function () { + var model = parseUnitModel({ + data: { values: [] }, + mark: 'point', + transform: [{ bin: true, field: 'field', as: 'a' }, { timeUnit: 'month', field: 'field', as: 'b' }], + encoding: { + x: { field: 'a', type: 'temporal', timeUnit: 'month' } + } + }); + var root = new DataFlowNode(null); + var parse = new AncestorParse(); + var result = parseTransformArray(root, model, parse); + assert.isTrue(root.children[0] instanceof BinNode); + assert.isTrue(result instanceof TimeUnitNode); + assert.deepEqual(parse.combine(), { a: 'number', a_end: 'number', b: 'date' }); + }); + it('should return a BinNode and a AggregateNode', function () { + var model = parseUnitModel({ + data: { values: [] }, + mark: 'point', + transform: [{ bin: true, field: 'field', as: 'a' }, { aggregate: [{ op: 'count', field: 'f', as: 'b' }, { op: 'sum', field: 'f', as: 'c' }], groupby: ['field'] }], + encoding: { + x: { field: 'a', type: 'temporal', timeUnit: 'month' } + } + }); + var root = new DataFlowNode(null); + var result = parseTransformArray(root, model, new AncestorParse()); + assert.isTrue(root.children[0] instanceof BinNode); + assert.isTrue(result instanceof AggregateNode); + }); + it('should return a WindowTransform Node', function () { + var transform = { + window: [ + { + op: 'count', + field: 'f', + as: 'b', + } + ], + }; + var model = parseUnitModel({ + data: { values: [] }, + mark: 'point', + transform: [ + transform + ], + encoding: { + x: { field: 'a', type: 'temporal', timeUnit: 'month' } + } + }); + var root = new DataFlowNode(null); + parseTransformArray(root, model, new AncestorParse()); + assert.isTrue(root.children[0] instanceof WindowTransformNode); + }); + it('should return a WindowTransform Node with optional properties', function () { + var transform = { + window: [ + { + op: 'row_number', + as: 'ordered_row_number', + }, + ], + ignorePeers: false, + sort: [ + { + field: 'f', + order: 'ascending' + } + ] + }; + var model = parseUnitModel({ + data: { values: [] }, + mark: 'point', + transform: [ + transform + ], + encoding: { + x: { field: 'a', type: 'temporal', timeUnit: 'month' } + } + }); + var root = new DataFlowNode(null); + parseTransformArray(root, model, new AncestorParse()); + assert.isTrue(root.children[0] instanceof WindowTransformNode); + }); + it('should return a WindowTransform Node', function () { + var transform = { + window: [ + { + op: 'count', + field: 'f', + as: 'b', + } + ], + }; + var model = parseUnitModel({ + data: { values: [] }, + mark: 'point', + transform: [ + transform + ], + encoding: { + x: { field: 'a', type: 'temporal', timeUnit: 'month' } + } + }); + var root = new DataFlowNode(null); + parseTransformArray(root, model, new AncestorParse()); + assert.isTrue(root.children[0] instanceof WindowTransformNode); + }); + it('should return a WindowTransform Node with optional properties', function () { + var transform = { + window: [ + { + op: 'row_number', + as: 'ordered_row_number', + }, + ], + ignorePeers: false, + sort: [ + { + field: 'f', + order: 'ascending' + } + ] + }; + var model = parseUnitModel({ + data: { values: [] }, + mark: 'point', + transform: [ + transform + ], + encoding: { + x: { field: 'a', type: 'temporal', timeUnit: 'month' } + } + }); + var root = new DataFlowNode(null); + parseTransformArray(root, model, new AncestorParse()); + assert.isTrue(root.children[0] instanceof WindowTransformNode); + }); + }); +}); +//# sourceMappingURL=parse.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/parse.test.js.map b/build/test/compile/data/parse.test.js.map new file mode 100644 index 0000000000..0c411e055c --- /dev/null +++ b/build/test/compile/data/parse.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.test.js","sourceRoot":"","sources":["../../../../test/compile/data/parse.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {AncestorParse} from '../../../src/compile/data';\nimport {AggregateNode} from '../../../src/compile/data/aggregate';\nimport {BinNode} from '../../../src/compile/data/bin';\nimport {CalculateNode} from '../../../src/compile/data/calculate';\nimport {DataFlowNode} from '../../../src/compile/data/dataflow';\nimport {FilterNode} from '../../../src/compile/data/filter';\nimport {ParseNode} from '../../../src/compile/data/formatparse';\nimport {parseTransformArray} from '../../../src/compile/data/parse';\nimport {TimeUnitNode} from '../../../src/compile/data/timeunit';\nimport {WindowTransformNode} from '../../../src/compile/data/window';\nimport {Transform} from '../../../src/transform';\nimport {parseUnitModel} from '../../util';\n\ndescribe('compile/data/parse', () => {\n describe('parseTransformArray()', () => {\n it('should return a CalculateNode and a FilterNode', () => {\n const model = parseUnitModel({\n data: {values: []},\n mark: 'point',\n transform: [{calculate: 'calculate', as: 'as'}, {filter: 'filter'}],\n encoding: {\n x: {field: 'a', type: 'temporal', timeUnit: 'month'}\n }\n });\n\n const root = new DataFlowNode(null);\n const result = parseTransformArray(root, model, new AncestorParse());\n assert.isTrue(root.children[0] instanceof CalculateNode);\n assert.isTrue(result instanceof FilterNode);\n });\n\n it('should add a parse node for filter transforms with time unit', () => {\n const model = parseUnitModel({\n \"data\": {\"url\": \"a.json\"},\n \"transform\": [{\n \"filter\": {\n \"not\": {\n \"and\": [{\n \"or\": [\n {\n \"timeUnit\": \"year\",\n \"field\": \"date\",\n \"equal\": 2005\n },\n \"datum.a > 5\"\n ]\n }]\n }\n }\n }],\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"b\", \"type\": \"temporal\"},\n \"color\": {\"field\": \"c\", \"type\": \"ordinal\"},\n \"shape\": {\"field\": \"d\", \"type\": \"nominal\"}\n }\n });\n\n const root = new DataFlowNode(null);\n const parse = new AncestorParse();\n const result = parseTransformArray(root, model, parse);\n\n assert.isTrue(root.children[0] instanceof ParseNode);\n assert.isTrue(result instanceof FilterNode);\n assert.deepEqual((root.children[0] as ParseNode).parse, {\n date: 'date'\n });\n assert.deepEqual(parse.combine(), {date: 'date'});\n });\n\n it('should return a BinNode node and a TimeUnitNode', () => {\n const model = parseUnitModel({\n data: {values: []},\n mark: 'point',\n transform: [{bin: true, field: 'field', as: 'a'}, {timeUnit: 'month', field: 'field', as: 'b'}],\n encoding: {\n x: {field: 'a', type: 'temporal', timeUnit: 'month'}\n }\n });\n\n const root = new DataFlowNode(null);\n const parse = new AncestorParse();\n const result = parseTransformArray(root, model, parse);\n assert.isTrue(root.children[0] instanceof BinNode);\n assert.isTrue(result instanceof TimeUnitNode);\n assert.deepEqual(parse.combine(), {a: 'number', a_end: 'number', b: 'date'});\n });\n\n it('should return a BinNode and a AggregateNode', () => {\n const model = parseUnitModel({\n data: {values: []},\n mark: 'point',\n transform: [{bin: true, field: 'field', as: 'a'}, {aggregate: [{op: 'count', field: 'f', as: 'b'}, {op: 'sum', field: 'f', as: 'c'}], groupby: ['field']}],\n encoding: {\n x: {field: 'a', type: 'temporal', timeUnit: 'month'}\n }\n });\n\n const root = new DataFlowNode(null);\n const result = parseTransformArray(root, model, new AncestorParse());\n assert.isTrue(root.children[0] instanceof BinNode);\n assert.isTrue(result instanceof AggregateNode);\n });\n\n it ('should return a WindowTransform Node', () => {\n const transform: Transform = {\n window: [\n {\n op: 'count',\n field: 'f',\n as: 'b',\n }\n ],\n };\n const model = parseUnitModel({\n data: {values: []},\n mark: 'point',\n transform: [\n transform\n ],\n encoding: {\n x: {field: 'a', type: 'temporal', timeUnit: 'month'}\n }\n });\n const root = new DataFlowNode(null);\n parseTransformArray(root, model, new AncestorParse());\n assert.isTrue(root.children[0] instanceof WindowTransformNode);\n });\n it ('should return a WindowTransform Node with optional properties', () => {\n const transform: Transform = {\n window: [\n {\n op: 'row_number',\n as: 'ordered_row_number',\n },\n ],\n ignorePeers: false,\n sort: [\n {\n field:'f',\n order:'ascending'\n }\n ]\n };\n const model = parseUnitModel({\n data: {values: []},\n mark: 'point',\n transform: [\n transform\n ],\n encoding: {\n x: {field: 'a', type: 'temporal', timeUnit: 'month'}\n }\n });\n const root = new DataFlowNode(null);\n parseTransformArray(root, model, new AncestorParse());\n assert.isTrue(root.children[0] instanceof WindowTransformNode);\n });\n\n it ('should return a WindowTransform Node', () => {\n const transform: Transform = {\n window: [\n {\n op: 'count',\n field: 'f',\n as: 'b',\n }\n ],\n };\n const model = parseUnitModel({\n data: {values: []},\n mark: 'point',\n transform: [\n transform\n ],\n encoding: {\n x: {field: 'a', type: 'temporal', timeUnit: 'month'}\n }\n });\n const root = new DataFlowNode(null);\n parseTransformArray(root, model, new AncestorParse());\n assert.isTrue(root.children[0] instanceof WindowTransformNode);\n });\n it ('should return a WindowTransform Node with optional properties', () => {\n const transform: Transform = {\n window: [\n {\n op: 'row_number',\n as: 'ordered_row_number',\n },\n ],\n ignorePeers: false,\n sort: [\n {\n field:'f',\n order:'ascending'\n }\n ]\n };\n const model = parseUnitModel({\n data: {values: []},\n mark: 'point',\n transform: [\n transform\n ],\n encoding: {\n x: {field: 'a', type: 'temporal', timeUnit: 'month'}\n }\n });\n const root = new DataFlowNode(null);\n parseTransformArray(root, model, new AncestorParse());\n assert.isTrue(root.children[0] instanceof WindowTransformNode);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/source.test.d.ts b/build/test/compile/data/source.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/source.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/source.test.js b/build/test/compile/data/source.test.js new file mode 100644 index 0000000000..602a806e6a --- /dev/null +++ b/build/test/compile/data/source.test.js @@ -0,0 +1,105 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { SourceNode } from '../../../src/compile/data/source'; +function parse(data) { + return new SourceNode(data); +} +describe('compile/data/source', function () { + describe('compileUnit', function () { + describe('with explicit values', function () { + var source = parse({ + values: [{ a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }] + }); + it('should have values', function () { + assert.deepEqual(source.data.values, [{ a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }]); + }); + it('should have no source.format.type', function () { + assert.deepEqual(source.data.format, undefined); + }); + }); + describe('with explicit values as CSV', function () { + var source = parse({ + values: "a\n1\n2\n3", + format: { type: 'csv' } + }); + it('should have values', function () { + assert.deepEqual(source.data.values, "a\n1\n2\n3"); + }); + it('should have correct type', function () { + assert.equal(source.data.format.type, 'csv'); + }); + }); + describe('with link to url', function () { + var source = parse({ + url: 'http://foo.bar/file.csv', + }); + it('should have format.type csv', function () { + assert.equal(source.data.format.type, 'csv'); + }); + it('should have correct url', function () { + assert.equal(source.data.url, 'http://foo.bar/file.csv'); + }); + }); + describe('without file ending', function () { + var source = parse({ + url: 'http://foo.bar/file.baz', + }); + it('should have format.type json', function () { + assert.equal(source.data.format.type, 'json'); + }); + }); + describe('with no data specified', function () { + var source = parse(undefined); + it('should provide placeholder source data', function () { + assert.equal(source.dataName, 'source'); + }); + }); + describe('with named data source provided', function () { + var source = parse({ name: 'foo' }); + it('should provide named source data', function () { + assert.equal(source.dataName, 'foo'); + }); + }); + describe('data format', function () { + describe('json', function () { + it('should include property if specified', function () { + var source = parse({ + url: 'http://foo.bar', + format: { type: 'json', property: 'baz' } + }); + assert.equal(source.data.format.property, 'baz'); + }); + }); + describe('topojson', function () { + describe('feature property is specified', function () { + var source = parse({ + url: 'http://foo.bar', + format: { type: 'topojson', feature: 'baz' } + }); + it('should have format.type topojson', function () { + assert.equal(source.data.format.type, 'topojson'); + }); + it('should have format.feature baz', function () { + assert.equal(source.data.format.feature, 'baz'); + }); + }); + describe('mesh property is specified', function () { + var source = parse({ + url: 'http://foo.bar', + format: { type: 'topojson', mesh: 'baz' } + }); + it('should have format.type topojson', function () { + assert.equal(source.data.format.type, 'topojson'); + }); + it('should have format.mesh baz', function () { + assert.equal(source.data.format.mesh, 'baz'); + }); + }); + }); + }); + }); + describe('assemble', function () { + // TODO: write test + }); +}); +//# sourceMappingURL=source.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/source.test.js.map b/build/test/compile/data/source.test.js.map new file mode 100644 index 0000000000..33e863241c --- /dev/null +++ b/build/test/compile/data/source.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"source.test.js","sourceRoot":"","sources":["../../../../test/compile/data/source.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\n\nimport {SourceNode} from '../../../src/compile/data/source';\nimport {Data} from '../../../src/data';\n\nfunction parse(data: Data) {\n return new SourceNode(data);\n}\n\ndescribe('compile/data/source', () => {\n describe('compileUnit', () => {\n describe('with explicit values', () => {\n const source = parse({\n values: [{a: 1, b:2, c:3}, {a: 4, b:5, c:6}]\n });\n\n it('should have values', () => {\n assert.deepEqual(source.data.values, [{a: 1, b:2, c:3}, {a: 4, b:5, c:6}]);\n });\n\n it('should have no source.format.type', () => {\n assert.deepEqual(source.data.format, undefined);\n });\n });\n\n describe('with explicit values as CSV', () => {\n const source = parse({\n values: \"a\\n1\\n2\\n3\",\n format: {type: 'csv'}\n });\n\n it('should have values', () => {\n assert.deepEqual(source.data.values, \"a\\n1\\n2\\n3\");\n });\n\n it('should have correct type', () => {\n assert.equal(source.data.format.type, 'csv');\n });\n });\n\n describe('with link to url', () => {\n const source = parse({\n url: 'http://foo.bar/file.csv',\n });\n\n it('should have format.type csv', () => {\n assert.equal(source.data.format.type, 'csv');\n });\n it('should have correct url', () => {\n assert.equal(source.data.url, 'http://foo.bar/file.csv');\n });\n });\n\n describe('without file ending', () => {\n const source = parse({\n url: 'http://foo.bar/file.baz',\n });\n\n it('should have format.type json', () => {\n assert.equal(source.data.format.type, 'json');\n });\n });\n\n describe('with no data specified', () => {\n const source = parse(undefined);\n\n it('should provide placeholder source data', () => {\n assert.equal(source.dataName, 'source');\n });\n });\n\n describe('with named data source provided', () => {\n const source = parse({name: 'foo'});\n\n it('should provide named source data', () => {\n assert.equal(source.dataName, 'foo');\n });\n });\n\n describe('data format', () => {\n describe('json', () => {\n it('should include property if specified', () => {\n const source = parse({\n url: 'http://foo.bar',\n format: {type: 'json', property: 'baz'}\n });\n\n assert.equal(source.data.format.property, 'baz');\n });\n });\n\n describe('topojson', () => {\n describe('feature property is specified', () => {\n const source = parse({\n url: 'http://foo.bar',\n format: {type: 'topojson', feature: 'baz'}\n });\n\n it('should have format.type topojson', () => {\n assert.equal(source.data.format.type, 'topojson');\n });\n it('should have format.feature baz', () => {\n assert.equal(source.data.format.feature, 'baz');\n });\n });\n\n describe('mesh property is specified', () => {\n const source = parse({\n url: 'http://foo.bar',\n format: {type: 'topojson', mesh: 'baz'}\n });\n\n it('should have format.type topojson', () => {\n assert.equal(source.data.format.type, 'topojson');\n });\n it('should have format.mesh baz', () => {\n assert.equal(source.data.format.mesh, 'baz');\n });\n });\n });\n });\n });\n\n describe('assemble', () => {\n // TODO: write test\n });\n});\n\n"]} \ No newline at end of file diff --git a/build/test/compile/data/stack.test.d.ts b/build/test/compile/data/stack.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/stack.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/stack.test.js b/build/test/compile/data/stack.test.js new file mode 100644 index 0000000000..0b2e4098f1 --- /dev/null +++ b/build/test/compile/data/stack.test.js @@ -0,0 +1,290 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { StackNode } from '../../../src/compile/data/stack'; +import { parseUnitModelWithScale } from '../../util'; +function parse(model) { + return StackNode.makeFromEncoding(null, model).stack; +} +function assemble(model) { + return StackNode.makeFromEncoding(null, model).assemble(); +} +describe('compile/data/stack', function () { + describe('StackNode.makeFromEncoding', function () { + it('should produce correct stack component for bar with color', function () { + var model = parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "nominal" }, + "color": { "field": "c", "type": "ordinal", } + } + }); + assert.deepEqual(parse(model), { + dimensionFieldDef: { field: 'b', type: 'nominal' }, + facetby: [], + stackField: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: false, + as: ['sum_a_start', 'sum_a_end'] + }); + }); + it('should produce correct stack component with both start and end of the binned field for bar with color and binned y', function () { + var model = parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "bin": true, "field": "b", "type": "quantitative" }, + "color": { "field": "c", "type": "ordinal", } + } + }); + assert.deepEqual(parse(model), { + dimensionFieldDef: { "bin": { maxbins: 10 }, "field": "b", "type": "quantitative" }, + facetby: [], + stackField: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: false, + as: ['sum_a_start', 'sum_a_end'] + }); + }); + it('should produce correct stack component for 1D bar with color', function () { + var model = parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "c", "type": "ordinal", } + } + }); + assert.deepEqual(parse(model), { + dimensionFieldDef: undefined, + facetby: [], + stackField: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: false, + as: ['sum_a_start', 'sum_a_end'] + }); + assert.deepEqual(assemble(model), [{ + type: 'stack', + groupby: [], + field: 'sum_a', + sort: { + field: ['c'], + order: ['descending'] + }, + as: ['sum_a_start', 'sum_a_end'], + offset: 'zero' + } + ]); + }); + it('should produce correct stack component for area with color and order', function () { + var model = parseUnitModelWithScale({ + "mark": "area", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "nominal" }, + "color": { "field": "c", "type": "nominal" }, + "order": { "aggregate": "mean", "field": "d", "type": "quantitative" } + } + }); + assert.deepEqual(parse(model), { + dimensionFieldDef: { field: 'b', type: 'nominal' }, + facetby: [], + stackField: 'sum_a', + stackby: ['c'], + sort: { + field: ['mean_d'], + order: ['ascending'] + }, + offset: 'zero', + impute: true, + as: ['sum_a_start', 'sum_a_end'] + }); + assert.deepEqual(assemble(model), [ + { + type: 'impute', + field: 'sum_a', + groupby: ['c'], + key: 'b', + method: "value", + value: 0 + }, + { + type: 'stack', + groupby: ['b'], + field: 'sum_a', + sort: { + field: ['mean_d'], + order: ['ascending'] + }, + as: ['sum_a_start', 'sum_a_end'], + offset: 'zero' + } + ]); + }); + it('should produce correct stack component for area with color and binned dimension', function () { + var model = parseUnitModelWithScale({ + "mark": "area", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "bin": true, "field": "b", "type": "quantitative" }, + "color": { "field": "c", "type": "nominal" } + } + }); + assert.deepEqual(parse(model), { + dimensionFieldDef: { "bin": { maxbins: 10 }, "field": "b", "type": "quantitative" }, + facetby: [], + stackField: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: true, + as: ['sum_a_start', 'sum_a_end'] + }); + assert.deepEqual(assemble(model), [ + { + type: 'formula', + expr: '(datum[\"bin_maxbins_10_b\"]+datum[\"bin_maxbins_10_b_end\"])/2', + as: 'bin_maxbins_10_b_mid' + }, + { + type: 'impute', + field: 'sum_a', + groupby: ['c'], + key: 'bin_maxbins_10_b_mid', + method: "value", + value: 0 + }, + { + type: 'stack', + groupby: ['bin_maxbins_10_b_mid'], + field: 'sum_a', + sort: { + field: ['c'], + order: ['descending'] + }, + as: ['sum_a_start', 'sum_a_end'], + offset: 'zero' + } + ]); + }); + }); + describe('StackNode.makeFromTransform', function () { + it('should fill in offset and sort properly', function () { + var transform = { + stack: 'people', + groupby: ['age'], + as: ['v1', 'v2'] + }; + var stack = StackNode.makeFromTransform(null, transform); + assert.deepEqual(stack.assemble(), [{ + type: 'stack', + groupby: ['age'], + field: 'people', + offset: 'zero', + sort: { field: [], order: [] }, + as: ['v1', 'v2'] + }]); + }); + it('should fill in partial "as" field properly', function () { + var transform = { + stack: 'people', + groupby: ['age', 'gender'], + offset: 'normalize', + as: "val" + }; + var stack = StackNode.makeFromTransform(null, transform); + assert.deepEqual(stack.assemble(), [{ + type: 'stack', + groupby: ['age', 'gender'], + field: 'people', + offset: 'normalize', + sort: { field: [], order: [] }, + as: ["val", "val_end"] + }]); + }); + it('should handle complete "sort"', function () { + var transform = { + stack: 'people', + groupby: ['age', 'gender'], + offset: 'normalize', + sort: [{ 'field': 'height', 'order': 'ascending' }, + { 'field': 'weight', 'order': 'descending' }], + as: 'val' + }; + var stack = StackNode.makeFromTransform(null, transform); + assert.deepEqual(stack.assemble(), [{ + type: 'stack', + groupby: ['age', 'gender'], + field: 'people', + offset: 'normalize', + sort: { field: ['height', 'weight'], order: ['ascending', 'descending'] }, + as: ["val", "val_end"] + }]); + }); + it('should handle incomplete "sort" field', function () { + var transform = { + stack: 'people', + groupby: ['age', 'gender'], + offset: 'normalize', + sort: [{ 'field': 'height' }], + as: 'val' + }; + var stack = StackNode.makeFromTransform(null, transform); + assert.deepEqual(stack.assemble(), [{ + type: 'stack', + groupby: ['age', 'gender'], + field: 'people', + offset: 'normalize', + sort: { field: ['height'], order: ['ascending'] }, + as: ["val", "val_end"] + }]); + }); + }); + describe('StackNode.producedFields', function () { + it('should give producedfields correctly', function () { + var transform = { + stack: 'people', + groupby: ['age'], + as: 'people' + }; + var stack = StackNode.makeFromTransform(null, transform); + assert.deepEqual(stack.producedFields(), { + people: true, + people_end: true + }); + }); + it('should give producedFields correctly when in encoding channel', function () { + var model = parseUnitModelWithScale({ + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "nominal" }, + "color": { "field": "c", "type": "ordinal", } + } + }); + var stack = StackNode.makeFromEncoding(null, model); + assert.deepEqual(stack.producedFields(), { + sum_a_start: true, + sum_a_end: true + }); + }); + }); +}); +//# sourceMappingURL=stack.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/stack.test.js.map b/build/test/compile/data/stack.test.js.map new file mode 100644 index 0000000000..124e41d779 --- /dev/null +++ b/build/test/compile/data/stack.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"stack.test.js","sourceRoot":"","sources":["../../../../test/compile/data/stack.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\n\nimport {StackComponent, StackNode} from '../../../src/compile/data/stack';\nimport {UnitModel} from '../../../src/compile/unit';\nimport {Transform} from '../../../src/transform';\nimport {VgComparatorOrder, VgSort, VgTransform} from '../../../src/vega.schema';\nimport {parseUnitModelWithScale} from '../../util';\n\nfunction parse(model: UnitModel) {\n return StackNode.makeFromEncoding(null, model).stack;\n}\n\nfunction assemble(model: UnitModel) {\n return StackNode.makeFromEncoding(null, model).assemble();\n}\ndescribe ('compile/data/stack', () => {\n\n describe('StackNode.makeFromEncoding', () => {\n it('should produce correct stack component for bar with color', () => {\n const model = parseUnitModelWithScale({\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"b\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"c\", \"type\": \"ordinal\",}\n }\n });\n\n assert.deepEqual(parse(model), {\n dimensionFieldDef: {field: 'b', type: 'nominal'},\n facetby: [],\n stackField: 'sum_a',\n stackby: ['c'],\n sort: {\n field: ['c'],\n order: ['descending']\n },\n offset: 'zero',\n impute: false,\n as: ['sum_a_start', 'sum_a_end']\n });\n });\n\n it('should produce correct stack component with both start and end of the binned field for bar with color and binned y', () => {\n const model = parseUnitModelWithScale({\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"y\": {\"bin\": true, \"field\": \"b\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"c\", \"type\": \"ordinal\",}\n }\n });\n\n assert.deepEqual(parse(model), {\n dimensionFieldDef: {\"bin\": {maxbins: 10}, \"field\": \"b\", \"type\": \"quantitative\"},\n facetby: [],\n stackField: 'sum_a',\n stackby: ['c'],\n sort: {\n field: ['c'],\n order: ['descending']\n },\n offset: 'zero',\n impute: false,\n as: ['sum_a_start', 'sum_a_end']\n });\n });\n\n it('should produce correct stack component for 1D bar with color', () => {\n const model = parseUnitModelWithScale({\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"c\", \"type\": \"ordinal\",}\n }\n });\n\n assert.deepEqual(parse(model), {\n dimensionFieldDef: undefined,\n facetby: [],\n stackField: 'sum_a',\n stackby: ['c'],\n sort: {\n field: ['c'],\n order: ['descending']\n },\n offset: 'zero',\n impute: false,\n as: ['sum_a_start', 'sum_a_end']\n });\n\n assert.deepEqual(assemble(model), [{\n type: 'stack',\n groupby: [],\n field: 'sum_a',\n sort: {\n field: ['c'],\n order: ['descending']\n },\n as: ['sum_a_start', 'sum_a_end'],\n offset: 'zero'\n }\n ]);\n });\n\n it('should produce correct stack component for area with color and order', function() {\n const model = parseUnitModelWithScale({\n \"mark\": \"area\",\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"b\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"c\", \"type\": \"nominal\"},\n \"order\": {\"aggregate\": \"mean\", \"field\": \"d\", \"type\": \"quantitative\"}\n }\n });\n\n assert.deepEqual(parse(model), {\n dimensionFieldDef: {field: 'b', type: 'nominal'},\n facetby: [],\n stackField: 'sum_a',\n stackby: ['c'],\n sort: {\n field: ['mean_d'],\n order: ['ascending']\n },\n offset: 'zero',\n impute: true,\n as: ['sum_a_start', 'sum_a_end']\n });\n\n assert.deepEqual(assemble(model), [\n {\n type: 'impute',\n field: 'sum_a',\n groupby: ['c'],\n key: 'b',\n method: \"value\",\n value: 0\n },\n {\n type: 'stack',\n groupby: ['b'],\n field: 'sum_a',\n sort: {\n field: ['mean_d'],\n order: ['ascending']\n },\n as: ['sum_a_start', 'sum_a_end'],\n offset: 'zero'\n }\n ]);\n });\n\n it('should produce correct stack component for area with color and binned dimension', function() {\n const model = parseUnitModelWithScale({\n \"mark\": \"area\",\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"y\": {\"bin\": true, \"field\": \"b\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"c\", \"type\": \"nominal\"}\n }\n });\n\n assert.deepEqual(parse(model), {\n dimensionFieldDef: {\"bin\": {maxbins: 10}, \"field\": \"b\", \"type\": \"quantitative\"},\n facetby: [],\n stackField: 'sum_a',\n stackby: ['c'],\n sort: {\n field: ['c'],\n order: ['descending']\n },\n offset: 'zero',\n impute: true,\n as: ['sum_a_start', 'sum_a_end']\n });\n\n assert.deepEqual(assemble(model), [\n {\n type: 'formula',\n expr: '(datum[\\\"bin_maxbins_10_b\\\"]+datum[\\\"bin_maxbins_10_b_end\\\"])/2',\n as: 'bin_maxbins_10_b_mid'\n },\n {\n type: 'impute',\n field: 'sum_a',\n groupby: ['c'],\n key: 'bin_maxbins_10_b_mid',\n method: \"value\",\n value: 0\n },\n {\n type: 'stack',\n groupby: ['bin_maxbins_10_b_mid'],\n field: 'sum_a',\n sort: {\n field: ['c'],\n order: ['descending']\n },\n as: ['sum_a_start', 'sum_a_end'],\n offset: 'zero'\n }\n ]);\n });\n });\n\n describe('StackNode.makeFromTransform', () => {\n it('should fill in offset and sort properly', () => {\n const transform: Transform = {\n stack : 'people',\n groupby: ['age'],\n as: ['v1', 'v2']\n };\n const stack = StackNode.makeFromTransform(null, transform);\n assert.deepEqual(stack.assemble(), [{\n type: 'stack',\n groupby: ['age'],\n field: 'people',\n offset: 'zero',\n sort: {field: [] as string[], order: [] as VgComparatorOrder[]} as VgSort,\n as: ['v1', 'v2']\n }]);\n });\n\n it('should fill in partial \"as\" field properly', () => {\n const transform: Transform = {\n stack : 'people',\n groupby: ['age', 'gender'],\n offset: 'normalize',\n as: \"val\"\n };\n const stack = StackNode.makeFromTransform(null, transform);\n assert.deepEqual(stack.assemble(), [{\n type: 'stack',\n groupby: ['age', 'gender'],\n field: 'people',\n offset: 'normalize',\n sort: {field: [] as string[], order: [] as VgComparatorOrder[]} as VgSort,\n as: [\"val\", \"val_end\"]\n }]);\n });\n\n it('should handle complete \"sort\"', () => {\n const transform: Transform = {\n stack : 'people',\n groupby: ['age', 'gender'],\n offset: 'normalize',\n sort: [{'field': 'height', 'order': 'ascending'},\n {'field': 'weight', 'order': 'descending'}],\n as: 'val'\n };\n const stack = StackNode.makeFromTransform(null, transform);\n assert.deepEqual(stack.assemble(), [{\n type: 'stack',\n groupby: ['age', 'gender'],\n field: 'people',\n offset: 'normalize',\n sort: {field: ['height', 'weight'], order: ['ascending', 'descending']},\n as: [\"val\", \"val_end\"]\n }]);\n });\n\n it('should handle incomplete \"sort\" field', () => {\n const transform: Transform = {\n stack : 'people',\n groupby: ['age', 'gender'],\n offset: 'normalize',\n sort: [{'field': 'height'}],\n as: 'val'\n };\n const stack = StackNode.makeFromTransform(null, transform);\n\n assert.deepEqual(stack.assemble(), [{\n type: 'stack',\n groupby: ['age', 'gender'],\n field: 'people',\n offset: 'normalize',\n sort: {field: ['height'], order: ['ascending']},\n as: [\"val\", \"val_end\"]\n }]);\n });\n\n });\n describe('StackNode.producedFields', () => {\n it('should give producedfields correctly', () => {\n const transform: Transform = {\n stack: 'people',\n groupby: ['age'],\n as: 'people'\n\n };\n const stack = StackNode.makeFromTransform(null, transform);\n assert.deepEqual(stack.producedFields(), {\n people: true,\n people_end: true\n });\n\n });\n\n it('should give producedFields correctly when in encoding channel', () => {\n const model = parseUnitModelWithScale({\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"b\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"c\", \"type\": \"ordinal\",}\n }\n });\n const stack = StackNode.makeFromEncoding(null, model);\n assert.deepEqual(stack.producedFields(), {\n sum_a_start: true,\n sum_a_end: true\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/timeunit.test.d.ts b/build/test/compile/data/timeunit.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/timeunit.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/timeunit.test.js b/build/test/compile/data/timeunit.test.js new file mode 100644 index 0000000000..d8c767fe81 --- /dev/null +++ b/build/test/compile/data/timeunit.test.js @@ -0,0 +1,37 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { TimeUnitNode } from '../../../src/compile/data/timeunit'; +import { parseUnitModel } from '../../util'; +function assembleFromEncoding(model) { + return TimeUnitNode.makeFromEncoding(null, model).assemble(); +} +function assembleFromTransform(t) { + return TimeUnitNode.makeFromTransform(null, t).assemble(); +} +describe('compile/data/timeunit', function () { + describe('parseUnit', function () { + it('should return a dictionary of formula transform', function () { + var model = parseUnitModel({ + "data": { "values": [] }, + "mark": "point", + "encoding": { + "x": { field: 'a', type: 'temporal', timeUnit: 'month' } + } + }); + assert.deepEqual(assembleFromEncoding(model), [{ + type: 'formula', + as: 'month_a', + expr: 'datetime(0, month(datum["a"]), 1, 0, 0, 0, 0)' + }]); + }); + it('should return a dictionary of formula transform from transform array', function () { + var t = { field: 'date', as: 'month_date', timeUnit: 'month' }; + assert.deepEqual(assembleFromTransform(t), [{ + type: 'formula', + as: 'month_date', + expr: 'datetime(0, month(datum["date"]), 1, 0, 0, 0, 0)' + }]); + }); + }); +}); +//# sourceMappingURL=timeunit.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/timeunit.test.js.map b/build/test/compile/data/timeunit.test.js.map new file mode 100644 index 0000000000..752b3c08e3 --- /dev/null +++ b/build/test/compile/data/timeunit.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"timeunit.test.js","sourceRoot":"","sources":["../../../../test/compile/data/timeunit.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,YAAY,EAAC,MAAM,oCAAoC,CAAC;AAGhE,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAE1C,8BAA8B,KAAqB;IACjD,OAAO,YAAY,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC/D,CAAC;AAED,+BAA+B,CAAoB;IACjD,OAAO,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC5D,CAAC;AAED,QAAQ,CAAC,uBAAuB,EAAE;IAChC,QAAQ,CAAC,WAAW,EAAE;QAEpB,EAAE,CAAC,iDAAiD,EAAE;YAEpD,IAAM,KAAK,GAAG,cAAc,CAAC;gBAC3B,MAAM,EAAE,EAAC,QAAQ,EAAE,EAAE,EAAC;gBACtB,MAAM,EAAE,OAAO;gBACf,UAAU,EAAE;oBACV,GAAG,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAC;iBACvD;aACF,CAAC,CAAC;YAEH,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC7C,IAAI,EAAE,SAAS;oBACf,EAAE,EAAE,SAAS;oBACb,IAAI,EAAE,+CAA+C;iBACtD,CAAC,CAAC,CAAC;QACN,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sEAAsE,EAAE;YACzE,IAAM,CAAC,GAAsB,EAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAC,CAAC;YAElF,MAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC1C,IAAI,EAAE,SAAS;oBACf,EAAE,EAAE,YAAY;oBAChB,IAAI,EAAE,kDAAkD;iBACzD,CAAC,CAAC,CAAC;QACN,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {TimeUnitNode} from '../../../src/compile/data/timeunit';\nimport {ModelWithField} from '../../../src/compile/model';\nimport {TimeUnitTransform} from '../../../src/transform';\nimport {parseUnitModel} from '../../util';\n\nfunction assembleFromEncoding(model: ModelWithField) {\n return TimeUnitNode.makeFromEncoding(null, model).assemble();\n}\n\nfunction assembleFromTransform(t: TimeUnitTransform) {\n return TimeUnitNode.makeFromTransform(null, t).assemble();\n}\n\ndescribe('compile/data/timeunit', () => {\n describe('parseUnit', () => {\n\n it('should return a dictionary of formula transform', () => {\n\n const model = parseUnitModel({\n \"data\": {\"values\": []},\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {field: 'a', type: 'temporal', timeUnit: 'month'}\n }\n });\n\n assert.deepEqual(assembleFromEncoding(model), [{\n type: 'formula',\n as: 'month_a',\n expr: 'datetime(0, month(datum[\"a\"]), 1, 0, 0, 0, 0)'\n }]);\n });\n\n it('should return a dictionary of formula transform from transform array', () => {\n const t: TimeUnitTransform = {field: 'date', as: 'month_date', timeUnit: 'month'};\n\n assert.deepEqual(assembleFromTransform(t), [{\n type: 'formula',\n as: 'month_date',\n expr: 'datetime(0, month(datum[\"date\"]), 1, 0, 0, 0, 0)'\n }]);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/data/window.test.d.ts b/build/test/compile/data/window.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/data/window.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/data/window.test.js b/build/test/compile/data/window.test.js new file mode 100644 index 0000000000..d7e85ba3da --- /dev/null +++ b/build/test/compile/data/window.test.js @@ -0,0 +1,148 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { WindowTransformNode } from '../../../src/compile/data/window'; +describe('compile/data/window', function () { + it('creates correct window nodes for calculating sort field of crossed facet', function () { + var window = WindowTransformNode.makeFromFacet(null, { + row: { field: 'r', type: 'nominal' }, + column: { field: 'c', type: 'nominal', sort: { op: 'median', field: 'x' } } + }); + expect(window.assemble()).toEqual({ + type: 'window', + ops: ['median'], + fields: ['x'], + params: [null], + as: ['median_x_by_c'], + frame: [null, null], + groupby: ['c'], + sort: { + field: [], + order: [] + } + }); + }); + it('does not create any window nodes for crossed facet', function () { + assert.deepEqual(WindowTransformNode.makeFromFacet(null, { + row: { field: 'a', type: 'nominal' } + }), null); + }); + it('should return a proper vg transform', function () { + var transform = { + window: [ + { + op: 'row_number', + as: 'ordered_row_number', + }, + ], + ignorePeers: false, + sort: [ + { + field: 'f', + order: 'ascending' + } + ], + groupby: ['f'], + frame: [null, 0] + }; + var window = new WindowTransformNode(null, transform); + assert.deepEqual(window.assemble(), { + type: 'window', + ops: ['row_number'], + fields: [null], + params: [null], + sort: { + field: ["f"], + order: ["ascending"], + }, + ignorePeers: false, + as: ['ordered_row_number'], + frame: [null, 0], + groupby: ['f'] + }); + }); + it('should augment as with default as', function () { + var transform = { + window: [ + { + op: 'row_number', + as: undefined // intentionally omit for testing + }, + ], + ignorePeers: false, + sort: [ + { + field: 'f', + order: 'ascending' + } + ], + groupby: ['f'], + frame: [null, 0] + }; + var window = new WindowTransformNode(null, transform); + assert.deepEqual(window.assemble(), { + type: 'window', + ops: ['row_number'], + fields: [null], + params: [null], + sort: { + field: ["f"], + order: ["ascending"], + }, + ignorePeers: false, + as: ['row_number'], + frame: [null, 0], + groupby: ['f'] + }); + }); + it('should return a proper produced fields', function () { + var transform = { + window: [ + { + op: 'row_number', + as: 'ordered_row_number', + }, + { + op: 'count', + as: 'count_field' + }, + { + op: 'sum', + as: 'sum_field' + } + ], + ignorePeers: false, + sort: [ + { + field: 'f', + order: 'ascending' + } + ], + groupby: ['f'], + frame: [null, 0] + }; + var window = new WindowTransformNode(null, transform); + assert.deepEqual({ "count_field": true, "ordered_row_number": true, "sum_field": true }, window.producedFields()); + }); + it('should clone to an equivalent version', function () { + var transform = { + window: [ + { + op: 'row_number', + as: 'ordered_row_number', + }, + ], + ignorePeers: false, + sort: [ + { + field: 'f', + order: 'ascending' + } + ], + groupby: ['f'], + frame: [null, 0] + }; + var window = new WindowTransformNode(null, transform); + assert.deepEqual(window, window.clone()); + }); +}); +//# sourceMappingURL=window.test.js.map \ No newline at end of file diff --git a/build/test/compile/data/window.test.js.map b/build/test/compile/data/window.test.js.map new file mode 100644 index 0000000000..f936a25052 --- /dev/null +++ b/build/test/compile/data/window.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"window.test.js","sourceRoot":"","sources":["../../../../test/compile/data/window.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {WindowTransformNode} from '../../../src/compile/data/window';\nimport {Transform} from '../../../src/transform';\n\ndescribe('compile/data/window', () => {\n it('creates correct window nodes for calculating sort field of crossed facet', () => {\n const window = WindowTransformNode.makeFromFacet(null, {\n row: {field: 'r', type: 'nominal'},\n column: {field: 'c', type: 'nominal', sort: {op: 'median', field: 'x'}}\n });\n\n expect(window.assemble()).toEqual({\n type: 'window',\n ops: ['median'],\n fields: ['x'],\n params: [null],\n as: ['median_x_by_c'],\n frame: [null, null],\n groupby: ['c'],\n sort: {\n field: [],\n order: []\n }\n });\n });\n\n it('does not create any window nodes for crossed facet', () => {\n assert.deepEqual(WindowTransformNode.makeFromFacet(null, {\n row: {field: 'a', type: 'nominal'}\n }), null);\n });\n\n\n it('should return a proper vg transform', () => {\n const transform: Transform = {\n window: [\n {\n op: 'row_number',\n as: 'ordered_row_number',\n },\n ],\n ignorePeers: false,\n sort:\n [\n {\n field: 'f',\n order: 'ascending'\n }\n ],\n groupby: ['f'],\n frame: [null, 0]\n };\n const window = new WindowTransformNode(null, transform);\n assert.deepEqual(window.assemble(), {\n type: 'window',\n ops: ['row_number'],\n fields: [null],\n params: [null],\n sort: {\n field: [\"f\"],\n order: [\"ascending\"],\n },\n ignorePeers: false,\n as: ['ordered_row_number'],\n frame: [null, 0],\n groupby: ['f']\n });\n });\n\n it('should augment as with default as', () => {\n const transform: Transform = {\n window: [\n {\n op: 'row_number',\n as: undefined // intentionally omit for testing\n },\n ],\n ignorePeers: false,\n sort:\n [\n {\n field: 'f',\n order: 'ascending'\n }\n ],\n groupby: ['f'],\n frame: [null, 0]\n };\n const window = new WindowTransformNode(null, transform);\n assert.deepEqual(window.assemble(), {\n type: 'window',\n ops: ['row_number'],\n fields: [null],\n params: [null],\n sort: {\n field: [\"f\"],\n order: [\"ascending\"],\n },\n ignorePeers: false,\n as: ['row_number'],\n frame: [null, 0],\n groupby: ['f']\n });\n });\n\n it('should return a proper produced fields', () => {\n const transform: Transform = {\n window: [\n {\n op: 'row_number',\n as: 'ordered_row_number',\n },\n {\n op: 'count',\n as: 'count_field'\n },\n {\n op: 'sum',\n as: 'sum_field'\n }\n ],\n ignorePeers: false,\n sort:\n [\n {\n field:'f',\n order:'ascending'\n }\n ],\n groupby: ['f'],\n frame: [null, 0]\n };\n const window = new WindowTransformNode(null, transform);\n assert.deepEqual({\"count_field\": true, \"ordered_row_number\": true, \"sum_field\": true}, window.producedFields());\n });\n\n it('should clone to an equivalent version', () => {\n const transform: Transform = {\n window: [\n {\n op: 'row_number',\n as: 'ordered_row_number',\n },\n ],\n ignorePeers: false,\n sort:\n [\n {\n field:'f',\n order:'ascending'\n }\n ],\n groupby: ['f'],\n frame: [null, 0]\n };\n const window = new WindowTransformNode(null, transform);\n assert.deepEqual(window, window.clone());\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/facet.test.d.ts b/build/test/compile/facet.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/facet.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/facet.test.js b/build/test/compile/facet.test.js new file mode 100644 index 0000000000..60a38702eb --- /dev/null +++ b/build/test/compile/facet.test.js @@ -0,0 +1,404 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { ROW, SHAPE } from '../../src/channel'; +import * as log from '../../src/log'; +import { ORDINAL } from '../../src/type'; +import { parseFacetModel, parseFacetModelWithScale } from '../util'; +describe('FacetModel', function () { + describe('initFacet', function () { + it('should drop unsupported channel and throws warning', log.wrap(function (localLogger) { + var model = parseFacetModel({ + facet: ({ + shape: { field: 'a', type: 'quantitative' } + }), + spec: { + mark: 'point', + encoding: {} + } + }); + assert.equal(model.facet['shape'], undefined); + assert.equal(localLogger.warns[0], log.message.incompatibleChannel(SHAPE, 'facet')); + })); + it('should drop channel without field and value and throws warning', log.wrap(function (localLogger) { + var model = parseFacetModel({ + facet: { + row: { type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: {} + } + }); + assert.equal(model.facet.row, undefined); + assert.equal(localLogger.warns[0], log.message.emptyFieldDef({ type: ORDINAL }, ROW)); + })); + it('should drop channel without field and value and throws warning', log.wrap(function (localLogger) { + var model = parseFacetModel({ + facet: { + row: { field: 'a', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: {} + } + }); + assert.deepEqual(model.facet.row, { field: 'a', type: 'quantitative' }); + assert.equal(localLogger.warns[0], log.message.facetChannelShouldBeDiscrete(ROW)); + })); + }); + describe('parseAxisAndHeader', function () { + // TODO: add more tests + // - correctly join title for nested facet + // - correctly generate headers with right labels and axes + it('applies text format to the fieldref of a temporal field', function () { + var model = parseFacetModelWithScale({ + facet: { + column: { timeUnit: 'year', field: 'date', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + model.parseAxisAndHeader(); + var headerMarks = model.assembleHeaderMarks(); + var columnHeader = headerMarks.filter(function (d) { + return d.name === "column_header"; + })[0]; + assert(columnHeader.title.text.signal, "timeFormat(parent[\"year_date\"], '%Y')"); + }); + it('applies number format for fieldref of a quantitative field', function () { + var model = parseFacetModelWithScale({ + facet: { + column: { field: 'a', type: 'quantitative', format: 'd' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + model.parseAxisAndHeader(); + var headerMarks = model.assembleHeaderMarks(); + var columnHeader = headerMarks.filter(function (d) { + return d.name === "column_header"; + })[0]; + assert(columnHeader.title.text.signal, "format(parent[\"a\"], 'd')"); + }); + it('ignores number format for fieldref of a binned field', function () { + var model = parseFacetModelWithScale({ + facet: { + column: { bin: true, field: 'a', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + model.parseAxisAndHeader(); + var headerMarks = model.assembleHeaderMarks(); + var columnHeader = headerMarks.filter(function (d) { + return d.name === "column_header"; + })[0]; + assert(columnHeader.title.text.signal, "parent[\"a\"]"); + }); + }); + describe('parseScale', function () { + it('should correctly set scale component for a model', function () { + var model = parseFacetModelWithScale({ + facet: { + row: { field: 'a', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' } + } + } + }); + assert(model.component.scales['x']); + }); + it('should create independent scales if resolve is set to independent', function () { + var model = parseFacetModelWithScale({ + facet: { + row: { field: 'a', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' } + } + }, + resolve: { + scale: { + x: 'independent' + } + } + }); + assert(!model.component.scales['x']); + }); + }); + describe('assembleHeaderMarks', function () { + it('should sort headers in ascending order', function () { + var model = parseFacetModelWithScale({ + facet: { + column: { field: 'a', type: 'quantitative', format: 'd' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + model.parseAxisAndHeader(); + var headerMarks = model.assembleHeaderMarks(); + var columnHeader = headerMarks.filter(function (d) { + return d.name === "column_header"; + })[0]; + assert.deepEqual(columnHeader.sort, { field: 'datum["a"]', order: 'ascending' }); + }); + }); + describe('assembleGroup', function () { + it('includes a columns fields in the encode block for facet with column that parent is also a facet.', function () { + var model = parseFacetModelWithScale({ + facet: { + column: { field: 'a', type: 'quantitative' } + }, + spec: { + facet: { + column: { field: 'c', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' } + } + } + } + // TODO: remove "any" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760 + }); + model.parseData(); + var group = model.child.assembleGroup([]); + assert.deepEqual(group.encode.update.columns, { field: 'distinct_c' }); + }); + }); + describe('assembleLayout', function () { + it('returns a layout with a column signal for facet with column', function () { + var model = parseFacetModelWithScale({ + facet: { + column: { field: 'a', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' } + } + } + }); + var layout = model.assembleLayout(); + assert.deepEqual(layout, { + padding: { row: 10, column: 10 }, + columns: { + signal: "length(data('column_domain'))" + }, + bounds: 'full', + align: 'all' + }); + }); + it('returns a layout without a column signal for facet with column that parent is also a facet.', function () { + var model = parseFacetModelWithScale({ + facet: { + column: { field: 'a', type: 'quantitative' } + }, + spec: { + facet: { + column: { field: 'c', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' } + } + } + } + // TODO: remove "any" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760 + }); + var layout = model.child.assembleLayout(); + assert.deepEqual(layout.columns, undefined); + }); + it('returns a layout with header band if child spec is also a facet', function () { + var model = parseFacetModelWithScale({ + "$schema": "https://vega.github.io/schema/vega-lite/v2.json", + "data": { "url": "data/cars.json" }, + "facet": { "row": { "field": "Origin", "type": "ordinal" } }, + "spec": { + "facet": { "row": { "field": "Cylinders", "type": "ordinal" } }, + "spec": { + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Acceleration", "type": "quantitative" } + } + } + } + // TODO: remove "any" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760 + }); + model.parseLayoutSize(); + model.parseAxisAndHeader(); + var layout = model.assembleLayout(); + assert.deepEqual(layout.headerBand, { row: 0.5 }); + }); + }); + describe('assembleMarks', function () { + it('should add cross and sort if we facet by multiple dimensions', function () { + var model = parseFacetModelWithScale({ + facet: { + row: { field: 'a', type: 'ordinal' }, + column: { field: 'b', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'c', type: 'quantitative' } + } + } + }); + model.parse(); + var marks = model.assembleMarks(); + assert(marks[0].from.facet.aggregate.cross); + assert.deepEqual(marks[0].sort, { + field: [ + 'datum["a"]', + 'datum["b"]' + ], + order: [ + 'ascending', + 'ascending' + ] + }); + }); + it('should add cross and sort if we facet by multiple dimensions with sort array', function () { + var model = parseFacetModelWithScale({ + facet: { + row: { field: 'a', type: 'ordinal', sort: ['a1', 'a2'] }, + column: { field: 'b', type: 'ordinal', sort: ['b1', 'b2'] } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'c', type: 'quantitative' } + } + } + }); + model.parse(); + var marks = model.assembleMarks(); + assert(marks[0].from.facet.aggregate.cross); + expect(marks[0].sort).toEqual({ + field: [ + 'datum["row_a_sort_index"]', + 'datum["column_b_sort_index"]' + ], + order: [ + 'ascending', + 'ascending' + ] + }); + }); + it('should add cross and sort if we facet by multiple dimensions with sort fields', function () { + var model = parseFacetModelWithScale({ + facet: { + row: { field: 'a', type: 'ordinal', sort: { field: 'd', op: 'median' } }, + column: { field: 'b', type: 'ordinal', sort: { field: 'e', op: 'median' } } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'c', type: 'quantitative' } + } + } + }); + model.parse(); + var marks = model.assembleMarks(); + expect(marks[0].from.facet.aggregate).toEqual({ + cross: true, + fields: ['median_d_by_a', 'median_e_by_b'], + ops: ['max', 'max'], + as: ['median_d_by_a', 'median_e_by_b'] + }); + expect(marks[0].sort).toEqual({ + field: [ + 'datum["median_d_by_a"]', + 'datum["median_e_by_b"]' + ], + order: [ + 'ascending', + 'ascending' + ] + }); + }); + it('should add calculate cardinality for independent scales', function () { + var model = parseFacetModelWithScale({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'rect', + encoding: { + x: { field: 'b', type: 'nominal' }, + y: { field: 'c', type: 'nominal' } + } + }, + resolve: { + scale: { + x: 'independent', + y: 'independent' + } + } + }); + model.parse(); + var marks = model.assembleMarks(); + assert.deepEqual(marks[0].from.facet.aggregate, { + fields: ['b', 'c'], + ops: ['distinct', 'distinct'], + as: ['distinct_b', 'distinct_c'] + }); + }); + it('should add calculate cardinality for child column facet', function () { + var model = parseFacetModelWithScale({ + facet: { + column: { field: 'a', type: 'quantitative' } + }, + spec: { + facet: { + column: { field: 'c', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' } + } + } + } + // TODO: remove "any" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760 + }); + model.parse(); + var marks = model.assembleMarks(); + assert.deepEqual(marks[0].from.facet.aggregate, { + fields: ['c'], + ops: ['distinct'], + as: ['distinct_c'] + }); + }); + }); +}); +//# sourceMappingURL=facet.test.js.map \ No newline at end of file diff --git a/build/test/compile/facet.test.js.map b/build/test/compile/facet.test.js.map new file mode 100644 index 0000000000..f9faa59f5e --- /dev/null +++ b/build/test/compile/facet.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"facet.test.js","sourceRoot":"","sources":["../../../test/compile/facet.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport {ROW, SHAPE} from '../../src/channel';\nimport {FacetModel} from '../../src/compile/facet';\nimport {FacetMapping} from '../../src/facet';\nimport {PositionFieldDef} from '../../src/fielddef';\nimport * as log from '../../src/log';\nimport {ORDINAL} from '../../src/type';\nimport {VgLayout} from '../../src/vega.schema';\nimport {parseFacetModel, parseFacetModelWithScale} from '../util';\n\ndescribe('FacetModel', function() {\n describe('initFacet', () => {\n it('should drop unsupported channel and throws warning', log.wrap((localLogger) => {\n const model = parseFacetModel({\n facet: ({\n shape: {field: 'a', type: 'quantitative'}\n }) as FacetMapping, // Cast to allow invalid facet type for test\n spec: {\n mark: 'point',\n encoding: {}\n }\n });\n assert.equal(model.facet['shape'], undefined);\n assert.equal(localLogger.warns[0], log.message.incompatibleChannel(SHAPE, 'facet'));\n }));\n\n it('should drop channel without field and value and throws warning', log.wrap((localLogger) => {\n const model = parseFacetModel({\n facet: {\n row: {type: 'ordinal'}\n },\n spec: {\n mark: 'point',\n encoding: {}\n }\n });\n assert.equal(model.facet.row, undefined);\n assert.equal(localLogger.warns[0], log.message.emptyFieldDef({type: ORDINAL}, ROW));\n }));\n\n it('should drop channel without field and value and throws warning', log.wrap((localLogger) => {\n const model = parseFacetModel({\n facet: {\n row: {field: 'a', type: 'quantitative'}\n },\n spec: {\n mark: 'point',\n encoding: {}\n }\n });\n assert.deepEqual>(model.facet.row, {field: 'a', type: 'quantitative'});\n assert.equal(localLogger.warns[0], log.message.facetChannelShouldBeDiscrete(ROW));\n }));\n });\n\n describe('parseAxisAndHeader', () => {\n // TODO: add more tests\n // - correctly join title for nested facet\n // - correctly generate headers with right labels and axes\n\n\n it('applies text format to the fieldref of a temporal field', () => {\n const model = parseFacetModelWithScale({\n facet: {\n column: {timeUnit:'year', field: 'date', type: 'ordinal'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parseAxisAndHeader();\n const headerMarks = model.assembleHeaderMarks();\n const columnHeader = headerMarks.filter(d => {\n return d.name === \"column_header\";\n })[0];\n\n assert(columnHeader.title.text.signal, \"timeFormat(parent[\\\"year_date\\\"], '%Y')\");\n });\n\n it('applies number format for fieldref of a quantitative field', () => {\n const model = parseFacetModelWithScale({\n facet: {\n column: {field: 'a', type: 'quantitative', format: 'd'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parseAxisAndHeader();\n const headerMarks = model.assembleHeaderMarks();\n const columnHeader = headerMarks.filter(d => {\n return d.name === \"column_header\";\n })[0];\n\n assert(columnHeader.title.text.signal, \"format(parent[\\\"a\\\"], 'd')\");\n });\n\n it('ignores number format for fieldref of a binned field', () => {\n const model = parseFacetModelWithScale({\n facet: {\n column: {bin: true, field: 'a', type: 'quantitative'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parseAxisAndHeader();\n const headerMarks = model.assembleHeaderMarks();\n const columnHeader = headerMarks.filter(d => {\n return d.name === \"column_header\";\n })[0];\n\n assert(columnHeader.title.text.signal, \"parent[\\\"a\\\"]\");\n });\n });\n\n describe('parseScale', () => {\n it('should correctly set scale component for a model', () => {\n const model = parseFacetModelWithScale({\n facet: {\n row: {field: 'a', type: 'quantitative'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'}\n }\n }\n });\n\n\n assert(model.component.scales['x']);\n });\n\n it('should create independent scales if resolve is set to independent', () => {\n const model = parseFacetModelWithScale({\n facet: {\n row: {field: 'a', type: 'quantitative'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'}\n }\n },\n resolve: {\n scale: {\n x: 'independent'\n }\n }\n });\n\n assert(!model.component.scales['x']);\n });\n });\n\n describe('assembleHeaderMarks', () => {\n it('should sort headers in ascending order', () => {\n const model = parseFacetModelWithScale({\n facet: {\n column: {field: 'a', type: 'quantitative', format: 'd'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parseAxisAndHeader();\n\n const headerMarks = model.assembleHeaderMarks();\n const columnHeader = headerMarks.filter(d => {\n return d.name === \"column_header\";\n })[0];\n\n assert.deepEqual(columnHeader.sort, {field: 'datum[\"a\"]', order: 'ascending'});\n });\n });\n\n describe('assembleGroup', () => {\n it('includes a columns fields in the encode block for facet with column that parent is also a facet.', () => {\n const model = parseFacetModelWithScale({\n facet: {\n column: {field: 'a', type: 'quantitative'}\n },\n spec: {\n facet: {\n column: {field: 'c', type: 'quantitative'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'}\n }\n }\n }\n // TODO: remove \"any\" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760\n } as any);\n model.parseData();\n const group = model.child.assembleGroup([]);\n assert.deepEqual(group.encode.update.columns, {field: 'distinct_c'});\n });\n });\n\n describe('assembleLayout', () => {\n it('returns a layout with a column signal for facet with column', () => {\n const model = parseFacetModelWithScale({\n facet: {\n column: {field: 'a', type: 'quantitative'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'}\n }\n }\n });\n const layout = model.assembleLayout();\n assert.deepEqual(layout, {\n padding: {row: 10, column: 10},\n columns: {\n signal: \"length(data('column_domain'))\"\n },\n bounds: 'full',\n align: 'all'\n });\n });\n\n it('returns a layout without a column signal for facet with column that parent is also a facet.', () => {\n const model = parseFacetModelWithScale({\n facet: {\n column: {field: 'a', type: 'quantitative'}\n },\n spec: {\n facet: {\n column: {field: 'c', type: 'quantitative'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'}\n }\n }\n }\n // TODO: remove \"any\" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760\n } as any);\n const layout = model.child.assembleLayout();\n assert.deepEqual(layout.columns, undefined);\n });\n\n it('returns a layout with header band if child spec is also a facet', () => {\n const model = parseFacetModelWithScale({\n \"$schema\": \"https://vega.github.io/schema/vega-lite/v2.json\",\n \"data\": {\"url\": \"data/cars.json\"},\n \"facet\": {\"row\": {\"field\": \"Origin\",\"type\": \"ordinal\"}},\n \"spec\": {\n \"facet\": {\"row\": {\"field\": \"Cylinders\",\"type\": \"ordinal\"}},\n \"spec\": {\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Acceleration\",\"type\": \"quantitative\"}\n }\n }\n }\n // TODO: remove \"any\" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760\n } as any);\n model.parseLayoutSize();\n model.parseAxisAndHeader();\n const layout = model.assembleLayout();\n assert.deepEqual(layout.headerBand, {row: 0.5});\n });\n });\n\n describe('assembleMarks', () => {\n it('should add cross and sort if we facet by multiple dimensions', () => {\n const model: FacetModel = parseFacetModelWithScale({\n facet: {\n row: {field: 'a', type: 'ordinal'},\n column: {field: 'b', type: 'ordinal'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parse();\n\n const marks = model.assembleMarks();\n\n assert(marks[0].from.facet.aggregate.cross);\n assert.deepEqual(marks[0].sort, {\n field: [\n 'datum[\"a\"]',\n 'datum[\"b\"]'\n ],\n order: [\n 'ascending',\n 'ascending'\n ]\n });\n });\n\n\n it('should add cross and sort if we facet by multiple dimensions with sort array', () => {\n const model: FacetModel = parseFacetModelWithScale({\n facet: {\n row: {field: 'a', type: 'ordinal', sort: ['a1', 'a2']},\n column: {field: 'b', type: 'ordinal', sort: ['b1', 'b2']}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parse();\n\n const marks = model.assembleMarks();\n\n assert(marks[0].from.facet.aggregate.cross);\n expect(marks[0].sort).toEqual({\n field: [\n 'datum[\"row_a_sort_index\"]',\n 'datum[\"column_b_sort_index\"]'\n ],\n order: [\n 'ascending',\n 'ascending'\n ]\n });\n });\n\n\n it('should add cross and sort if we facet by multiple dimensions with sort fields', () => {\n const model: FacetModel = parseFacetModelWithScale({\n facet: {\n row: {field: 'a', type: 'ordinal', sort: {field: 'd', op: 'median'}},\n column: {field: 'b', type: 'ordinal', sort: {field: 'e', op: 'median'}}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parse();\n\n const marks = model.assembleMarks();\n\n expect(marks[0].from.facet.aggregate).toEqual({\n cross: true,\n fields: ['median_d_by_a', 'median_e_by_b'],\n ops: ['max', 'max'],\n as: ['median_d_by_a', 'median_e_by_b']\n });\n\n expect(marks[0].sort).toEqual({\n field: [\n 'datum[\"median_d_by_a\"]',\n 'datum[\"median_e_by_b\"]'\n ],\n order: [\n 'ascending',\n 'ascending'\n ]\n });\n });\n\n it('should add calculate cardinality for independent scales', () => {\n const model: FacetModel = parseFacetModelWithScale({\n facet: {\n row: {field: 'a', type: 'ordinal'}\n },\n spec: {\n mark: 'rect',\n encoding: {\n x: {field: 'b', type: 'nominal'},\n y: {field: 'c', type: 'nominal'}\n }\n },\n resolve: {\n scale: {\n x: 'independent',\n y: 'independent'\n }\n }\n });\n model.parse();\n\n const marks = model.assembleMarks();\n\n assert.deepEqual(marks[0].from.facet.aggregate, {\n fields: ['b', 'c'],\n ops: ['distinct', 'distinct'],\n as: ['distinct_b', 'distinct_c']\n });\n });\n\n it('should add calculate cardinality for child column facet', () => {\n const model: FacetModel = parseFacetModelWithScale({\n facet: {\n column: {field: 'a', type: 'quantitative'}\n },\n spec: {\n facet: {\n column: {field: 'c', type: 'quantitative'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'}\n }\n }\n }\n // TODO: remove \"any\" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760\n } as any);\n model.parse();\n\n const marks = model.assembleMarks();\n\n assert.deepEqual(marks[0].from.facet.aggregate, {\n fields: ['c'],\n ops: ['distinct'],\n as: ['distinct_c']\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/header/index.test.d.ts b/build/test/compile/header/index.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/header/index.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/header/index.test.js b/build/test/compile/header/index.test.js new file mode 100644 index 0000000000..57ad02e8bb --- /dev/null +++ b/build/test/compile/header/index.test.js @@ -0,0 +1,185 @@ +import * as tslib_1 from "tslib"; +import { assert } from 'chai'; +import { getHeaderGroups, getTitleGroup, labelAlign, labelBaseline } from '../../../src/compile/header'; +import { getHeaderProperties } from '../../../src/compile/header/index'; +import { HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP } from '../../../src/header'; +import { parseFacetModel } from '../../util'; +describe('compile/header/index', function () { + describe('label aligns correctly according to angle', function () { + assert.deepEqual(labelAlign(23), { align: { value: 'right' } }); + assert.deepEqual(labelAlign(135), { align: { value: 'left' } }); + assert.deepEqual(labelAlign(50), { align: { value: 'right' } }); + }); + describe('label baseline adjusted according to angle', function () { + assert.deepEqual(labelBaseline(10), { baseline: 'middle' }); + assert.deepEqual(labelBaseline(90), { baseline: 'top' }); + }); + describe('getHeaderGroups', function () { + it('should correctly process sort descending', function () { + var model = parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal', sort: 'ascending' }, + column: { field: 'a', type: 'ordinal', sort: 'descending' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + model.parseScale(); + model.parseLayoutSize(); + model.parseAxisAndHeader(); + var rowHeaderGroups = getHeaderGroups(model, 'row'); + var columnHeaderGroups = getHeaderGroups(model, 'column'); + assert.equal(rowHeaderGroups[0].sort.order, 'ascending'); + assert.equal(columnHeaderGroups[0].sort.order, 'descending'); + }); + it('should correctly process sort field', function () { + var model = parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal', sort: { field: 'd', op: 'min' } } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + model.parseScale(); + model.parseLayoutSize(); + model.parseAxisAndHeader(); + var rowHeaderGroups = getHeaderGroups(model, 'row'); + assert.equal(rowHeaderGroups[0].sort.field, 'datum["min_d"]'); + }); + }); + describe('getTitleGroup', function () { + var model = parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' }, + column: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + model.parseScale(); + model.parseLayoutSize(); + model.parseAxisAndHeader(); + describe('for column', function () { + var columnLabelGroup = getTitleGroup(model, 'column'); + var title = columnLabelGroup.title, columnTitleGroupTopLevelProps = tslib_1.__rest(columnLabelGroup, ["title"]); + it('returns a header group mark with correct name, role, and type.', function () { + assert.deepEqual(columnTitleGroupTopLevelProps, { + name: 'column-title', + type: 'group', + role: 'column-title' + }); + }); + var name = title.text; + it('contains a correct title definition, including the correct name and orientation', function () { + assert.deepEqual(title, { + text: name, + offset: 10, + orient: undefined, + style: 'guide-title' + }); + }); + }); + describe('for row', function () { + var rowTitleGroup = getTitleGroup(model, 'row'); + var title = rowTitleGroup.title, rowTitleGroupTopLevelProps = tslib_1.__rest(rowTitleGroup, ["title"]); + it('returns a header group mark with correct name, role, and type.', function () { + assert.deepEqual(rowTitleGroupTopLevelProps, { + name: 'row-title', + type: 'group', + role: 'row-title' + }); + }); + var name = title.text; + it('contains a correct title definition, including the correct name and orientation.', function () { + assert.deepEqual(title, { + text: name, + offset: 10, + orient: 'left', + style: 'guide-title' + }); + }); + }); + }); + describe('getHeaderProperties', function () { + describe('for title properties', function () { + var titleSpec = parseFacetModel({ + config: { header: { titleFontSize: 20 } }, + facet: { + row: { field: 'a', type: 'ordinal', header: { titleFontSize: 40 } } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + titleSpec.parseScale(); + titleSpec.parseLayoutSize(); + titleSpec.parseAxisAndHeader(); + var config = titleSpec.config; + var facetFieldDef = titleSpec.component.layoutHeaders['row'].facetFieldDef; + var headerTitleProps = getHeaderProperties(undefined, facetFieldDef, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP); + it('should return the correct title property from header', function () { + assert.deepEqual(headerTitleProps, { fontSize: 40 }); + }); + var configTitleProps = getHeaderProperties(config, undefined, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP); + it('should return the correct title property from config', function () { + assert.deepEqual(configTitleProps, { fontSize: 20 }); + }); + var bothTitleProps = getHeaderProperties(config, facetFieldDef, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP); + it('should overwrite the config title property with the header title property', function () { + assert.deepEqual(bothTitleProps, { fontSize: 40 }); + }); + }); + describe('for label properties', function () { + var labelSpec = parseFacetModel({ + config: { header: { labelFontSize: 20 } }, + facet: { + row: { field: 'a', type: 'ordinal', header: { labelFontSize: 40 } } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + labelSpec.parseScale(); + labelSpec.parseLayoutSize(); + labelSpec.parseAxisAndHeader(); + var config = labelSpec.config; + var facetFieldDef = labelSpec.component.layoutHeaders['row'].facetFieldDef; + var headerLabelProps = getHeaderProperties(undefined, facetFieldDef, HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP); + it('should return the correct label property from header', function () { + assert.deepEqual(headerLabelProps, { fontSize: 40 }); + }); + var configLabelProps = getHeaderProperties(config, undefined, HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP); + it('should return the correct label property from config', function () { + assert.deepEqual(configLabelProps, { fontSize: 20 }); + }); + var bothLabelProps = getHeaderProperties(config, facetFieldDef, HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP); + it('should overwrite the config label property with the header label property', function () { + assert.deepEqual(bothLabelProps, { fontSize: 40 }); + }); + }); + }); +}); +//# sourceMappingURL=index.test.js.map \ No newline at end of file diff --git a/build/test/compile/header/index.test.js.map b/build/test/compile/header/index.test.js.map new file mode 100644 index 0000000000..916882084f --- /dev/null +++ b/build/test/compile/header/index.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../../test/compile/header/index.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {getHeaderGroups, getTitleGroup, labelAlign, labelBaseline} from '../../../src/compile/header';\nimport {getHeaderProperties} from '../../../src/compile/header/index';\nimport {HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP} from '../../../src/header';\nimport {parseFacetModel} from '../../util';\n\ndescribe('compile/header/index', () => {\n describe('label aligns correctly according to angle', () => {\n assert.deepEqual(labelAlign(23), {align: {value: 'right'}});\n assert.deepEqual(labelAlign(135), {align: {value: 'left'}});\n assert.deepEqual(labelAlign(50), {align: {value: 'right'}});\n });\n\n describe('label baseline adjusted according to angle', () => {\n assert.deepEqual(labelBaseline(10), {baseline: 'middle'});\n assert.deepEqual(labelBaseline(90), {baseline: 'top'});\n });\n\n describe('getHeaderGroups', () => {\n it('should correctly process sort descending', () => {\n const model = parseFacetModel({\n facet: {\n row: {field: 'a', type: 'ordinal', sort: 'ascending'},\n column: {field: 'a', type: 'ordinal', sort: 'descending'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parseScale();\n model.parseLayoutSize();\n model.parseAxisAndHeader();\n\n const rowHeaderGroups = getHeaderGroups(model, 'row');\n const columnHeaderGroups = getHeaderGroups(model, 'column');\n assert.equal(rowHeaderGroups[0].sort.order, 'ascending');\n assert.equal(columnHeaderGroups[0].sort.order, 'descending');\n });\n\n it('should correctly process sort field', () => {\n const model = parseFacetModel({\n facet: {\n row: {field: 'a', type: 'ordinal', sort: {field: 'd', op: 'min'}}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parseScale();\n model.parseLayoutSize();\n model.parseAxisAndHeader();\n\n const rowHeaderGroups = getHeaderGroups(model, 'row');\n assert.equal(rowHeaderGroups[0].sort.field, 'datum[\"min_d\"]');\n });\n });\n\n describe('getTitleGroup', () => {\n const model = parseFacetModel({\n facet: {\n row: {field: 'a', type: 'ordinal'},\n column: {field: 'a', type: 'ordinal'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parseScale();\n model.parseLayoutSize();\n model.parseAxisAndHeader();\n\n describe('for column', () => {\n const columnLabelGroup = getTitleGroup(model, 'column');\n const {title, ...columnTitleGroupTopLevelProps} = columnLabelGroup;\n it('returns a header group mark with correct name, role, and type.', () => {\n assert.deepEqual(columnTitleGroupTopLevelProps, {\n name: 'column-title',\n type: 'group',\n role: 'column-title'\n });\n });\n const name = title.text;\n it('contains a correct title definition, including the correct name and orientation', () => {\n assert.deepEqual(title, {\n text: name,\n offset: 10,\n orient: undefined,\n style: 'guide-title'\n });\n });\n });\n\n describe('for row', () => {\n const rowTitleGroup = getTitleGroup(model, 'row');\n const {title, ...rowTitleGroupTopLevelProps} = rowTitleGroup;\n it('returns a header group mark with correct name, role, and type.', () => {\n assert.deepEqual(rowTitleGroupTopLevelProps, {\n name: 'row-title',\n type: 'group',\n role: 'row-title'\n });\n });\n const name = title.text;\n it('contains a correct title definition, including the correct name and orientation.', () => {\n assert.deepEqual(title, {\n text: name,\n offset: 10,\n orient: 'left',\n style: 'guide-title'\n });\n });\n });\n });\n\n describe('getHeaderProperties', () => {\n describe('for title properties', () => {\n const titleSpec = parseFacetModel({\n config: {header: {titleFontSize: 20}},\n facet: {\n row: {field: 'a', type: 'ordinal', header: {titleFontSize: 40}}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n titleSpec.parseScale();\n titleSpec.parseLayoutSize();\n titleSpec.parseAxisAndHeader();\n const config = titleSpec.config;\n const facetFieldDef = titleSpec.component.layoutHeaders['row'].facetFieldDef;\n\n const headerTitleProps = getHeaderProperties(undefined, facetFieldDef, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP);\n it('should return the correct title property from header', () => {\n assert.deepEqual(headerTitleProps, {fontSize: 40});\n });\n\n const configTitleProps = getHeaderProperties(config, undefined, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP);\n it('should return the correct title property from config', () => {\n assert.deepEqual(configTitleProps, {fontSize: 20});\n });\n\n const bothTitleProps = getHeaderProperties(config, facetFieldDef, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP);\n it('should overwrite the config title property with the header title property', () => {\n assert.deepEqual(bothTitleProps, {fontSize: 40});\n });\n });\n\n describe('for label properties', () => {\n const labelSpec = parseFacetModel({\n config: {header: {labelFontSize: 20}},\n facet: {\n row: {field: 'a', type: 'ordinal', header: {labelFontSize: 40}}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n labelSpec.parseScale();\n labelSpec.parseLayoutSize();\n labelSpec.parseAxisAndHeader();\n const config = labelSpec.config;\n const facetFieldDef = labelSpec.component.layoutHeaders['row'].facetFieldDef;\n\n const headerLabelProps = getHeaderProperties(undefined, facetFieldDef, HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP);\n it('should return the correct label property from header', () => {\n assert.deepEqual(headerLabelProps, {fontSize: 40});\n });\n\n const configLabelProps = getHeaderProperties(config, undefined, HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP);\n it('should return the correct label property from config', () => {\n assert.deepEqual(configLabelProps, {fontSize: 20});\n });\n\n const bothLabelProps = getHeaderProperties(config, facetFieldDef, HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP);\n it('should overwrite the config label property with the header label property', () => {\n assert.deepEqual(bothLabelProps, {fontSize: 40});\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/layer.test.d.ts b/build/test/compile/layer.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/layer.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/layer.test.js b/build/test/compile/layer.test.js new file mode 100644 index 0000000000..73e786a153 --- /dev/null +++ b/build/test/compile/layer.test.js @@ -0,0 +1,95 @@ +import { assert } from 'chai'; +import { parseLayerModel } from '../util'; +describe('Layer', function () { + describe('parseScale', function () { + it('should merge domains', function () { + var model = parseLayerModel({ + layer: [{ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }, { + mark: 'point', + encoding: { + x: { field: 'b', type: 'ordinal' } + } + }] + }); + assert.equal(model.children.length, 2); + model.parseScale(); + assert.deepEqual(model.component.scales['x'].domains, [{ + data: 'layer_0_main', + field: 'a', + sort: true + }, { + data: 'layer_1_main', + field: 'b', + sort: true + }]); + }); + it('should union explicit and referenced domains', function () { + var model = parseLayerModel({ + layer: [{ + mark: 'point', + encoding: { + x: { scale: { domain: [1, 2, 3] }, field: 'b', type: 'ordinal' } + } + }, { + mark: 'point', + encoding: { + x: { field: 'b', type: 'ordinal' } + } + }] + }); + model.parseScale(); + assert.deepEqual(model.component.scales['x'].domains, [ + [1, 2, 3], + { + data: 'layer_1_main', + field: 'b', + sort: true + } + ]); + }); + }); + describe('dual axis chart', function () { + var model = parseLayerModel({ + layer: [{ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' } + } + }, { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' } + } + }], + resolve: { + scale: { + x: 'independent' + } + } + }); + assert.equal(model.children.length, 2); + it('should leave scales in children when set to be independent', function () { + model.parseScale(); + assert.equal(model.component.scales['x'], undefined); + assert.deepEqual(model.children[0].component.scales['x'].domains, [{ + data: 'layer_0_main', + field: 'a' + }]); + assert.deepEqual(model.children[1].component.scales['x'].domains, [{ + data: 'layer_1_main', + field: 'b' + }]); + }); + it('should create second axis on top', function () { + model.parseAxisAndHeader(); + assert.equal(model.component.axes['x'].length, 2); + assert.equal(model.component.axes['x'][1].implicit.orient, 'top'); + }); + }); +}); +//# sourceMappingURL=layer.test.js.map \ No newline at end of file diff --git a/build/test/compile/layer.test.js.map b/build/test/compile/layer.test.js.map new file mode 100644 index 0000000000..61fb7155bb --- /dev/null +++ b/build/test/compile/layer.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"layer.test.js","sourceRoot":"","sources":["../../../test/compile/layer.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {parseLayerModel} from '../util';\n\ndescribe('Layer', function() {\n describe('parseScale', () => {\n it('should merge domains', () => {\n const model = parseLayerModel({\n layer: [{\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal'}\n }\n },{\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'ordinal'}\n }\n }]\n });\n assert.equal(model.children.length, 2);\n model.parseScale();\n\n assert.deepEqual(model.component.scales['x'].domains, [{\n data: 'layer_0_main',\n field: 'a',\n sort: true\n }, {\n data: 'layer_1_main',\n field: 'b',\n sort: true\n }]);\n });\n\n it('should union explicit and referenced domains', () => {\n const model = parseLayerModel({\n layer: [{\n mark: 'point',\n encoding: {\n x: {scale: {domain: [1, 2, 3]}, field: 'b', type: 'ordinal'}\n }\n }, {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'ordinal'}\n }\n }]\n });\n model.parseScale();\n\n assert.deepEqual(model.component.scales['x'].domains, [\n [1, 2, 3],\n {\n data: 'layer_1_main',\n field: 'b',\n sort: true\n }]);\n });\n });\n\n describe('dual axis chart', () => {\n const model = parseLayerModel({\n layer: [{\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'quantitative'}\n }\n }, {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'}\n }\n }],\n resolve: {\n scale: {\n x: 'independent'\n }\n }\n });\n\n assert.equal(model.children.length, 2);\n\n it('should leave scales in children when set to be independent', () => {\n model.parseScale();\n\n assert.equal(model.component.scales['x'], undefined);\n assert.deepEqual(model.children[0].component.scales['x'].domains, [{\n data: 'layer_0_main',\n field: 'a'\n }]);\n assert.deepEqual(model.children[1].component.scales['x'].domains, [{\n data: 'layer_1_main',\n field: 'b'\n }]);\n });\n\n it('should create second axis on top', () => {\n model.parseAxisAndHeader();\n\n assert.equal(model.component.axes['x'].length, 2);\n assert.equal(model.component.axes['x'][1].implicit.orient, 'top');\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/layout/header.test.d.ts b/build/test/compile/layout/header.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/layout/header.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/layout/header.test.js b/build/test/compile/layout/header.test.js new file mode 100644 index 0000000000..57b748cad0 --- /dev/null +++ b/build/test/compile/layout/header.test.js @@ -0,0 +1,130 @@ +import * as tslib_1 from "tslib"; +import { assert } from 'chai'; +import { getHeaderGroups, getTitleGroup, labelAlign, labelBaseline } from '../../../src/compile/layout/header'; +import { parseFacetModel } from '../../util'; +describe('compile/layout/header', function () { + describe('label aligns correctly according to angle', function () { + assert.deepEqual(labelAlign(23), { align: { value: 'right' } }); + assert.deepEqual(labelAlign(135), { align: { value: 'left' } }); + assert.deepEqual(labelAlign(50), { align: { value: 'right' } }); + }); + describe('label baseline adjusted according to angle', function () { + assert.deepEqual(labelBaseline(10), { baseline: { value: 'middle' } }); + assert.deepEqual(labelBaseline(90), { baseline: { value: 'top' } }); + }); + describe('getHeaderGroups', function () { + it('should correctly process sort descending', function () { + var model = parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal', sort: 'ascending' }, + column: { field: 'a', type: 'ordinal', sort: 'descending' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + model.parseScale(); + model.parseLayoutSize(); + model.parseAxisAndHeader(); + var rowHeaderGroups = getHeaderGroups(model, 'row'); + var columnHeaderGroups = getHeaderGroups(model, 'column'); + assert.equal(rowHeaderGroups[0].sort.order, 'ascending'); + assert.equal(columnHeaderGroups[0].sort.order, 'descending'); + }); + it('should correctly process sort field', function () { + var model = parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal', sort: { field: 'd', op: 'min' } } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + model.parseScale(); + model.parseLayoutSize(); + model.parseAxisAndHeader(); + var rowHeaderGroups = getHeaderGroups(model, 'row'); + assert.equal(rowHeaderGroups[0].sort.field, 'datum["min_d"]'); + }); + }); + describe('getTitleGroup', function () { + var model = parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' }, + column: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + model.parseScale(); + model.parseLayoutSize(); + model.parseAxisAndHeader(); + describe('for column', function () { + var columnLabelGroup = getTitleGroup(model, 'column'); + var marks = columnLabelGroup.marks, columnTitleGroupTopLevelProps = tslib_1.__rest(columnLabelGroup, ["marks"]); + it('returns a header group mark with correct name, role, type, and from.', function () { + assert.deepEqual(columnTitleGroupTopLevelProps, { + name: 'column_title', + type: 'group', + role: 'column-title' + }); + }); + var textMark = marks[0]; + it('contains a correct text mark with the correct role and encode as the only item in marks', function () { + assert.equal(marks.length, 1); + assert.deepEqual(textMark, { + type: 'text', + role: 'column-title-text', + style: 'guide-title', + encode: { + update: { + text: { value: 'a' }, + align: { value: 'center' } + } + } + }); + }); + }); + describe('for row', function () { + var rowTitleGroup = getTitleGroup(model, 'row'); + var marks = rowTitleGroup.marks, rowTitleGroupTopLevelProps = tslib_1.__rest(rowTitleGroup, ["marks"]); + it('returns a header group mark with correct name, role, type, from, and encode.', function () { + assert.deepEqual(rowTitleGroupTopLevelProps, { + name: 'row_title', + type: 'group', + role: 'row-title' + }); + }); + var textMark = marks[0]; + it('contains a correct text mark with the correct role and encode as the only item in marks', function () { + assert.equal(marks.length, 1); + assert.deepEqual(textMark, { + type: 'text', + role: 'row-title-text', + style: 'guide-title', + encode: { + update: { + text: { value: 'a' }, + angle: { value: 270 }, + align: { value: 'center' } + } + } + }); + }); + }); + }); +}); +//# sourceMappingURL=header.test.js.map \ No newline at end of file diff --git a/build/test/compile/layout/header.test.js.map b/build/test/compile/layout/header.test.js.map new file mode 100644 index 0000000000..6e1be2b93f --- /dev/null +++ b/build/test/compile/layout/header.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"header.test.js","sourceRoot":"","sources":["../../../../test/compile/layout/header.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {getHeaderGroups, getTitleGroup, labelAlign, labelBaseline} from '../../../src/compile/layout/header';\nimport {VgMarkGroup} from '../../../src/vega.schema';\nimport {parseFacetModel} from '../../util';\n\ndescribe('compile/layout/header', () => {\n describe('label aligns correctly according to angle', () => {\n assert.deepEqual(labelAlign(23), {align: {value: 'right'}});\n assert.deepEqual(labelAlign(135), {align: {value: 'left'}});\n assert.deepEqual(labelAlign(50), {align: {value: 'right'}});\n });\n\n describe('label baseline adjusted according to angle', () => {\n assert.deepEqual(labelBaseline(10), {baseline: {value: 'middle'}});\n assert.deepEqual(labelBaseline(90), {baseline: {value: 'top'}});\n });\n\n describe('getHeaderGroups', () => {\n it('should correctly process sort descending', () => {\n const model = parseFacetModel({\n facet: {\n row: {field: 'a', type: 'ordinal', sort: 'ascending'},\n column: {field: 'a', type: 'ordinal', sort: 'descending'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parseScale();\n model.parseLayoutSize();\n model.parseAxisAndHeader();\n\n const rowHeaderGroups = getHeaderGroups(model, 'row');\n const columnHeaderGroups = getHeaderGroups(model, 'column');\n assert.equal(rowHeaderGroups[0].sort.order, 'ascending');\n assert.equal(columnHeaderGroups[0].sort.order, 'descending');\n });\n\n it('should correctly process sort field', () => {\n const model = parseFacetModel({\n facet: {\n row: {field: 'a', type: 'ordinal', sort: {field: 'd', op: 'min'}}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parseScale();\n model.parseLayoutSize();\n model.parseAxisAndHeader();\n\n const rowHeaderGroups = getHeaderGroups(model, 'row');\n assert.equal(rowHeaderGroups[0].sort.field, 'datum[\"min_d\"]');\n });\n });\n\n describe('getTitleGroup', () => {\n const model = parseFacetModel({\n facet: {\n row: {field: 'a', type: 'ordinal'},\n column: {field: 'a', type: 'ordinal'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }\n });\n model.parseScale();\n model.parseLayoutSize();\n model.parseAxisAndHeader();\n\n describe('for column', () => {\n const columnLabelGroup = getTitleGroup(model, 'column');\n const {marks, ...columnTitleGroupTopLevelProps} = columnLabelGroup;\n it('returns a header group mark with correct name, role, type, and from.', () => {\n\n assert.deepEqual(columnTitleGroupTopLevelProps, {\n name: 'column_title',\n type: 'group',\n role: 'column-title'\n });\n });\n const textMark = marks[0];\n\n it('contains a correct text mark with the correct role and encode as the only item in marks', () => {\n assert.equal(marks.length, 1);\n assert.deepEqual(textMark, {\n type: 'text',\n role: 'column-title-text',\n style: 'guide-title',\n encode: {\n update: {\n text: {value: 'a'},\n align: {value: 'center'}\n }\n }\n });\n });\n });\n\n describe('for row', () => {\n const rowTitleGroup = getTitleGroup(model, 'row');\n const {marks, ...rowTitleGroupTopLevelProps} = rowTitleGroup;\n it('returns a header group mark with correct name, role, type, from, and encode.', () => {\n\n assert.deepEqual(rowTitleGroupTopLevelProps, {\n name: 'row_title',\n type: 'group',\n role: 'row-title'\n });\n });\n const textMark = marks[0];\n\n it('contains a correct text mark with the correct role and encode as the only item in marks', () => {\n assert.equal(marks.length, 1);\n assert.deepEqual(textMark, {\n type: 'text',\n role: 'row-title-text',\n style: 'guide-title',\n encode: {\n update: {\n text: {value: 'a'},\n angle: {value: 270},\n align: {value: 'center'}\n }\n }\n });\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/layoutsize/assemble.test.d.ts b/build/test/compile/layoutsize/assemble.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/layoutsize/assemble.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/layoutsize/assemble.test.js b/build/test/compile/layoutsize/assemble.test.js new file mode 100644 index 0000000000..0f065fb1c8 --- /dev/null +++ b/build/test/compile/layoutsize/assemble.test.js @@ -0,0 +1,163 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { parseFacetModel, parseUnitModelWithScaleAndLayoutSize } from '../../util'; +import { X } from '../../../src/channel'; +import { sizeSignals } from '../../../src/compile/layoutsize/assemble'; +import * as log from '../../../src/log'; +describe('compile/layout', function () { + describe('sizeExpr', function () { + it('should return correct formula for ordinal-point scale', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }); + var size = sizeSignals(model, 'width'); + assert.deepEqual(size, [{ + name: 'x_step', + value: 21 + }, { + name: 'width', + update: 'bandspace(domain(\'x\').length, 1, 0.5) * x_step' + }]); + }); + it('should return correct formula for ordinal-band scale with custom padding', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'rect', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { padding: 0.3 } }, + } + }); + var size = sizeSignals(model, 'width'); + assert.deepEqual(size, [{ + name: 'x_step', + value: 21 + }, { + name: 'width', + update: 'bandspace(domain(\'x\').length, 0.3, 0.3) * x_step' + }]); + }); + it('should return correct formula for ordinal-band scale with custom paddingInner', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'rect', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { paddingInner: 0.3 } }, + } + }); + var size = sizeSignals(model, 'width'); + assert.deepEqual(size, [{ + name: 'x_step', + value: 21 + }, { + name: 'width', + update: 'bandspace(domain(\'x\').length, 0.3, 0.15) * x_step' + }]); + }); + it('should return only step if parent is facet', function () { + var model = parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'nominal' } + } + }, + resolve: { + scale: { x: 'independent' } + } + }); + model.parseScale(); + model.parseLayoutSize(); + var size = sizeSignals(model.child, 'width'); + assert.deepEqual(size, [{ + name: 'child_x_step', + value: 21 + }]); + }); + it('should return static view size for ordinal x-scale with null', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { rangeStep: null } } + } + }); + var size = sizeSignals(model, 'width'); + assert.deepEqual(size, [{ name: 'width', value: 200 }]); + }); + it('should return static view size for ordinal y-scale with null', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + y: { field: 'a', type: 'ordinal', scale: { rangeStep: null } } + } + }); + var size = sizeSignals(model, 'height'); + assert.deepEqual(size, [{ name: 'height', value: 200 }]); + }); + it('should return static view size for ordinal scale with top-level width', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + width: 205, + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }); + var size = sizeSignals(model, 'width'); + assert.deepEqual(size, [{ name: 'width', value: 205 }]); + }); + it('should return static view size for ordinal scale with top-level width even if there is numeric rangeStep', log.wrap(function (localLogger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + width: 205, + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { rangeStep: 21 } } + } + }); + var size = sizeSignals(model, 'width'); + assert.deepEqual(size, [{ name: 'width', value: 205 }]); + assert.equal(localLogger.warns[0], log.message.rangeStepDropped(X)); + })); + it('should return static view width for non-ordinal x-scale', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' } + } + }); + var size = sizeSignals(model, 'width'); + assert.deepEqual(size, [{ name: 'width', value: 200 }]); + }); + it('should return static view size for non-ordinal y-scale', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + y: { field: 'a', type: 'quantitative' } + } + }); + var size = sizeSignals(model, 'height'); + assert.deepEqual(size, [{ name: 'height', value: 200 }]); + }); + it('should return default rangeStep if axis is not mapped', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: {}, + config: { scale: { rangeStep: 17 } } + }); + var size = sizeSignals(model, 'width'); + assert.deepEqual(size, [{ name: 'width', value: 17 }]); + }); + it('should return textXRangeStep if axis is not mapped for X of text mark', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'text', + encoding: {}, + config: { scale: { textXRangeStep: 91 } } + }); + var size = sizeSignals(model, 'width'); + assert.deepEqual(size, [{ name: 'width', value: 91 }]); + }); + }); +}); +//# sourceMappingURL=assemble.test.js.map \ No newline at end of file diff --git a/build/test/compile/layoutsize/assemble.test.js.map b/build/test/compile/layoutsize/assemble.test.js.map new file mode 100644 index 0000000000..81c4c32db4 --- /dev/null +++ b/build/test/compile/layoutsize/assemble.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.test.js","sourceRoot":"","sources":["../../../../test/compile/layoutsize/assemble.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {parseFacetModel, parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\nimport {X} from '../../../src/channel';\nimport {sizeSignals} from '../../../src/compile/layoutsize/assemble';\nimport * as log from '../../../src/log';\n\ndescribe('compile/layout', () => {\n describe('sizeExpr', () => {\n it('should return correct formula for ordinal-point scale', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'point', // point mark produce ordinal-point scale by default\n encoding: {\n x: {field: 'a', type: 'ordinal'}\n }\n });\n\n const size = sizeSignals(model, 'width');\n assert.deepEqual(size, [{\n name: 'x_step',\n value: 21\n },{\n name: 'width',\n update: 'bandspace(domain(\\'x\\').length, 1, 0.5) * x_step'\n }]);\n });\n\n it('should return correct formula for ordinal-band scale with custom padding', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'rect', // rect produces ordinal-band by default\n encoding: {\n x: {field: 'a', type: 'ordinal', scale: {padding: 0.3}},\n }\n });\n\n const size = sizeSignals(model, 'width');\n assert.deepEqual(size, [{\n name: 'x_step',\n value: 21\n },{\n name: 'width',\n update: 'bandspace(domain(\\'x\\').length, 0.3, 0.3) * x_step'\n }]);\n });\n\n it('should return correct formula for ordinal-band scale with custom paddingInner', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'rect', // rect produces ordinal-band by default\n encoding: {\n x: {field: 'a', type: 'ordinal', scale: {paddingInner: 0.3}},\n }\n });\n\n const size = sizeSignals(model, 'width');\n assert.deepEqual(size, [{\n name: 'x_step',\n value: 21\n },{\n name: 'width',\n update: 'bandspace(domain(\\'x\\').length, 0.3, 0.15) * x_step'\n }]);\n });\n\n\n it('should return only step if parent is facet', () => {\n const model = parseFacetModel({\n facet: {\n row: {field: 'a', type: 'ordinal'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'nominal'}\n }\n },\n resolve: {\n scale: {x: 'independent'}\n }\n });\n model.parseScale();\n model.parseLayoutSize();\n\n const size = sizeSignals(model.child, 'width');\n assert.deepEqual(size, [{\n name: 'child_x_step',\n value: 21\n }]);\n });\n\n it('should return static view size for ordinal x-scale with null', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal', scale: {rangeStep: null}}\n }\n });\n\n const size = sizeSignals(model, 'width');\n assert.deepEqual(size, [{name: 'width', value: 200}]);\n });\n\n\n it('should return static view size for ordinal y-scale with null', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'point',\n encoding: {\n y: {field: 'a', type: 'ordinal', scale: {rangeStep: null}}\n }\n });\n\n const size = sizeSignals(model, 'height');\n assert.deepEqual(size, [{name: 'height', value: 200}]);\n });\n\n it('should return static view size for ordinal scale with top-level width', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n width: 205,\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal'}\n }\n });\n\n const size = sizeSignals(model, 'width');\n assert.deepEqual(size, [{name: 'width', value: 205}]);\n });\n\n it('should return static view size for ordinal scale with top-level width even if there is numeric rangeStep', log.wrap((localLogger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n width: 205,\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal', scale: {rangeStep: 21}}\n }\n });\n\n const size = sizeSignals(model, 'width');\n assert.deepEqual(size, [{name: 'width', value: 205}]);\n assert.equal(localLogger.warns[0], log.message.rangeStepDropped(X));\n }));\n\n it('should return static view width for non-ordinal x-scale', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'quantitative'}\n }\n });\n\n const size = sizeSignals(model, 'width');\n assert.deepEqual(size, [{name: 'width', value: 200}]);\n });\n\n\n it('should return static view size for non-ordinal y-scale', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'point',\n encoding: {\n y: {field: 'a', type: 'quantitative'}\n }\n });\n\n const size = sizeSignals(model, 'height');\n assert.deepEqual(size, [{name: 'height', value: 200}]);\n });\n\n it('should return default rangeStep if axis is not mapped', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'point',\n encoding: {},\n config: {scale: {rangeStep: 17}}\n });\n const size = sizeSignals(model, 'width');\n assert.deepEqual(size, [{name: 'width', value: 17}]);\n });\n\n it('should return textXRangeStep if axis is not mapped for X of text mark', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'text',\n encoding: {},\n config: {scale: {textXRangeStep: 91}}\n });\n const size = sizeSignals(model, 'width');\n assert.deepEqual(size, [{name: 'width', value: 91}]);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/layoutsize/parse.test.d.ts b/build/test/compile/layoutsize/parse.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/layoutsize/parse.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/layoutsize/parse.test.js b/build/test/compile/layoutsize/parse.test.js new file mode 100644 index 0000000000..b8ef3298e8 --- /dev/null +++ b/build/test/compile/layoutsize/parse.test.js @@ -0,0 +1,80 @@ +import { assert } from 'chai'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('compile/layout', function () { + describe('parseUnitLayoutSize', function () { + it('should have width, height = provided top-level width, height', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + width: 123, + height: 456, + mark: 'text', + encoding: {}, + config: { scale: { textXRangeStep: 91 } } + }); + assert.deepEqual(model.component.layoutSize.explicit.width, 123); + assert.deepEqual(model.component.layoutSize.explicit.height, 456); + }); + it('should have width = default textXRangeStep for text mark without x', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'text', + encoding: {}, + config: { scale: { textXRangeStep: 91 } } + }); + assert.deepEqual(model.component.layoutSize.implicit.width, 91); + }); + it('should have width/height = config.scale.rangeStep for non-text mark without x,y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: {}, + config: { scale: { rangeStep: 23 } } + }); + assert.deepEqual(model.component.layoutSize.implicit.width, 23); + assert.deepEqual(model.component.layoutSize.implicit.height, 23); + }); + it('should have width/height = config.view.width/height for non-ordinal x,y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' }, + y: { field: 'b', type: 'quantitative' } + }, + config: { view: { width: 123, height: 456 } } + }); + assert.deepEqual(model.component.layoutSize.implicit.width, 123); + assert.deepEqual(model.component.layoutSize.implicit.height, 456); + }); + it('should have width/height = config.view.width/height for geoshape', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'geoshape', + encoding: {}, + config: { view: { width: 123, height: 456 } } + }); + assert.deepEqual(model.component.layoutSize.implicit.width, 123); + assert.deepEqual(model.component.layoutSize.implicit.height, 456); + }); + it('should have width/height = config.view.width/height for non-ordinal x,y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { rangeStep: null } }, + y: { field: 'b', type: 'ordinal', scale: { rangeStep: null } } + }, + config: { view: { width: 123, height: 456 } } + }); + assert.deepEqual(model.component.layoutSize.implicit.width, 123); + assert.deepEqual(model.component.layoutSize.implicit.height, 456); + }); + it('should have width/height = undefined for non-ordinal x,y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' }, + y: { field: 'b', type: 'ordinal' } + }, + config: { view: { width: 123, height: 456 } } + }); + assert.deepEqual(model.component.layoutSize.get('width'), 'range-step'); + assert.deepEqual(model.component.layoutSize.get('height'), 'range-step'); + }); + }); +}); +//# sourceMappingURL=parse.test.js.map \ No newline at end of file diff --git a/build/test/compile/layoutsize/parse.test.js.map b/build/test/compile/layoutsize/parse.test.js.map new file mode 100644 index 0000000000..399bab025a --- /dev/null +++ b/build/test/compile/layoutsize/parse.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.test.js","sourceRoot":"","sources":["../../../../test/compile/layoutsize/parse.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('compile/layout', () => {\n describe('parseUnitLayoutSize', () => {\n it('should have width, height = provided top-level width, height', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n width: 123,\n height: 456,\n mark: 'text',\n encoding: {},\n config: {scale: {textXRangeStep: 91}}\n });\n\n assert.deepEqual(model.component.layoutSize.explicit.width, 123);\n assert.deepEqual(model.component.layoutSize.explicit.height, 456);\n });\n\n it('should have width = default textXRangeStep for text mark without x', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'text',\n encoding: {},\n config: {scale: {textXRangeStep: 91}}\n });\n\n assert.deepEqual(model.component.layoutSize.implicit.width, 91);\n });\n\n it('should have width/height = config.scale.rangeStep for non-text mark without x,y', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'point',\n encoding: {},\n config: {scale: {rangeStep: 23}}\n });\n\n assert.deepEqual(model.component.layoutSize.implicit.width, 23);\n assert.deepEqual(model.component.layoutSize.implicit.height, 23);\n });\n\n it('should have width/height = config.view.width/height for non-ordinal x,y', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'quantitative'},\n y: {field: 'b', type: 'quantitative'}\n },\n config: {view: {width: 123, height: 456}}\n });\n\n assert.deepEqual(model.component.layoutSize.implicit.width, 123);\n assert.deepEqual(model.component.layoutSize.implicit.height, 456);\n });\n\n it('should have width/height = config.view.width/height for geoshape', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'geoshape',\n encoding: {},\n config: {view: {width: 123, height: 456}}\n });\n\n assert.deepEqual(model.component.layoutSize.implicit.width, 123);\n assert.deepEqual(model.component.layoutSize.implicit.height, 456);\n });\n\n it('should have width/height = config.view.width/height for non-ordinal x,y', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal', scale: {rangeStep: null}},\n y: {field: 'b', type: 'ordinal', scale: {rangeStep: null}}\n },\n config: {view: {width: 123, height: 456}}\n });\n\n assert.deepEqual(model.component.layoutSize.implicit.width, 123);\n assert.deepEqual(model.component.layoutSize.implicit.height, 456);\n });\n\n it('should have width/height = undefined for non-ordinal x,y', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal'},\n y: {field: 'b', type: 'ordinal'}\n },\n config: {view: {width: 123, height: 456}}\n });\n\n assert.deepEqual(model.component.layoutSize.get('width'), 'range-step');\n assert.deepEqual(model.component.layoutSize.get('height'), 'range-step');\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/legend/assemble.test.d.ts b/build/test/compile/legend/assemble.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/legend/assemble.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/legend/assemble.test.js b/build/test/compile/legend/assemble.test.js new file mode 100644 index 0000000000..9bd9be791c --- /dev/null +++ b/build/test/compile/legend/assemble.test.js @@ -0,0 +1,45 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { parseUnitModelWithScale } from '../../util'; +describe('legend/assemble', function () { + it('merges legend of the same field with the default type.', function () { + var model = parseUnitModelWithScale({ + "$schema": "https://vega.github.io/schema/vega-lite/v2.json", + "description": "A scatterplot showing horsepower and miles per gallons.", + "data": { "url": "data/cars.json" }, + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" }, + "shape": { "field": "Origin", "type": "nominal" } + } + }); + model.parseLegend(); + var legends = model.assembleLegends(); + assert.equal(legends.length, 1); + assert.equal(legends[0].title, 'Origin'); + assert.equal(legends[0].stroke, 'color'); + assert.equal(legends[0].shape, 'shape'); + }); + it('merges legend of the same field and favor symbol legend over gradient', function () { + var model = parseUnitModelWithScale({ + "data": { "values": [{ "a": "A", "b": 28 }, { "a": "B", "b": 55 }] }, + "mark": "bar", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" }, + "color": { "field": "b", "type": "quantitative" }, + "size": { "field": "b", "type": "quantitative" } + } + }); + model.parseLegend(); + var legends = model.assembleLegends(); + assert.equal(legends.length, 1); + assert.equal(legends[0].title, 'b'); + assert.equal(legends[0].type, 'symbol'); + assert.equal(legends[0].fill, 'color'); + assert.equal(legends[0].size, 'size'); + }); +}); +//# sourceMappingURL=assemble.test.js.map \ No newline at end of file diff --git a/build/test/compile/legend/assemble.test.js.map b/build/test/compile/legend/assemble.test.js.map new file mode 100644 index 0000000000..409901f442 --- /dev/null +++ b/build/test/compile/legend/assemble.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.test.js","sourceRoot":"","sources":["../../../../test/compile/legend/assemble.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,uBAAuB,EAAC,MAAM,YAAY,CAAC;AAGnD,QAAQ,CAAC,iBAAiB,EAAE;IAC1B,EAAE,CAAC,wDAAwD,EAAE;QAC3D,IAAM,KAAK,GAAG,uBAAuB,CAAC;YACpC,SAAS,EAAE,iDAAiD;YAC5D,aAAa,EAAE,yDAAyD;YACxE,MAAM,EAAE,EAAC,KAAK,EAAE,gBAAgB,EAAC;YACjC,MAAM,EAAE,OAAO;YACf,UAAU,EAAE;gBACV,GAAG,EAAE,EAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAC;gBACpD,GAAG,EAAE,EAAC,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,cAAc,EAAC;gBAC1D,OAAO,EAAE,EAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC;gBAC/C,OAAO,EAAE,EAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC;aAChD;SACF,CAAC,CAAC;QACH,KAAK,CAAC,WAAW,EAAE,CAAC;QAEpB,IAAM,OAAO,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAEhC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE;QAC1E,IAAM,KAAK,GAAG,uBAAuB,CAAC;YACpC,MAAM,EAAE,EAAC,QAAQ,EAAE,CAAC,EAAC,GAAG,EAAE,GAAG,EAAC,GAAG,EAAE,EAAE,EAAC,EAAC,EAAC,GAAG,EAAE,GAAG,EAAC,GAAG,EAAE,EAAE,EAAC,CAAC,EAAC;YAC3D,MAAM,EAAE,KAAK;YACb,UAAU,EAAE;gBACV,GAAG,EAAE,EAAC,OAAO,EAAE,GAAG,EAAC,MAAM,EAAE,SAAS,EAAC;gBACrC,GAAG,EAAE,EAAC,OAAO,EAAE,GAAG,EAAC,MAAM,EAAE,cAAc,EAAC;gBAC1C,OAAO,EAAE,EAAC,OAAO,EAAE,GAAG,EAAC,MAAM,EAAE,cAAc,EAAC;gBAC9C,MAAM,EAAE,EAAC,OAAO,EAAE,GAAG,EAAC,MAAM,EAAE,cAAc,EAAC;aAC9C;SACF,CAAC,CAAC;QAEH,KAAK,CAAC,WAAW,EAAE,CAAC;QAEpB,IAAM,OAAO,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {parseUnitModelWithScale} from '../../util';\n\n\ndescribe('legend/assemble', () => {\n it('merges legend of the same field with the default type.', () => {\n const model = parseUnitModelWithScale({\n \"$schema\": \"https://vega.github.io/schema/vega-lite/v2.json\",\n \"description\": \"A scatterplot showing horsepower and miles per gallons.\",\n \"data\": {\"url\": \"data/cars.json\"},\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"shape\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n });\n model.parseLegend();\n\n const legends = model.assembleLegends();\n assert.equal(legends.length, 1);\n\n assert.equal(legends[0].title, 'Origin');\n assert.equal(legends[0].stroke, 'color');\n assert.equal(legends[0].shape, 'shape');\n });\n\n it('merges legend of the same field and favor symbol legend over gradient', () => {\n const model = parseUnitModelWithScale({\n \"data\": {\"values\": [{\"a\": \"A\",\"b\": 28},{\"a\": \"B\",\"b\": 55}]},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"a\",\"type\": \"ordinal\"},\n \"y\": {\"field\": \"b\",\"type\": \"quantitative\"},\n \"color\": {\"field\": \"b\",\"type\": \"quantitative\"},\n \"size\": {\"field\": \"b\",\"type\": \"quantitative\"}\n }\n });\n\n model.parseLegend();\n\n const legends = model.assembleLegends();\n assert.equal(legends.length, 1);\n assert.equal(legends[0].title, 'b');\n assert.equal(legends[0].type, 'symbol');\n assert.equal(legends[0].fill, 'color');\n assert.equal(legends[0].size, 'size');\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/legend/encode.test.d.ts b/build/test/compile/legend/encode.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/legend/encode.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/legend/encode.test.js b/build/test/compile/legend/encode.test.js new file mode 100644 index 0000000000..9b28f8d73f --- /dev/null +++ b/build/test/compile/legend/encode.test.js @@ -0,0 +1,95 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { COLOR } from '../../../src/channel'; +import * as encode from '../../../src/compile/legend/encode'; +import { TimeUnit } from '../../../src/timeunit'; +import { TEMPORAL } from '../../../src/type'; +import { parseUnitModelWithScale } from '../../util'; +describe('compile/legend', function () { + describe('encode.symbols', function () { + it('should not have fill, strokeDash, or strokeDashOffset', function () { + var symbol = encode.symbols({ field: 'a', type: 'nominal' }, {}, parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + color: { field: "a", type: "nominal" } + } + }), COLOR, 'symbol'); + assert.deepEqual(symbol.fill, { value: 'transparent' }); + assert.isUndefined((symbol || {}).strokeDash); + assert.isUndefined((symbol || {}).strokeDashOffset); + }); + it('should return specific symbols.shape.value if user has specified', function () { + var symbol = encode.symbols({ field: 'a', type: 'nominal' }, {}, parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + shape: { value: "square" } + } + }), COLOR, 'symbol'); + assert.deepEqual(symbol.shape['value'], 'square'); + }); + it('should have default opacity', function () { + var symbol = encode.symbols({ field: 'a', type: 'nominal' }, {}, parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" } + } + }), COLOR, 'symbol'); + assert.deepEqual(symbol.opacity['value'], 0.7); // default opacity is 0.7. + }); + it('should return the maximum value when there is a condition', function () { + var symbol = encode.symbols({ field: 'a', type: 'nominal' }, {}, parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + opacity: { + condition: { selection: "brush", value: 1 }, + value: 0 + } + } + }), COLOR, 'symbol'); + assert.deepEqual(symbol.opacity['value'], 1); + }); + }); + describe('encode.gradient', function () { + it('should have default opacity', function () { + var gradient = encode.gradient({ field: 'a', type: 'quantitative' }, {}, parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "quantitative" } + } + }), COLOR, 'gradient'); + assert.deepEqual(gradient.opacity['value'], 0.7); // default opacity is 0.7. + }); + }); + describe('encode.labels', function () { + it('should return correct expression for the timeUnit: TimeUnit.MONTH', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal" }, + color: { field: "a", type: "temporal", timeUnit: "month" } + } + }); + var fieldDef = { field: 'a', type: TEMPORAL, timeUnit: TimeUnit.MONTH }; + var label = encode.labels(fieldDef, {}, model, COLOR, 'gradient'); + var expected = "timeFormat(datum.value, '%b')"; + assert.deepEqual(label.text.signal, expected); + }); + it('should return correct expression for the timeUnit: TimeUnit.QUARTER', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal" }, + color: { field: "a", type: "temporal", timeUnit: "quarter" } + } + }); + var fieldDef = { field: 'a', type: TEMPORAL, timeUnit: TimeUnit.QUARTER }; + var label = encode.labels(fieldDef, {}, model, COLOR, 'gradient'); + var expected = "'Q' + quarter(datum.value)"; + assert.deepEqual(label.text.signal, expected); + }); + }); +}); +//# sourceMappingURL=encode.test.js.map \ No newline at end of file diff --git a/build/test/compile/legend/encode.test.js.map b/build/test/compile/legend/encode.test.js.map new file mode 100644 index 0000000000..6d8f602ce2 --- /dev/null +++ b/build/test/compile/legend/encode.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"encode.test.js","sourceRoot":"","sources":["../../../../test/compile/legend/encode.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {COLOR} from '../../../src/channel';\nimport * as encode from '../../../src/compile/legend/encode';\nimport {TimeUnit} from '../../../src/timeunit';\nimport {TEMPORAL} from '../../../src/type';\nimport {parseUnitModelWithScale} from '../../util';\n\ndescribe('compile/legend', function() {\n describe('encode.symbols', function() {\n it('should not have fill, strokeDash, or strokeDashOffset', function() {\n\n const symbol = encode.symbols({field: 'a', type: 'nominal'}, {}, parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"nominal\"},\n color: {field: \"a\", type: \"nominal\"}\n }\n }), COLOR, 'symbol');\n assert.deepEqual(symbol.fill, {value: 'transparent'});\n assert.isUndefined((symbol||{}).strokeDash);\n assert.isUndefined((symbol||{}).strokeDashOffset);\n });\n\n it('should return specific symbols.shape.value if user has specified', function() {\n\n const symbol = encode.symbols({field: 'a', type: 'nominal'}, {}, parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"nominal\"},\n shape: {value: \"square\"}}\n }), COLOR, 'symbol');\n assert.deepEqual(symbol.shape['value'], 'square');\n });\n\n it('should have default opacity', function() {\n\n const symbol = encode.symbols({field: 'a', type: 'nominal'}, {}, parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"nominal\"}}\n }), COLOR, 'symbol');\n assert.deepEqual(symbol.opacity['value'], 0.7); // default opacity is 0.7.\n });\n\n it('should return the maximum value when there is a condition', function() {\n\n const symbol = encode.symbols({field: 'a', type: 'nominal'}, {}, parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"nominal\"},\n opacity: {\n condition: {selection: \"brush\", value: 1},\n value: 0\n }}\n }), COLOR, 'symbol');\n assert.deepEqual(symbol.opacity['value'], 1);\n });\n });\n\n describe('encode.gradient', function() {\n it('should have default opacity', function() {\n const gradient = encode.gradient({field: 'a', type: 'quantitative'}, {}, parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"quantitative\"}}\n }), COLOR, 'gradient');\n\n assert.deepEqual(gradient.opacity['value'], 0.7); // default opacity is 0.7.\n });\n });\n\n describe('encode.labels', function() {\n it('should return correct expression for the timeUnit: TimeUnit.MONTH', function() {\n\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"temporal\"},\n color: {field: \"a\", type: \"temporal\", timeUnit: \"month\"}\n }\n });\n\n const fieldDef = {field: 'a', type: TEMPORAL, timeUnit: TimeUnit.MONTH};\n const label = encode.labels(fieldDef, {}, model, COLOR, 'gradient');\n const expected = `timeFormat(datum.value, '%b')`;\n assert.deepEqual(label.text.signal, expected);\n });\n\n it('should return correct expression for the timeUnit: TimeUnit.QUARTER', function() {\n\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"temporal\"},\n color: {field: \"a\", type: \"temporal\", timeUnit: \"quarter\"}}\n });\n\n const fieldDef = {field: 'a', type: TEMPORAL, timeUnit: TimeUnit.QUARTER};\n const label = encode.labels(fieldDef, {}, model, COLOR, 'gradient');\n const expected = `'Q' + quarter(datum.value)`;\n assert.deepEqual(label.text.signal, expected);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/legend/parse.test.d.ts b/build/test/compile/legend/parse.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/legend/parse.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/legend/parse.test.js b/build/test/compile/legend/parse.test.js new file mode 100644 index 0000000000..e81562608a --- /dev/null +++ b/build/test/compile/legend/parse.test.js @@ -0,0 +1,173 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { COLOR, OPACITY, SHAPE, SIZE } from '../../../src/channel'; +import * as legendParse from '../../../src/compile/legend/parse'; +import { parseLegend } from '../../../src/compile/legend/parse'; +import { isFieldDef } from '../../../src/fielddef'; +import { GEOJSON } from '../../../src/type'; +import { parseLayerModel, parseUnitModelWithScale } from '../../util'; +describe('compile/legend', function () { + describe('parseUnitLegend()', function () { + it("should not produce a Vega legend object on channel 'shape' with type 'geojson'", function () { + var spec = { + "mark": "geoshape", + "data": { "url": "data/income.json" }, + "transform": [ + { + "lookup": "id", + "from": { + "data": { + "url": "data/us-10m.json", + "format": { "type": "topojson", "feature": "states" } + }, + "key": "id" + }, + "as": "geo" + } + ], + "encoding": { + "shape": { "field": "geo", "type": "geojson" } + } + }; + var unitModel = parseUnitModelWithScale(spec); + var channelDef = unitModel.encoding[SHAPE]; + assert.isTrue(isFieldDef(channelDef)); + if (isFieldDef(channelDef)) { + assert.equal(channelDef.type, GEOJSON); + } + parseLegend(unitModel); + var legendComp = unitModel.component.legends; + assert.isUndefined(legendComp[SHAPE]); + }); + }); + describe('parseLegendForChannel()', function () { + it('should produce a Vega legend object with correct type and scale for color', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + color: { field: "a", type: "quantitative" } + } + }); + var def = legendParse.parseLegendForChannel(model, COLOR).combine(); + assert.isObject(def); + assert.equal(def.title, 'a'); + assert.equal(def.stroke, 'color'); + assert.equal(def.type, 'gradient'); + }); + it('should produce no legend title when title is null, "", or false', function () { + for (var _i = 0, _a = [null, '', false]; _i < _a.length; _i++) { + var val = _a[_i]; + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + color: { + field: "a", type: "quantitative", + legend: { title: val } // Need to cast as false is not valid, but we want to fall back gracefully + } + } + }); + var def = legendParse.parseLegendForChannel(model, COLOR).combine(); + assert.doesNotHaveAnyKeys(def, ['title']); + } + }); + it('should store fieldDef.title as explicit', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + color: { + field: "a", type: "quantitative", + legend: { title: 'foo' } // Need to cast as false is not valid, but we want to fall back gracefully + } + } + }); + var def = legendParse.parseLegendForChannel(model, COLOR).combine(); + assert.equal(def.title, 'foo'); + }); + [SIZE, SHAPE, OPACITY].forEach(function (channel) { + it("should produce a Vega legend object with correct type and scale for " + channel, function () { + var spec = { + mark: "point", + encoding: { + x: { field: "a", type: "nominal" } + } + }; + spec.encoding[channel] = { field: "a", type: "nominal" }; + var model = parseUnitModelWithScale(spec); + var def = legendParse.parseLegendForChannel(model, channel).combine(); + var channelDef = model.encoding[channel]; + if (isFieldDef(channelDef)) { + assert.notEqual(channelDef.type, GEOJSON); + } + if (channel !== OPACITY) { + assert.equal(def.encode.symbols.update.opacity.value, 0.7); + } + else { + assert.isUndefined(def.encode.symbols.update.opacity); + } + assert.isObject(def); + assert.equal(def.title, "a"); + }); + }); + }); + describe('parseNonUnitLegend()', function () { + it('should correctly merge orient by favoring explicit orient', function () { + var model = parseLayerModel({ + "$schema": "https://vega.github.io/schema/vega-lite/v2.json", + "description": "Google's stock price over time.", + "data": { "url": "data/stocks.csv" }, + "layer": [ + { + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" }, + "color": { "field": "symbol", "type": "nominal" } + } + }, { + "mark": { "type": "point", "filled": true }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" }, + "color": { "field": "symbol", "type": "nominal", "legend": { "orient": "left" } } + } + } + ] + }); + model.parseScale(); + model.parseLegend(); + assert.equal(model.component.legends.color.explicit.orient, 'left'); + }); + it('should correctly merge legend that exists only on one plot', function () { + var model = parseLayerModel({ + "$schema": "https://vega.github.io/schema/vega-lite/v2.json", + "description": "Google's stock price over time.", + "data": { "url": "data/stocks.csv" }, + "layer": [ + { + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, { + "mark": { "type": "point", "filled": true }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" }, + "color": { "field": "symbol", "type": "nominal" } + } + } + ] + }); + model.parseScale(); + model.parseLegend(); + assert.isOk(model.component.legends.color); + assert.isUndefined(model.children[0].component.legends.color); + assert.isUndefined(model.children[1].component.legends.color); + }); + }); +}); +//# sourceMappingURL=parse.test.js.map \ No newline at end of file diff --git a/build/test/compile/legend/parse.test.js.map b/build/test/compile/legend/parse.test.js.map new file mode 100644 index 0000000000..eb7dcc88ac --- /dev/null +++ b/build/test/compile/legend/parse.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.test.js","sourceRoot":"","sources":["../../../../test/compile/legend/parse.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAC,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,WAAW,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAC,WAAW,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAC,eAAe,EAAE,uBAAuB,EAAC,MAAM,YAAY,CAAC;AAEpE,QAAQ,CAAC,gBAAgB,EAAE;IACzB,QAAQ,CAAC,mBAAmB,EAAE;QAC5B,EAAE,CAAC,gFAAgF,EAAE;YACnF,IAAM,IAAI,GAAuB;gBAC/B,MAAM,EAAE,UAAU;gBAClB,MAAM,EAAE,EAAC,KAAK,EAAE,kBAAkB,EAAC;gBACnC,WAAW,EAAE;oBACX;wBACE,QAAQ,EAAE,IAAI;wBACd,MAAM,EAAE;4BACN,MAAM,EAAE;gCACN,KAAK,EAAE,kBAAkB;gCACzB,QAAQ,EAAE,EAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAC;6BACpD;4BACD,KAAK,EAAE,IAAI;yBACZ;wBACD,IAAI,EAAE,KAAK;qBACZ;iBACF;gBACD,UAAU,EAAE;oBACV,OAAO,EAAE,EAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAC;iBAC7C;aACF,CAAC;YAEF,IAAM,SAAS,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;YAChD,IAAM,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;YACtC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE;gBAC1B,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;aACxC;YACD,WAAW,CAAC,SAAS,CAAC,CAAC;YACvB,IAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC;YAC/C,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,yBAAyB,EAAE;QAClC,EAAE,CAAC,2EAA2E,EAAE;YAC9E,IAAM,KAAK,GAAG,uBAAuB,CAAC;gBACpC,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE;oBACR,CAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAC;oBAChC,KAAK,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC;iBAC1C;aACF,CAAC,CAAC;YAEH,IAAM,GAAG,GAAG,WAAW,CAAC,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;YACtE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACrB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAClC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iEAAiE,EAAE;YACpE,KAAkB,UAAiB,EAAjB,MAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,EAAjB,cAAiB,EAAjB,IAAiB,EAAE;gBAAhC,IAAM,GAAG,SAAA;gBACZ,IAAM,KAAK,GAAG,uBAAuB,CAAC;oBACpC,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE;wBACR,CAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAC;wBAChC,KAAK,EAAE;4BACL,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc;4BAChC,MAAM,EAAE,EAAC,KAAK,EAAE,GAAU,EAAC,CAAC,0EAA0E;yBACvG;qBACF;iBACF,CAAC,CAAC;gBAEH,IAAM,GAAG,GAAG,WAAW,CAAC,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;gBACtE,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;aAC3C;QACH,CAAC,CAAC,CAAC;QAGH,EAAE,CAAC,yCAAyC,EAAE;YAC5C,IAAM,KAAK,GAAG,uBAAuB,CAAC;gBACpC,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE;oBACR,CAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAC;oBAChC,KAAK,EAAE;wBACL,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc;wBAChC,MAAM,EAAE,EAAC,KAAK,EAAE,KAAK,EAAC,CAAC,0EAA0E;qBAClG;iBACF;aACF,CAAC,CAAC;YAEH,IAAM,GAAG,GAAG,WAAW,CAAC,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;YACtE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,UAAA,OAAO;YACpC,EAAE,CAAC,yEAAuE,OAAS,EAAE;gBACnF,IAAM,IAAI,GAAuB;oBAC/B,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE;wBACR,CAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAC;qBACjC;iBACF,CAAC;gBACF,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAC,CAAC;gBAEvD,IAAM,KAAK,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;gBAE5C,IAAM,GAAG,GAAG,WAAW,CAAC,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;gBAExE,IAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAC3C,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE;oBAC1B,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;iBAC3C;gBAED,IAAI,OAAO,KAAK,OAAO,EAAE;oBACvB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;iBAC5D;qBAAM;oBACL,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;iBACvD;gBACD,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBACrB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sBAAsB,EAAE;QAC/B,EAAE,CAAC,2DAA2D,EAAE;YAC9D,IAAM,KAAK,GAAG,eAAe,CAAC;gBAC5B,SAAS,EAAE,iDAAiD;gBAC5D,aAAa,EAAE,iCAAiC;gBAChD,MAAM,EAAE,EAAC,KAAK,EAAE,iBAAiB,EAAC;gBAClC,OAAO,EAAE;oBACP;wBACE,MAAM,EAAE,MAAM;wBACd,UAAU,EAAE;4BACV,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAC;4BAC1C,GAAG,EAAE,EAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAC;4BAC/C,OAAO,EAAE,EAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC;yBAChD;qBACF,EAAC;wBACA,MAAM,EAAE,EAAC,MAAM,EAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAC;wBACxC,UAAU,EAAE;4BACV,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAC;4BAC1C,GAAG,EAAE,EAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAC;4BAC/C,OAAO,EAAE,EAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAC,QAAQ,EAAE,MAAM,EAAC,EAAC;yBAC9E;qBACF;iBACF;aACF,CAAC,CAAC;YACH,KAAK,CAAC,UAAU,EAAE,CAAC;YACnB,KAAK,CAAC,WAAW,EAAE,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE;YAC/D,IAAM,KAAK,GAAG,eAAe,CAAC;gBAC5B,SAAS,EAAE,iDAAiD;gBAC5D,aAAa,EAAE,iCAAiC;gBAChD,MAAM,EAAE,EAAC,KAAK,EAAE,iBAAiB,EAAC;gBAClC,OAAO,EAAE;oBACP;wBACE,MAAM,EAAE,MAAM;wBACd,UAAU,EAAE;4BACV,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAC;4BAC1C,GAAG,EAAE,EAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAC;yBAChD;qBACF,EAAC;wBACA,MAAM,EAAE,EAAC,MAAM,EAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAC;wBACxC,UAAU,EAAE;4BACV,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAC;4BAC1C,GAAG,EAAE,EAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAC;4BAC/C,OAAO,EAAE,EAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC;yBAChD;qBACF;iBACF;aACF,CAAC,CAAC;YACH,KAAK,CAAC,UAAU,EAAE,CAAC;YACnB,KAAK,CAAC,WAAW,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC3C,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9D,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {COLOR, OPACITY, SHAPE, SIZE} from '../../../src/channel';\nimport * as legendParse from '../../../src/compile/legend/parse';\nimport {parseLegend} from '../../../src/compile/legend/parse';\nimport {isFieldDef} from '../../../src/fielddef';\nimport {NormalizedUnitSpec} from '../../../src/spec';\nimport {GEOJSON} from '../../../src/type';\nimport {parseLayerModel, parseUnitModelWithScale} from '../../util';\n\ndescribe('compile/legend', function () {\n describe('parseUnitLegend()', function () {\n it(`should not produce a Vega legend object on channel 'shape' with type 'geojson'`, function () {\n const spec: NormalizedUnitSpec = {\n \"mark\": \"geoshape\",\n \"data\": {\"url\": \"data/income.json\"},\n \"transform\": [\n {\n \"lookup\": \"id\",\n \"from\": {\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\"type\": \"topojson\", \"feature\": \"states\"}\n },\n \"key\": \"id\"\n },\n \"as\": \"geo\"\n }\n ],\n \"encoding\": {\n \"shape\": {\"field\": \"geo\", \"type\": \"geojson\"}\n }\n };\n\n const unitModel = parseUnitModelWithScale(spec);\n const channelDef = unitModel.encoding[SHAPE];\n assert.isTrue(isFieldDef(channelDef));\n if (isFieldDef(channelDef)) {\n assert.equal(channelDef.type, GEOJSON);\n }\n parseLegend(unitModel);\n const legendComp = unitModel.component.legends;\n assert.isUndefined(legendComp[SHAPE]);\n });\n });\n\n describe('parseLegendForChannel()', function() {\n it('should produce a Vega legend object with correct type and scale for color', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"nominal\"},\n color: {field: \"a\", type: \"quantitative\"}\n }\n });\n\n const def = legendParse.parseLegendForChannel(model, COLOR).combine();\n assert.isObject(def);\n assert.equal(def.title, 'a');\n assert.equal(def.stroke, 'color');\n assert.equal(def.type, 'gradient');\n });\n\n it('should produce no legend title when title is null, \"\", or false', function () {\n for (const val of [null, '', false]) {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"nominal\"},\n color: {\n field: \"a\", type: \"quantitative\",\n legend: {title: val as any} // Need to cast as false is not valid, but we want to fall back gracefully\n }\n }\n });\n\n const def = legendParse.parseLegendForChannel(model, COLOR).combine();\n assert.doesNotHaveAnyKeys(def, ['title']);\n }\n });\n\n\n it('should store fieldDef.title as explicit', function () {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"nominal\"},\n color: {\n field: \"a\", type: \"quantitative\",\n legend: {title: 'foo'} // Need to cast as false is not valid, but we want to fall back gracefully\n }\n }\n });\n\n const def = legendParse.parseLegendForChannel(model, COLOR).combine();\n assert.equal(def.title, 'foo');\n });\n\n [SIZE, SHAPE, OPACITY].forEach(channel => {\n it(`should produce a Vega legend object with correct type and scale for ${channel}`, function() {\n const spec: NormalizedUnitSpec = {\n mark: \"point\",\n encoding: {\n x: {field: \"a\", type: \"nominal\"}\n }\n };\n spec.encoding[channel] = {field: \"a\", type: \"nominal\"};\n\n const model = parseUnitModelWithScale(spec);\n\n const def = legendParse.parseLegendForChannel(model, channel).combine();\n\n const channelDef = model.encoding[channel];\n if (isFieldDef(channelDef)) {\n assert.notEqual(channelDef.type, GEOJSON);\n }\n\n if (channel !== OPACITY) {\n assert.equal(def.encode.symbols.update.opacity.value, 0.7);\n } else {\n assert.isUndefined(def.encode.symbols.update.opacity);\n }\n assert.isObject(def);\n assert.equal(def.title, \"a\");\n });\n });\n });\n\n describe('parseNonUnitLegend()', () => {\n it('should correctly merge orient by favoring explicit orient', () => {\n const model = parseLayerModel({\n \"$schema\": \"https://vega.github.io/schema/vega-lite/v2.json\",\n \"description\": \"Google's stock price over time.\",\n \"data\": {\"url\": \"data/stocks.csv\"},\n \"layer\": [\n {\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"symbol\", \"type\": \"nominal\"}\n }\n },{\n \"mark\": {\"type\":\"point\", \"filled\": true},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"symbol\", \"type\": \"nominal\", \"legend\": {\"orient\": \"left\"}}\n }\n }\n ]\n });\n model.parseScale();\n model.parseLegend();\n assert.equal(model.component.legends.color.explicit.orient, 'left');\n });\n\n it('should correctly merge legend that exists only on one plot', () => {\n const model = parseLayerModel({\n \"$schema\": \"https://vega.github.io/schema/vega-lite/v2.json\",\n \"description\": \"Google's stock price over time.\",\n \"data\": {\"url\": \"data/stocks.csv\"},\n \"layer\": [\n {\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n },{\n \"mark\": {\"type\":\"point\", \"filled\": true},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"symbol\", \"type\": \"nominal\"}\n }\n }\n ]\n });\n model.parseScale();\n model.parseLegend();\n assert.isOk(model.component.legends.color);\n assert.isUndefined(model.children[0].component.legends.color);\n assert.isUndefined(model.children[1].component.legends.color);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/legend/properties.test.d.ts b/build/test/compile/legend/properties.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/legend/properties.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/legend/properties.test.js b/build/test/compile/legend/properties.test.js new file mode 100644 index 0000000000..f4e563c00f --- /dev/null +++ b/build/test/compile/legend/properties.test.js @@ -0,0 +1,46 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { COLOR, SIZE } from '../../../src/channel'; +import * as properties from '../../../src/compile/legend/properties'; +describe('compile/legend', function () { + describe('values()', function () { + it('should return correct timestamp values for DateTimes', function () { + var values = properties.values({ values: [{ year: 1970 }, { year: 1980 }] }, { field: 'a', type: 'temporal' }); + assert.deepEqual(values, [ + { "signal": "datetime(1970, 0, 1, 0, 0, 0, 0)" }, + { "signal": "datetime(1980, 0, 1, 0, 0, 0, 0)" }, + ]); + }); + it('should simply return values for non-DateTime', function () { + var values = properties.values({ values: [1, 2, 3, 4] }, { field: 'a', type: 'quantitative' }); + assert.deepEqual(values, [1, 2, 3, 4]); + }); + }); + describe('type()', function () { + it('should return gradient type for color scale', function () { + var t = properties.type('quantitative', COLOR, 'sequential'); + assert.equal(t, 'gradient'); + }); + it('should not return gradient type for size scale', function () { + var t = properties.type('quantitative', SIZE, 'linear'); + assert.equal(t, undefined); + }); + it('should return no type for color scale with bin', function () { + var t = properties.type('quantitative', COLOR, 'bin-ordinal'); + assert.equal(t, undefined); + }); + it('should return gradient type for color scale with time scale', function () { + var t = properties.type('temporal', COLOR, 'time'); + assert.equal(t, 'gradient'); + }); + it('should return no type for color scale with ordinal scale and temporal type', function () { + var t = properties.type('temporal', COLOR, 'ordinal'); + assert.equal(t, undefined); + }); + it('should return no type for color scale with ordinal scale and ordinal type', function () { + var t = properties.type('ordinal', COLOR, 'ordinal'); + assert.equal(t, undefined); + }); + }); +}); +//# sourceMappingURL=properties.test.js.map \ No newline at end of file diff --git a/build/test/compile/legend/properties.test.js.map b/build/test/compile/legend/properties.test.js.map new file mode 100644 index 0000000000..90be9fae49 --- /dev/null +++ b/build/test/compile/legend/properties.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"properties.test.js","sourceRoot":"","sources":["../../../../test/compile/legend/properties.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,KAAK,EAAE,IAAI,EAAC,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,UAAU,MAAM,wCAAwC,CAAC;AAErE,QAAQ,CAAC,gBAAgB,EAAE;IACzB,QAAQ,CAAC,UAAU,EAAE;QACnB,EAAE,CAAC,sDAAsD,EAAE;YACzD,IAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,EAAC,MAAM,EAAE,CAAC,EAAC,IAAI,EAAE,IAAI,EAAC,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,EAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAC,CAAC,CAAC;YAEzG,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE;gBACvB,EAAC,QAAQ,EAAE,kCAAkC,EAAC;gBAC9C,EAAC,QAAQ,EAAE,kCAAkC,EAAC;aAC/C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE;YACjD,IAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,EAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC,CAAC,CAAC;YAE7F,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IAEL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE;QACjB,EAAE,CAAC,6CAA6C,EAAE;YAChD,IAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;YAC/D,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE;YACnD,IAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC1D,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE;YACnD,IAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;YAChE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6DAA6D,EAAE;YAChE,IAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4EAA4E,EAAE;YAC/E,IAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;YACxD,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2EAA2E,EAAE;YAC9E,IAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;YACvD,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {COLOR, SIZE} from '../../../src/channel';\nimport * as properties from '../../../src/compile/legend/properties';\n\ndescribe('compile/legend', function() {\n describe('values()', () => {\n it('should return correct timestamp values for DateTimes', () => {\n const values = properties.values({values: [{year: 1970}, {year: 1980}]}, {field: 'a', type: 'temporal'});\n\n assert.deepEqual(values, [\n {\"signal\": \"datetime(1970, 0, 1, 0, 0, 0, 0)\"},\n {\"signal\": \"datetime(1980, 0, 1, 0, 0, 0, 0)\"},\n ]);\n });\n\n it('should simply return values for non-DateTime', () => {\n const values = properties.values({values: [1, 2, 3, 4]}, {field: 'a', type: 'quantitative'});\n\n assert.deepEqual(values, [1,2,3,4]);\n });\n\n });\n\n describe('type()', () => {\n it('should return gradient type for color scale', () => {\n const t = properties.type('quantitative', COLOR, 'sequential');\n assert.equal(t, 'gradient');\n });\n\n it('should not return gradient type for size scale', () => {\n const t = properties.type('quantitative', SIZE, 'linear');\n assert.equal(t, undefined);\n });\n\n it('should return no type for color scale with bin', () => {\n const t = properties.type('quantitative', COLOR, 'bin-ordinal');\n assert.equal(t, undefined);\n });\n\n it('should return gradient type for color scale with time scale', () => {\n const t = properties.type('temporal', COLOR, 'time');\n assert.equal(t, 'gradient');\n });\n\n it('should return no type for color scale with ordinal scale and temporal type', () => {\n const t = properties.type('temporal', COLOR, 'ordinal');\n assert.equal(t, undefined);\n });\n\n it('should return no type for color scale with ordinal scale and ordinal type', () => {\n const t = properties.type('ordinal', COLOR, 'ordinal');\n assert.equal(t, undefined);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/area.test.d.ts b/build/test/compile/mark/area.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/area.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/area.test.js b/build/test/compile/mark/area.test.js new file mode 100644 index 0000000000..e0b8e1d38f --- /dev/null +++ b/build/test/compile/mark/area.test.js @@ -0,0 +1,211 @@ +/* tslint:disable quotemark */ +import * as tslib_1 from "tslib"; +import { assert } from 'chai'; +import { COLOR, X, Y } from '../../../src/channel'; +import { area } from '../../../src/compile/mark/area'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('Mark: Area', function () { + function verticalArea(moreEncoding) { + if (moreEncoding === void 0) { moreEncoding = {}; } + return { + "mark": "area", + "encoding": tslib_1.__assign({ "x": { "timeUnit": "year", "field": "Year", "type": "temporal" }, "y": { "aggregate": "count", "type": "quantitative" } }, moreEncoding), + "data": { "url": "data/cars.json" } + }; + } + describe('vertical area, with log', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "area", + "encoding": { + "x": { "bin": true, "type": "quantitative", "field": "IMDB_Rating" }, + "y": { "scale": { "type": 'log' }, "type": "quantitative", "field": 'US_Gross', "aggregate": "mean" } + }, + "data": { "url": 'data/movies.json' } + }); + var props = area.encodeEntry(model); + it('should end on axis', function () { + assert.deepEqual(props.y2, { field: { group: 'height' } }); + }); + it('should has no height', function () { + assert.isUndefined(props.height); + }); + }); + describe('stacked vertical area, with binned dimension', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "area", + "encoding": { + "x": { "bin": true, "type": "quantitative", "field": "IMDB_Rating" }, + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" }, + "color": { "type": "nominal", "field": 'c' } + }, + "data": { "url": 'data/movies.json' } + }); + var props = area.encodeEntry(model); + it('should use bin_mid for x', function () { + assert.deepEqual(props.x, { field: 'bin_maxbins_10_IMDB_Rating_mid', scale: 'x' }); + }); + }); + describe('vertical area, with zero=false', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "area", + "encoding": { + "x": { "bin": true, "type": "quantitative", "field": "IMDB_Rating" }, + "y": { "scale": { "zero": false }, "type": "quantitative", "field": 'US_Gross', "aggregate": "mean" } + }, + "data": { "url": 'data/movies.json' } + }); + var props = area.encodeEntry(model); + it('should end on axis', function () { + assert.deepEqual(props.y2, { field: { group: 'height' } }); + }); + it('should has no height', function () { + assert.isUndefined(props.height); + }); + }); + describe('vertical area', function () { + var model = parseUnitModelWithScaleAndLayoutSize(verticalArea()); + var props = area.encodeEntry(model); + it('should have scale for x', function () { + assert.deepEqual(props.x, { scale: X, field: 'year_Year' }); + }); + it('should have scale for y', function () { + assert.deepEqual(props.y, { scale: Y, field: 'count_*' }); + }); + it('should have the correct value for y2', function () { + assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + }); + }); + describe('vertical area with binned dimension', function () { + var model = parseUnitModelWithScaleAndLayoutSize(verticalArea()); + var props = area.encodeEntry(model); + it('should have scale for x', function () { + assert.deepEqual(props.x, { scale: X, field: 'year_Year' }); + }); + it('should have scale for y', function () { + assert.deepEqual(props.y, { scale: Y, field: 'count_*' }); + }); + it('should have the correct value for y2', function () { + assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + }); + }); + describe('vertical stacked area with color', function () { + var model = parseUnitModelWithScaleAndLayoutSize(verticalArea({ + "color": { "field": "Origin", "type": "quantitative" } + })); + var props = area.encodeEntry(model); + it('should have the correct value for y and y2', function () { + assert.deepEqual(props.y, { scale: 'y', field: 'count_*_end' }); + assert.deepEqual(props.y2, { scale: 'y', field: 'count_*_start' }); + }); + it('should have correct orient', function () { + assert.deepEqual(props.orient, { value: 'vertical' }); + }); + it('should have scale for color', function () { + assert.deepEqual(props.fill, { scale: COLOR, field: 'Origin' }); + }); + }); + function horizontalArea(moreEncoding) { + if (moreEncoding === void 0) { moreEncoding = {}; } + return { + "mark": "area", + "encoding": tslib_1.__assign({ "y": { "timeUnit": "year", "field": "Year", "type": "temporal" }, "x": { "aggregate": "count", "type": "quantitative" } }, moreEncoding), + "data": { "url": "data/cars.json" } + }; + } + describe('horizontal area', function () { + var model = parseUnitModelWithScaleAndLayoutSize(horizontalArea()); + var props = area.encodeEntry(model); + it('should have scale for y', function () { + assert.deepEqual(props.y, { scale: Y, field: 'year_Year' }); + }); + it('should have scale for x', function () { + assert.deepEqual(props.x, { scale: X, field: 'count_*' }); + }); + it('should have the correct value for x2', function () { + assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + }); + }); + describe('horizontal area, with log', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "area", + "encoding": { + "y": { "bin": true, "type": "quantitative", "field": "IMDB_Rating" }, + "x": { "scale": { "type": 'log' }, "type": "quantitative", "field": 'US_Gross', "aggregate": "mean" } + }, + "data": { "url": 'data/movies.json' } + }); + var props = area.encodeEntry(model); + it('should end on axis', function () { + assert.deepEqual(props.x2, { value: 0 }); + }); + it('should have no width', function () { + assert.isUndefined(props.width); + }); + }); + describe('horizontal area, with zero=false', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "area", + "encoding": { + "y": { "bin": true, "type": "quantitative", "field": "IMDB_Rating" }, + "x": { "scale": { "zero": false }, "type": "quantitative", "field": 'US_Gross', "aggregate": "mean" } + }, + "data": { "url": 'data/movies.json' } + }); + var props = area.encodeEntry(model); + it('should end on axis', function () { + assert.deepEqual(props.x2, { value: 0 }); + }); + it('should have no width', function () { + assert.isUndefined(props.width); + }); + }); + describe('horizontal stacked area with color', function () { + var model = parseUnitModelWithScaleAndLayoutSize(horizontalArea({ + "color": { "field": "Origin", "type": "nominal" } + })); + var props = area.encodeEntry(model); + it('should have the correct value for x and x2', function () { + assert.deepEqual(props.x, { scale: 'x', field: 'count_*_end' }); + assert.deepEqual(props.x2, { scale: 'x', field: 'count_*_start' }); + }); + it('should have correct orient', function () { + assert.deepEqual(props.orient, { value: 'horizontal' }); + }); + it('should have scale for color', function () { + assert.deepEqual(props.fill, { scale: COLOR, field: 'Origin' }); + }); + }); + describe('ranged area', function () { + it('vertical area should work with aggregate', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/cars.json" }, + "mark": "area", + "encoding": { + "x": { "timeUnit": "year", "field": "Year", "type": "temporal" }, + "y": { "aggregate": "min", "field": "Weight_in_lbs", "type": "quantitative" }, + "y2": { "aggregate": "max", "field": "Weight_in_lbs", "type": "quantitative" } + } + }); + var props = area.encodeEntry(model); + assert.deepEqual(props.x, { scale: 'x', field: 'year_Year' }); + assert.deepEqual(props.y, { scale: 'y', field: 'min_Weight_in_lbs' }); + assert.deepEqual(props.y2, { scale: 'y', field: 'max_Weight_in_lbs' }); + }); + it('horizontal area should work with aggregate', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/cars.json" }, + "mark": "area", + "encoding": { + "y": { "timeUnit": "year", "field": "Year", "type": "temporal" }, + "x": { "aggregate": "min", "field": "Weight_in_lbs", "type": "quantitative" }, + "x2": { "aggregate": "max", "field": "Weight_in_lbs", "type": "quantitative" } + } + }); + var props = area.encodeEntry(model); + assert.deepEqual(props.y, { scale: 'y', field: 'year_Year' }); + assert.deepEqual(props.x, { scale: 'x', field: 'min_Weight_in_lbs' }); + assert.deepEqual(props.x2, { scale: 'x', field: 'max_Weight_in_lbs' }); + }); + }); +}); +//# sourceMappingURL=area.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/area.test.js.map b/build/test/compile/mark/area.test.js.map new file mode 100644 index 0000000000..b86f44e548 --- /dev/null +++ b/build/test/compile/mark/area.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"area.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/area.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport {COLOR, X, Y} from '../../../src/channel';\nimport {area} from '../../../src/compile/mark/area';\nimport {Encoding} from '../../../src/encoding';\nimport {NormalizedUnitSpec} from '../../../src/spec';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('Mark: Area', function() {\n function verticalArea(moreEncoding: Encoding = {}): NormalizedUnitSpec {\n return {\n \"mark\": \"area\",\n \"encoding\":\n {\n \"x\": {\"timeUnit\": \"year\", \"field\": \"Year\", \"type\": \"temporal\"},\n \"y\": {\"aggregate\": \"count\", \"type\": \"quantitative\"},\n ...moreEncoding,\n },\n \"data\": {\"url\": \"data/cars.json\"}\n };\n }\n\n describe('vertical area, with log', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"area\",\n \"encoding\": {\n \"x\": {\"bin\": true, \"type\": \"quantitative\", \"field\": \"IMDB_Rating\"},\n \"y\": {\"scale\": {\"type\": 'log'}, \"type\": \"quantitative\", \"field\": 'US_Gross', \"aggregate\": \"mean\"}\n },\n \"data\": {\"url\": 'data/movies.json'}\n });\n const props = area.encodeEntry(model);\n\n it('should end on axis', function() {\n assert.deepEqual(props.y2, {field: {group: 'height'}});\n });\n\n it('should has no height', function() {\n assert.isUndefined(props.height);\n });\n });\n\n describe('stacked vertical area, with binned dimension', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"area\",\n \"encoding\": {\n \"x\": {\"bin\": true, \"type\": \"quantitative\", \"field\": \"IMDB_Rating\"},\n \"y\": {\"type\": \"quantitative\", \"field\": 'US_Gross', \"aggregate\": \"sum\"},\n \"color\": {\"type\": \"nominal\", \"field\": 'c'}\n },\n \"data\": {\"url\": 'data/movies.json'}\n });\n const props = area.encodeEntry(model);\n\n it('should use bin_mid for x', function() {\n assert.deepEqual(props.x, {field: 'bin_maxbins_10_IMDB_Rating_mid', scale: 'x'});\n });\n });\n\n describe('vertical area, with zero=false', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"area\",\n \"encoding\": {\n \"x\": {\"bin\": true, \"type\": \"quantitative\", \"field\": \"IMDB_Rating\"},\n \"y\": {\"scale\": {\"zero\": false}, \"type\": \"quantitative\", \"field\": 'US_Gross', \"aggregate\": \"mean\"}\n },\n \"data\": {\"url\": 'data/movies.json'}\n });\n const props = area.encodeEntry(model);\n\n it('should end on axis', function() {\n assert.deepEqual(props.y2, {field: {group: 'height'}});\n });\n\n it('should has no height', function() {\n assert.isUndefined(props.height);\n });\n });\n\n describe('vertical area', function() {\n const model = parseUnitModelWithScaleAndLayoutSize(verticalArea());\n const props = area.encodeEntry(model);\n\n it('should have scale for x', function() {\n assert.deepEqual(props.x, {scale: X, field: 'year_Year'});\n });\n\n it('should have scale for y', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'count_*'});\n });\n\n it('should have the correct value for y2', () => {\n assert.deepEqual(props.y2, {scale: 'y', value: 0});\n });\n });\n\n describe('vertical area with binned dimension', function() {\n const model = parseUnitModelWithScaleAndLayoutSize(verticalArea());\n const props = area.encodeEntry(model);\n\n it('should have scale for x', function() {\n assert.deepEqual(props.x, {scale: X, field: 'year_Year'});\n });\n\n it('should have scale for y', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'count_*'});\n });\n\n it('should have the correct value for y2', () => {\n assert.deepEqual(props.y2, {scale: 'y', value: 0});\n });\n });\n\n describe('vertical stacked area with color', function () {\n const model = parseUnitModelWithScaleAndLayoutSize(verticalArea({\n \"color\": {\"field\": \"Origin\", \"type\": \"quantitative\"}\n }));\n\n const props = area.encodeEntry(model);\n\n it('should have the correct value for y and y2', () => {\n assert.deepEqual(props.y, {scale: 'y', field: 'count_*_end'});\n assert.deepEqual(props.y2, {scale: 'y', field: 'count_*_start'});\n });\n\n it('should have correct orient', () => {\n assert.deepEqual(props.orient, {value: 'vertical'});\n });\n\n it('should have scale for color', function () {\n assert.deepEqual(props.fill, {scale: COLOR, field: 'Origin'});\n });\n });\n\n function horizontalArea(moreEncoding: Encoding = {}): NormalizedUnitSpec {\n return {\n \"mark\": \"area\",\n \"encoding\": {\n \"y\": {\"timeUnit\": \"year\", \"field\": \"Year\", \"type\": \"temporal\"},\n \"x\": {\"aggregate\": \"count\", \"type\": \"quantitative\"},\n ...moreEncoding,\n },\n \"data\": {\"url\": \"data/cars.json\"}\n };\n }\n\n describe('horizontal area', function() {\n const model = parseUnitModelWithScaleAndLayoutSize(horizontalArea());\n const props = area.encodeEntry(model);\n\n it('should have scale for y', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'year_Year'});\n });\n\n it('should have scale for x', function() {\n assert.deepEqual(props.x, {scale: X, field: 'count_*'});\n });\n\n it('should have the correct value for x2', () => {\n assert.deepEqual(props.x2, {scale: 'x' , value: 0});\n });\n });\n\n describe('horizontal area, with log', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"area\",\n \"encoding\": {\n \"y\": {\"bin\": true, \"type\": \"quantitative\", \"field\": \"IMDB_Rating\"},\n \"x\": {\"scale\": {\"type\": 'log'}, \"type\": \"quantitative\", \"field\": 'US_Gross', \"aggregate\": \"mean\"}\n },\n \"data\": {\"url\": 'data/movies.json'}\n });\n\n const props = area.encodeEntry(model);\n\n it('should end on axis', function() {\n assert.deepEqual(props.x2, {value: 0});\n });\n\n it('should have no width', function() {\n assert.isUndefined(props.width);\n });\n });\n\n describe('horizontal area, with zero=false', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"area\",\n \"encoding\": {\n \"y\": {\"bin\": true, \"type\": \"quantitative\", \"field\": \"IMDB_Rating\"},\n \"x\": {\"scale\": {\"zero\": false}, \"type\": \"quantitative\", \"field\": 'US_Gross', \"aggregate\": \"mean\"}\n },\n \"data\": {\"url\": 'data/movies.json'}\n });\n\n const props = area.encodeEntry(model);\n\n it('should end on axis', function() {\n assert.deepEqual(props.x2, {value: 0});\n });\n\n it('should have no width', function() {\n assert.isUndefined(props.width);\n });\n });\n\n describe('horizontal stacked area with color', function () {\n const model = parseUnitModelWithScaleAndLayoutSize(horizontalArea({\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }));\n\n const props = area.encodeEntry(model);\n\n it('should have the correct value for x and x2', () => {\n assert.deepEqual(props.x, {scale: 'x', field: 'count_*_end'});\n assert.deepEqual(props.x2, {scale: 'x', field: 'count_*_start'});\n });\n\n it('should have correct orient', () => {\n assert.deepEqual(props.orient, {value: 'horizontal'});\n });\n\n it('should have scale for color', function () {\n assert.deepEqual(props.fill, {scale: COLOR, field: 'Origin'});\n });\n });\n\n describe('ranged area', function () {\n it ('vertical area should work with aggregate', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/cars.json\"},\n \"mark\": \"area\",\n \"encoding\": {\n \"x\": {\"timeUnit\": \"year\", \"field\": \"Year\", \"type\": \"temporal\"},\n \"y\": {\"aggregate\": \"min\", \"field\": \"Weight_in_lbs\", \"type\": \"quantitative\"},\n \"y2\": {\"aggregate\": \"max\", \"field\": \"Weight_in_lbs\", \"type\": \"quantitative\"}\n }\n });\n const props = area.encodeEntry(model);\n assert.deepEqual(props.x, {scale: 'x', field: 'year_Year'});\n assert.deepEqual(props.y, {scale: 'y', field: 'min_Weight_in_lbs'});\n assert.deepEqual(props.y2, {scale: 'y', field: 'max_Weight_in_lbs'});\n });\n\n it ('horizontal area should work with aggregate', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/cars.json\"},\n \"mark\": \"area\",\n \"encoding\": {\n \"y\": {\"timeUnit\": \"year\", \"field\": \"Year\", \"type\": \"temporal\"},\n \"x\": {\"aggregate\": \"min\", \"field\": \"Weight_in_lbs\", \"type\": \"quantitative\"},\n \"x2\": {\"aggregate\": \"max\", \"field\": \"Weight_in_lbs\", \"type\": \"quantitative\"}\n }\n });\n const props = area.encodeEntry(model);\n assert.deepEqual(props.y, {scale: 'y', field: 'year_Year'});\n assert.deepEqual(props.x, {scale: 'x', field: 'min_Weight_in_lbs'});\n assert.deepEqual(props.x2, {scale: 'x', field: 'max_Weight_in_lbs'});\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/bar.test.d.ts b/build/test/compile/mark/bar.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/bar.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/bar.test.js b/build/test/compile/mark/bar.test.js new file mode 100644 index 0000000000..055ac27d20 --- /dev/null +++ b/build/test/compile/mark/bar.test.js @@ -0,0 +1,652 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { bar } from '../../../src/compile/mark/bar'; +import * as log from '../../../src/log'; +import { defaultBarConfig } from '../../../src/mark'; +import { defaultScaleConfig } from '../../../src/scale'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('Mark: Bar', function () { + describe('simple vertical', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar, with y from zero to field value and with band value for x/width ', function () { + assert.deepEqual(props.x, { scale: 'x', field: 'Origin' }); + assert.deepEqual(props.width, { scale: 'x', band: true }); + assert.deepEqual(props.y, { scale: 'y', field: 'mean_Acceleration' }); + assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + assert.isUndefined(props.height); + }); + }); + it('should draw vertical bar, with y from zero to field value and bar with quantitative x, x2, and y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "bin_start", "type": "quantitative" }, + "x2": { "field": "bin_end", "type": "quantitative" }, + "y": { "type": "quantitative", "field": 'Acceleration' } + } + }); + var props = bar.encodeEntry(model); + assert.deepEqual(props.x, { scale: 'x', field: 'bin_start' }); + assert.deepEqual(props.x2, { scale: 'x', field: 'bin_end' }); + assert.deepEqual(props.y, { scale: 'y', field: 'Acceleration' }); + assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + assert.isUndefined(props.height); + }); + it('should draw vertical bar, with y from zero to field value and with band value for x/width when domain that includes zero is specified', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "type": "quantitative", "field": 'Acceleration', "aggregate": "mean", "scale": { "domain": [-1, 1] } } + } + }); + var props = bar.encodeEntry(model); + assert.deepEqual(props.x, { scale: 'x', field: 'Origin' }); + assert.deepEqual(props.width, { scale: 'x', band: true }); + assert.deepEqual(props.y, { scale: 'y', field: 'mean_Acceleration' }); + assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + assert.isUndefined(props.height); + }); + it('should draw vertical bar, with y from "group: height" to field value when domain that excludes zero is specified', log.wrap(function (logger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "type": "quantitative", "field": 'Acceleration', "aggregate": "mean", "scale": { "domain": [1, 2] } } + } + }); + var props = bar.encodeEntry(model); + assert.deepEqual(props.y, { scale: 'y', field: 'mean_Acceleration' }); + assert.deepEqual(props.y2, { field: { group: 'height' } }); + assert.isUndefined(props.height); + assert.equal(logger.warns[0], log.message.nonZeroScaleUsedWithLengthMark('bar', 'y', { zeroFalse: false })); + })); + it('should draw vertical bar, with y from "group: height" to field value when zero=false for y-scale', log.wrap(function (logger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "type": "quantitative", "field": 'Acceleration', "aggregate": "mean", "scale": { "zero": false } } + } + }); + var props = bar.encodeEntry(model); + assert.deepEqual(props.y, { scale: 'y', field: 'mean_Acceleration' }); + assert.deepEqual(props.y2, { field: { group: 'height' } }); + assert.isUndefined(props.height); + assert.equal(logger.warns[0], log.message.nonZeroScaleUsedWithLengthMark('bar', 'y', { zeroFalse: true })); + })); + it('should draw vertical bar, with y from "group: height" to field value when y-scale type is log', log.wrap(function (logger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "type": "quantitative", "field": 'Acceleration', "aggregate": "mean", "scale": { "type": "log" } } + } + }); + var props = bar.encodeEntry(model); + assert.deepEqual(props.y, { scale: 'y', field: 'mean_Acceleration' }); + assert.deepEqual(props.y2, { field: { group: 'height' } }); + assert.isUndefined(props.height); + assert.equal(logger.warns[0], log.message.nonZeroScaleUsedWithLengthMark('bar', 'y', { scaleType: 'log' })); + })); + describe('simple horizontal', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar from zero to field value and with band value for x/width', function () { + assert.deepEqual(props.y, { scale: 'y', field: 'Origin' }); + assert.deepEqual(props.height, { scale: 'y', band: true }); + assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + assert.isUndefined(props.width); + }); + }); + it('should draw horizontal bar, with y from zero to field value and bar with quantitative x, x2, and y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "bin_start", "type": "quantitative" }, + "y2": { "field": "bin_end", "type": "quantitative" }, + "x": { "type": "quantitative", "field": 'Acceleration' } + } + }); + var props = bar.encodeEntry(model); + assert.deepEqual(props.y, { scale: 'y', field: 'bin_start' }); + assert.deepEqual(props.y2, { scale: 'y', field: 'bin_end' }); + assert.deepEqual(props.x, { scale: 'x', field: 'Acceleration' }); + assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + assert.isUndefined(props.height); + }); + describe('simple horizontal with point scale', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal", "scale": { "type": "point" } }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar from zero to field value and y with center position and height = rangeStep - 1', function () { + assert.deepEqual(props.yc, { scale: 'y', field: 'Origin' }); + assert.deepEqual(props.height, { value: defaultScaleConfig.rangeStep - 1 }); + assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + assert.isUndefined(props.width); + }); + }); + describe('simple horizontal with size value', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" }, + "size": { "value": 5 } + } + }); + var props = bar.encodeEntry(model); + it('should set height to 5 and center y', function () { + assert.deepEqual(props.height, { value: 5 }); + assert.deepEqual(props.yc, { scale: 'y', field: 'Origin', band: 0.5 }); + }); + }); + describe('simple horizontal with size value in mark def', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": { "type": "bar", "size": 5 }, + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should set height to 5 and center y', function () { + assert.deepEqual(props.height, { value: 5 }); + assert.deepEqual(props.yc, { scale: 'y', field: 'Origin', band: 0.5 }); + }); + }); + describe('simple horizontal with size field', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" }, + "size": { "aggregate": "mean", "field": "Horsepower", "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar from zero to field value and with band value for x/width', function () { + assert.deepEqual(props.yc, { scale: 'y', field: 'Origin', band: 0.5 }); + assert.deepEqual(props.height, { scale: 'size', field: 'mean_Horsepower' }); + assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + assert.isUndefined(props.width); + }); + }); + describe('horizontal binned', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar with y and y2', function () { + assert.deepEqual(props.y2, { scale: 'y', field: 'bin_maxbins_10_Horsepower' }); + assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_end', offset: defaultBarConfig.binSpacing }); + assert.isUndefined(props.height); + }); + }); + describe('horizontal binned, sort descending', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "bin": true, "field": 'Horsepower', "type": "quantitative", "sort": "descending" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar with y and y2', function () { + assert.deepEqual(props.y2, { scale: 'y', field: 'bin_maxbins_10_Horsepower', offset: defaultBarConfig.binSpacing }); + assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_end' }); + assert.isUndefined(props.height); + }); + }); + describe('horizontal binned, reverse', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "bin": true, "field": 'Horsepower', "type": "quantitative", "scale": { "reverse": true } }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar with y and y2', function () { + assert.deepEqual(props.y2, { scale: 'y', field: 'bin_maxbins_10_Horsepower', offset: defaultBarConfig.binSpacing }); + assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_end' }); + assert.isUndefined(props.height); + }); + }); + describe('vertical binned', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "y": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar with x and x2', function () { + assert.deepEqual(props.x2, { scale: 'x', field: 'bin_maxbins_10_Horsepower', offset: defaultBarConfig.binSpacing }); + assert.deepEqual(props.x, { scale: 'x', field: 'bin_maxbins_10_Horsepower_end' }); + assert.isUndefined(props.width); + }); + }); + describe('vertical binned, sort descending', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "bin": true, "field": 'Horsepower', "type": "quantitative", "sort": "descending" }, + "y": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar with x and x2', function () { + assert.deepEqual(props.x2, { scale: 'x', field: 'bin_maxbins_10_Horsepower' }); + assert.deepEqual(props.x, { scale: 'x', field: 'bin_maxbins_10_Horsepower_end', offset: defaultBarConfig.binSpacing }); + assert.isUndefined(props.width); + }); + }); + describe('horizontal binned with ordinal', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "bin": true, "field": 'Horsepower', "type": "ordinal" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar with y', function () { + assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_range' }); + assert.deepEqual(props.height, { scale: 'y', band: true }); + }); + }); + describe('vertical binned with ordinal', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "bin": true, "field": 'Horsepower', "type": "ordinal" }, + "y": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar with y', function () { + assert.deepEqual(props.x, { scale: 'x', field: 'bin_maxbins_10_Horsepower_range' }); + assert.deepEqual(props.width, { scale: 'x', band: true }); + }); + }); + describe('horizontal binned with no spacing', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + }, + "config": { "bar": { "binSpacing": 0 } } + }); + var props = bar.encodeEntry(model); + it('should draw bar with y and y2', function () { + assert.deepEqual(props.y2, { scale: 'y', field: 'bin_maxbins_10_Horsepower' }); + assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_end' }); + assert.isUndefined(props.height); + }); + }); + describe('vertical binned with no spacing', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "y": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + }, + "config": { "bar": { "binSpacing": 0 } } + }); + var props = bar.encodeEntry(model); + it('should draw bar with x and x2', function () { + assert.deepEqual(props.x2, { scale: 'x', field: 'bin_maxbins_10_Horsepower' }); + assert.deepEqual(props.x, { scale: 'x', field: 'bin_maxbins_10_Horsepower_end' }); + assert.isUndefined(props.width); + }); + }); + describe('simple horizontal binned with size', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" }, + "size": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar with y centered on bin_mid and height = size field', function () { + assert.deepEqual(props.yc, { signal: '(scale("y", datum["bin_maxbins_10_Horsepower"]) + scale("y", datum["bin_maxbins_10_Horsepower_end"]))/2' }); + assert.deepEqual(props.height, { scale: 'size', field: 'mean_Acceleration' }); + }); + }); + describe('vertical binned with size', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "y": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" }, + "size": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should draw bar with x centered on bin_mid and width = size field', function () { + assert.deepEqual(props.xc, { signal: '(scale(\"x\", datum[\"bin_maxbins_10_Horsepower\"]) + scale(\"x\", datum[\"bin_maxbins_10_Horsepower_end\"]))/2' }); + assert.deepEqual(props.width, { scale: 'size', field: 'mean_Acceleration' }); + }); + }); + describe('vertical, with log', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "scale": { "type": 'log' }, "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = bar.encodeEntry(model); + it('should end on axis and has no height', function () { + assert.deepEqual(props.y2, { field: { group: 'height' } }); + assert.isUndefined(props.height); + }); + }); + describe('horizontal, with log', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "scale": { "type": 'log' }, "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = bar.encodeEntry(model); + it('should end on axis and has no width', function () { + assert.deepEqual(props.x2, { value: 0 }); + assert.isUndefined(props.width); + }); + }); + describe('vertical, with fit mode', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "width": 120, + "height": 120, + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "aggregate": "mean", "field": "Horsepower", "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should use x and with band true', function () { + assert.deepEqual(props.x, { + scale: 'x', + field: 'Origin', + }); + assert.deepEqual(props.width, { + scale: 'x', + band: true, + }); + }); + }); + describe('horizontal, with fit mode', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "width": 120, + "height": 120, + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": "Horsepower", "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + it('should use y with band true', function () { + assert.deepEqual(props.y, { + scale: 'y', + field: 'Origin', + }); + assert.deepEqual(props.height, { + scale: 'y', + band: true, + }); + }); + }); + describe('vertical with zero=false', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "scale": { "zero": false }, "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = bar.encodeEntry(model); + it('should end on axis nad have no height', function () { + assert.deepEqual(props.y2, { field: { group: 'height' } }); + assert.isUndefined(props.height); + }); + }); + describe('horizontal with zero=false', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "scale": { "zero": false }, "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = bar.encodeEntry(model); + it('should end on axis and have no width', function () { + assert.deepEqual(props.x2, { value: 0 }); + assert.isUndefined(props.width); + }); + }); + describe('1D vertical', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" } }, + "data": { "url": 'data/movies.json' } + }); + var props = bar.encodeEntry(model); + it('should have y end on axis, have no-height and have x-offset', function () { + assert.deepEqual(props.y, { scale: 'y', field: 'sum_US_Gross' }); + assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + assert.isUndefined(props.height); + assert.deepEqual(props.xc, { + mult: 0.5, + signal: 'width' + }); + }); + }); + describe('1D vertical with size value', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" }, + "size": { "value": 5 } + }, + "data": { "url": 'data/movies.json' } + }); + var props = bar.encodeEntry(model); + it('should have width = 5', function () { + assert.deepEqual(props.width, { value: 5 }); + }); + }); + describe('1D vertical with barSize config', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/movies.json' }, + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" } + }, + "config": { + "bar": { "discreteBandSize": 5 } + } + }); + var props = bar.encodeEntry(model); + it('should have width = 5', function () { + assert.deepEqual(props.width, { value: 5 }); + }); + }); + describe('1D horizontal', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { "x": { "type": "quantitative", "field": 'US_Gross', "aggregate": 'sum' } }, + "data": { "url": 'data/movies.json' } + }); + var props = bar.encodeEntry(model); + it('should end on axis, have no width, and have y-offset', function () { + assert.deepEqual(props.x, { scale: 'x', field: 'sum_US_Gross' }); + assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + assert.isUndefined(props.width); + assert.deepEqual(props.yc, { + mult: 0.5, + signal: 'height' + }); + }); + }); + describe('QxQ horizontal', function () { + // This is generally a terrible idea, but we should still test + // if the output show expected results + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": 'Acceleration', "type": "quantitative" }, + "y": { "field": 'Horsepower', "type": "quantitative" } + }, + "config": { + "mark": { "orient": "horizontal" } + } + }); + var props = bar.encodeEntry(model); + it('should produce horizontal bar using x, x2', function () { + assert.deepEqual(props.x, { scale: 'x', field: 'Acceleration' }); + assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + assert.deepEqual(props.yc, { scale: 'y', field: 'Horsepower' }); + assert.deepEqual(props.height, { value: defaultBarConfig.continuousBandSize }); + }); + }); + describe('QxQ vertical', function () { + // This is generally a terrible idea, but we should still test + // if the output show expected results + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": 'Acceleration', "type": "quantitative" }, + "y": { "field": 'Horsepower', "type": "quantitative" } + }, + "config": { + "mark": { "orient": "vertical" } + } + }); + var props = bar.encodeEntry(model); + it('should produce horizontal bar using x, x2', function () { + assert.deepEqual(props.xc, { scale: 'x', field: 'Acceleration' }); + assert.deepEqual(props.width, { value: defaultBarConfig.continuousBandSize }); + assert.deepEqual(props.y, { scale: 'y', field: 'Horsepower' }); + assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + }); + }); + describe('OxN', function () { + // This is generally a terrible idea, but we should still test + // if the output show expected results + it('should produce vertical bar using x, width', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": 'Origin', "type": "nominal" }, + "y": { "field": 'Cylinders', "type": "ordinal" } + } + }); + var props = bar.encodeEntry(model); + assert.deepEqual(props.x, { scale: 'x', field: 'Origin' }); + assert.deepEqual(props.width, { scale: 'x', band: true }); + assert.deepEqual(props.y, { scale: 'y', field: 'Cylinders' }); + assert.deepEqual(props.height, { scale: 'y', band: true }); + }); + }); + describe('ranged bar', function () { + // TODO: gantt chart with temporal + // TODO: gantt chart with ordinal + it('vertical bars should work with aggregate', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/population.json" }, + "mark": "bar", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { "field": "people", "aggregate": "q1", "type": "quantitative" }, + "y2": { "field": "people", "aggregate": "q3", "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + assert.deepEqual(props.x, { scale: 'x', field: 'age' }); + assert.deepEqual(props.y, { scale: 'y', field: 'q1_people' }); + assert.deepEqual(props.y2, { scale: 'y', field: 'q3_people' }); + }); + it('horizontal bars should work with aggregate', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/population.json" }, + "mark": "bar", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { "field": "people", "aggregate": "q1", "type": "quantitative" }, + "x2": { "field": "people", "aggregate": "q3", "type": "quantitative" } + } + }); + var props = bar.encodeEntry(model); + assert.deepEqual(props.y, { scale: 'y', field: 'age' }); + assert.deepEqual(props.x, { scale: 'x', field: 'q1_people' }); + assert.deepEqual(props.x2, { scale: 'x', field: 'q3_people' }); + }); + }); +}); +//# sourceMappingURL=bar.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/bar.test.js.map b/build/test/compile/mark/bar.test.js.map new file mode 100644 index 0000000000..2668e87ce0 --- /dev/null +++ b/build/test/compile/mark/bar.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bar.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/bar.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport {bar} from '../../../src/compile/mark/bar';\nimport * as log from '../../../src/log';\nimport {defaultBarConfig} from '../../../src/mark';\nimport {defaultScaleConfig} from '../../../src/scale';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('Mark: Bar', function() {\n describe('simple vertical', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"y\": {\"type\": \"quantitative\", \"field\": 'Acceleration', \"aggregate\": \"mean\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar, with y from zero to field value and with band value for x/width ', function() {\n assert.deepEqual(props.x, {scale: 'x', field: 'Origin'});\n assert.deepEqual(props.width, {scale: 'x', band: true});\n assert.deepEqual(props.y, {scale: 'y', field: 'mean_Acceleration'});\n assert.deepEqual(props.y2, {scale: 'y', value: 0});\n assert.isUndefined(props.height);\n });\n });\n\n it('should draw vertical bar, with y from zero to field value and bar with quantitative x, x2, and y', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"bin_start\", \"type\": \"quantitative\"},\n \"x2\": {\"field\": \"bin_end\", \"type\": \"quantitative\"},\n \"y\": {\"type\": \"quantitative\", \"field\": 'Acceleration'}\n }\n });\n const props = bar.encodeEntry(model);\n assert.deepEqual(props.x, {scale: 'x', field: 'bin_start'});\n assert.deepEqual(props.x2, {scale: 'x', field: 'bin_end'});\n assert.deepEqual(props.y, {scale: 'y', field: 'Acceleration'});\n assert.deepEqual(props.y2, {scale: 'y', value: 0});\n assert.isUndefined(props.height);\n });\n\n it('should draw vertical bar, with y from zero to field value and with band value for x/width when domain that includes zero is specified', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"y\": {\"type\": \"quantitative\", \"field\": 'Acceleration', \"aggregate\": \"mean\", \"scale\": {\"domain\": [-1, 1]}}\n }\n });\n const props = bar.encodeEntry(model);\n\n assert.deepEqual(props.x, {scale: 'x', field: 'Origin'});\n assert.deepEqual(props.width, {scale: 'x', band: true});\n assert.deepEqual(props.y, {scale: 'y', field: 'mean_Acceleration'});\n assert.deepEqual(props.y2, {scale: 'y', value: 0});\n assert.isUndefined(props.height);\n });\n\n it('should draw vertical bar, with y from \"group: height\" to field value when domain that excludes zero is specified', log.wrap((logger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"y\": {\"type\": \"quantitative\", \"field\": 'Acceleration', \"aggregate\": \"mean\", \"scale\": {\"domain\": [1, 2]}}\n }\n });\n const props = bar.encodeEntry(model);\n\n assert.deepEqual(props.y, {scale: 'y', field: 'mean_Acceleration'});\n assert.deepEqual(props.y2, {field: {group: 'height'}});\n assert.isUndefined(props.height);\n\n assert.equal(logger.warns[0], log.message.nonZeroScaleUsedWithLengthMark('bar', 'y', {zeroFalse: false}));\n }));\n\n it('should draw vertical bar, with y from \"group: height\" to field value when zero=false for y-scale', log.wrap((logger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"y\": {\"type\": \"quantitative\", \"field\": 'Acceleration', \"aggregate\": \"mean\", \"scale\": {\"zero\": false}}\n }\n });\n const props = bar.encodeEntry(model);\n\n assert.deepEqual(props.y, {scale: 'y', field: 'mean_Acceleration'});\n assert.deepEqual(props.y2, {field: {group: 'height'}});\n assert.isUndefined(props.height);\n\n assert.equal(logger.warns[0], log.message.nonZeroScaleUsedWithLengthMark('bar', 'y', {zeroFalse: true}));\n }));\n\n it('should draw vertical bar, with y from \"group: height\" to field value when y-scale type is log', log.wrap((logger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"y\": {\"type\": \"quantitative\", \"field\": 'Acceleration', \"aggregate\": \"mean\", \"scale\": {\"type\": \"log\"}}\n }\n });\n const props = bar.encodeEntry(model);\n\n assert.deepEqual(props.y, {scale: 'y', field: 'mean_Acceleration'});\n assert.deepEqual(props.y2, {field: {group: 'height'}});\n assert.isUndefined(props.height);\n\n assert.equal(logger.warns[0], log.message.nonZeroScaleUsedWithLengthMark('bar', 'y', {scaleType: 'log'}));\n }));\n\n describe('simple horizontal', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar from zero to field value and with band value for x/width', function() {\n assert.deepEqual(props.y, {scale: 'y', field: 'Origin'});\n assert.deepEqual(props.height, {scale: 'y', band: true});\n assert.deepEqual(props.x, {scale: 'x', field: 'mean_Acceleration'});\n assert.deepEqual(props.x2, {scale: 'x', value: 0});\n assert.isUndefined(props.width);\n });\n });\n\n it('should draw horizontal bar, with y from zero to field value and bar with quantitative x, x2, and y', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"field\": \"bin_start\", \"type\": \"quantitative\"},\n \"y2\": {\"field\": \"bin_end\", \"type\": \"quantitative\"},\n \"x\": {\"type\": \"quantitative\", \"field\": 'Acceleration'}\n }\n });\n const props = bar.encodeEntry(model);\n assert.deepEqual(props.y, {scale: 'y', field: 'bin_start'});\n assert.deepEqual(props.y2, {scale: 'y', field: 'bin_end'});\n assert.deepEqual(props.x, {scale: 'x', field: 'Acceleration'});\n assert.deepEqual(props.x2, {scale: 'x', value: 0});\n assert.isUndefined(props.height);\n });\n\n describe('simple horizontal with point scale', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"field\": \"Origin\", \"type\": \"nominal\", \"scale\": {\"type\": \"point\"}},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar from zero to field value and y with center position and height = rangeStep - 1', function() {\n assert.deepEqual(props.yc, {scale: 'y', field: 'Origin'});\n assert.deepEqual(props.height, {value: defaultScaleConfig.rangeStep - 1});\n assert.deepEqual(props.x, {scale: 'x', field: 'mean_Acceleration'});\n assert.deepEqual(props.x2, {scale: 'x', value: 0});\n assert.isUndefined(props.width);\n });\n });\n\n describe('simple horizontal with size value', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"},\n \"size\": {\"value\": 5}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should set height to 5 and center y', function () {\n assert.deepEqual(props.height, {value: 5});\n assert.deepEqual(props.yc, {scale: 'y', field: 'Origin', band: 0.5});\n });\n });\n\n describe('simple horizontal with size value in mark def', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": {\"type\": \"bar\", \"size\": 5},\n \"encoding\": {\n \"y\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should set height to 5 and center y', function () {\n assert.deepEqual(props.height, {value: 5});\n assert.deepEqual(props.yc, {scale: 'y', field: 'Origin', band: 0.5});\n });\n });\n\n describe('simple horizontal with size field', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"},\n \"size\": {\"aggregate\": \"mean\", \"field\": \"Horsepower\", \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n\n it('should draw bar from zero to field value and with band value for x/width', function() {\n assert.deepEqual(props.yc, {scale: 'y', field: 'Origin', band: 0.5});\n assert.deepEqual(props.height, {scale: 'size', field: 'mean_Horsepower'});\n assert.deepEqual(props.x, {scale: 'x', field: 'mean_Acceleration'});\n assert.deepEqual(props.x2, {scale: 'x', value: 0});\n assert.isUndefined(props.width);\n });\n });\n\n describe('horizontal binned', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"quantitative\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar with y and y2', function() {\n assert.deepEqual(props.y2, {scale: 'y', field: 'bin_maxbins_10_Horsepower'});\n assert.deepEqual(props.y, {scale: 'y', field: 'bin_maxbins_10_Horsepower_end', offset: defaultBarConfig.binSpacing});\n assert.isUndefined(props.height);\n });\n });\n\n describe('horizontal binned, sort descending', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"quantitative\", \"sort\": \"descending\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar with y and y2', function() {\n assert.deepEqual(props.y2, {scale: 'y', field: 'bin_maxbins_10_Horsepower', offset: defaultBarConfig.binSpacing});\n assert.deepEqual(props.y, {scale: 'y', field: 'bin_maxbins_10_Horsepower_end'});\n assert.isUndefined(props.height);\n });\n });\n\n describe('horizontal binned, reverse', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"quantitative\", \"scale\": {\"reverse\": true}},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar with y and y2', function() {\n assert.deepEqual(props.y2, {scale: 'y', field: 'bin_maxbins_10_Horsepower', offset: defaultBarConfig.binSpacing});\n assert.deepEqual(props.y, {scale: 'y', field: 'bin_maxbins_10_Horsepower_end'});\n assert.isUndefined(props.height);\n });\n });\n\n describe('vertical binned', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"quantitative\"},\n \"y\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar with x and x2', function() {\n assert.deepEqual(props.x2, {scale: 'x', field: 'bin_maxbins_10_Horsepower', offset: defaultBarConfig.binSpacing});\n assert.deepEqual(props.x, {scale: 'x', field: 'bin_maxbins_10_Horsepower_end'});\n assert.isUndefined(props.width);\n });\n });\n\n describe('vertical binned, sort descending', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"quantitative\", \"sort\": \"descending\"},\n \"y\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar with x and x2', function() {\n assert.deepEqual(props.x2, {scale: 'x', field: 'bin_maxbins_10_Horsepower'});\n assert.deepEqual(props.x, {scale: 'x', field: 'bin_maxbins_10_Horsepower_end', offset: defaultBarConfig.binSpacing});\n assert.isUndefined(props.width);\n });\n });\n\n\n describe('horizontal binned with ordinal', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"ordinal\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar with y', function() {\n assert.deepEqual(props.y, {scale: 'y', field: 'bin_maxbins_10_Horsepower_range'});\n assert.deepEqual(props.height, {scale: 'y', band: true});\n });\n });\n\n describe('vertical binned with ordinal', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"ordinal\"},\n \"y\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar with y', function() {\n assert.deepEqual(props.x, {scale: 'x', field: 'bin_maxbins_10_Horsepower_range'});\n assert.deepEqual(props.width, {scale: 'x', band: true});\n });\n });\n\n\n describe('horizontal binned with no spacing', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"quantitative\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n },\n \"config\": {\"bar\": {\"binSpacing\": 0}}\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar with y and y2', function() {\n assert.deepEqual(props.y2, {scale: 'y', field: 'bin_maxbins_10_Horsepower'});\n assert.deepEqual(props.y, {scale: 'y', field: 'bin_maxbins_10_Horsepower_end'});\n assert.isUndefined(props.height);\n });\n });\n\n describe('vertical binned with no spacing', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"quantitative\"},\n \"y\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n },\n \"config\": {\"bar\": {\"binSpacing\": 0}}\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar with x and x2', function() {\n assert.deepEqual(props.x2, {scale: 'x', field: 'bin_maxbins_10_Horsepower'});\n assert.deepEqual(props.x, {scale: 'x', field: 'bin_maxbins_10_Horsepower_end'});\n assert.isUndefined(props.width);\n });\n });\n\n describe('simple horizontal binned with size', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"quantitative\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"},\n \"size\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar with y centered on bin_mid and height = size field', function() {\n assert.deepEqual(props.yc, {signal: '(scale(\"y\", datum[\"bin_maxbins_10_Horsepower\"]) + scale(\"y\", datum[\"bin_maxbins_10_Horsepower_end\"]))/2'});\n assert.deepEqual(props.height, {scale: 'size', field: 'mean_Acceleration'});\n });\n });\n\n describe('vertical binned with size', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"quantitative\"},\n \"y\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"},\n \"size\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should draw bar with x centered on bin_mid and width = size field', function() {\n assert.deepEqual(props.xc, {signal: '(scale(\\\"x\\\", datum[\\\"bin_maxbins_10_Horsepower\\\"]) + scale(\\\"x\\\", datum[\\\"bin_maxbins_10_Horsepower_end\\\"]))/2'});\n assert.deepEqual(props.width, {scale: 'size', field: 'mean_Acceleration'});\n });\n });\n\n describe('vertical, with log', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"y\": {\"scale\": {\"type\": 'log'}, \"type\": \"quantitative\", \"field\": 'Acceleration', \"aggregate\": \"mean\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should end on axis and has no height', function() {\n assert.deepEqual(props.y2, {field: {group: 'height'}});\n assert.isUndefined(props.height);\n });\n });\n\n describe('horizontal, with log', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"x\": {\"scale\": {\"type\": 'log'}, \"type\": \"quantitative\", \"field\": 'Acceleration', \"aggregate\": \"mean\"}\n }\n });\n\n const props = bar.encodeEntry(model);\n\n it('should end on axis and has no width', function() {\n assert.deepEqual(props.x2, {value: 0});\n assert.isUndefined(props.width);\n });\n });\n\n describe('vertical, with fit mode', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"width\": 120,\n \"height\": 120,\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"y\": {\"aggregate\": \"mean\", \"field\": \"Horsepower\", \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should use x and with band true', () => {\n assert.deepEqual(props.x, {\n scale: 'x',\n field: 'Origin',\n });\n assert.deepEqual(props.width, {\n scale: 'x',\n band: true,\n });\n });\n });\n\n describe('horizontal, with fit mode', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"width\": 120,\n \"height\": 120,\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": \"Horsepower\", \"type\": \"quantitative\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should use y with band true', () => {\n assert.deepEqual(props.y, {\n scale: 'y',\n field: 'Origin',\n });\n assert.deepEqual(props.height, {\n scale: 'y',\n band: true,\n });\n });\n });\n\n describe('vertical with zero=false', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"y\": {\"scale\": {\"zero\": false}, \"type\": \"quantitative\", \"field\": 'Acceleration', \"aggregate\": \"mean\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should end on axis nad have no height', function() {\n assert.deepEqual(props.y2, {field: {group: 'height'}});\n assert.isUndefined(props.height);\n });\n });\n\n describe('horizontal with zero=false', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"x\": {\"scale\": {\"zero\": false}, \"type\": \"quantitative\", \"field\": 'Acceleration', \"aggregate\": \"mean\"}\n }\n });\n\n const props = bar.encodeEntry(model);\n it('should end on axis and have no width', function() {\n assert.deepEqual(props.x2, {value: 0});\n assert.isUndefined(props.width);\n });\n });\n\n describe('1D vertical', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\"y\": {\"type\": \"quantitative\", \"field\": 'US_Gross', \"aggregate\": \"sum\"}},\n \"data\": {\"url\": 'data/movies.json'}\n });\n const props = bar.encodeEntry(model);\n\n it('should have y end on axis, have no-height and have x-offset', function() {\n assert.deepEqual(props.y, {scale: 'y', field: 'sum_US_Gross'});\n assert.deepEqual(props.y2, {scale: 'y', value: 0});\n assert.isUndefined(props.height);\n assert.deepEqual(props.xc, {\n mult: 0.5,\n signal: 'width'\n });\n });\n });\n\n describe('1D vertical with size value', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": 'US_Gross', \"aggregate\": \"sum\"},\n \"size\": {\"value\": 5}\n },\n \"data\": {\"url\": 'data/movies.json'}\n });\n const props = bar.encodeEntry(model);\n\n it('should have width = 5', function() {\n assert.deepEqual(props.width, {value: 5});\n });\n });\n\n describe('1D vertical with barSize config', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/movies.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": 'US_Gross', \"aggregate\": \"sum\"}\n },\n \"config\": {\n \"bar\": {\"discreteBandSize\": 5}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should have width = 5', function() {\n assert.deepEqual(props.width, {value: 5});\n });\n });\n\n describe('1D horizontal', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\"x\": {\"type\": \"quantitative\", \"field\": 'US_Gross', \"aggregate\": 'sum'}},\n \"data\": {\"url\": 'data/movies.json'}\n });\n const props = bar.encodeEntry(model);\n\n it('should end on axis, have no width, and have y-offset', function() {\n assert.deepEqual(props.x, {scale: 'x', field: 'sum_US_Gross'});\n assert.deepEqual(props.x2, {scale: 'x', value: 0});\n assert.isUndefined(props.width);\n assert.deepEqual(props.yc, {\n mult: 0.5,\n signal: 'height'\n });\n });\n });\n\n describe('QxQ horizontal', function() {\n // This is generally a terrible idea, but we should still test\n // if the output show expected results\n\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": 'Acceleration', \"type\": \"quantitative\"},\n \"y\": {\"field\": 'Horsepower', \"type\": \"quantitative\"}\n },\n \"config\": {\n \"mark\": {\"orient\": \"horizontal\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should produce horizontal bar using x, x2', function() {\n assert.deepEqual(props.x, {scale: 'x', field: 'Acceleration'});\n assert.deepEqual(props.x2, {scale: 'x', value: 0});\n assert.deepEqual(props.yc, {scale: 'y', field: 'Horsepower'});\n assert.deepEqual(props.height, {value: defaultBarConfig.continuousBandSize});\n });\n });\n\n describe('QxQ vertical', function() {\n // This is generally a terrible idea, but we should still test\n // if the output show expected results\n\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": 'Acceleration', \"type\": \"quantitative\"},\n \"y\": {\"field\": 'Horsepower', \"type\": \"quantitative\"}\n },\n \"config\": {\n \"mark\": {\"orient\": \"vertical\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n it('should produce horizontal bar using x, x2', function() {\n assert.deepEqual(props.xc, {scale: 'x', field: 'Acceleration'});\n assert.deepEqual(props.width, {value: defaultBarConfig.continuousBandSize});\n assert.deepEqual(props.y, {scale: 'y', field: 'Horsepower'});\n assert.deepEqual(props.y2, {scale: 'y', value: 0});\n });\n });\n\n describe('OxN', function() {\n // This is generally a terrible idea, but we should still test\n // if the output show expected results\n it('should produce vertical bar using x, width', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": 'Origin', \"type\": \"nominal\"},\n \"y\": {\"field\": 'Cylinders', \"type\": \"ordinal\"}\n }\n });\n const props = bar.encodeEntry(model);\n\n assert.deepEqual(props.x, {scale: 'x', field: 'Origin'});\n assert.deepEqual(props.width, {scale: 'x', band: true});\n assert.deepEqual(props.y, {scale: 'y', field: 'Cylinders'});\n assert.deepEqual(props.height, {scale: 'y', band: true});\n });\n });\n\n describe('ranged bar', function() {\n // TODO: gantt chart with temporal\n\n // TODO: gantt chart with ordinal\n\n it('vertical bars should work with aggregate', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/population.json\"},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\": \"age\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"people\", \"aggregate\": \"q1\", \"type\": \"quantitative\"},\n \"y2\": {\"field\": \"people\", \"aggregate\": \"q3\", \"type\": \"quantitative\"}\n }\n });\n\n const props = bar.encodeEntry(model);\n assert.deepEqual(props.x, {scale: 'x', field: 'age'});\n assert.deepEqual(props.y, {scale: 'y', field: 'q1_people'});\n assert.deepEqual(props.y2, {scale: 'y', field: 'q3_people'});\n });\n\n it('horizontal bars should work with aggregate', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/population.json\"},\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"field\": \"age\", \"type\": \"ordinal\"},\n \"x\": {\"field\": \"people\", \"aggregate\": \"q1\", \"type\": \"quantitative\"},\n \"x2\": {\"field\": \"people\", \"aggregate\": \"q3\", \"type\": \"quantitative\"}\n }\n });\n\n const props = bar.encodeEntry(model);\n assert.deepEqual(props.y, {scale: 'y', field: 'age'});\n assert.deepEqual(props.x, {scale: 'x', field: 'q1_people'});\n assert.deepEqual(props.x2, {scale: 'x', field: 'q3_people'});\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/geoshape.test.d.ts b/build/test/compile/mark/geoshape.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/geoshape.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/geoshape.test.js b/build/test/compile/mark/geoshape.test.js new file mode 100644 index 0000000000..ec3e94b93a --- /dev/null +++ b/build/test/compile/mark/geoshape.test.js @@ -0,0 +1,41 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { geoshape } from '../../../src/compile/mark/geoshape'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('Mark: Geoshape', function () { + describe('encode', function () { + it('should create no properties', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "geoshape", + "projection": { + "type": "albersUsa" + }, + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": { + "color": { + "value": "black" + }, + "opacity": { + "value": 0.8 + } + } + }); + var props = geoshape.encodeEntry(model); + assert.deepEqual({ + "fill": { + "value": "black" + }, + "opacity": { + "value": 0.8 + } + }, props); + }); + }); +}); +//# sourceMappingURL=geoshape.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/geoshape.test.js.map b/build/test/compile/mark/geoshape.test.js.map new file mode 100644 index 0000000000..4ab2c05197 --- /dev/null +++ b/build/test/compile/mark/geoshape.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"geoshape.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/geoshape.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,QAAQ,EAAC,MAAM,oCAAoC,CAAC;AAC5D,OAAO,EAAC,oCAAoC,EAAC,MAAM,YAAY,CAAC;AAEhE,QAAQ,CAAC,gBAAgB,EAAE;IACzB,QAAQ,CAAC,QAAQ,EAAE;QACjB,EAAE,CAAC,6BAA6B,EAAE;YAChC,IAAM,KAAK,GAAG,oCAAoC,CAAC;gBACjD,MAAM,EAAE,UAAU;gBAClB,YAAY,EAAE;oBACZ,MAAM,EAAE,WAAW;iBACpB;gBACD,MAAM,EAAE;oBACN,KAAK,EAAE,kBAAkB;oBACzB,QAAQ,EAAE;wBACR,MAAM,EAAE,UAAU;wBAClB,SAAS,EAAE,QAAQ;qBACpB;iBACF;gBACD,UAAU,EAAE;oBACV,OAAO,EAAE;wBACP,OAAO,EAAE,OAAO;qBACjB;oBACD,SAAS,EAAE;wBACT,OAAO,EAAE,GAAG;qBACb;iBACF;aACF,CAAC,CAAC;YACH,IAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,CAAC,SAAS,CAAC;gBACf,MAAM,EAAE;oBACN,OAAO,EAAE,OAAO;iBACjB;gBACD,SAAS,EAAE;oBACT,OAAO,EAAE,GAAG;iBACb;aACF,EAAE,KAAK,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport {geoshape} from '../../../src/compile/mark/geoshape';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('Mark: Geoshape', function() {\n describe('encode', function () {\n it('should create no properties', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"geoshape\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {\n \"color\": {\n \"value\": \"black\"\n },\n \"opacity\": {\n \"value\": 0.8\n }\n }\n });\n const props = geoshape.encodeEntry(model);\n assert.deepEqual({\n \"fill\": {\n \"value\": \"black\"\n },\n \"opacity\": {\n \"value\": 0.8\n }\n }, props);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/init.test.d.ts b/build/test/compile/mark/init.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/init.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/init.test.js b/build/test/compile/mark/init.test.js new file mode 100644 index 0000000000..8ff3ead066 --- /dev/null +++ b/build/test/compile/mark/init.test.js @@ -0,0 +1,385 @@ +/* tslint:disable quotemark */ +import * as log from '../../../src/log'; +import { assert } from 'chai'; +import { CIRCLE, POINT, PRIMITIVE_MARKS, SQUARE, TICK } from '../../../src/mark'; +import { without } from '../../../src/util'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('compile/mark/init', function () { + describe('defaultOpacity', function () { + it('should return 0.7 by default for unaggregated point, tick, circle, and square', function () { + for (var _i = 0, _a = [POINT, TICK, CIRCLE, SQUARE]; _i < _a.length; _i++) { + var mark = _a[_i]; + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: mark, + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "quantitative", "field": "bar" } + }, + }); + assert.equal(model.markDef.opacity, 0.7); + } + }); + it('should return undefined by default for aggregated point, tick, circle, and square', function () { + for (var _i = 0, _a = [POINT, TICK, CIRCLE, SQUARE]; _i < _a.length; _i++) { + var mark = _a[_i]; + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: mark, + "encoding": { + "y": { "aggregate": "mean", "type": "quantitative", "field": "foo" }, + "x": { "type": "nominal", "field": "bar" } + }, + }); + assert.equal(model.markDef.opacity, undefined); + } + }); + it('should use specified opacity', function () { + for (var _i = 0, _a = [POINT, TICK, CIRCLE, SQUARE]; _i < _a.length; _i++) { + var mark = _a[_i]; + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: { type: mark, opacity: 0.9 }, + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "quantitative", "field": "bar" } + }, + }); + assert.equal(model.markDef.opacity, 0.9); + } + }); + it('should return undefined by default for other marks', function () { + var otherMarks = without(PRIMITIVE_MARKS, [POINT, TICK, CIRCLE, SQUARE]); + for (var _i = 0, otherMarks_1 = otherMarks; _i < otherMarks_1.length; _i++) { + var mark = otherMarks_1[_i]; + var model = parseUnitModelWithScaleAndLayoutSize({ + mark: mark, + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "nominal", "field": "bar" } + }, + }); + assert.equal(model.markDef.opacity, undefined); + } + }); + }); + describe('orient', function () { + it('should return correct default for QxQ', log.wrap(function (localLogger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "quantitative", "field": "bar" } + }, + }); + assert.equal(model.markDef.orient, 'vertical'); + })); + it('should return correct default for empty plot', log.wrap(function (localLogger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + encoding: {} + }); + assert.equal(model.markDef.orient, undefined); + })); + it('should return correct orient for bar with both axes discrete', log.wrap(function (localLogger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "x": { "type": "ordinal", "field": "foo" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + assert.equal(model.markDef.orient, undefined); + })); + it('should return correct orient for vertical bar', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "ordinal", "field": "bar" } + }, + }); + assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal bar', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical bar with raw temporal dimension', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "temporal", "field": "bar" } + }, + }); + assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal bar with raw temporal dimension', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "temporal", "field": "bar" } + }, + }); + assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical tick', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "tick", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for vertical tick with bin', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "tick", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "quantitative", "field": "bar", "bin": true } + }, + }); + assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for vertical tick of continuous timeUnit dotplot', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "tick", + "encoding": { + "x": { "type": "temporal", "field": "foo", "timeUnit": "yearmonthdate" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal tick', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "tick", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "ordinal", "field": "bar" } + }, + }); + assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical rule', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "value": 0 }, + }, + }); + assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal rule', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "value": 0 }, + }, + }); + assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return undefined for line segment rule', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "value": 0 }, + "x": { "value": 0 }, + "y2": { "value": 100 }, + "x2": { "value": 100 }, + }, + }); + assert.equal(model.markDef.orient, undefined); + }); + it('should return undefined for line segment rule with only x and y without x2, y2', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "value": 0 }, + "x": { "value": 0 } + }, + }); + assert.equal(model.markDef.orient, undefined); + }); + it('should return correct orient for horizontal rules without x2 ', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "field": "b", "type": "quantitative" }, + "y": { "field": "a", "type": "ordinal" }, + }, + }); + assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical rules without y2 ', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "field": "b", "type": "quantitative" }, + "x": { "field": "a", "type": "ordinal" }, + }, + }); + assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for vertical rule with range', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "type": "ordinal", "field": "foo" }, + "y": { "type": "quantitative", "field": "bar" }, + "y2": { "type": "quantitative", "field": "baz" } + }, + }); + assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal rule with range', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "type": "ordinal", "field": "foo" }, + "x": { "type": "quantitative", "field": "bar" }, + "x2": { "type": "quantitative", "field": "baz" } + }, + }); + assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for horizontal rule with range and no ordinal', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "type": "quantitative", "field": "bar" }, + "x2": { "type": "quantitative", "field": "baz" } + }, + }); + assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical rule with range and no ordinal', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "type": "quantitative", "field": "bar" }, + "y2": { "type": "quantitative", "field": "baz" } + }, + }); + assert.equal(model.markDef.orient, 'vertical'); + }); + }); + describe('cursor', function () { + it('cursor should be undefined when no href channel defined', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "temporal", "field": "bar" } + }, + }); + assert.equal(model.markDef.cursor, undefined); + }); + it('should return pointer cursor when href channel present', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "selection": { "test": { "type": "single" } }, + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" }, + "href": { + "condition": { "selection": "test", "value": "https://vega.github.io/schema/vega-lite/v2.json" }, + "field": "a", + "type": "ordinal" + }, + }, + }); + assert.equal(model.markDef.cursor, 'pointer'); + }); + it('should return specified cursor when href channel present but cursor specified', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": { "type": "bar", "cursor": "auto" }, + "selection": { "test": { "type": "single" } }, + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" }, + "href": { + "condition": { "selection": "test", "value": "http://www.google.com" }, + "field": "a", + "type": "ordinal" + }, + }, + }); + assert.equal(model.markDef.cursor, 'auto'); + }); + it('should return pointer cursor when href channel specified in mark definition', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": { "type": "bar", "href": "http://www.google.com" }, + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "temporal", "field": "bar" } + } + }); + assert.equal(model.markDef.cursor, 'pointer'); + }); + it('should return specified cursor when href channel specified in mark definition but cursor also specified in mark', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": { "type": "bar", "href": "http://www.google.com", "cursor": "auto" }, + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "temporal", "field": "bar" } + } + }); + assert.equal(model.markDef.cursor, 'auto'); + }); + it('should return pointer cursor when href channel specified in mark config', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "config": { + "mark": { + "href": "http://www.google.com" + } + }, + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "temporal", "field": "bar" } + } + }); + assert.equal(model.markDef.cursor, 'pointer'); + }); + it('should return specified cursor when href channel specified in mark config but cursor also specified in mark', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "config": { + "mark": { + "href": "http://www.google.com" + } + }, + "mark": { "type": "bar", "cursor": "auto" }, + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "temporal", "field": "bar" } + } + }); + assert.equal(model.markDef.cursor, 'auto'); + }); + it('should not specify cursor in the markdef if defined in the config', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "config": { + "mark": { + "href": "http://www.google.com", + "cursor": "auto" + } + }, + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "temporal", "field": "bar" } + } + }); + assert.equal(model.markDef.cursor, undefined); + }); + }); +}); +//# sourceMappingURL=init.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/init.test.js.map b/build/test/compile/mark/init.test.js.map new file mode 100644 index 0000000000..46953e2356 --- /dev/null +++ b/build/test/compile/mark/init.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"init.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/init.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport * as log from '../../../src/log';\n\nimport {assert} from 'chai';\nimport {CIRCLE, Mark, POINT, PRIMITIVE_MARKS, SQUARE, TICK} from '../../../src/mark';\nimport {without} from '../../../src/util';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('compile/mark/init', function() {\n describe('defaultOpacity', () => {\n it('should return 0.7 by default for unaggregated point, tick, circle, and square', () => {\n for (const mark of [POINT, TICK, CIRCLE, SQUARE]) {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark,\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"quantitative\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.opacity, 0.7);\n }\n });\n\n it('should return undefined by default for aggregated point, tick, circle, and square', () => {\n for (const mark of [POINT, TICK, CIRCLE, SQUARE]) {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark,\n \"encoding\": {\n \"y\": {\"aggregate\": \"mean\", \"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"nominal\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.opacity, undefined);\n }\n });\n\n it('should use specified opacity', () => {\n for (const mark of [POINT, TICK, CIRCLE, SQUARE]) {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark: {type: mark, opacity: 0.9},\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"quantitative\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.opacity, 0.9);\n }\n });\n\n it('should return undefined by default for other marks', () => {\n const otherMarks = without(PRIMITIVE_MARKS, [POINT, TICK, CIRCLE, SQUARE]);\n for (const mark of otherMarks) {\n const model = parseUnitModelWithScaleAndLayoutSize({\n mark,\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"nominal\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.opacity, undefined);\n }\n });\n });\n\n describe('orient', function() {\n it('should return correct default for QxQ', log.wrap((localLogger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"quantitative\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.orient, 'vertical');\n }));\n\n it('should return correct default for empty plot', log.wrap((localLogger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n encoding: {}\n });\n assert.equal(model.markDef.orient, undefined);\n }));\n\n it('should return correct orient for bar with both axes discrete', log.wrap((localLogger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"type\": \"ordinal\", \"field\": \"foo\"},\n \"y\": {\"type\": \"ordinal\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.orient, undefined);\n }));\n\n\n it('should return correct orient for vertical bar', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"ordinal\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.orient, 'vertical');\n });\n\n it('should return correct orient for horizontal bar', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"y\": {\"type\": \"ordinal\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.orient, 'horizontal');\n });\n\n it('should return correct orient for vertical bar with raw temporal dimension', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"temporal\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.orient, 'vertical');\n });\n\n it('should return correct orient for horizontal bar with raw temporal dimension', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"y\": {\"type\": \"temporal\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.orient, 'horizontal');\n });\n\n it('should return correct orient for vertical tick', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"tick\",\n \"encoding\": {\n \"x\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"y\": {\"type\": \"ordinal\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.orient, 'vertical');\n });\n\n it('should return correct orient for vertical tick with bin', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"tick\",\n \"encoding\": {\n \"x\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"y\": {\"type\": \"quantitative\", \"field\": \"bar\", \"bin\": true}\n },\n });\n assert.equal(model.markDef.orient, 'vertical');\n });\n\n it('should return correct orient for vertical tick of continuous timeUnit dotplot', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"tick\",\n \"encoding\": {\n \"x\": {\"type\": \"temporal\", \"field\": \"foo\", \"timeUnit\": \"yearmonthdate\"},\n \"y\": {\"type\": \"ordinal\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.orient, 'vertical');\n });\n\n it('should return correct orient for horizontal tick', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"tick\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"ordinal\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.orient, 'horizontal');\n });\n\n it('should return correct orient for vertical rule', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"value\": 0},\n },\n });\n assert.equal(model.markDef.orient, 'vertical');\n });\n\n it('should return correct orient for horizontal rule', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"value\": 0},\n },\n });\n assert.equal(model.markDef.orient, 'horizontal');\n });\n\n it('should return undefined for line segment rule', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"value\": 0},\n \"x\": {\"value\": 0},\n \"y2\": {\"value\": 100},\n \"x2\": {\"value\": 100},\n },\n });\n assert.equal(model.markDef.orient, undefined);\n });\n\n it('should return undefined for line segment rule with only x and y without x2, y2', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"value\": 0},\n \"x\": {\"value\": 0}\n },\n });\n assert.equal(model.markDef.orient, undefined);\n });\n\n it('should return correct orient for horizontal rules without x2 ', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"b\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"a\", \"type\": \"ordinal\"},\n },\n });\n\n assert.equal(model.markDef.orient, 'horizontal');\n });\n\n it('should return correct orient for vertical rules without y2 ', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"field\": \"b\", \"type\": \"quantitative\"},\n \"x\": {\"field\": \"a\", \"type\": \"ordinal\"},\n },\n });\n\n assert.equal(model.markDef.orient, 'vertical');\n });\n\n it('should return correct orient for vertical rule with range', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"type\": \"ordinal\", \"field\": \"foo\"},\n \"y\": {\"type\": \"quantitative\", \"field\": \"bar\"},\n \"y2\": {\"type\": \"quantitative\", \"field\": \"baz\"}\n },\n });\n assert.equal(model.markDef.orient, 'vertical');\n });\n\n it('should return correct orient for horizontal rule with range', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"type\": \"ordinal\", \"field\": \"foo\"},\n \"x\": {\"type\": \"quantitative\", \"field\": \"bar\"},\n \"x2\": {\"type\": \"quantitative\", \"field\": \"baz\"}\n },\n });\n assert.equal(model.markDef.orient, 'horizontal');\n });\n\n it('should return correct orient for horizontal rule with range and no ordinal', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"type\": \"quantitative\", \"field\": \"bar\"},\n \"x2\": {\"type\": \"quantitative\", \"field\": \"baz\"}\n },\n });\n assert.equal(model.markDef.orient, 'horizontal');\n });\n\n it('should return correct orient for vertical rule with range and no ordinal', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"bar\"},\n \"y2\": {\"type\": \"quantitative\", \"field\": \"baz\"}\n },\n });\n assert.equal(model.markDef.orient, 'vertical');\n });\n });\n\n describe('cursor', function() {\n it('cursor should be undefined when no href channel defined', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"temporal\", \"field\": \"bar\"}\n },\n });\n assert.equal(model.markDef.cursor, undefined);\n });\n\n it('should return pointer cursor when href channel present', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"selection\": {\"test\": {\"type\": \"single\"}},\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"b\", \"type\": \"quantitative\"},\n \"href\": {\n \"condition\": {\"selection\": \"test\", \"value\": \"https://vega.github.io/schema/vega-lite/v2.json\"},\n \"field\": \"a\",\n \"type\": \"ordinal\"\n },\n },\n });\n assert.equal(model.markDef.cursor, 'pointer');\n });\n\n it('should return specified cursor when href channel present but cursor specified', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": {\"type\": \"bar\", \"cursor\": \"auto\"},\n \"selection\": {\"test\": {\"type\": \"single\"}},\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"b\", \"type\": \"quantitative\"},\n \"href\": {\n \"condition\": {\"selection\": \"test\", \"value\": \"http://www.google.com\"},\n \"field\": \"a\",\n \"type\": \"ordinal\"\n },\n },\n });\n assert.equal(model.markDef.cursor, 'auto');\n });\n\n it('should return pointer cursor when href channel specified in mark definition', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": {\"type\": \"bar\", \"href\": \"http://www.google.com\"},\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"temporal\", \"field\": \"bar\"}\n }\n });\n assert.equal(model.markDef.cursor, 'pointer');\n });\n\n it('should return specified cursor when href channel specified in mark definition but cursor also specified in mark', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": {\"type\": \"bar\", \"href\": \"http://www.google.com\", \"cursor\": \"auto\"},\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"temporal\", \"field\": \"bar\"}\n }\n });\n assert.equal(model.markDef.cursor, 'auto');\n });\n\n it('should return pointer cursor when href channel specified in mark config', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"config\": {\n \"mark\": {\n \"href\": \"http://www.google.com\"\n }\n },\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"temporal\", \"field\": \"bar\"}\n }\n });\n assert.equal(model.markDef.cursor, 'pointer');\n });\n\n it('should return specified cursor when href channel specified in mark config but cursor also specified in mark', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"config\": {\n \"mark\": {\n \"href\": \"http://www.google.com\"\n }\n },\n \"mark\": {\"type\": \"bar\", \"cursor\": \"auto\"},\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"temporal\", \"field\": \"bar\"}\n }\n });\n assert.equal(model.markDef.cursor, 'auto');\n });\n\n it('should not specify cursor in the markdef if defined in the config', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"config\": {\n \"mark\": {\n \"href\": \"http://www.google.com\",\n \"cursor\": \"auto\"\n }\n },\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\"type\": \"quantitative\", \"field\": \"foo\"},\n \"x\": {\"type\": \"temporal\", \"field\": \"bar\"}\n }\n });\n assert.equal(model.markDef.cursor, undefined);\n });\n\n });\n});\n\n\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/line.test.d.ts b/build/test/compile/mark/line.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/line.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/line.test.js b/build/test/compile/mark/line.test.js new file mode 100644 index 0000000000..138752125e --- /dev/null +++ b/build/test/compile/mark/line.test.js @@ -0,0 +1,137 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { COLOR, X, Y } from '../../../src/channel'; +import { line } from '../../../src/compile/mark/line'; +import * as log from '../../../src/log'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('Mark: Line', function () { + describe('with x, y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative" } + } + }); + var props = line.encodeEntry(model); + it('should have scale for x', function () { + assert.deepEqual(props.x, { scale: X, field: 'year' }); + }); + it('should have scale for y', function () { + assert.deepEqual(props.y, { scale: Y, field: 'yield' }); + }); + }); + describe('with x, y, color', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative" }, + "color": { "field": "Acceleration", "type": "quantitative" } + } + }); + var props = line.encodeEntry(model); + it('should have scale for color', function () { + assert.deepEqual(props.stroke, { scale: COLOR, field: 'Acceleration' }); + }); + }); + describe('with x, y, size', function () { + it('should have scale for size', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative", "aggregate": "mean" }, + "size": { "field": "variety", "type": "nominal" } + } + }); + var props = line.encodeEntry(model); + assert.deepEqual(props.strokeWidth, { scale: 'size', field: 'variety' }); + }); + it('should drop aggregate size field', log.wrap(function (localLogger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative", "aggregate": "mean" }, + "size": { "field": "Acceleration", "type": "quantitative", "aggregate": "mean" } + } + }); + var props = line.encodeEntry(model); + // If size field is dropped, then strokeWidth only have value + assert.isNotOk(props.strokeWidth && props.strokeWidth['scale']); + assert.equal(localLogger.warns[0], log.message.LINE_WITH_VARYING_SIZE); + })); + }); + describe('with stacked y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative", "aggregate": "sum" }, + "color": { "field": "a", "type": "nominal" } + }, + "config": { "stack": "zero" } + }); + var props = line.encodeEntry(model); + it('should use y_end', function () { + assert.deepEqual(props.y, { scale: Y, field: 'sum_yield_end' }); + }); + }); + describe('with stacked x', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "y": { "field": "year", "type": "ordinal" }, + "x": { "field": "yield", "type": "quantitative", "aggregate": "sum" }, + "color": { "field": "a", "type": "nominal" } + }, + "config": { "stack": "zero" } + }); + var props = line.encodeEntry(model); + it('should use x_end', function () { + assert.deepEqual(props.x, { scale: X, field: 'sum_yield_end' }); + }); + }); + describe('with x', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "line", + "encoding": { "x": { "field": "year", "type": "ordinal" } }, + "data": { "url": "data/barley.json" } + }); + var props = line.encodeEntry(model); + it('should be centered on y', function () { + assert.deepEqual(props.y, { + mult: 0.5, + signal: 'height' + }); + }); + it('should scale on x', function () { + assert.deepEqual(props.x, { scale: X, field: 'year' }); + }); + }); + describe('with y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "line", + "encoding": { "y": { "field": "year", "type": "ordinal" } }, + "data": { "url": "data/barley.json" } + }); + var props = line.encodeEntry(model); + it('should be centered on x', function () { + assert.deepEqual(props.x, { + mult: 0.5, + signal: 'width' + }); + }); + it('should scale on y', function () { + assert.deepEqual(props.y, { scale: Y, field: 'year' }); + }); + }); +}); +//# sourceMappingURL=line.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/line.test.js.map b/build/test/compile/mark/line.test.js.map new file mode 100644 index 0000000000..df7503c9e8 --- /dev/null +++ b/build/test/compile/mark/line.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"line.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/line.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAC,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAC,IAAI,EAAC,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAC,oCAAoC,EAAC,MAAM,YAAY,CAAC;AAEhE,QAAQ,CAAC,YAAY,EAAE;IAErB,QAAQ,CAAC,WAAW,EAAE;QACpB,IAAM,KAAK,GAAG,oCAAoC,CAAC;YACjD,MAAM,EAAE,EAAC,KAAK,EAAE,kBAAkB,EAAC;YACnC,MAAM,EAAE,MAAM;YACd,UAAU,EAAE;gBACV,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAC;gBACzC,GAAG,EAAE,EAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAC;aAChD;SACF,CAAC,CAAC;QACH,IAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEtC,EAAE,CAAC,yBAAyB,EAAE;YAC5B,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAC,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yBAAyB,EAAE;YAC5B,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAC,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE;QAC3B,IAAM,KAAK,GAAG,oCAAoC,CAAC;YACjD,MAAM,EAAE,EAAC,KAAK,EAAE,kBAAkB,EAAC;YACnC,MAAM,EAAE,MAAM;YACd,UAAU,EAAE;gBACV,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAC;gBACzC,GAAG,EAAE,EAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAC;gBAC/C,OAAO,EAAE,EAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAC;aAC3D;SACF,CAAC,CAAC;QACH,IAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEtC,EAAE,CAAC,6BAA6B,EAAE;YAChC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAGH,QAAQ,CAAC,iBAAiB,EAAE;QAC1B,EAAE,CAAC,4BAA4B,EAAE;YAC/B,IAAM,KAAK,GAAG,oCAAoC,CAAC;gBACjD,MAAM,EAAE,EAAC,KAAK,EAAE,kBAAkB,EAAC;gBACnC,MAAM,EAAE,MAAM;gBACd,UAAU,EAAE;oBACV,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAC;oBACzC,GAAG,EAAE,EAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,EAAC;oBACpE,MAAM,EAAE,EAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAC;iBAChD;aACF,CAAC,CAAC;YACH,IAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAEtC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,EAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAC,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,CAAC,IAAI,CAAC,UAAC,WAAW;YAC1D,IAAM,KAAK,GAAG,oCAAoC,CAAC;gBACjD,MAAM,EAAE,EAAC,KAAK,EAAE,kBAAkB,EAAC;gBACnC,MAAM,EAAE,MAAM;gBACd,UAAU,EAAE;oBACV,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAC;oBACzC,GAAG,EAAE,EAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,EAAC;oBACpE,MAAM,EAAE,EAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,EAAC;iBAC/E;aACF,CAAC,CAAC;YACH,IAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAEtC,6DAA6D;YAC7D,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;YAChE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE;QACzB,IAAM,KAAK,GAAG,oCAAoC,CAAC;YACjD,MAAM,EAAE,EAAC,KAAK,EAAE,kBAAkB,EAAC;YACnC,MAAM,EAAE,MAAM;YACd,UAAU,EAAE;gBACV,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAC;gBACzC,GAAG,EAAE,EAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,KAAK,EAAC;gBACnE,OAAO,EAAE,EAAC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAC;aAC3C;YACD,QAAQ,EAAE,EAAC,OAAO,EAAG,MAAM,EAAC;SAC7B,CAAC,CAAC;QACH,IAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEtC,EAAE,CAAC,kBAAkB,EAAE;YACrB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,eAAe,EAAC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE;QACzB,IAAM,KAAK,GAAG,oCAAoC,CAAC;YACjD,MAAM,EAAE,EAAC,KAAK,EAAE,kBAAkB,EAAC;YACnC,MAAM,EAAE,MAAM;YACd,UAAU,EAAE;gBACV,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAC;gBACzC,GAAG,EAAE,EAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,KAAK,EAAC;gBACnE,OAAO,EAAE,EAAC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAC;aAC3C;YACD,QAAQ,EAAE,EAAC,OAAO,EAAG,MAAM,EAAC;SAC7B,CAAC,CAAC;QACH,IAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEtC,EAAE,CAAC,kBAAkB,EAAE;YACrB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,eAAe,EAAC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE;QACjB,IAAM,KAAK,GAAG,oCAAoC,CAAC;YACjD,MAAM,EAAE,MAAM;YACd,UAAU,EAAE,EAAC,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAC,EAAC;YACvD,MAAM,EAAE,EAAC,KAAK,EAAE,kBAAkB,EAAC;SACpC,CAAC,CAAC;QAEH,IAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEtC,EAAE,CAAC,yBAAyB,EAAE;YAC5B,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE;gBACxB,IAAI,EAAE,GAAG;gBACT,MAAM,EAAE,QAAQ;aACjB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mBAAmB,EAAE;YACtB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAC,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE;QACjB,IAAM,KAAK,GAAG,oCAAoC,CAAC;YACjD,MAAM,EAAE,MAAM;YACd,UAAU,EAAE,EAAC,GAAG,EAAE,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAC,EAAC;YACvD,MAAM,EAAE,EAAC,KAAK,EAAE,kBAAkB,EAAC;SACpC,CAAC,CAAC;QAEH,IAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEtC,EAAE,CAAC,yBAAyB,EAAE;YAC5B,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE;gBACxB,IAAI,EAAE,GAAG;gBACT,MAAM,EAAE,OAAO;aAChB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mBAAmB,EAAE;YACtB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAC,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\n\nimport {COLOR, X, Y} from '../../../src/channel';\nimport {line} from '../../../src/compile/mark/line';\nimport * as log from '../../../src/log';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('Mark: Line', function() {\n\n describe('with x, y', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"year\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"yield\", \"type\": \"quantitative\"}\n }\n });\n const props = line.encodeEntry(model);\n\n it('should have scale for x', function() {\n assert.deepEqual(props.x, {scale: X, field: 'year'});\n });\n\n it('should have scale for y', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'yield'});\n });\n });\n\n describe('with x, y, color', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"year\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"yield\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"Acceleration\", \"type\": \"quantitative\"}\n }\n });\n const props = line.encodeEntry(model);\n\n it('should have scale for color', function () {\n assert.deepEqual(props.stroke, {scale: COLOR, field: 'Acceleration'});\n });\n });\n\n\n describe('with x, y, size', function () {\n it('should have scale for size', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"year\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"yield\", \"type\": \"quantitative\", \"aggregate\": \"mean\"},\n \"size\": {\"field\": \"variety\", \"type\": \"nominal\"}\n }\n });\n const props = line.encodeEntry(model);\n\n assert.deepEqual(props.strokeWidth, {scale: 'size', field: 'variety'});\n });\n\n it('should drop aggregate size field', log.wrap((localLogger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"year\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"yield\", \"type\": \"quantitative\", \"aggregate\": \"mean\"},\n \"size\": {\"field\": \"Acceleration\", \"type\": \"quantitative\", \"aggregate\": \"mean\"}\n }\n });\n const props = line.encodeEntry(model);\n\n // If size field is dropped, then strokeWidth only have value\n assert.isNotOk(props.strokeWidth && props.strokeWidth['scale']);\n assert.equal(localLogger.warns[0], log.message.LINE_WITH_VARYING_SIZE);\n }));\n });\n\n describe('with stacked y', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"year\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"yield\", \"type\": \"quantitative\", \"aggregate\": \"sum\"},\n \"color\": {\"field\": \"a\", \"type\": \"nominal\"}\n },\n \"config\": {\"stack\": \"zero\"}\n });\n const props = line.encodeEntry(model);\n\n it('should use y_end', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'sum_yield_end'});\n });\n });\n\n describe('with stacked x', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": \"line\",\n \"encoding\": {\n \"y\": {\"field\": \"year\", \"type\": \"ordinal\"},\n \"x\": {\"field\": \"yield\", \"type\": \"quantitative\", \"aggregate\": \"sum\"},\n \"color\": {\"field\": \"a\", \"type\": \"nominal\"}\n },\n \"config\": {\"stack\": \"zero\"}\n });\n const props = line.encodeEntry(model);\n\n it('should use x_end', function() {\n assert.deepEqual(props.x, {scale: X, field: 'sum_yield_end'});\n });\n });\n\n describe('with x', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"line\",\n \"encoding\": {\"x\": {\"field\": \"year\", \"type\": \"ordinal\"}},\n \"data\": {\"url\": \"data/barley.json\"}\n });\n\n const props = line.encodeEntry(model);\n\n it('should be centered on y', function() {\n assert.deepEqual(props.y, {\n mult: 0.5,\n signal: 'height'\n });\n });\n\n it('should scale on x', function() {\n assert.deepEqual(props.x, {scale: X, field: 'year'});\n });\n });\n\n describe('with y', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"line\",\n \"encoding\": {\"y\": {\"field\": \"year\", \"type\": \"ordinal\"}},\n \"data\": {\"url\": \"data/barley.json\"}\n });\n\n const props = line.encodeEntry(model);\n\n it('should be centered on x', function() {\n assert.deepEqual(props.x, {\n mult: 0.5,\n signal: 'width'\n });\n });\n\n it('should scale on y', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'year'});\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/mark.test.d.ts b/build/test/compile/mark/mark.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/mark.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/mark.test.js b/build/test/compile/mark/mark.test.js new file mode 100644 index 0000000000..4d062da567 --- /dev/null +++ b/build/test/compile/mark/mark.test.js @@ -0,0 +1,286 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { COLOR, DETAIL, OPACITY, SIZE, UNIT_CHANNELS } from '../../../src/channel'; +import { getSort, parseMarkGroup, pathGroupingFields } from '../../../src/compile/mark/mark'; +import { GEOSHAPE } from '../../../src/mark'; +import { parseFacetModel, parseUnitModel, parseUnitModelWithScale, parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('Mark', function () { + describe('parseMarkGroup', function () { + // PATH + describe('Multi-series Line', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": { "type": "line", "style": "trend" }, + "encoding": { + "x": { "field": "date", "type": "temporal", "axis": { "format": "%Y" } }, + "y": { "field": "price", "type": "quantitative" }, + "color": { "field": "symbol", "type": "nominal" } + } + }); + it('should have a facet directive and a nested mark group that uses the faceted data.', function () { + var markGroup = parseMarkGroup(model)[0]; + assert.equal(markGroup.name, 'pathgroup'); + assert.deepEqual(markGroup.from, { + facet: { + name: 'faceted_path_main', + data: 'main', + groupby: ['symbol'] + } + }); + var submarkGroup = markGroup.marks[0]; + assert.equal(submarkGroup.name, 'marks'); + assert.equal(submarkGroup.type, 'line'); + assert.deepEqual(submarkGroup.style, ['line', 'trend']); + assert.equal(submarkGroup.from.data, 'faceted_path_main'); + }); + it('should not have post encoding transform', function () { + var markGroup = parseMarkGroup(model)[0]; + assert.equal(markGroup.name, 'pathgroup'); + assert.deepEqual(markGroup.from, { + facet: { + name: 'faceted_path_main', + data: 'main', + groupby: ['symbol'] + } + }); + var submarkGroup = markGroup.marks[0]; + assert.isUndefined(submarkGroup.transform); + }); + }); + describe('Single Line', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal", "axis": { "format": "%Y" } }, + "y": { "field": "price", "type": "quantitative" } + } + }); + it('should have mark group with proper data and key', function () { + var markGroup = parseMarkGroup(model)[0]; + assert.equal(markGroup.name, 'marks'); + assert.equal(markGroup.type, 'line'); + assert.equal(markGroup.from.data, 'main'); + }); + it('should not have post encoding transform', function () { + var markGroup = parseMarkGroup(model); + assert.isUndefined(markGroup[0].transform); + }); + // NON-PATH + }); + describe('Points with key', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "x": { "field": "date", "type": "temporal", "axis": { "format": "%Y" } }, + "y": { "field": "price", "type": "quantitative" }, + "key": { "field": "k", "type": "quantitative" } + } + }); + it('should have mark group with proper data and key', function () { + var markGroup = parseMarkGroup(model)[0]; + assert.equal(markGroup.type, 'symbol'); + assert.equal(markGroup.key.field, 'k'); + assert.equal(markGroup.from.data, 'main'); + }); + it('should not have post encoding transform', function () { + var markGroup = parseMarkGroup(model); + assert.isUndefined(markGroup[0].transform); + }); + }); + it('Geoshape should have post encoding transform', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "geoshape", + "projection": { + "type": "albersUsa" + }, + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {} + }); + var markGroup = parseMarkGroup(model); + assert.isDefined(markGroup[0].transform); + assert.equal(markGroup[0].transform[0].type, GEOSHAPE); + }); + describe('Aggregated Bar with a color with binned x', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "Cost__Other", "aggregate": "sum" }, + "y": { "bin": true, "type": "quantitative", "field": "Cost__Total_$" }, + "color": { "type": "ordinal", "field": "Effect__Amount_of_damage" } + } + }); + it('should use main stacked data source', function () { + var markGroup = parseMarkGroup(model); + assert.equal(markGroup[0].from.data, 'main'); + assert.equal(markGroup[0].style, 'bar'); + }); + it('should not have post encoding transform', function () { + var markGroup = parseMarkGroup(model); + assert.isUndefined(markGroup[0].transform); + }); + }); + describe('Faceted aggregated Bar with a color with binned x', function () { + var model = parseFacetModel({ + facet: { + row: { field: 'a', type: 'nominal' } + }, + spec: { + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "Cost__Other", "aggregate": "sum" }, + "y": { "bin": true, "type": "quantitative", "field": "Cost__Total_$" }, + "color": { "type": "ordinal", "field": "Effect__Amount_of_damage" } + } + } + }); + it('should use faceted data source', function () { + model.parseScale(); + model.parseLayoutSize(); + var markGroup = parseMarkGroup(model.child); + assert.equal(markGroup[0].from.data, 'child_main'); + }); + it('should not have post encoding transform', function () { + model.parseScale(); + model.parseLayoutSize(); + var markGroup = parseMarkGroup(model.child); + assert.isUndefined(markGroup[0].transform); + }); + }); + describe('Aggregated bar', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "Cost__Other", "aggregate": "sum" }, + "y": { "bin": true, "type": "quantitative", "field": "Cost__Total_$" } + } + }); + it('should use main aggregated data source', function () { + var markGroup = parseMarkGroup(model); + assert.equal(markGroup[0].from.data, 'main'); + }); + it('should not have post encoding transform', function () { + var markGroup = parseMarkGroup(model); + assert.isUndefined(markGroup[0].transform); + }); + }); + }); + describe('getSort', function () { + it('should order by order field', function () { + var model = parseUnitModel({ + "data": { "url": "data/driving.json" }, + "mark": "line", + "encoding": { + "x": { "field": "miles", "type": "quantitative", "scale": { "zero": false } }, + "y": { "field": "gas", "type": "quantitative", "scale": { "zero": false } }, + "order": { "field": "year", "type": "temporal" } + } + }); + assert.deepEqual(getSort(model), { + field: ['datum[\"year\"]'], + order: ['ascending'] + }); + }); + it('should have no sort if order = {value: null}', function () { + var model = parseUnitModel({ + "data": { "url": "data/driving.json" }, + "mark": "line", + "encoding": { + "x": { "field": "miles", "type": "quantitative", "scale": { "zero": false } }, + "y": { "field": "gas", "type": "quantitative", "scale": { "zero": false } }, + "order": { "value": null } + } + }); + assert.equal(getSort(model), undefined); + }); + it('should order by x by default if x is the dimension', function () { + var model = parseUnitModelWithScale({ + "data": { "url": "data/movies.json" }, + "mark": "line", + "encoding": { + "x": { + "bin": { "maxbins": 10 }, + "field": "IMDB_Rating", + "type": "quantitative" + }, + "color": { + "field": "Source", + "type": "nominal" + }, + "y": { + "aggregate": "count", + "type": "quantitative" + } + } + }); + assert.deepEqual(getSort(model), { + field: 'datum[\"bin_maxbins_10_IMDB_Rating\"]', + order: 'descending' + }); + }); + it('should not order by a missing dimension', function () { + var model = parseUnitModelWithScale({ + "data": { "url": "data/movies.json" }, + "mark": "line", + "encoding": { + "color": { + "field": "Source", + "type": "nominal" + }, + "y": { + "aggregate": "count", + "type": "quantitative" + } + } + }); + assert.deepEqual(getSort(model), undefined); + }); + }); + describe('pathGroupingFields()', function () { + it('should return fields for unaggregate detail, color, size, opacity fieldDefs.', function () { + var _a; + for (var _i = 0, _b = [DETAIL, COLOR, SIZE, OPACITY]; _i < _b.length; _i++) { + var channel = _b[_i]; + assert.deepEqual(pathGroupingFields('line', (_a = {}, _a[channel] = { field: 'a', type: 'nominal' }, _a)), ['a']); + } + }); + it('should not return a field for size of a trail mark.', function () { + assert.deepEqual(pathGroupingFields('trail', { size: { field: 'a', type: 'nominal' } }), []); + }); + it('should not return fields for aggregate detail, color, size, opacity fieldDefs.', function () { + var _a; + for (var _i = 0, _b = [DETAIL, COLOR, SIZE, OPACITY]; _i < _b.length; _i++) { + var channel = _b[_i]; + assert.deepEqual(pathGroupingFields('line', (_a = {}, _a[channel] = { aggregate: 'mean', field: 'a', type: 'nominal' }, _a)), [], channel); + } + }); + it('should return condition detail fields for color, size, shape', function () { + var _a; + for (var _i = 0, _b = [COLOR, SIZE, OPACITY]; _i < _b.length; _i++) { + var channel = _b[_i]; + assert.deepEqual(pathGroupingFields('line', (_a = {}, _a[channel] = { + condition: { selection: 'sel', field: 'a', type: 'nominal' } + }, _a)), ['a']); + } + }); + it('should not return errors for all channels', function () { + var _loop_1 = function (channel) { + assert.doesNotThrow(function () { + var _a; + pathGroupingFields('line', (_a = {}, + _a[channel] = { field: 'a', type: 'nominal' }, + _a)); + }); + }; + for (var _i = 0, UNIT_CHANNELS_1 = UNIT_CHANNELS; _i < UNIT_CHANNELS_1.length; _i++) { + var channel = UNIT_CHANNELS_1[_i]; + _loop_1(channel); + } + }); + }); +}); +//# sourceMappingURL=mark.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/mark.test.js.map b/build/test/compile/mark/mark.test.js.map new file mode 100644 index 0000000000..a4c140dd15 --- /dev/null +++ b/build/test/compile/mark/mark.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mark.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/mark.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {COLOR, DETAIL, OPACITY, SIZE, UNIT_CHANNELS} from '../../../src/channel';\nimport {getSort, parseMarkGroup, pathGroupingFields} from '../../../src/compile/mark/mark';\nimport {UnitModel} from '../../../src/compile/unit';\nimport {GEOSHAPE} from '../../../src/mark';\nimport {parseFacetModel, parseUnitModel, parseUnitModelWithScale, parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('Mark', function() {\n describe('parseMarkGroup', function() {\n // PATH\n describe('Multi-series Line', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": {\"type\": \"line\", \"style\": \"trend\"},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\", \"axis\": {\"format\": \"%Y\"}},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"symbol\", \"type\": \"nominal\"}\n }\n });\n it('should have a facet directive and a nested mark group that uses the faceted data.', () => {\n const markGroup = parseMarkGroup(model)[0];\n assert.equal(markGroup.name, 'pathgroup');\n assert.deepEqual(markGroup.from, {\n facet: {\n name: 'faceted_path_main',\n data: 'main',\n groupby: ['symbol']\n }\n });\n const submarkGroup = markGroup.marks[0];\n assert.equal(submarkGroup.name, 'marks');\n assert.equal(submarkGroup.type, 'line');\n assert.deepEqual(submarkGroup.style, ['line', 'trend']);\n assert.equal(submarkGroup.from.data, 'faceted_path_main');\n });\n\n it('should not have post encoding transform', () => {\n const markGroup = parseMarkGroup(model)[0];\n assert.equal(markGroup.name, 'pathgroup');\n assert.deepEqual(markGroup.from, {\n facet: {\n name: 'faceted_path_main',\n data: 'main',\n groupby: ['symbol']\n }\n });\n const submarkGroup = markGroup.marks[0];\n assert.isUndefined(submarkGroup.transform);\n });\n });\n\n describe('Single Line', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\", \"axis\": {\"format\": \"%Y\"}},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n });\n it('should have mark group with proper data and key', () => {\n const markGroup = parseMarkGroup(model)[0];\n assert.equal(markGroup.name, 'marks');\n assert.equal(markGroup.type, 'line');\n assert.equal(markGroup.from.data, 'main');\n });\n\n it('should not have post encoding transform', () => {\n const markGroup = parseMarkGroup(model);\n assert.isUndefined(markGroup[0].transform);\n });\n\n // NON-PATH\n });\n describe('Points with key', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\", \"axis\": {\"format\": \"%Y\"}},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"},\n \"key\": {\"field\": \"k\", \"type\": \"quantitative\"}\n }\n });\n it('should have mark group with proper data and key', () => {\n const markGroup = parseMarkGroup(model)[0];\n assert.equal(markGroup.type, 'symbol');\n assert.equal(markGroup.key.field, 'k');\n assert.equal(markGroup.from.data, 'main');\n });\n\n it('should not have post encoding transform', () => {\n const markGroup = parseMarkGroup(model);\n assert.isUndefined(markGroup[0].transform);\n });\n });\n\n it('Geoshape should have post encoding transform', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"geoshape\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {}\n });\n const markGroup = parseMarkGroup(model);\n assert.isDefined(markGroup[0].transform);\n assert.equal(markGroup[0].transform[0].type, GEOSHAPE);\n });\n\n describe('Aggregated Bar with a color with binned x', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"type\": \"quantitative\", \"field\": \"Cost__Other\", \"aggregate\": \"sum\"},\n \"y\": {\"bin\": true, \"type\": \"quantitative\", \"field\": \"Cost__Total_$\"},\n \"color\": {\"type\": \"ordinal\", \"field\": \"Effect__Amount_of_damage\"}\n }\n });\n it('should use main stacked data source', () => {\n const markGroup = parseMarkGroup(model);\n assert.equal(markGroup[0].from.data, 'main');\n assert.equal(markGroup[0].style, 'bar');\n });\n it('should not have post encoding transform', () => {\n const markGroup = parseMarkGroup(model);\n assert.isUndefined(markGroup[0].transform);\n });\n });\n\n describe('Faceted aggregated Bar with a color with binned x', () => {\n const model = parseFacetModel({\n facet: {\n row: {field: 'a', type: 'nominal'}\n },\n spec: {\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"type\": \"quantitative\", \"field\": \"Cost__Other\", \"aggregate\": \"sum\"},\n \"y\": {\"bin\": true, \"type\": \"quantitative\", \"field\": \"Cost__Total_$\"},\n \"color\": {\"type\": \"ordinal\", \"field\": \"Effect__Amount_of_damage\"}\n }\n }\n });\n it('should use faceted data source', () => {\n model.parseScale();\n model.parseLayoutSize();\n\n const markGroup = parseMarkGroup(model.child as UnitModel);\n assert.equal(markGroup[0].from.data, 'child_main');\n });\n\n it('should not have post encoding transform', () => {\n model.parseScale();\n model.parseLayoutSize();\n\n const markGroup = parseMarkGroup(model.child as UnitModel);\n assert.isUndefined(markGroup[0].transform);\n });\n });\n\n describe('Aggregated bar', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"type\": \"quantitative\", \"field\": \"Cost__Other\", \"aggregate\": \"sum\"},\n \"y\": {\"bin\": true, \"type\": \"quantitative\", \"field\": \"Cost__Total_$\"}\n }\n });\n\n it('should use main aggregated data source', () => {\n const markGroup = parseMarkGroup(model);\n assert.equal(markGroup[0].from.data, 'main');\n });\n\n it('should not have post encoding transform', () => {\n const markGroup = parseMarkGroup(model);\n assert.isUndefined(markGroup[0].transform);\n });\n });\n });\n\n describe('getSort', () => {\n it('should order by order field', function () {\n const model = parseUnitModel({\n \"data\": {\"url\": \"data/driving.json\"},\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"miles\", \"type\": \"quantitative\", \"scale\": {\"zero\": false}},\n \"y\": {\"field\": \"gas\", \"type\": \"quantitative\", \"scale\": {\"zero\": false}},\n \"order\": {\"field\": \"year\", \"type\": \"temporal\"}\n }\n });\n assert.deepEqual(getSort(model), {\n field: ['datum[\\\"year\\\"]'],\n order: ['ascending']\n });\n });\n\n it('should have no sort if order = {value: null}', function () {\n const model = parseUnitModel({\n \"data\": {\"url\": \"data/driving.json\"},\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"miles\", \"type\": \"quantitative\", \"scale\": {\"zero\": false}},\n \"y\": {\"field\": \"gas\", \"type\": \"quantitative\", \"scale\": {\"zero\": false}},\n \"order\": {\"value\": null}\n }\n });\n assert.equal(getSort(model), undefined);\n });\n\n it('should order by x by default if x is the dimension', function () {\n const model = parseUnitModelWithScale({\n \"data\": {\"url\": \"data/movies.json\"},\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\n \"bin\": {\"maxbins\": 10},\n \"field\": \"IMDB_Rating\",\n \"type\": \"quantitative\"\n },\n \"color\": {\n \"field\": \"Source\",\n \"type\": \"nominal\"\n },\n \"y\": {\n \"aggregate\": \"count\",\n \"type\": \"quantitative\"\n }\n }\n });\n assert.deepEqual(getSort(model), {\n field: 'datum[\\\"bin_maxbins_10_IMDB_Rating\\\"]',\n order: 'descending'\n });\n });\n\n it('should not order by a missing dimension', function () {\n const model = parseUnitModelWithScale({\n \"data\": {\"url\": \"data/movies.json\"},\n \"mark\": \"line\",\n \"encoding\": {\n \"color\": {\n \"field\": \"Source\",\n \"type\": \"nominal\"\n },\n \"y\": {\n \"aggregate\": \"count\",\n \"type\": \"quantitative\"\n }\n }\n });\n assert.deepEqual(getSort(model), undefined);\n });\n });\n\n describe('pathGroupingFields()', () => {\n it('should return fields for unaggregate detail, color, size, opacity fieldDefs.', () => {\n for (const channel of [DETAIL, COLOR, SIZE, OPACITY]) {\n assert.deepEqual(\n pathGroupingFields('line', {[channel]: {field: 'a', type: 'nominal'}}),\n ['a']\n );\n }\n });\n\n it('should not return a field for size of a trail mark.', () => {\n assert.deepEqual(\n pathGroupingFields('trail', {size: {field: 'a', type: 'nominal'}}),\n []\n );\n });\n\n it('should not return fields for aggregate detail, color, size, opacity fieldDefs.', () => {\n for (const channel of [DETAIL, COLOR, SIZE, OPACITY]) {\n assert.deepEqual(\n pathGroupingFields('line', {[channel]: {aggregate: 'mean', field: 'a', type: 'nominal'}}),\n [],\n channel\n );\n }\n });\n\n it('should return condition detail fields for color, size, shape', () => {\n for (const channel of [COLOR, SIZE, OPACITY]) {\n assert.deepEqual(\n pathGroupingFields('line', {[channel]: {\n condition: {selection: 'sel', field: 'a', type: 'nominal'}\n }}),\n ['a']\n );\n }\n });\n\n it('should not return errors for all channels', () => {\n for (const channel of UNIT_CHANNELS) {\n assert.doesNotThrow(\n () => {\n pathGroupingFields('line', {\n [channel]: {field: 'a', type: 'nominal'}\n });\n }\n );\n }\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/mixins.test.d.ts b/build/test/compile/mark/mixins.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/mixins.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/mixins.test.js b/build/test/compile/mark/mixins.test.js new file mode 100644 index 0000000000..ed2d899985 --- /dev/null +++ b/build/test/compile/mark/mixins.test.js @@ -0,0 +1,229 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { X, Y } from '../../../src/channel'; +import { color, pointPosition, tooltip } from '../../../src/compile/mark/mixins'; +import * as log from '../../../src/log'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('compile/mark/mixins', function () { + describe('color()', function () { + it('color should be mapped to fill for bar', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "bar", + "encoding": { + "x": { + "field": "gender", "type": "nominal", + "scale": { "rangeStep": 6 }, + "axis": null + }, + "color": { + "field": "gender", "type": "nominal", + "scale": { "range": ["#EA98D2", "#659CCA"] } + } + }, + "data": { "url": "data/population.json" } + }); + var colorMixins = color(model); + assert.deepEqual(colorMixins.fill, { "field": "gender", "scale": "color" }); + }); + it('color should be mapped to stroke for point', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "x": { + "field": "gender", "type": "nominal", + "scale": { "rangeStep": 6 }, + "axis": null + }, + "color": { + "field": "gender", "type": "nominal", + "scale": { "range": ["#EA98D2", "#659CCA"] } + } + }, + "data": { "url": "data/population.json" } + }); + var colorMixins = color(model); + assert.deepEqual(colorMixins.stroke, { "field": "gender", "scale": "color" }); + assert.propertyVal(colorMixins.fill, 'value', "transparent"); + }); + it('add transparent fill when stroke is encoded', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "x": { + "field": "gender", "type": "nominal", + "scale": { "rangeStep": 6 }, + "axis": null + }, + "stroke": { + "field": "gender", "type": "nominal", + "scale": { "range": ["#EA98D2", "#659CCA"] } + } + }, + "data": { "url": "data/population.json" } + }); + var colorMixins = color(model); + assert.deepEqual(colorMixins.stroke, { "field": "gender", "scale": "stroke" }); + assert.propertyVal(colorMixins.fill, 'value', "transparent"); + }); + it('ignores color if fill is specified', log.wrap(function (logger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "x": { + "field": "gender", "type": "nominal", + "scale": { "rangeStep": 6 }, + "axis": null + }, + "fill": { + "field": "gender", "type": "nominal", + "scale": { "range": ["#EA98D2", "#659CCA"] } + }, + "color": { + "field": "gender", "type": "nominal", + "scale": { "range": ["#EA98D2", "#659CCA"] } + } + }, + "data": { "url": "data/population.json" } + }); + var colorMixins = color(model); + assert.isUndefined(colorMixins.stroke); + assert.deepEqual(colorMixins.fill, { "field": "gender", "scale": "fill" }); + assert.equal(logger.warns[0], log.message.droppingColor('encoding', { fill: true })); + })); + it('ignores color property if fill is specified', log.wrap(function (logger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": { "type": "point", "color": "red" }, + "encoding": { + "x": { + "field": "gender", "type": "nominal", + "scale": { "rangeStep": 6 }, + "axis": null + }, + "fill": { + "field": "gender", "type": "nominal", + "scale": { "range": ["#EA98D2", "#659CCA"] } + } + }, + "data": { "url": "data/population.json" } + }); + var colorMixins = color(model); + assert.isUndefined(colorMixins.stroke); + assert.deepEqual(colorMixins.fill, { "field": "gender", "scale": "fill" }); + assert.equal(logger.warns[0], log.message.droppingColor('property', { fill: true })); + })); + it('should apply stroke property over color property', log.wrap(function (logger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": { "type": "point", "color": "red", "stroke": "blue" }, + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + } + }); + var props = color(model); + assert.deepEqual(props.stroke, { value: "blue" }); + assert.equal(logger.warns[0], log.message.droppingColor('property', { stroke: true })); + })); + it('should apply ignore color property when fill is specified', log.wrap(function (logger) { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": { "type": "point", "color": "red", "fill": "blue" }, + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + } + }); + var props = color(model); + assert.isUndefined(props.stroke); + assert.equal(logger.warns[0], log.message.droppingColor('property', { fill: true })); + })); + it('should apply color property', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": { "type": "point", "color": "red" }, + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + } + }); + var props = color(model); + assert.deepEqual(props.stroke, { value: "red" }); + }); + it('should apply color from mark-specific config over general mark config', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + }, + "config": { "mark": { "color": "blue" }, "point": { "color": "red" } } + }); + var props = color(model); + assert.deepEqual(props.stroke, { value: "red" }); + }); + it('should apply stroke mark config over color mark config', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + }, + "config": { "mark": { "color": "red", "stroke": "blue" } } + }); + var props = color(model); + assert.deepEqual(props.stroke, { value: "blue" }); + }); + it('should apply stroke mark config over color mark config', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + }, + "config": { "point": { "color": "red", "stroke": "blue" } } + }); + var props = color(model); + assert.deepEqual(props.stroke, { value: "blue" }); + }); + }); + describe('tooltip()', function () { + it('generates tooltip object signal for an array of tooltip fields', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "tooltip": [ + { "field": "Horsepower", "type": "quantitative" }, + { "field": "Acceleration", "type": "quantitative" } + ] + } + }); + var props = tooltip(model); + assert.deepEqual(props.tooltip, { signal: '{"Horsepower": format(datum["Horsepower"], ""), "Acceleration": format(datum["Acceleration"], "")}' }); + }); + }); + describe('midPoint()', function () { + it('should return correctly for lat/lng', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { + "url": "data/zipcodes.csv", + "format": { + "type": "csv" + } + }, + "mark": "point", + "encoding": { + "longitude": { + "field": "longitude", + "type": "quantitative" + }, + "latitude": { + "field": "latitude", + "type": "quantitative" + } + } + }); + [X, Y].forEach(function (channel) { + var mixins = pointPosition(channel, model, 'zeroOrMin'); + assert.equal(mixins[channel].field, model.getName(channel)); + }); + }); + }); +}); +//# sourceMappingURL=mixins.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/mixins.test.js.map b/build/test/compile/mark/mixins.test.js.map new file mode 100644 index 0000000000..f794252b47 --- /dev/null +++ b/build/test/compile/mark/mixins.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mixins.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/mixins.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {X, Y} from '../../../src/channel';\nimport {color, pointPosition, tooltip} from '../../../src/compile/mark/mixins';\nimport * as log from '../../../src/log';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('compile/mark/mixins', () => {\n describe('color()', function() {\n it('color should be mapped to fill for bar', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\n \"field\": \"gender\", \"type\": \"nominal\",\n \"scale\": {\"rangeStep\": 6},\n \"axis\": null\n },\n \"color\": {\n \"field\": \"gender\", \"type\": \"nominal\",\n \"scale\": {\"range\": [\"#EA98D2\", \"#659CCA\"]}\n }\n },\n \"data\": {\"url\": \"data/population.json\"}\n });\n\n const colorMixins = color(model);\n assert.deepEqual(colorMixins.fill, {\"field\": \"gender\", \"scale\": \"color\"});\n });\n\n it('color should be mapped to stroke for point', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\n \"field\": \"gender\", \"type\": \"nominal\",\n \"scale\": {\"rangeStep\": 6},\n \"axis\": null\n },\n \"color\": {\n \"field\": \"gender\", \"type\": \"nominal\",\n \"scale\": {\"range\": [\"#EA98D2\", \"#659CCA\"]}\n }\n },\n \"data\": {\"url\": \"data/population.json\"}\n });\n\n const colorMixins = color(model);\n assert.deepEqual(colorMixins.stroke, {\"field\": \"gender\", \"scale\": \"color\"});\n assert.propertyVal(colorMixins.fill, 'value', \"transparent\");\n });\n\n it('add transparent fill when stroke is encoded', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\n \"field\": \"gender\", \"type\": \"nominal\",\n \"scale\": {\"rangeStep\": 6},\n \"axis\": null\n },\n \"stroke\": {\n \"field\": \"gender\", \"type\": \"nominal\",\n \"scale\": {\"range\": [\"#EA98D2\", \"#659CCA\"]}\n }\n },\n \"data\": {\"url\": \"data/population.json\"}\n });\n\n const colorMixins = color(model);\n assert.deepEqual(colorMixins.stroke, {\"field\": \"gender\", \"scale\": \"stroke\"});\n assert.propertyVal(colorMixins.fill, 'value', \"transparent\");\n });\n\n it('ignores color if fill is specified', log.wrap((logger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\n \"field\": \"gender\", \"type\": \"nominal\",\n \"scale\": {\"rangeStep\": 6},\n \"axis\": null\n },\n \"fill\": {\n \"field\": \"gender\", \"type\": \"nominal\",\n \"scale\": {\"range\": [\"#EA98D2\", \"#659CCA\"]}\n },\n \"color\": {\n \"field\": \"gender\", \"type\": \"nominal\",\n \"scale\": {\"range\": [\"#EA98D2\", \"#659CCA\"]}\n }\n },\n \"data\": {\"url\": \"data/population.json\"}\n });\n\n const colorMixins = color(model);\n assert.isUndefined(colorMixins.stroke);\n assert.deepEqual(colorMixins.fill, {\"field\": \"gender\", \"scale\": \"fill\"});\n assert.equal(logger.warns[0], log.message.droppingColor('encoding', {fill: true}));\n }));\n\n it('ignores color property if fill is specified', log.wrap((logger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": {\"type\": \"point\", \"color\": \"red\"},\n \"encoding\": {\n \"x\": {\n \"field\": \"gender\", \"type\": \"nominal\",\n \"scale\": {\"rangeStep\": 6},\n \"axis\": null\n },\n \"fill\": {\n \"field\": \"gender\", \"type\": \"nominal\",\n \"scale\": {\"range\": [\"#EA98D2\", \"#659CCA\"]}\n }\n },\n \"data\": {\"url\": \"data/population.json\"}\n });\n\n const colorMixins = color(model);\n assert.isUndefined(colorMixins.stroke);\n assert.deepEqual(colorMixins.fill, {\"field\": \"gender\", \"scale\": \"fill\"});\n assert.equal(logger.warns[0], log.message.droppingColor('property', {fill: true}));\n }));\n\n it('should apply stroke property over color property', log.wrap((logger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": {\"type\": \"point\", \"color\": \"red\", \"stroke\": \"blue\"},\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\", \"type\": \"quantitative\"}\n }\n });\n const props = color(model);\n assert.deepEqual(props.stroke, {value: \"blue\"});\n assert.equal(logger.warns[0], log.message.droppingColor('property', {stroke: true}));\n }));\n\n it('should apply ignore color property when fill is specified', log.wrap((logger) => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": {\"type\": \"point\", \"color\": \"red\", \"fill\": \"blue\"},\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\", \"type\": \"quantitative\"}\n }\n });\n const props = color(model);\n assert.isUndefined(props.stroke);\n assert.equal(logger.warns[0], log.message.droppingColor('property', {fill: true}));\n }));\n\n it('should apply color property', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": {\"type\": \"point\", \"color\": \"red\"},\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\", \"type\": \"quantitative\"}\n }\n });\n const props = color(model);\n assert.deepEqual(props.stroke, {value: \"red\"});\n });\n\n it('should apply color from mark-specific config over general mark config', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\", \"type\": \"quantitative\"}\n },\n \"config\": {\"mark\": {\"color\": \"blue\"}, \"point\": {\"color\": \"red\"}}\n });\n const props = color(model);\n assert.deepEqual(props.stroke, {value: \"red\"});\n });\n\n it('should apply stroke mark config over color mark config', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\", \"type\": \"quantitative\"}\n },\n \"config\": {\"mark\": {\"color\": \"red\", \"stroke\": \"blue\"}}\n });\n const props = color(model);\n assert.deepEqual(props.stroke, {value: \"blue\"});\n });\n\n it('should apply stroke mark config over color mark config', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\", \"type\": \"quantitative\"}\n },\n \"config\": {\"point\": {\"color\": \"red\", \"stroke\": \"blue\"}}\n });\n const props = color(model);\n assert.deepEqual(props.stroke, {value: \"blue\"});\n });\n });\n\n describe('tooltip()', () => {\n it('generates tooltip object signal for an array of tooltip fields', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"tooltip\": [\n {\"field\": \"Horsepower\", \"type\": \"quantitative\"},\n {\"field\": \"Acceleration\", \"type\": \"quantitative\"}\n ]\n }\n });\n const props = tooltip(model);\n assert.deepEqual(props.tooltip, {signal: '{\"Horsepower\": format(datum[\"Horsepower\"], \"\"), \"Acceleration\": format(datum[\"Acceleration\"], \"\")}'});\n });\n });\n\n describe('midPoint()', function () {\n it('should return correctly for lat/lng', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\n \"url\": \"data/zipcodes.csv\",\n \"format\": {\n \"type\": \"csv\"\n }\n },\n \"mark\": \"point\",\n \"encoding\": {\n \"longitude\": {\n \"field\": \"longitude\",\n \"type\": \"quantitative\"\n },\n \"latitude\": {\n \"field\": \"latitude\",\n \"type\": \"quantitative\"\n }\n }\n });\n\n [X, Y].forEach((channel) => {\n const mixins = pointPosition(channel, model, 'zeroOrMin');\n assert.equal(mixins[channel].field, model.getName(channel));\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/point.test.d.ts b/build/test/compile/mark/point.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/point.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/point.test.js b/build/test/compile/mark/point.test.js new file mode 100644 index 0000000000..f9dd289b66 --- /dev/null +++ b/build/test/compile/mark/point.test.js @@ -0,0 +1,273 @@ +/* tslint:disable quotemark */ +import * as tslib_1 from "tslib"; +import { assert } from 'chai'; +import { COLOR, SHAPE, SIZE, X, Y } from '../../../src/channel'; +import { circle, point, square } from '../../../src/compile/mark/point'; +import { defaultMarkConfig } from '../../../src/mark'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('Mark: Point', function () { + function pointXY(moreEncoding) { + if (moreEncoding === void 0) { moreEncoding = {}; } + return { + "mark": "point", + "encoding": tslib_1.__assign({ "x": { "field": "year", "type": "ordinal" }, "y": { "field": "yield", "type": "quantitative" } }, moreEncoding), + "data": { "url": "data/barley.json" } + }; + } + describe('with x', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { "x": { "field": "year", "type": "ordinal" } }, + "data": { "url": "data/barley.json" } + }); + var props = point.encodeEntry(model); + it('should be centered on y', function () { + assert.deepEqual(props.y, { + mult: 0.5, + signal: 'height' + }); + }); + it('should scale on x', function () { + assert.deepEqual(props.x, { scale: X, field: 'year' }); + }); + }); + describe('with stacked x', function () { + // This is a simplified example for stacked point. + // In reality this will be used as stacked's overlayed marker + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = point.encodeEntry(model); + it('should use stack_end on x', function () { + assert.deepEqual(props.x, { scale: X, field: 'sum_a_end' }); + }); + }); + describe('with y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { "y": { "field": "year", "type": "ordinal" } }, + "data": { "url": "data/barley.json" } + }); + var props = point.encodeEntry(model); + it('should be centered on x', function () { + assert.deepEqual(props.x, { + mult: 0.5, + signal: 'width' + }); + }); + it('should scale on y', function () { + assert.deepEqual(props.y, { scale: Y, field: 'year' }); + }); + }); + describe('with stacked y', function () { + // This is a simplified example for stacked point. + // In reality this will be used as stacked's overlayed marker + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "y": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = point.encodeEntry(model); + it('should use stack_end on y', function () { + assert.deepEqual(props.y, { scale: Y, field: 'sum_a_end' }); + }); + }); + describe('with x and y', function () { + var model = parseUnitModelWithScaleAndLayoutSize(pointXY()); + var props = point.encodeEntry(model); + it('should scale on x', function () { + assert.deepEqual(props.x, { scale: X, field: 'year' }); + }); + it('should scale on y', function () { + assert.deepEqual(props.y, { scale: Y, field: 'yield' }); + }); + it('should be an unfilled circle', function () { + assert.deepEqual(props.fill, { value: 'transparent' }); + assert.deepEqual(props.stroke, { value: defaultMarkConfig.color }); + }); + }); + describe('with band x and quantitative y', function () { + it('should offset band position by half band', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/barley.json" }, + "mark": "point", + "encoding": { + "x": { "field": "year", "type": "ordinal", "scale": { "type": "band" } }, + "y": { "field": "yield", "type": "quantitative" } + } + }); + var props = point.encodeEntry(model); + assert.deepEqual(props.x, { scale: 'x', field: 'year', band: 0.5 }); + }); + }); + describe('with x, y, size', function () { + var model = parseUnitModelWithScaleAndLayoutSize(pointXY({ + "size": { "aggregate": "count", "type": "quantitative" } + })); + var props = point.encodeEntry(model); + it('should have scale for size', function () { + assert.deepEqual(props.size, { scale: SIZE, field: 'count_*' }); + }); + }); + describe('with x, y, color', function () { + var model = parseUnitModelWithScaleAndLayoutSize(pointXY({ + "color": { "field": "yield", "type": "quantitative" } + })); + var props = point.encodeEntry(model); + it('should have scale for color', function () { + assert.deepEqual(props.stroke, { scale: COLOR, field: 'yield' }); + }); + }); + describe('with x, y, and condition-only color', function () { + var model = parseUnitModelWithScaleAndLayoutSize(tslib_1.__assign({}, pointXY({ + "color": { "condition": { "selection": "test", "field": "yield", "type": "quantitative" } } + }), { selection: { test: { type: 'single' } } })); + model.parseSelection(); + var props = point.encodeEntry(model); + it('should have one condition for color with scale for "yield"', function () { + assert.isArray(props.stroke); + assert.equal(props.stroke['length'], 2); + assert.equal(props.stroke[0].scale, COLOR); + assert.equal(props.stroke[0].field, 'yield'); + }); + }); + describe('with x, y, and condition-only color', function () { + var model = parseUnitModelWithScaleAndLayoutSize(tslib_1.__assign({}, pointXY({ + "color": { "condition": { "test": "true", "field": "yield", "type": "quantitative" } } + }))); + model.parseSelection(); + var props = point.encodeEntry(model); + it('should have one condition for color with scale for "yield"', function () { + assert.isArray(props.stroke); + assert.equal(props.stroke['length'], 2); + assert.equal(props.stroke[0].test, "true"); + assert.equal(props.stroke[1].value, "#4c78a8"); + }); + }); + describe('with x, y, shape', function () { + var model = parseUnitModelWithScaleAndLayoutSize(pointXY({ + "shape": { "field": "site", "type": "nominal" } + })); + var props = point.encodeEntry(model); + it('should have scale for shape', function () { + assert.deepEqual(props.shape, { scale: SHAPE, field: 'site' }); + }); + }); + describe('with constant color, shape, and size', function () { + var model = parseUnitModelWithScaleAndLayoutSize(pointXY({ + "shape": { "value": "circle" }, + "color": { "value": "red" }, + "size": { "value": 23 } + })); + var props = point.encodeEntry(model); + it('should correct shape, color and size', function () { + assert.deepEqual(props.shape, { value: "circle" }); + assert.deepEqual(props.stroke, { value: "red" }); + assert.deepEqual(props.size, { value: 23 }); + }); + }); + describe('with tooltip', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "tooltip": { "value": "foo" } + } + }); + var props = point.encodeEntry(model); + it('should pass tooltip value to encoding', function () { + assert.deepEqual(props.tooltip, { value: "foo" }); + }); + }); + describe('with href', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "point", + "encoding": { + "href": { "value": "https://idl.cs.washington.edu/" } + } + }); + var props = point.encodeEntry(model); + it('should pass href value to encoding', function () { + assert.deepEqual(props.href, { value: 'https://idl.cs.washington.edu/' }); + }); + }); +}); +describe('Mark: Square', function () { + it('should have correct shape', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "square", + "encoding": { + "color": { "value": "blue" } + } + }); + var props = square.encodeEntry(model); + assert.propertyVal(props.shape, 'value', 'square'); + }); + it('should be filled by default', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "square", + "encoding": { + "color": { "value": "blue" } + } + }); + var props = square.encodeEntry(model); + assert.propertyVal(props.fill, 'value', 'blue'); + }); + it('with config.mark.filled:false should have transparent fill', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "square", + "encoding": { + "color": { "value": "blue" } + }, + "config": { + "mark": { + "filled": false + } + } + }); + var props = square.encodeEntry(model); + assert.propertyVal(props.stroke, 'value', 'blue'); + assert.propertyVal(props.fill, 'value', 'transparent'); + }); +}); +describe('Mark: Circle', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "circle", + "encoding": { + "color": { "value": "blue" } + } + }); + var props = circle.encodeEntry(model); + it('should have correct shape', function () { + assert.propertyVal(props.shape, 'value', 'circle'); + }); + it('should be filled by default', function () { + assert.propertyVal(props.fill, 'value', 'blue'); + }); + it('with config.mark.filled:false should have transparent fill', function () { + var filledCircleModel = parseUnitModelWithScaleAndLayoutSize({ + "mark": "circle", + "encoding": { + "color": { "value": "blue" } + }, + "config": { + "mark": { + "filled": false + } + } + }); + var filledCircleProps = circle.encodeEntry(filledCircleModel); + assert.propertyVal(filledCircleProps.stroke, 'value', 'blue'); + assert.propertyVal(filledCircleProps.fill, 'value', 'transparent'); + }); +}); +//# sourceMappingURL=point.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/point.test.js.map b/build/test/compile/mark/point.test.js.map new file mode 100644 index 0000000000..41b4b56610 --- /dev/null +++ b/build/test/compile/mark/point.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"point.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/point.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport {COLOR, SHAPE, SIZE, X, Y} from '../../../src/channel';\nimport {circle, point, square} from '../../../src/compile/mark/point';\nimport {Encoding} from '../../../src/encoding';\nimport {defaultMarkConfig} from '../../../src/mark';\nimport {NormalizedUnitSpec} from '../../../src/spec';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('Mark: Point', function() {\n\n function pointXY(moreEncoding: Encoding = {}): NormalizedUnitSpec {\n return {\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"year\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"yield\", \"type\": \"quantitative\"},\n ...moreEncoding,\n },\n \"data\": {\"url\": \"data/barley.json\"}\n };\n }\n\n describe('with x', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\"x\": {\"field\": \"year\", \"type\": \"ordinal\"}},\n \"data\": {\"url\": \"data/barley.json\"}\n });\n\n const props = point.encodeEntry(model);\n\n it('should be centered on y', function() {\n assert.deepEqual(props.y, {\n mult: 0.5,\n signal: 'height'\n });\n });\n\n it('should scale on x', function() {\n assert.deepEqual(props.x, {scale: X, field: 'year'});\n });\n });\n\n describe('with stacked x', function() {\n // This is a simplified example for stacked point.\n // In reality this will be used as stacked's overlayed marker\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"b\", \"type\": \"ordinal\"}\n },\n \"data\": {\"url\": \"data/barley.json\"},\n \"config\": {\"stack\": \"zero\"}\n });\n\n const props = point.encodeEntry(model);\n\n it('should use stack_end on x', function() {\n assert.deepEqual(props.x, {scale: X, field: 'sum_a_end'});\n });\n });\n\n describe('with y', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\"y\": {\"field\": \"year\", \"type\": \"ordinal\"}},\n \"data\": {\"url\": \"data/barley.json\"}\n });\n\n const props = point.encodeEntry(model);\n\n it('should be centered on x', function() {\n assert.deepEqual(props.x, {\n mult: 0.5,\n signal: 'width'\n });\n });\n\n it('should scale on y', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'year'});\n });\n });\n\n describe('with stacked y', function() {\n // This is a simplified example for stacked point.\n // In reality this will be used as stacked's overlayed marker\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"y\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"b\", \"type\": \"ordinal\"}\n },\n \"data\": {\"url\": \"data/barley.json\"},\n \"config\": {\"stack\": \"zero\"}\n });\n\n const props = point.encodeEntry(model);\n\n it('should use stack_end on y', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'sum_a_end'});\n });\n });\n\n describe('with x and y', function() {\n const model = parseUnitModelWithScaleAndLayoutSize(pointXY());\n const props = point.encodeEntry(model);\n\n it('should scale on x', function() {\n assert.deepEqual(props.x, {scale: X, field: 'year'});\n });\n\n it('should scale on y', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'yield'});\n });\n\n it('should be an unfilled circle', function() {\n assert.deepEqual(props.fill, {value: 'transparent'});\n assert.deepEqual(props.stroke, {value: defaultMarkConfig.color});\n });\n });\n\n describe('with band x and quantitative y', () => {\n it('should offset band position by half band', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": \"point\",\n \"encoding\":{\n \"x\": {\"field\": \"year\", \"type\": \"ordinal\", \"scale\": {\"type\": \"band\"}},\n \"y\": {\"field\": \"yield\", \"type\": \"quantitative\"}\n }\n });\n const props = point.encodeEntry(model);\n assert.deepEqual(props.x, {scale: 'x', field: 'year', band: 0.5});\n });\n });\n\n describe('with x, y, size', function () {\n const model = parseUnitModelWithScaleAndLayoutSize(pointXY({\n \"size\": {\"aggregate\": \"count\", \"type\": \"quantitative\"}\n }));\n const props = point.encodeEntry(model);\n\n it('should have scale for size', function () {\n assert.deepEqual(props.size, {scale: SIZE, field: 'count_*'});\n });\n });\n\n describe('with x, y, color', function () {\n const model = parseUnitModelWithScaleAndLayoutSize(pointXY({\n \"color\": {\"field\": \"yield\", \"type\": \"quantitative\"}\n }));\n const props = point.encodeEntry(model);\n\n it('should have scale for color', function () {\n assert.deepEqual(props.stroke, {scale: COLOR, field: 'yield'});\n });\n });\n\n describe('with x, y, and condition-only color', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n ...pointXY({\n \"color\": {\"condition\": {\"selection\": \"test\", \"field\": \"yield\", \"type\": \"quantitative\"}}\n }),\n selection: {test: {type: 'single'}}\n });\n model.parseSelection();\n const props = point.encodeEntry(model);\n\n it('should have one condition for color with scale for \"yield\"', function () {\n assert.isArray(props.stroke);\n assert.equal(props.stroke['length'], 2);\n assert.equal(props.stroke[0].scale, COLOR);\n assert.equal(props.stroke[0].field, 'yield');\n });\n });\n\n describe('with x, y, and condition-only color', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n ...pointXY({\n \"color\": {\"condition\": {\"test\": \"true\", \"field\": \"yield\", \"type\": \"quantitative\"}}\n })\n });\n model.parseSelection();\n const props = point.encodeEntry(model);\n\n it('should have one condition for color with scale for \"yield\"', function () {\n assert.isArray(props.stroke);\n assert.equal(props.stroke['length'], 2);\n assert.equal(props.stroke[0].test, \"true\");\n assert.equal(props.stroke[1].value, \"#4c78a8\");\n });\n });\n\n describe('with x, y, shape', function () {\n const model = parseUnitModelWithScaleAndLayoutSize(pointXY({\n \"shape\": {\"field\": \"site\", \"type\": \"nominal\"}\n }));\n const props = point.encodeEntry(model);\n\n it('should have scale for shape', function () {\n assert.deepEqual(props.shape, {scale: SHAPE, field: 'site'});\n });\n });\n\n describe('with constant color, shape, and size', function() {\n const model = parseUnitModelWithScaleAndLayoutSize(pointXY({\n \"shape\": {\"value\": \"circle\"},\n \"color\": {\"value\": \"red\"},\n \"size\": {\"value\": 23}\n }));\n const props = point.encodeEntry(model);\n it('should correct shape, color and size', function () {\n assert.deepEqual(props.shape, {value: \"circle\"});\n assert.deepEqual(props.stroke, {value: \"red\"});\n assert.deepEqual(props.size, {value: 23});\n });\n });\n\n describe('with tooltip', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"tooltip\": {\"value\": \"foo\"}\n }\n });\n const props = point.encodeEntry(model);\n\n it('should pass tooltip value to encoding', () => {\n assert.deepEqual(props.tooltip, {value: \"foo\"});\n });\n });\n\n describe('with href', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"point\",\n \"encoding\": {\n \"href\": {\"value\": \"https://idl.cs.washington.edu/\"}\n }\n });\n const props = point.encodeEntry(model);\n\n it('should pass href value to encoding', () => {\n assert.deepEqual(props.href, {value: 'https://idl.cs.washington.edu/'});\n });\n });\n});\n\ndescribe('Mark: Square', function() {\n it('should have correct shape', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"square\",\n \"encoding\": {\n \"color\": {\"value\": \"blue\"}\n }\n });\n const props = square.encodeEntry(model);\n\n assert.propertyVal(props.shape, 'value', 'square');\n });\n\n it('should be filled by default', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"square\",\n \"encoding\": {\n \"color\": {\"value\": \"blue\"}\n }\n });\n const props = square.encodeEntry(model);\n\n assert.propertyVal(props.fill, 'value', 'blue');\n });\n\n it('with config.mark.filled:false should have transparent fill', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"square\",\n \"encoding\": {\n \"color\": {\"value\": \"blue\"}\n },\n \"config\" : {\n \"mark\" : {\n \"filled\" : false\n }\n }\n });\n\n const props = square.encodeEntry(model);\n\n assert.propertyVal(props.stroke, 'value', 'blue');\n assert.propertyVal(props.fill, 'value', 'transparent');\n });\n});\n\ndescribe('Mark: Circle', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"circle\",\n \"encoding\": {\n \"color\": {\"value\": \"blue\"}\n }\n });\n const props = circle.encodeEntry(model);\n\n it('should have correct shape', function() {\n assert.propertyVal(props.shape, 'value', 'circle');\n });\n\n it('should be filled by default', function() {\n assert.propertyVal(props.fill, 'value', 'blue');\n });\n\n it('with config.mark.filled:false should have transparent fill', function() {\n const filledCircleModel = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"circle\",\n \"encoding\": {\n \"color\": {\"value\": \"blue\"}\n },\n \"config\" : {\n \"mark\" : {\n \"filled\" : false\n }\n }\n });\n\n const filledCircleProps = circle.encodeEntry(filledCircleModel);\n\n assert.propertyVal(filledCircleProps.stroke, 'value', 'blue');\n assert.propertyVal(filledCircleProps.fill, 'value', 'transparent');\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/rect.test.d.ts b/build/test/compile/mark/rect.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/rect.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/rect.test.js b/build/test/compile/mark/rect.test.js new file mode 100644 index 0000000000..2d1f035dab --- /dev/null +++ b/build/test/compile/mark/rect.test.js @@ -0,0 +1,137 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { rect } from '../../../src/compile/mark/rect'; +import * as log from '../../../src/log'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('Mark: Rect', function () { + describe('simple vertical', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = rect.encodeEntry(model); + it('should draw bar, with y from zero to field value and x band', function () { + assert.deepEqual(props.x, { scale: 'x', field: 'Origin' }); + assert.deepEqual(props.width, { scale: 'x', band: true }); + assert.deepEqual(props.y, { scale: 'y', field: 'mean_Acceleration' }); + assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + assert.isUndefined(props.height); + }); + }); + describe('simple horizontal', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = rect.encodeEntry(model); + it('should draw bar from zero to field value and y band', function () { + assert.deepEqual(props.y, { scale: 'y', field: 'Origin' }); + assert.deepEqual(props.height, { scale: 'y', band: true }); + assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + assert.isUndefined(props.width); + }); + }); + describe('simple horizontal with size field', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" }, + "size": { "aggregate": "mean", "field": "Horsepower", "type": "quantitative" } + } + }); + var props = rect.encodeEntry(model); + log.wrap(function (localLogger) { + it('should draw bar from zero to field value and with band value for x/width', function () { + assert.deepEqual(props.y, { scale: 'y', field: 'Origin' }); + assert.deepEqual(props.height, { scale: 'y', band: true }); + assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + assert.isUndefined(props.width); + }); + it('should throw warning', function () { + assert.equal(localLogger.warns[0], log.message.cannotApplySizeToNonOrientedMark('rect')); + }); + }); + }); + describe('horizontal binned', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "y": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = rect.encodeEntry(model); + it('should draw bar with y and y2', function () { + assert.deepEqual(props.y2, { scale: 'y', field: 'bin_maxbins_10_Horsepower' }); + assert.deepEqual(props.y, { scale: 'y', field: 'bin_maxbins_10_Horsepower_end' }); + assert.isUndefined(props.height); + }); + }); + describe('vertical binned', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "x": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "y": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = rect.encodeEntry(model); + it('should draw bar with x and x2', function () { + assert.deepEqual(props.x2, { scale: 'x', field: 'bin_maxbins_10_Horsepower' }); + assert.deepEqual(props.x, { scale: 'x', field: 'bin_maxbins_10_Horsepower_end' }); + assert.isUndefined(props.width); + }); + }); + describe('simple ranged', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "y": { "aggregate": "min", "field": 'Horsepower', "type": "quantitative" }, + "y2": { "aggregate": "max", "field": 'Horsepower', "type": "quantitative" }, + "x": { "aggregate": "min", "field": 'Acceleration', "type": "quantitative" }, + "x2": { "aggregate": "max", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = rect.encodeEntry(model); + it('should draw rectangle with x, x2, y, y2', function () { + assert.deepEqual(props.x, { scale: 'x', field: 'min_Acceleration' }); + assert.deepEqual(props.x2, { scale: 'x', field: 'max_Acceleration' }); + assert.deepEqual(props.y, { scale: 'y', field: 'min_Horsepower' }); + assert.deepEqual(props.y2, { scale: 'y', field: 'max_Horsepower' }); + }); + }); + describe('simple heatmap', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { "url": "data/cars.json" }, + "mark": "rect", + "encoding": { + "y": { "field": "Origin", "type": "ordinal" }, + "x": { "field": "Cylinders", "type": "ordinal" }, + "color": { "aggregate": "mean", "field": "Horsepower", "type": "quantitative" } + } + }); + var props = rect.encodeEntry(model); + it('should draw rect with x and y bands', function () { + assert.deepEqual(props.x, { scale: 'x', field: 'Cylinders' }); + assert.deepEqual(props.width, { scale: 'x', band: true }); + assert.deepEqual(props.y, { scale: 'y', field: 'Origin' }); + assert.deepEqual(props.height, { scale: 'y', band: true }); + }); + }); +}); +//# sourceMappingURL=rect.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/rect.test.js.map b/build/test/compile/mark/rect.test.js.map new file mode 100644 index 0000000000..cd459284f3 --- /dev/null +++ b/build/test/compile/mark/rect.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rect.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/rect.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\nimport {assert} from 'chai';\nimport {rect} from '../../../src/compile/mark/rect';\nimport * as log from '../../../src/log';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('Mark: Rect', function() {\n describe('simple vertical', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"rect\",\n \"encoding\": {\n \"x\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"y\": {\"type\": \"quantitative\", \"field\": 'Acceleration', \"aggregate\": \"mean\"}\n }\n });\n const props = rect.encodeEntry(model);\n\n it('should draw bar, with y from zero to field value and x band', function() {\n assert.deepEqual(props.x, {scale: 'x', field: 'Origin'});\n assert.deepEqual(props.width, {scale: 'x', band: true});\n assert.deepEqual(props.y, {scale: 'y', field: 'mean_Acceleration'});\n assert.deepEqual(props.y2, {scale: 'y', value: 0});\n assert.isUndefined(props.height);\n });\n });\n\n describe('simple horizontal', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"rect\",\n \"encoding\": {\n \"y\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = rect.encodeEntry(model);\n\n it('should draw bar from zero to field value and y band', function() {\n assert.deepEqual(props.y, {scale: 'y', field: 'Origin'});\n assert.deepEqual(props.height, {scale: 'y', band: true});\n assert.deepEqual(props.x, {scale: 'x', field: 'mean_Acceleration'});\n assert.deepEqual(props.x2, {scale: 'x', value: 0});\n assert.isUndefined(props.width);\n });\n });\n\n describe('simple horizontal with size field', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"rect\",\n \"encoding\": {\n \"y\": {\"field\": \"Origin\", \"type\": \"nominal\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"},\n \"size\": {\"aggregate\": \"mean\", \"field\": \"Horsepower\", \"type\": \"quantitative\"}\n }\n });\n const props = rect.encodeEntry(model);\n\n log.wrap((localLogger) => {\n it('should draw bar from zero to field value and with band value for x/width', function() {\n assert.deepEqual(props.y, {scale: 'y', field: 'Origin'});\n assert.deepEqual(props.height, {scale: 'y', band: true});\n assert.deepEqual(props.x, {scale: 'x', field: 'mean_Acceleration'});\n assert.deepEqual(props.x2, {scale: 'x', value: 0});\n assert.isUndefined(props.width);\n });\n\n it('should throw warning', ()=> {\n assert.equal(localLogger.warns[0], log.message.cannotApplySizeToNonOrientedMark('rect'));\n });\n });\n });\n\n describe('horizontal binned', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"rect\",\n \"encoding\": {\n \"y\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"quantitative\"},\n \"x\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = rect.encodeEntry(model);\n\n it('should draw bar with y and y2', function() {\n assert.deepEqual(props.y2, {scale: 'y', field: 'bin_maxbins_10_Horsepower'});\n assert.deepEqual(props.y, {scale: 'y', field: 'bin_maxbins_10_Horsepower_end'});\n assert.isUndefined(props.height);\n });\n });\n\n describe('vertical binned', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"rect\",\n \"encoding\": {\n \"x\": {\"bin\": true, \"field\": 'Horsepower', \"type\": \"quantitative\"},\n \"y\": {\"aggregate\": \"mean\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = rect.encodeEntry(model);\n\n it('should draw bar with x and x2', function() {\n assert.deepEqual(props.x2, {scale: 'x', field: 'bin_maxbins_10_Horsepower'});\n assert.deepEqual(props.x, {scale: 'x', field: 'bin_maxbins_10_Horsepower_end'});\n assert.isUndefined(props.width);\n });\n });\n\n\n describe('simple ranged', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": 'data/cars.json'},\n \"mark\": \"rect\",\n \"encoding\": {\n \"y\": {\"aggregate\": \"min\", \"field\": 'Horsepower', \"type\": \"quantitative\"},\n \"y2\": {\"aggregate\": \"max\", \"field\": 'Horsepower', \"type\": \"quantitative\"},\n \"x\": {\"aggregate\": \"min\", \"field\": 'Acceleration', \"type\": \"quantitative\"},\n \"x2\": {\"aggregate\": \"max\", \"field\": 'Acceleration', \"type\": \"quantitative\"}\n }\n });\n const props = rect.encodeEntry(model);\n\n it('should draw rectangle with x, x2, y, y2', function() {\n assert.deepEqual(props.x, {scale: 'x', field: 'min_Acceleration'});\n assert.deepEqual(props.x2, {scale: 'x', field: 'max_Acceleration'});\n assert.deepEqual(props.y, {scale: 'y', field: 'min_Horsepower'});\n assert.deepEqual(props.y2, {scale: 'y', field: 'max_Horsepower'});\n });\n });\n\n describe('simple heatmap', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\"url\": \"data/cars.json\"},\n \"mark\": \"rect\",\n \"encoding\": {\n \"y\": {\"field\": \"Origin\", \"type\": \"ordinal\"},\n \"x\": {\"field\": \"Cylinders\", \"type\": \"ordinal\"},\n \"color\": {\"aggregate\": \"mean\", \"field\": \"Horsepower\", \"type\": \"quantitative\"}\n }\n });\n const props = rect.encodeEntry(model);\n\n it('should draw rect with x and y bands', function() {\n assert.deepEqual(props.x, {scale: 'x', field: 'Cylinders'});\n assert.deepEqual(props.width, {scale: 'x', band: true});\n assert.deepEqual(props.y, {scale: 'y', field: 'Origin'});\n assert.deepEqual(props.height, {scale: 'y', band: true});\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/rule.test.d.ts b/build/test/compile/mark/rule.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/rule.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/rule.test.js b/build/test/compile/mark/rule.test.js new file mode 100644 index 0000000000..b49a9b77f5 --- /dev/null +++ b/build/test/compile/mark/rule.test.js @@ -0,0 +1,213 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { COLOR, X, Y } from '../../../src/channel'; +import { rule } from '../../../src/compile/mark/rule'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('Mark: Rule', function () { + describe('without encoding', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": {} + }); + var props = rule.encodeEntry(model); + it('should not show anything', function () { + assert.isUndefined(props.x); + assert.isUndefined(props.y); + }); + }); + describe('with x-only', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { "x": { "field": "a", "type": "quantitative" } } + }); + var props = rule.encodeEntry(model); + it('should create vertical rule that fits height', function () { + assert.deepEqual(props.x, { scale: X, field: 'a' }); + assert.deepEqual(props.y, { field: { group: 'height' } }); + assert.deepEqual(props.y2, { value: 0 }); + }); + }); + describe('with y-only', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { "y": { "field": "a", "type": "quantitative" } } + }); + var props = rule.encodeEntry(model); + it('should create horizontal rule that fits height', function () { + assert.deepEqual(props.y, { scale: Y, field: 'a' }); + assert.deepEqual(props.x, { value: 0 }); + assert.deepEqual(props.x2, { field: { group: 'width' } }); + }); + }); + describe('with x and x2 only', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "x2": { "field": "a2", "type": "quantitative" } + } + }); + var props = rule.encodeEntry(model); + it('should create horizontal rule on the axis', function () { + assert.deepEqual(props.x, { scale: X, field: 'a' }); + assert.deepEqual(props.x2, { scale: X, field: 'a2' }); + assert.deepEqual(props.y, { + mult: 0.5, + signal: 'height' + }); + }); + }); + describe('with y and y2 only', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "field": "a", "type": "quantitative" }, + "y2": { "field": "a2", "type": "quantitative" } + } + }); + var props = rule.encodeEntry(model); + it('should create horizontal rules on the axis', function () { + assert.deepEqual(props.y, { scale: Y, field: 'a' }); + assert.deepEqual(props.y2, { scale: Y, field: 'a2' }); + assert.deepEqual(props.x, { + mult: 0.5, + signal: 'width' + }); + }); + }); + describe('with x, x2, and y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "x2": { "field": "a2", "type": "quantitative" }, + "y": { "field": "b", "type": "quantitative" } + } + }); + var props = rule.encodeEntry(model); + it('should create horizontal rules', function () { + assert.deepEqual(props.x, { scale: X, field: 'a' }); + assert.deepEqual(props.x2, { scale: X, field: 'a2' }); + assert.deepEqual(props.y, { scale: Y, field: 'b' }); + }); + }); + describe('with x, x2, y, and y2', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "x2": { "field": "a2", "type": "quantitative" }, + "y": { "field": "b", "type": "quantitative" }, + "y2": { "field": "b2", "type": "quantitative" } + } + }); + var props = rule.encodeEntry(model); + it('should create oblique rules', function () { + assert.deepEqual(props.x, { scale: X, field: 'a' }); + assert.deepEqual(props.x2, { scale: X, field: 'a2' }); + assert.deepEqual(props.y, { scale: Y, field: 'b' }); + assert.deepEqual(props.y2, { scale: Y, field: 'b2' }); + }); + }); + describe('with x and y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "quantitative" } + } + }); + var props = rule.encodeEntry(model); + it('should create oblique rules', function () { + assert.deepEqual(props.x, { scale: X, field: 'a' }); + assert.deepEqual(props.y, { scale: Y, field: 'b' }); + }); + }); + describe('with y, y2, and x', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "field": "a", "type": "quantitative" }, + "y2": { "field": "a2", "type": "quantitative" }, + "x": { "field": "b", "type": "quantitative" } + } + }); + var props = rule.encodeEntry(model); + it('should create vertical rules', function () { + assert.deepEqual(props.y, { scale: Y, field: 'a' }); + assert.deepEqual(props.y2, { scale: Y, field: 'a2' }); + assert.deepEqual(props.x, { scale: X, field: 'b' }); + }); + }); + describe('with nominal x, quantitative y with no y2', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" } + } + }); + var props = rule.encodeEntry(model); + it('should create vertical rule that emulates bar chart', function () { + assert.equal(model.markDef.orient, 'vertical'); + assert.deepEqual(props.x, { scale: X, field: 'a', band: 0.5 }); + assert.deepEqual(props.y, { scale: Y, field: 'b' }); + assert.deepEqual(props.y2, { scale: Y, value: 0 }); + }); + }); + describe('with nominal y, quantitative x with no y2', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "field": "a", "type": "ordinal" }, + "x": { "field": "b", "type": "quantitative" } + } + }); + var props = rule.encodeEntry(model); + it('should create horizontal rule that emulates bar chart', function () { + assert.equal(model.markDef.orient, 'horizontal'); + assert.deepEqual(props.x, { scale: X, field: 'b' }); + assert.deepEqual(props.x2, { scale: X, value: 0 }); + assert.deepEqual(props.y, { scale: Y, field: 'a', band: 0.5 }); + }); + }); + describe('horizontal stacked rule with color', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "y": { "field": "a", "type": "ordinal" }, + "x": { "aggregate": "sum", "field": "b", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" } + }, + "config": { + "stack": "zero" + } + }); + var props = rule.encodeEntry(model); + it('should have the correct value for x, x2, and color', function () { + assert.deepEqual(props.x, { scale: 'x', field: 'sum_b_end' }); + assert.deepEqual(props.x2, { scale: 'x', field: 'sum_b_start' }); + assert.deepEqual(props.stroke, { scale: COLOR, field: 'Origin' }); + }); + }); + describe('vertical stacked rule with color', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "aggregate": "sum", "field": "b", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" } + }, + "config": { + "stack": "zero" + } + }); + var props = rule.encodeEntry(model); + it('should have the correct value for y, y2, and color', function () { + assert.deepEqual(props.y, { scale: 'y', field: 'sum_b_end' }); + assert.deepEqual(props.y2, { scale: 'y', field: 'sum_b_start' }); + assert.deepEqual(props.stroke, { scale: COLOR, field: 'Origin' }); + }); + }); +}); +//# sourceMappingURL=rule.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/rule.test.js.map b/build/test/compile/mark/rule.test.js.map new file mode 100644 index 0000000000..b927023184 --- /dev/null +++ b/build/test/compile/mark/rule.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rule.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/rule.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport {COLOR, X, Y} from '../../../src/channel';\nimport {rule} from '../../../src/compile/mark/rule';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('Mark: Rule', function() {\n\n describe('without encoding', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {}\n });\n\n const props = rule.encodeEntry(model);\n\n it('should not show anything', function() {\n assert.isUndefined(props.x);\n assert.isUndefined(props.y);\n });\n });\n\n describe('with x-only', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\"x\": {\"field\": \"a\", \"type\": \"quantitative\"}}\n });\n\n const props = rule.encodeEntry(model);\n\n it('should create vertical rule that fits height', function() {\n assert.deepEqual(props.x, {scale: X, field: 'a'});\n assert.deepEqual(props.y, {field: {group: 'height'}});\n assert.deepEqual(props.y2, {value: 0});\n });\n });\n\n describe('with y-only', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\"y\": {\"field\": \"a\", \"type\": \"quantitative\"}}\n });\n\n const props = rule.encodeEntry(model);\n\n it('should create horizontal rule that fits height', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'a'});\n assert.deepEqual(props.x, {value: 0});\n assert.deepEqual(props.x2, {field: {group: 'width'}});\n });\n });\n\n describe('with x and x2 only', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"quantitative\"},\n \"x2\": {\"field\": \"a2\", \"type\": \"quantitative\"}\n }\n });\n\n const props = rule.encodeEntry(model);\n\n it('should create horizontal rule on the axis', function() {\n assert.deepEqual(props.x, {scale: X, field: 'a'});\n assert.deepEqual(props.x2, {scale: X, field: 'a2'});\n assert.deepEqual(props.y, {\n mult: 0.5,\n signal: 'height'\n });\n });\n });\n\n describe('with y and y2 only', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"field\": \"a\", \"type\": \"quantitative\"},\n \"y2\": {\"field\": \"a2\", \"type\": \"quantitative\"}\n }\n });\n\n const props = rule.encodeEntry(model);\n\n it('should create horizontal rules on the axis', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'a'});\n assert.deepEqual(props.y2, {scale: Y, field: 'a2'});\n assert.deepEqual(props.x, {\n mult: 0.5,\n signal: 'width'\n });\n });\n });\n\n describe('with x, x2, and y', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"quantitative\"},\n \"x2\": {\"field\": \"a2\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"b\", \"type\": \"quantitative\"}\n }\n });\n\n const props = rule.encodeEntry(model);\n\n it('should create horizontal rules', function () {\n assert.deepEqual(props.x, {scale: X, field: 'a'});\n assert.deepEqual(props.x2, {scale: X, field: 'a2'});\n assert.deepEqual(props.y, {scale: Y, field: 'b'});\n });\n });\n\n describe('with x, x2, y, and y2', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"quantitative\"},\n \"x2\": {\"field\": \"a2\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"b\", \"type\": \"quantitative\"},\n \"y2\": {\"field\": \"b2\", \"type\": \"quantitative\"}\n }\n });\n\n const props = rule.encodeEntry(model);\n\n it('should create oblique rules', function () {\n assert.deepEqual(props.x, {scale: X, field: 'a'});\n assert.deepEqual(props.x2, {scale: X, field: 'a2'});\n assert.deepEqual(props.y, {scale: Y, field: 'b'});\n assert.deepEqual(props.y2, {scale: Y, field: 'b2'});\n });\n });\n\n describe('with x and y', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"b\", \"type\": \"quantitative\"}\n }\n });\n\n const props = rule.encodeEntry(model);\n\n it('should create oblique rules', function () {\n assert.deepEqual(props.x, {scale: X, field: 'a'});\n assert.deepEqual(props.y, {scale: Y, field: 'b'});\n });\n });\n\n describe('with y, y2, and x', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"field\": \"a\", \"type\": \"quantitative\"},\n \"y2\": {\"field\": \"a2\", \"type\": \"quantitative\"},\n \"x\": {\"field\": \"b\", \"type\": \"quantitative\"}\n }\n });\n\n const props = rule.encodeEntry(model);\n\n it('should create vertical rules', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'a'});\n assert.deepEqual(props.y2, {scale: Y, field: 'a2'});\n assert.deepEqual(props.x, {scale: X, field: 'b'});\n });\n });\n\n describe('with nominal x, quantitative y with no y2', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"b\", \"type\": \"quantitative\"}\n }\n });\n\n const props = rule.encodeEntry(model);\n\n it('should create vertical rule that emulates bar chart', function() {\n assert.equal(model.markDef.orient, 'vertical');\n\n assert.deepEqual(props.x, {scale: X, field: 'a', band: 0.5});\n assert.deepEqual(props.y, {scale: Y, field: 'b'});\n assert.deepEqual(props.y2, {scale: Y, value: 0});\n });\n });\n\n describe('with nominal y, quantitative x with no y2', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"field\": \"a\", \"type\": \"ordinal\"},\n \"x\": {\"field\": \"b\", \"type\": \"quantitative\"}\n }\n });\n\n const props = rule.encodeEntry(model);\n\n it('should create horizontal rule that emulates bar chart', function() {\n assert.equal(model.markDef.orient, 'horizontal');\n\n assert.deepEqual(props.x, {scale: X, field: 'b'});\n assert.deepEqual(props.x2, {scale: X, value: 0});\n assert.deepEqual(props.y, {scale: Y, field: 'a', band: 0.5});\n });\n });\n\n\n describe('horizontal stacked rule with color', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"field\": \"a\", \"type\": \"ordinal\"},\n \"x\": {\"aggregate\": \"sum\", \"field\": \"b\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n },\n \"config\": {\n \"stack\": \"zero\"\n }\n });\n\n const props = rule.encodeEntry(model);\n\n it('should have the correct value for x, x2, and color', () => {\n assert.deepEqual(props.x, {scale: 'x', field: 'sum_b_end'});\n assert.deepEqual(props.x2, {scale: 'x', field: 'sum_b_start'});\n assert.deepEqual(props.stroke, {scale: COLOR, field: 'Origin'});\n });\n });\n\n describe('vertical stacked rule with color', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"ordinal\"},\n \"y\": {\"aggregate\": \"sum\", \"field\": \"b\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n },\n \"config\": {\n \"stack\": \"zero\"\n }\n });\n\n const props = rule.encodeEntry(model);\n\n it('should have the correct value for y, y2, and color', () => {\n assert.deepEqual(props.y, {scale: 'y', field: 'sum_b_end'});\n assert.deepEqual(props.y2, {scale: 'y', field: 'sum_b_start'});\n assert.deepEqual(props.stroke, {scale: COLOR, field: 'Origin'});\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/text.test.d.ts b/build/test/compile/mark/text.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/text.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/text.test.js b/build/test/compile/mark/text.test.js new file mode 100644 index 0000000000..5ced68f9b1 --- /dev/null +++ b/build/test/compile/mark/text.test.js @@ -0,0 +1,163 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { X, Y } from '../../../src/channel'; +import { text } from '../../../src/compile/mark/text'; +import { parseModelWithScale, parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('Mark: Text', function () { + describe('with stacked x', function () { + // This is a simplified example for stacked text. + // In reality this will be used as stacked's overlayed marker + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "text", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = text.encodeEntry(model); + it('should use stack_end on x', function () { + assert.deepEqual(props.x, { scale: X, field: 'sum_a_end' }); + }); + }); + describe('with stacked y', function () { + // This is a simplified example for stacked text. + // In reality this will be used as stacked's overlayed marker + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "text", + "encoding": { + "y": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = text.encodeEntry(model); + it('should use stack_end on y', function () { + assert.deepEqual(props.y, { scale: Y, field: 'sum_a_end' }); + }); + }); + describe('with quantitative and format', function () { + var spec = { + "mark": "text", + "encoding": { + "text": { "field": "foo", "type": "quantitative", "format": "d" } + } + }; + var model = parseUnitModelWithScaleAndLayoutSize(spec); + var props = text.encodeEntry(model); + it('should use number template', function () { + assert.deepEqual(props.text, { signal: "format(datum[\"foo\"], \"d\")" }); + }); + }); + describe('with binned quantitative', function () { + var spec = { + "mark": "text", + "encoding": { + "text": { "bin": true, "field": "foo", "type": "quantitative", "format": "d" } + } + }; + var model = parseUnitModelWithScaleAndLayoutSize(spec); + var props = text.encodeEntry(model); + it('should output correct bin range', function () { + assert.deepEqual(props.text, { signal: "datum[\"bin_maxbins_10_foo\"] === null || isNaN(datum[\"bin_maxbins_10_foo\"]) ? \"null\" : format(datum[\"bin_maxbins_10_foo\"], \"d\") + \" - \" + format(datum[\"bin_maxbins_10_foo_end\"], \"d\")" }); + }); + }); + describe('with temporal', function () { + var spec = { + "mark": "text", + "encoding": { + "text": { "field": "foo", "type": "temporal" } + } + }; + var model = parseUnitModelWithScaleAndLayoutSize(spec); + var props = text.encodeEntry(model); + it('should use date template', function () { + assert.deepEqual(props.text, { signal: "timeFormat(datum[\"foo\"], '')" }); + }); + }); + describe('with x, y, text (ordinal)', function () { + var spec = { + "mark": "text", + "encoding": { + "x": { "field": "Acceleration", "type": "ordinal" }, + "y": { "field": "Displacement", "type": "quantitative" }, + "text": { "field": "Origin", "type": "ordinal" }, + }, + "data": { "url": "data/cars.json" } + }; + var model = parseUnitModelWithScaleAndLayoutSize(spec); + var props = text.encodeEntry(model); + it('should scale on x', function () { + assert.deepEqual(props.x, { scale: X, field: 'Acceleration' }); + }); + it('should scale on y', function () { + assert.deepEqual(props.y, { scale: Y, field: 'Displacement' }); + }); + it('should be centered', function () { + assert.deepEqual(props.align, { value: "center" }); + }); + it('should map text without template', function () { + assert.deepEqual(props.text, { signal: "''+datum[\"Origin\"]" }); + }); + }); + describe('with size in mark def', function () { + var spec = { + "mark": { type: "text", size: 5 }, + "encoding": { + "text": { "field": "Origin", "type": "ordinal" }, + }, + "data": { "url": "data/cars.json" } + }; + var model = parseUnitModelWithScaleAndLayoutSize(spec); + var props = text.encodeEntry(model); + it('should map size to fontSize', function () { + assert.deepEqual(props.fontSize, { value: 5 }); + }); + }); + describe('with row, column, text, color, and size', function () { + var spec = { + "mark": "text", + "encoding": { + "row": { "field": "Origin", "type": "ordinal" }, + "column": { "field": "Cylinders", "type": "ordinal" }, + "text": { "field": "Acceleration", "type": "quantitative", "aggregate": "mean" }, + "color": { "field": "Acceleration", "type": "quantitative", "aggregate": "mean" }, + "size": { "field": "Acceleration", "type": "quantitative", "aggregate": "mean" } + }, + "data": { "url": "data/cars.json" } + }; + var model = parseModelWithScale(spec); + model.parseLayoutSize(); + var childModel = model.children[0]; + var props = text.encodeEntry(childModel); + it('should fit the view on x', function () { + assert.deepEqual(props.x, { signal: 'child_width', mult: 0.5 }); + }); + it('should center on y', function () { + assert.deepEqual(props.y, { + mult: 0.5, + signal: 'child_height' + }); + }); + it('should map text to expression', function () { + assert.deepEqual(props.text, { + signal: "format(datum[\"mean_Acceleration\"], \"\")" + }); + }); + it('should map color to fill', function () { + assert.deepEqual(props.fill, { + scale: 'color', + field: 'mean_Acceleration' + }); + }); + it('should map size to fontSize', function () { + assert.deepEqual(props.fontSize, { + scale: 'size', + field: 'mean_Acceleration' + }); + }); + }); +}); +//# sourceMappingURL=text.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/text.test.js.map b/build/test/compile/mark/text.test.js.map new file mode 100644 index 0000000000..ba96e69601 --- /dev/null +++ b/build/test/compile/mark/text.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"text.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/text.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\nimport {assert} from 'chai';\n\nimport {X, Y} from '../../../src/channel';\nimport {text} from '../../../src/compile/mark/text';\nimport {UnitModel} from '../../../src/compile/unit';\nimport {NormalizedUnitSpec, TopLevelSpec} from '../../../src/spec';\nimport {parseModelWithScale, parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\n\ndescribe('Mark: Text', function() {\n describe('with stacked x', function() {\n // This is a simplified example for stacked text.\n // In reality this will be used as stacked's overlayed marker\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"text\",\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"b\", \"type\": \"ordinal\"}\n },\n \"data\": {\"url\": \"data/barley.json\"},\n \"config\": {\"stack\": \"zero\"}\n });\n\n const props = text.encodeEntry(model);\n\n it('should use stack_end on x', function() {\n assert.deepEqual(props.x, {scale: X, field: 'sum_a_end'});\n });\n });\n\n describe('with stacked y', function() {\n // This is a simplified example for stacked text.\n // In reality this will be used as stacked's overlayed marker\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"text\",\n \"encoding\": {\n \"y\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"b\", \"type\": \"ordinal\"}\n },\n \"data\": {\"url\": \"data/barley.json\"},\n \"config\": {\"stack\": \"zero\"}\n });\n\n const props = text.encodeEntry(model);\n\n it('should use stack_end on y', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'sum_a_end'});\n });\n });\n\n describe('with quantitative and format', function() {\n const spec: NormalizedUnitSpec = {\n \"mark\": \"text\",\n \"encoding\": {\n \"text\": {\"field\": \"foo\", \"type\": \"quantitative\", \"format\": \"d\"}\n }\n };\n const model = parseUnitModelWithScaleAndLayoutSize(spec);\n const props = text.encodeEntry(model);\n\n it('should use number template', function() {\n assert.deepEqual(props.text, {signal: `format(datum[\"foo\"], \"d\")`});\n });\n });\n\n describe('with binned quantitative', function() {\n const spec: NormalizedUnitSpec = {\n \"mark\": \"text\",\n \"encoding\": {\n \"text\": {\"bin\": true, \"field\": \"foo\", \"type\": \"quantitative\", \"format\": \"d\"}\n }\n };\n const model = parseUnitModelWithScaleAndLayoutSize(spec);\n const props = text.encodeEntry(model);\n\n it('should output correct bin range', function() {\n assert.deepEqual(props.text, {signal: `datum[\"bin_maxbins_10_foo\"] === null || isNaN(datum[\"bin_maxbins_10_foo\"]) ? \"null\" : format(datum[\"bin_maxbins_10_foo\"], \"d\") + \" - \" + format(datum[\"bin_maxbins_10_foo_end\"], \"d\")`});\n });\n });\n\n describe('with temporal', function() {\n const spec: NormalizedUnitSpec = {\n \"mark\": \"text\",\n \"encoding\": {\n \"text\": {\"field\": \"foo\", \"type\": \"temporal\"}\n }\n };\n const model = parseUnitModelWithScaleAndLayoutSize(spec);\n const props = text.encodeEntry(model);\n\n it('should use date template', function() {\n assert.deepEqual(props.text, {signal: `timeFormat(datum[\"foo\"], '')`});\n });\n });\n\n describe('with x, y, text (ordinal)', function () {\n const spec: NormalizedUnitSpec = {\n \"mark\": \"text\",\n \"encoding\": {\n \"x\": {\"field\": \"Acceleration\", \"type\": \"ordinal\"},\n \"y\": {\"field\": \"Displacement\", \"type\": \"quantitative\"},\n \"text\": {\"field\": \"Origin\", \"type\": \"ordinal\"},\n },\n \"data\": {\"url\": \"data/cars.json\"}\n };\n const model = parseUnitModelWithScaleAndLayoutSize(spec);\n const props = text.encodeEntry(model);\n\n it('should scale on x', function() {\n assert.deepEqual(props.x, {scale: X, field: 'Acceleration'});\n });\n it('should scale on y', function() {\n assert.deepEqual(props.y, {scale: Y, field: 'Displacement'});\n });\n\n it('should be centered', function() {\n assert.deepEqual(props.align, {value: \"center\"});\n });\n\n it('should map text without template', function() {\n assert.deepEqual(props.text, {signal: `''+datum[\"Origin\"]`});\n });\n });\n\n describe('with size in mark def', function () {\n const spec: NormalizedUnitSpec = {\n \"mark\": {type: \"text\", size: 5},\n \"encoding\": {\n \"text\": {\"field\": \"Origin\", \"type\": \"ordinal\"},\n },\n \"data\": {\"url\": \"data/cars.json\"}\n };\n const model = parseUnitModelWithScaleAndLayoutSize(spec);\n const props = text.encodeEntry(model);\n\n it('should map size to fontSize', function () {\n assert.deepEqual(props.fontSize, {value: 5});\n });\n });\n\n describe('with row, column, text, color, and size', function() {\n const spec: TopLevelSpec = {\n \"mark\": \"text\",\n \"encoding\": {\n \"row\": {\"field\": \"Origin\", \"type\": \"ordinal\"},\n \"column\": {\"field\": \"Cylinders\", \"type\": \"ordinal\"},\n \"text\": {\"field\": \"Acceleration\", \"type\": \"quantitative\", \"aggregate\": \"mean\"},\n \"color\": {\"field\": \"Acceleration\", \"type\": \"quantitative\", \"aggregate\": \"mean\"},\n \"size\": {\"field\": \"Acceleration\", \"type\": \"quantitative\", \"aggregate\": \"mean\"}\n },\n \"data\": {\"url\": \"data/cars.json\"}\n };\n const model = parseModelWithScale(spec);\n model.parseLayoutSize();\n\n const childModel = model.children[0] as UnitModel;\n const props = text.encodeEntry(childModel);\n\n it('should fit the view on x', function() {\n assert.deepEqual(props.x, {signal: 'child_width', mult: 0.5});\n });\n\n it('should center on y', function() {\n assert.deepEqual(props.y, {\n mult: 0.5,\n signal: 'child_height'\n });\n });\n\n it('should map text to expression', function() {\n assert.deepEqual(props.text, {\n signal: `format(datum[\"mean_Acceleration\"], \"\")`\n });\n });\n\n it('should map color to fill', function() {\n assert.deepEqual(props.fill, {\n scale: 'color',\n field: 'mean_Acceleration'\n });\n });\n\n it('should map size to fontSize', function() {\n assert.deepEqual(props.fontSize, {\n scale: 'size',\n field: 'mean_Acceleration'\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/tick.test.d.ts b/build/test/compile/mark/tick.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/tick.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/tick.test.js b/build/test/compile/mark/tick.test.js new file mode 100644 index 0000000000..47d440a3aa --- /dev/null +++ b/build/test/compile/mark/tick.test.js @@ -0,0 +1,156 @@ +/* tslint:disable quotemark */ +// TODO: +// test mark-tick with the following test cases, +// looking at mark-point.test.ts as inspiration +// +// After finishing all test, make sure all lines in mark-tick.ts is tested +// (except the scaffold labels() method) +import { assert } from 'chai'; +import { SIZE, X, Y } from '../../../src/channel'; +import { tick } from '../../../src/compile/mark/tick'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('Mark: Tick', function () { + describe('with stacked x', function () { + // This is a simplified example for stacked tick. + // In reality this will be used as stacked's overlayed marker + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "tick", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = tick.encodeEntry(model); + it('should use stack_end on x', function () { + assert.deepEqual(props.xc, { scale: X, field: 'sum_a_end' }); + }); + }); + describe('with stacked y', function () { + // This is a simplified example for stacked tick. + // In reality this will be used as stacked's overlayed marker + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "tick", + "encoding": { + "y": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = tick.encodeEntry(model); + it('should use stack_end on y', function () { + assert.deepEqual(props.yc, { scale: Y, field: 'sum_a_end' }); + }); + }); + describe('with quantitative x', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + 'mark': 'tick', + 'encoding': { 'x': { 'field': 'Horsepower', 'type': 'quantitative' } }, + 'data': { 'url': 'data/cars.json' } + }); + var props = tick.encodeEntry(model); + it('should be centered on y', function () { + assert.deepEqual(props.yc, { + mult: 0.5, + signal: 'height' + }); + }); + it('should scale on x', function () { + assert.deepEqual(props.xc, { scale: X, field: 'Horsepower' }); + }); + it('width should tick thickness with orient vertical', function () { + assert.deepEqual(props.width, { value: 1 }); + }); + }); + describe('with quantitative y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + 'mark': 'tick', + 'encoding': { 'y': { 'field': 'Cylinders', 'type': 'quantitative' } }, + 'data': { 'url': 'data/cars.json' } + }); + var props = tick.encodeEntry(model); + it('should be centered on x', function () { + assert.deepEqual(props.xc, { + mult: 0.5, + signal: 'width' + }); + }); + it('should scale on y', function () { + assert.deepEqual(props.yc, { scale: Y, field: 'Cylinders' }); + }); + it('height should tick thickness with orient horizontal', function () { + assert.deepEqual(props.height, { value: 1 }); + }); + }); + describe('with quantitative x and ordinal y', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + 'mark': 'tick', + 'encoding': { + 'x': { 'field': 'Horsepower', 'type': 'quantitative' }, + 'y': { 'field': 'Cylinders', 'type': 'ordinal' } + }, + 'data': { 'url': 'data/cars.json' } + }); + var props = tick.encodeEntry(model); + it('should scale on x', function () { + assert.deepEqual(props.xc, { scale: X, field: 'Horsepower' }); + }); + it('should scale on y', function () { + assert.deepEqual(props.yc, { scale: Y, field: 'Cylinders' }); + }); + it('wiidth should be tick thickness with default orient vertical', function () { + assert.deepEqual(props.width, { value: 1 }); + }); + it('height should be matched to field with default orient vertical', function () { + assert.deepEqual(props.height, { value: 14 }); + }); + }); + describe('vertical ticks', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + 'mark': 'tick', + 'config': { 'mark': { 'orient': 'vertical' } }, + 'encoding': { + 'x': { 'field': 'Horsepower', 'type': 'quantitative' }, + 'y': { 'field': 'Cylinders', 'type': 'ordinal' }, + 'size': { 'field': 'Acceleration', 'type': 'quantitative' } + }, + 'data': { 'url': 'data/cars.json' }, + }); + var props = tick.encodeEntry(model); + it('maps size to height', function () { + assert.deepEqual(props.height, { 'field': 'Acceleration', 'scale': SIZE }); + }); + }); + describe('vertical ticks with size in mark def', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + 'mark': { 'type': 'tick', 'size': 5 }, + 'encoding': { + 'x': { 'field': 'Horsepower', 'type': 'quantitative' }, + 'y': { 'field': 'Cylinders', 'type': 'ordinal' } + }, + 'data': { 'url': 'data/cars.json' }, + }); + var props = tick.encodeEntry(model); + it('maps size to height in Vega', function () { + assert.deepEqual(props.height, { value: 5 }); + }); + }); + describe('vertical ticks (implicit)', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + 'mark': 'tick', + 'encoding': { + 'x': { 'field': 'Horsepower', 'type': 'quantitative' }, + 'y': { 'field': 'Cylinders', 'type': 'ordinal' }, + 'size': { 'field': 'Acceleration', 'type': 'quantitative' } + }, + 'data': { 'url': 'data/cars.json' }, + }); + var props = tick.encodeEntry(model); + it('maps size to height in Vega', function () { + assert.deepEqual(props.height, { 'field': 'Acceleration', 'scale': SIZE }); + }); + }); +}); +//# sourceMappingURL=tick.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/tick.test.js.map b/build/test/compile/mark/tick.test.js.map new file mode 100644 index 0000000000..e4f1c90164 --- /dev/null +++ b/build/test/compile/mark/tick.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tick.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/tick.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\n\n// TODO:\n// test mark-tick with the following test cases,\n// looking at mark-point.test.ts as inspiration\n//\n// After finishing all test, make sure all lines in mark-tick.ts is tested\n// (except the scaffold labels() method)\nimport {assert} from 'chai';\nimport {SIZE, X, Y} from '../../../src/channel';\nimport {tick} from '../../../src/compile/mark/tick';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('Mark: Tick', function() {\n describe('with stacked x', function() {\n // This is a simplified example for stacked tick.\n // In reality this will be used as stacked's overlayed marker\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"tick\",\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"b\", \"type\": \"ordinal\"}\n },\n \"data\": {\"url\": \"data/barley.json\"},\n \"config\": {\"stack\": \"zero\"}\n });\n\n const props = tick.encodeEntry(model);\n\n it('should use stack_end on x', function() {\n assert.deepEqual(props.xc, {scale: X, field: 'sum_a_end'});\n });\n });\n\n\n describe('with stacked y', function() {\n // This is a simplified example for stacked tick.\n // In reality this will be used as stacked's overlayed marker\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"tick\",\n \"encoding\": {\n \"y\": {\"aggregate\": \"sum\", \"field\": \"a\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"b\", \"type\": \"ordinal\"}\n },\n \"data\": {\"url\": \"data/barley.json\"},\n \"config\": {\"stack\": \"zero\"}\n });\n\n const props = tick.encodeEntry(model);\n\n it('should use stack_end on y', function() {\n assert.deepEqual(props.yc, {scale: Y, field: 'sum_a_end'});\n });\n });\n\n describe('with quantitative x', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n 'mark': 'tick',\n 'encoding': {'x': {'field': 'Horsepower', 'type': 'quantitative'}},\n 'data': {'url': 'data/cars.json'}\n });\n\n const props = tick.encodeEntry(model);\n it('should be centered on y', function() {\n assert.deepEqual(props.yc, {\n mult: 0.5,\n signal: 'height'\n });\n });\n\n it('should scale on x', function() {\n assert.deepEqual(props.xc, {scale: X, field: 'Horsepower'});\n });\n\n it('width should tick thickness with orient vertical', function() {\n assert.deepEqual(props.width, {value: 1});\n });\n });\n\n describe('with quantitative y', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n 'mark': 'tick',\n 'encoding': {'y': {'field': 'Cylinders','type': 'quantitative'}},\n 'data': {'url': 'data/cars.json'}\n });\n\n const props = tick.encodeEntry(model);\n it('should be centered on x', function() {\n assert.deepEqual(props.xc, {\n mult: 0.5,\n signal: 'width'\n });\n });\n\n it('should scale on y', function() {\n assert.deepEqual(props.yc, {scale: Y, field: 'Cylinders'});\n });\n\n it('height should tick thickness with orient horizontal', function() {\n assert.deepEqual(props.height, {value: 1});\n });\n });\n\n describe('with quantitative x and ordinal y', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n 'mark': 'tick',\n 'encoding':\n {\n 'x': {'field': 'Horsepower', 'type': 'quantitative'},\n 'y': {'field': 'Cylinders','type': 'ordinal'}\n },\n 'data': {'url': 'data/cars.json'}\n });\n const props = tick.encodeEntry(model);\n\n it('should scale on x', function() {\n assert.deepEqual(props.xc, {scale: X, field: 'Horsepower'});\n });\n\n it('should scale on y', function() {\n assert.deepEqual(props.yc, {scale: Y, field: 'Cylinders'});\n });\n\n it('wiidth should be tick thickness with default orient vertical', function() {\n assert.deepEqual(props.width, {value: 1});\n });\n\n it('height should be matched to field with default orient vertical', function() {\n assert.deepEqual(props.height, {value: 14});\n });\n });\n\n describe('vertical ticks', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n 'mark': 'tick',\n 'config': {'mark': {'orient': 'vertical'}},\n 'encoding':\n {\n 'x': {'field': 'Horsepower', 'type': 'quantitative'},\n 'y': {'field': 'Cylinders', 'type': 'ordinal'},\n 'size': {'field': 'Acceleration', 'type': 'quantitative'}\n },\n 'data': {'url': 'data/cars.json'},\n });\n const props = tick.encodeEntry(model);\n it('maps size to height', function () {\n assert.deepEqual(props.height, {'field': 'Acceleration', 'scale': SIZE});\n });\n });\n\n describe('vertical ticks with size in mark def', function () {\n const model = parseUnitModelWithScaleAndLayoutSize({\n 'mark': {'type': 'tick', 'size': 5},\n 'encoding':\n {\n 'x': {'field': 'Horsepower', 'type': 'quantitative'},\n 'y': {'field': 'Cylinders', 'type': 'ordinal'}\n },\n 'data': {'url': 'data/cars.json'},\n });\n const props = tick.encodeEntry(model);\n it('maps size to height in Vega', function () {\n assert.deepEqual(props.height, {value: 5});\n });\n });\n\n describe('vertical ticks (implicit)', function() {\n const model = parseUnitModelWithScaleAndLayoutSize({\n 'mark': 'tick',\n 'encoding':\n {\n 'x': {'field': 'Horsepower', 'type': 'quantitative'},\n 'y': {'field': 'Cylinders', 'type': 'ordinal'},\n 'size': {'field': 'Acceleration', 'type': 'quantitative'}\n },\n 'data': {'url': 'data/cars.json'},\n });\n const props = tick.encodeEntry(model);\n it('maps size to height in Vega', function() {\n assert.deepEqual(props.height, {'field': 'Acceleration', 'scale': SIZE});\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/mark/valueref.test.d.ts b/build/test/compile/mark/valueref.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/mark/valueref.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/mark/valueref.test.js b/build/test/compile/mark/valueref.test.js new file mode 100644 index 0000000000..ecb6153de2 --- /dev/null +++ b/build/test/compile/mark/valueref.test.js @@ -0,0 +1,28 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { getOffset, midPoint } from '../../../src/compile/mark/valueref'; +describe('compile/mark/valueref', function () { + describe("getOffset", function () { + var markDef = { + "type": "point", + "x2Offset": 100 + }; + it('should correctly get the offset value for the given channel', function () { + assert.equal(getOffset('x2', markDef), 100); + }); + it('should return undefined when the offset value for the given channel is not defined', function () { + assert.equal(getOffset('x', markDef), undefined); + }); + }); + describe('midPoint()', function () { + it('should return correct value for width', function () { + var ref = midPoint('x', { value: 'width' }, undefined, undefined, undefined, undefined); + assert.deepEqual(ref, { field: { group: 'width' } }); + }); + it('should return correct value for height', function () { + var ref = midPoint('y', { value: 'height' }, undefined, undefined, undefined, undefined); + assert.deepEqual(ref, { field: { group: 'height' } }); + }); + }); +}); +//# sourceMappingURL=valueref.test.js.map \ No newline at end of file diff --git a/build/test/compile/mark/valueref.test.js.map b/build/test/compile/mark/valueref.test.js.map new file mode 100644 index 0000000000..3b9fe0fe5b --- /dev/null +++ b/build/test/compile/mark/valueref.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"valueref.test.js","sourceRoot":"","sources":["../../../../test/compile/mark/valueref.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAC,MAAM,oCAAoC,CAAC;AAIvE,QAAQ,CAAC,uBAAuB,EAAE;IAChC,QAAQ,CAAC,WAAW,EAAE;QACpB,IAAM,OAAO,GAAY;YACvB,MAAM,EAAE,OAAO;YACf,UAAU,EAAE,GAAG;SAChB,CAAC;QACF,EAAE,CAAC,6DAA6D,EAAE;YAChE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,oFAAoF,EAAE;YACvF,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,CAAC;QAEnD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE;QACrB,EAAE,CAAC,uCAAuC,EAAE;YAC1C,IAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAC,KAAK,EAAE,OAAO,EAAC,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YACxF,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,EAAC,KAAK,EAAE,EAAC,KAAK,EAAE,OAAO,EAAC,EAAC,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,wCAAwC,EAAE;YAC3C,IAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAC,KAAK,EAAE,QAAQ,EAAC,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YACzF,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,EAAC,KAAK,EAAE,EAAC,KAAK,EAAE,QAAQ,EAAC,EAAC,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:quotemark */\nimport {assert} from 'chai';\n\nimport {getOffset, midPoint} from '../../../src/compile/mark/valueref';\nimport {MarkDef} from '../../../src/mark';\n\n\ndescribe('compile/mark/valueref', () => {\n describe(\"getOffset\", function () {\n const markDef: MarkDef = {\n \"type\": \"point\",\n \"x2Offset\": 100\n };\n it('should correctly get the offset value for the given channel', function () {\n assert.equal(getOffset('x2', markDef), 100);\n });\n it('should return undefined when the offset value for the given channel is not defined', function () {\n assert.equal(getOffset('x', markDef), undefined);\n\n });\n });\n\n describe('midPoint()', () => {\n it('should return correct value for width', () => {\n const ref = midPoint('x', {value: 'width'}, undefined, undefined, undefined, undefined);\n assert.deepEqual(ref, {field: {group: 'width'}});\n });\n it('should return correct value for height', () => {\n const ref = midPoint('y', {value: 'height'}, undefined, undefined, undefined, undefined);\n assert.deepEqual(ref, {field: {group: 'height'}});\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/model.test.d.ts b/build/test/compile/model.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/model.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/model.test.js b/build/test/compile/model.test.js new file mode 100644 index 0000000000..629daa992d --- /dev/null +++ b/build/test/compile/model.test.js @@ -0,0 +1,111 @@ +import { assert } from 'chai'; +import { NameMap } from '../../src/compile/model'; +import { parseFacetModel, parseFacetModelWithScale } from '../util'; +describe('Model', function () { + describe('NameMap', function () { + it('should rename correctly', function () { + var map = new NameMap(); + assert.equal(map.get('a'), 'a'); + map.rename('a', 'b'); + assert.equal(map.get('a'), 'b'); + assert.equal(map.get('b'), 'b'); + map.rename('b', 'c'); + assert.equal(map.get('a'), 'c'); + assert.equal(map.get('b'), 'c'); + assert.equal(map.get('c'), 'c'); + map.rename('z', 'a'); + assert.equal(map.get('a'), 'c'); + assert.equal(map.get('b'), 'c'); + assert.equal(map.get('c'), 'c'); + assert.equal(map.get('z'), 'c'); + }); + }); + describe('hasDescendantWithFieldOnChannel', function () { + it('should return true if a child plot has a field on x', function () { + var model = parseFacetModel({ + facet: { row: { field: 'a', type: 'nominal' } }, + spec: { + mark: 'point', + encoding: { + x: { field: 'x', type: 'quantitative' } + } + } + }); + assert(model.hasDescendantWithFieldOnChannel('x')); + }); + it('should return true if a descendant plot has x', function () { + var model = parseFacetModel({ + facet: { row: { field: 'a', type: 'nominal' } }, + spec: { + layer: [{ + mark: 'point', + encoding: { + x: { field: 'x', type: 'quantitative' } + } + }, { + mark: 'point', + encoding: { + color: { field: 'x', type: 'quantitative' } + } + },] + } + }); + assert(model.hasDescendantWithFieldOnChannel('x')); + }); + it('should return false if no descendant plot has a field on x', function () { + var model = parseFacetModel({ + facet: { row: { field: 'a', type: 'nominal' } }, + spec: { + mark: 'point', + encoding: { + color: { field: 'x', type: 'quantitative' } + } + } + }); + assert(!model.hasDescendantWithFieldOnChannel('x')); + }); + it('should return false if no descendant plot has a field on x', function () { + var model = parseFacetModel({ + facet: { row: { field: 'a', type: 'nominal' } }, + spec: { + layer: [{ + mark: 'point', + encoding: { + color: { field: 'x', type: 'quantitative' } + } + }, { + mark: 'point', + encoding: { + color: { field: 'x', type: 'quantitative' } + } + },] + } + }); + assert(!model.hasDescendantWithFieldOnChannel('x')); + }); + }); + describe('getSizeSignalRef', function () { + it('returns formula for step if parent is facet', function () { + var model = parseFacetModelWithScale({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'nominal', scale: { + padding: 0.345 + } } + } + }, + resolve: { + scale: { x: 'independent' } + } + }); + assert.deepEqual(model.child.getSizeSignalRef('width'), { + signal: "bandspace(datum[\"distinct_b\"], 1, 0.345) * child_x_step" + }); + }); + }); +}); +//# sourceMappingURL=model.test.js.map \ No newline at end of file diff --git a/build/test/compile/model.test.js.map b/build/test/compile/model.test.js.map new file mode 100644 index 0000000000..f984815a54 --- /dev/null +++ b/build/test/compile/model.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"model.test.js","sourceRoot":"","sources":["../../../test/compile/model.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {NameMap} from '../../src/compile/model';\nimport {parseFacetModel, parseFacetModelWithScale} from '../util';\n\ndescribe('Model', () => {\n describe('NameMap', function () {\n it('should rename correctly', function () {\n const map = new NameMap();\n assert.equal(map.get('a'), 'a');\n\n map.rename('a', 'b');\n assert.equal(map.get('a'), 'b');\n assert.equal(map.get('b'), 'b');\n\n map.rename('b', 'c');\n assert.equal(map.get('a'), 'c');\n assert.equal(map.get('b'), 'c');\n assert.equal(map.get('c'), 'c');\n\n map.rename('z', 'a');\n assert.equal(map.get('a'), 'c');\n assert.equal(map.get('b'), 'c');\n assert.equal(map.get('c'), 'c');\n assert.equal(map.get('z'), 'c');\n });\n });\n\n describe('hasDescendantWithFieldOnChannel', () => {\n it('should return true if a child plot has a field on x', () => {\n const model = parseFacetModel({\n facet: {row: {field: 'a', type: 'nominal'}},\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'x', type: 'quantitative'}\n }\n }\n });\n assert(model.hasDescendantWithFieldOnChannel('x'));\n });\n\n it('should return true if a descendant plot has x', () => {\n const model = parseFacetModel({\n facet: {row: {field: 'a', type: 'nominal'}},\n spec: {\n layer: [{\n mark: 'point',\n encoding: {\n x: {field: 'x', type: 'quantitative'}\n }\n },{\n mark: 'point',\n encoding: {\n color: {field: 'x', type: 'quantitative'}\n }\n },]\n }\n });\n assert(model.hasDescendantWithFieldOnChannel('x'));\n });\n\n it('should return false if no descendant plot has a field on x', () => {\n const model = parseFacetModel({\n facet: {row: {field: 'a', type: 'nominal'}},\n spec: {\n mark: 'point',\n encoding: {\n color: {field: 'x', type: 'quantitative'}\n }\n }\n });\n assert(!model.hasDescendantWithFieldOnChannel('x'));\n });\n\n it('should return false if no descendant plot has a field on x', () => {\n const model = parseFacetModel({\n facet: {row: {field: 'a', type: 'nominal'}},\n spec: {\n layer: [{\n mark: 'point',\n encoding: {\n color: {field: 'x', type: 'quantitative'}\n }\n },{\n mark: 'point',\n encoding: {\n color: {field: 'x', type: 'quantitative'}\n }\n },]\n }\n });\n assert(!model.hasDescendantWithFieldOnChannel('x'));\n });\n });\n\n describe('getSizeSignalRef', () => {\n it('returns formula for step if parent is facet', () => {\n const model = parseFacetModelWithScale({\n facet: {\n row: {field: 'a', type: 'ordinal'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'nominal', scale: {\n padding: 0.345\n }}\n }\n },\n resolve: {\n scale: {x: 'independent'}\n }\n });\n\n assert.deepEqual(model.child.getSizeSignalRef('width'), {\n signal: `bandspace(datum[\\\"distinct_b\\\"], 1, 0.345) * child_x_step`\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/projection/assemble.test.d.ts b/build/test/compile/projection/assemble.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/projection/assemble.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/projection/assemble.test.js b/build/test/compile/projection/assemble.test.js new file mode 100644 index 0000000000..1f2f7faf3d --- /dev/null +++ b/build/test/compile/projection/assemble.test.js @@ -0,0 +1,36 @@ +import { assert } from 'chai'; +import { assembleProjectionForModel } from '../../../src/compile/projection/assemble'; +import { isVgSignalRef } from '../../../src/vega.schema'; +import { parseUnitModelWithScaleAndLayoutSize } from '../../util'; +describe('compile/projection/assemble', function () { + describe('assembleProjectionForModel', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + 'mark': 'geoshape', + 'projection': { + 'type': 'albersUsa' + }, + 'data': { + 'url': 'data/us-10m.json', + 'format': { + 'type': 'topojson', + 'feature': 'states' + } + }, + 'encoding': {} + }); + model.parse(); + it('should not be empty', function () { + assert.isNotEmpty(assembleProjectionForModel(model)); + }); + it('should have properties of right type', function () { + var projection = assembleProjectionForModel(model)[0]; + assert.isDefined(projection.name); + assert.isString(projection.name); + assert.isDefined(projection.size); + assert.isTrue(isVgSignalRef(projection.size)); + assert.isDefined(projection.fit); + assert.isTrue(isVgSignalRef(projection.fit)); + }); + }); +}); +//# sourceMappingURL=assemble.test.js.map \ No newline at end of file diff --git a/build/test/compile/projection/assemble.test.js.map b/build/test/compile/projection/assemble.test.js.map new file mode 100644 index 0000000000..49d251db31 --- /dev/null +++ b/build/test/compile/projection/assemble.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.test.js","sourceRoot":"","sources":["../../../../test/compile/projection/assemble.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,0BAA0B,EAAC,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAC,oCAAoC,EAAC,MAAM,YAAY,CAAC;AAEhE,QAAQ,CAAC,6BAA6B,EAAE;IACtC,QAAQ,CAAC,4BAA4B,EAAE;QACrC,IAAM,KAAK,GAAG,oCAAoC,CAAC;YACjD,MAAM,EAAE,UAAU;YAClB,YAAY,EAAE;gBACZ,MAAM,EAAE,WAAW;aACpB;YACD,MAAM,EAAE;gBACN,KAAK,EAAE,kBAAkB;gBACzB,QAAQ,EAAE;oBACR,MAAM,EAAE,UAAU;oBAClB,SAAS,EAAE,QAAQ;iBACpB;aACF;YACD,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,EAAE,CAAC;QAEd,EAAE,CAAC,qBAAqB,EAAE;YACxB,MAAM,CAAC,UAAU,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE;YACzC,IAAM,UAAU,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACxD,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACjC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9C,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\nimport {assembleProjectionForModel} from '../../../src/compile/projection/assemble';\nimport {isVgSignalRef} from '../../../src/vega.schema';\nimport {parseUnitModelWithScaleAndLayoutSize} from '../../util';\n\ndescribe('compile/projection/assemble', () => {\n describe('assembleProjectionForModel', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n 'mark': 'geoshape',\n 'projection': {\n 'type': 'albersUsa'\n },\n 'data': {\n 'url': 'data/us-10m.json',\n 'format': {\n 'type': 'topojson',\n 'feature': 'states'\n }\n },\n 'encoding': {}\n });\n model.parse();\n\n it('should not be empty', () => {\n assert.isNotEmpty(assembleProjectionForModel(model));\n });\n\n it('should have properties of right type', () => {\n const projection = assembleProjectionForModel(model)[0];\n assert.isDefined(projection.name);\n assert.isString(projection.name);\n assert.isDefined(projection.size);\n assert.isTrue(isVgSignalRef(projection.size));\n assert.isDefined(projection.fit);\n assert.isTrue(isVgSignalRef(projection.fit));\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/projection/parse.test.d.ts b/build/test/compile/projection/parse.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/projection/parse.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/projection/parse.test.js b/build/test/compile/projection/parse.test.js new file mode 100644 index 0000000000..0ac393ac04 --- /dev/null +++ b/build/test/compile/projection/parse.test.js @@ -0,0 +1,304 @@ +import { assert } from 'chai'; +import { parseLayerModel, parseUnitModelWithScaleAndLayoutSize } from '../../util'; +/* tslint:disable:quotemark */ +describe('src/compile/projection/parse', function () { + describe('parseUnitProjection', function () { + it('should create projection from specified projection', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "geoshape", + "projection": { + "type": "albersUsa" + }, + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {} + }); + model.parse(); + assert.deepEqual(model.component.projection.explicit, { type: 'albersUsa' }); + }); + it('should create projection with no props', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "geoshape", + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {} + }); + model.parse(); + assert.deepEqual(model.component.projection.explicit, {}); + }); + it('should create projection from config', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "geoshape", + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {}, + "config": { + "projection": { + "type": "albersUsa" + } + } + }); + model.parse(); + assert.deepEqual(model.component.projection.explicit, { type: 'albersUsa' }); + }); + it('should add data with signal', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "data": { + "url": "data/airports.csv", + "format": { + "type": "csv" + } + }, + "mark": "circle", + "projection": { + "type": "albersUsa" + }, + "encoding": { + "longitude": { + "field": "longitude", + "type": "quantitative" + }, + "latitude": { + "field": "latitude", + "type": "quantitative" + } + } + }); + model.parse(); + assert.isObject(model.component.projection.data[0]); + assert.property(model.component.projection.data[0], 'signal'); + }); + it('should add data from main', function () { + var model = parseUnitModelWithScaleAndLayoutSize({ + "mark": "geoshape", + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {} + }); + model.parse(); + assert.isString(model.component.projection.data[0]); + assert.isNotObject(model.component.projection.data[0]); + assert.notProperty(model.component.projection.data[0], 'signal'); + }); + }); + describe('parseNonUnitProjection', function () { + it('should merge the same projection', function () { + var model = parseLayerModel({ + "layer": [ + { + "mark": "geoshape", + "projection": { + "type": "albersUsa" + }, + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {} + }, + { + "data": { + "url": "data/airports.csv" + }, + "mark": "circle", + "projection": { + "type": "albersUsa" + }, + "encoding": { + "longitude": { + "field": "longitude", + "type": "quantitative" + }, + "latitude": { + "field": "latitude", + "type": "quantitative" + } + } + } + ] + }); + model.parse(); + assert.deepEqual(model.component.projection.explicit, { type: 'albersUsa' }); + }); + it('should merge in empty projection to specified projection', function () { + var emptyFirst = parseLayerModel({ + "layer": [ + { + "mark": "geoshape", + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {} + }, + { + "data": { + "url": "data/airports.csv" + }, + "mark": "circle", + "projection": { + "type": "albersUsa" + }, + "encoding": { + "longitude": { + "field": "longitude", + "type": "quantitative" + }, + "latitude": { + "field": "latitude", + "type": "quantitative" + } + } + } + ] + }); + emptyFirst.parse(); + assert.deepEqual(emptyFirst.component.projection.explicit, { type: 'albersUsa' }); + var emptyLast = parseLayerModel({ + "layer": [ + { + "mark": "geoshape", + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {} + }, + { + "data": { + "url": "data/airports.csv" + }, + "mark": "circle", + "projection": { + "type": "albersUsa" + }, + "encoding": { + "longitude": { + "field": "longitude", + "type": "quantitative" + }, + "latitude": { + "field": "latitude", + "type": "quantitative" + } + } + } + ] + }); + emptyLast.parse(); + assert.deepEqual(emptyLast.component.projection.explicit, { type: 'albersUsa' }); + }); + it('should merge projections with same size, different data', function () { + var model = parseLayerModel({ + "layer": [ + { + "mark": "geoshape", + "projection": { + "type": "albersUsa" + }, + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {} + }, + { + "data": { + "url": "data/airports.csv" + }, + "mark": "circle", + "projection": { + "type": "albersUsa" + }, + "encoding": { + "longitude": { + "field": "longitude", + "type": "quantitative" + }, + "latitude": { + "field": "latitude", + "type": "quantitative" + } + } + } + ] + }); + model.parse(); + assert.deepEqual(model.component.projection.explicit, { type: 'albersUsa' }); + }); + it('should not merge different specified projections', function () { + var model = parseLayerModel({ + "layer": [ + { + "mark": "geoshape", + "projection": { + "type": "mercator" + }, + "data": { + "url": "data/us-10m.json", + "format": { + "type": "topojson", + "feature": "states" + } + }, + "encoding": {} + }, + { + "data": { + "url": "data/airports.csv" + }, + "mark": "circle", + "projection": { + "type": "albersUsa" + }, + "encoding": { + "longitude": { + "field": "longitude", + "type": "quantitative" + }, + "latitude": { + "field": "latitude", + "type": "quantitative" + } + } + } + ] + }); + model.parse(); + assert.isUndefined(model.component.projection); + }); + }); +}); +//# sourceMappingURL=parse.test.js.map \ No newline at end of file diff --git a/build/test/compile/projection/parse.test.js.map b/build/test/compile/projection/parse.test.js.map new file mode 100644 index 0000000000..7d2df30cb1 --- /dev/null +++ b/build/test/compile/projection/parse.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.test.js","sourceRoot":"","sources":["../../../../test/compile/projection/parse.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {parseLayerModel, parseUnitModelWithScaleAndLayoutSize} from '../../util';\n/* tslint:disable:quotemark */\n\ndescribe('src/compile/projection/parse', function () {\n describe('parseUnitProjection', () => {\n it('should create projection from specified projection', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"geoshape\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {}\n });\n model.parse();\n assert.deepEqual(model.component.projection.explicit, {type: 'albersUsa'});\n });\n\n it('should create projection with no props', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"geoshape\",\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {}\n });\n model.parse();\n assert.deepEqual(model.component.projection.explicit, {});\n });\n\n it('should create projection from config', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"geoshape\",\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {},\n \"config\": {\n \"projection\": {\n \"type\": \"albersUsa\"\n }\n }\n });\n model.parse();\n assert.deepEqual(model.component.projection.explicit, {type: 'albersUsa'});\n });\n\n it('should add data with signal', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"data\": {\n \"url\": \"data/airports.csv\",\n \"format\": {\n \"type\": \"csv\"\n }\n },\n \"mark\": \"circle\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"encoding\": {\n \"longitude\": {\n \"field\": \"longitude\",\n \"type\": \"quantitative\"\n },\n \"latitude\": {\n \"field\": \"latitude\",\n \"type\": \"quantitative\"\n }\n }\n });\n model.parse();\n assert.isObject(model.component.projection.data[0]);\n assert.property(model.component.projection.data[0], 'signal');\n });\n\n it('should add data from main', () => {\n const model = parseUnitModelWithScaleAndLayoutSize({\n \"mark\": \"geoshape\",\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {}\n });\n model.parse();\n assert.isString(model.component.projection.data[0]);\n assert.isNotObject(model.component.projection.data[0]);\n assert.notProperty(model.component.projection.data[0], 'signal');\n });\n });\n\n describe('parseNonUnitProjection', () => {\n it('should merge the same projection', () => {\n const model = parseLayerModel({\n \"layer\": [\n {\n \"mark\": \"geoshape\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {}\n },\n {\n \"data\": {\n \"url\": \"data/airports.csv\"\n },\n \"mark\": \"circle\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"encoding\": {\n \"longitude\": {\n \"field\": \"longitude\",\n \"type\": \"quantitative\"\n },\n \"latitude\": {\n \"field\": \"latitude\",\n \"type\": \"quantitative\"\n }\n }\n }\n ]\n });\n model.parse();\n assert.deepEqual(model.component.projection.explicit, {type: 'albersUsa'});\n });\n\n it('should merge in empty projection to specified projection', () => {\n const emptyFirst = parseLayerModel({\n \"layer\": [\n {\n \"mark\": \"geoshape\",\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {}\n },\n {\n \"data\": {\n \"url\": \"data/airports.csv\"\n },\n \"mark\": \"circle\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"encoding\": {\n \"longitude\": {\n \"field\": \"longitude\",\n \"type\": \"quantitative\"\n },\n \"latitude\": {\n \"field\": \"latitude\",\n \"type\": \"quantitative\"\n }\n }\n }\n ]\n });\n emptyFirst.parse();\n assert.deepEqual(emptyFirst.component.projection.explicit, {type: 'albersUsa'});\n const emptyLast = parseLayerModel({\n \"layer\": [\n {\n \"mark\": \"geoshape\",\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {}\n },\n {\n \"data\": {\n \"url\": \"data/airports.csv\"\n },\n \"mark\": \"circle\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"encoding\": {\n \"longitude\": {\n \"field\": \"longitude\",\n \"type\": \"quantitative\"\n },\n \"latitude\": {\n \"field\": \"latitude\",\n \"type\": \"quantitative\"\n }\n }\n }\n ]\n });\n emptyLast.parse();\n assert.deepEqual(emptyLast.component.projection.explicit, {type: 'albersUsa'});\n });\n\n it('should merge projections with same size, different data', () => {\n const model = parseLayerModel({\n \"layer\": [\n {\n \"mark\": \"geoshape\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {}\n },\n {\n \"data\": {\n \"url\": \"data/airports.csv\"\n },\n \"mark\": \"circle\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"encoding\": {\n \"longitude\": {\n \"field\": \"longitude\",\n \"type\": \"quantitative\"\n },\n \"latitude\": {\n \"field\": \"latitude\",\n \"type\": \"quantitative\"\n }\n }\n }\n ]\n });\n model.parse();\n assert.deepEqual(model.component.projection.explicit, {type: 'albersUsa'});\n });\n\n it('should not merge different specified projections', () => {\n const model = parseLayerModel({\n \"layer\": [\n {\n \"mark\": \"geoshape\",\n \"projection\": {\n \"type\": \"mercator\"\n },\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\n \"type\": \"topojson\",\n \"feature\": \"states\"\n }\n },\n \"encoding\": {}\n },\n {\n \"data\": {\n \"url\": \"data/airports.csv\"\n },\n \"mark\": \"circle\",\n \"projection\": {\n \"type\": \"albersUsa\"\n },\n \"encoding\": {\n \"longitude\": {\n \"field\": \"longitude\",\n \"type\": \"quantitative\"\n },\n \"latitude\": {\n \"field\": \"latitude\",\n \"type\": \"quantitative\"\n }\n }\n }\n ]\n });\n model.parse();\n assert.isUndefined(model.component.projection);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/repeat.test.d.ts b/build/test/compile/repeat.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/repeat.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/repeat.test.js b/build/test/compile/repeat.test.js new file mode 100644 index 0000000000..34dc9abbe4 --- /dev/null +++ b/build/test/compile/repeat.test.js @@ -0,0 +1,173 @@ +import { assert } from 'chai'; +import { replaceRepeaterInEncoding } from '../../src/compile/repeater'; +import * as log from '../../src/log'; +import { keys } from '../../src/util'; +import { parseRepeatModel } from '../util'; +describe('Repeat', function () { + describe('resolveRepeat', function () { + it('should resolve repeated fields', function () { + var resolved = replaceRepeaterInEncoding({ + x: { field: { repeat: 'row' }, type: 'quantitative' }, + y: { field: 'bar', type: 'quantitative' } + }, { row: 'foo' }); + assert.deepEqual(resolved, { + x: { field: 'foo', type: 'quantitative' }, + y: { field: 'bar', type: 'quantitative' } + }); + }); + it('should show warning if repeat in field def cannot be resolved', log.wrap(function (localLogger) { + var resolved = replaceRepeaterInEncoding({ + x: { field: { repeat: 'row' }, type: 'quantitative' }, + y: { field: 'bar', type: 'quantitative' } + }, { column: 'foo' }); + assert.equal(localLogger.warns[0], log.message.noSuchRepeatedValue('row')); + assert.deepEqual(resolved, { + y: { field: 'bar', type: 'quantitative' } + }); + })); + it('should support arrays fo field defs', function () { + var resolved = replaceRepeaterInEncoding({ + detail: [ + { field: { repeat: 'row' }, type: 'quantitative' }, + { field: 'bar', type: 'quantitative' } + ] + }, { row: 'foo' }); + assert.deepEqual(resolved, { + detail: [{ field: 'foo', type: 'quantitative' }, { field: 'bar', type: 'quantitative' }] + }); + }); + it('should replace fields in sort', function () { + var resolved = replaceRepeaterInEncoding({ + x: { field: 'bar', type: 'quantitative', sort: { field: { repeat: 'row' }, op: 'min' } } + }, { row: 'foo' }); + assert.deepEqual(resolved, { + x: { field: 'bar', type: 'quantitative', sort: { field: 'foo', op: 'min' } } + }); + }); + it('should replace fields in conditionals', function () { + var resolved = replaceRepeaterInEncoding({ + color: { + condition: { selection: 'test', field: { repeat: 'row' }, type: 'quantitative' }, + value: 'red' + } + }, { row: 'foo' }); + assert.deepEqual(resolved, { + color: { + condition: { selection: 'test', field: 'foo', type: 'quantitative' }, + value: 'red' + } + }); + }); + it('should replace fields in reveresed conditionals', function () { + var resolved = replaceRepeaterInEncoding({ + color: { + condition: { selection: 'test', value: 'red' }, + field: { repeat: 'row' }, type: 'quantitative' + } + }, { row: 'foo' }); + assert.deepEqual(resolved, { + color: { + condition: { selection: 'test', value: 'red' }, + field: 'foo', type: 'quantitative' + } + }); + }); + it('should show warning if repeat in conditional cannot be resolved', log.wrap(function (localLogger) { + var resolved = replaceRepeaterInEncoding({ + color: { + condition: { selection: 'test', field: { repeat: 'row' }, type: 'quantitative' }, + value: 'red' + } + }, { column: 'foo' }); + assert.equal(localLogger.warns[0], log.message.noSuchRepeatedValue('row')); + assert.deepEqual(resolved, { + color: { value: 'red' } + }); + })); + it('should show warning if repeat in a condition field def cannot be resolved', log.wrap(function (localLogger) { + var resolved = replaceRepeaterInEncoding({ + color: { + condition: { selection: 'test', value: 'red' }, + field: { repeat: 'row' }, type: 'quantitative' + } + }, { column: 'foo' }); + assert.equal(localLogger.warns[0], log.message.noSuchRepeatedValue('row')); + assert.deepEqual(resolved, { + color: { + condition: { selection: 'test', value: 'red' } + } + }); + })); + }); + describe('initialize children', function () { + it('should create a model per repeated value', function () { + var model = parseRepeatModel({ + repeat: { + row: ['Acceleration', 'Horsepower'] + }, + spec: { + mark: 'point', + encoding: { + x: { field: { repeat: 'row' }, type: 'quantitative' } + } + } + }); + assert.equal(model.children.length, 2); + }); + it('should create n*m models if row and column are specified', function () { + var model = parseRepeatModel({ + repeat: { + row: ['Acceleration', 'Horsepower', 'Displacement'], + column: ['Origin', 'NumCylinders'] + }, + spec: { + mark: 'point', + encoding: { + x: { field: { repeat: 'row' }, type: 'quantitative' }, + y: { field: { repeat: 'column' }, type: 'ordinal' } + } + } + }); + assert.equal(model.children.length, 6); + }); + it('should union color scales and legends', function () { + var model = parseRepeatModel({ + repeat: { + row: ['foo', 'bar'], + column: ['foo', 'bar'] + }, + spec: { + mark: 'point', + encoding: { + x: { field: { repeat: 'row' }, type: 'quantitative' }, + y: { field: { repeat: 'column' }, type: 'ordinal' }, + color: { field: 'baz', type: 'nominal' } + } + } + }); + model.parseScale(); + var colorScale = model.component.scales['color']; + assert.deepEqual(colorScale.domains.length, 4); + model.parseLegend(); + assert.equal(keys(model.component.legends).length, 1); + }); + }); + describe('resolve', function () { + it('cannot share axes', log.wrap(function (localLogger) { + parseRepeatModel({ + repeat: {}, + spec: { + mark: 'point', + encoding: {} + }, + resolve: { + axis: { + x: 'shared' + } + } + }); + assert.equal(localLogger.warns[0], log.message.REPEAT_CANNOT_SHARE_AXIS); + })); + }); +}); +//# sourceMappingURL=repeat.test.js.map \ No newline at end of file diff --git a/build/test/compile/repeat.test.js.map b/build/test/compile/repeat.test.js.map new file mode 100644 index 0000000000..24bb49a6d1 --- /dev/null +++ b/build/test/compile/repeat.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"repeat.test.js","sourceRoot":"","sources":["../../../test/compile/repeat.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAC,yBAAyB,EAAC,MAAM,4BAA4B,CAAC;AAErE,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,EAAC,IAAI,EAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAC,gBAAgB,EAAC,MAAM,SAAS,CAAC;AAEzC,QAAQ,CAAC,QAAQ,EAAE;IACjB,QAAQ,CAAC,eAAe,EAAE;QACxB,EAAE,CAAC,gCAAgC,EAAE;YACnC,IAAM,QAAQ,GAAG,yBAAyB,CAAC;gBACzC,CAAC,EAAE,EAAC,KAAK,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,IAAI,EAAE,cAAc,EAAC;gBACjD,CAAC,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAC;aACxC,EAAE,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC,CAAC;YAEjB,MAAM,CAAC,SAAS,CAAmB,QAAQ,EAAE;gBAC3C,CAAC,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAC;gBACvC,CAAC,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAC;aACxC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,CAAC,IAAI,CAAC,UAAC,WAAW;YACvF,IAAM,QAAQ,GAAG,yBAAyB,CAAC;gBACzC,CAAC,EAAE,EAAC,KAAK,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,IAAI,EAAE,cAAc,EAAC;gBACjD,CAAC,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAC;aACxC,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,CAAC,CAAC;YAEpB,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3E,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE;gBACzB,CAAC,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAC;aACxC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC,CAAC;QAEJ,EAAE,CAAC,qCAAqC,EAAE;YACxC,IAAM,QAAQ,GAAG,yBAAyB,CAAC;gBACzC,MAAM,EAAE;oBACN,EAAC,KAAK,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,IAAI,EAAE,cAAc,EAAC;oBAC9C,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAC;iBACrC;aACF,EAAE,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC,CAAC;YAEjB,MAAM,CAAC,SAAS,CAAmB,QAAQ,EAAE;gBAC3C,MAAM,EAAE,CAAC,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAC,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAC,CAAC;aACrF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE;YAClC,IAAM,QAAQ,GAAG,yBAAyB,CAAC;gBACzC,CAAC,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAC,KAAK,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,EAAE,EAAE,KAAK,EAAC,EAAC;aACnF,EAAE,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC,CAAC;YAEjB,MAAM,CAAC,SAAS,CAAmB,QAAQ,EAAE;gBAC3C,CAAC,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAC,EAAC;aACzE,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE;YAC1C,IAAM,QAAQ,GAAG,yBAAyB,CAAC;gBACzC,KAAK,EAAE;oBACL,SAAS,EAAE,EAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,IAAI,EAAE,cAAc,EAAC;oBAC5E,KAAK,EAAE,KAAK;iBACb;aACF,EAAE,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC,CAAC;YAEjB,MAAM,CAAC,SAAS,CAAmB,QAAQ,EAAE;gBAC3C,KAAK,EAAE;oBACL,SAAS,EAAE,EAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAC;oBAClE,KAAK,EAAE,KAAK;iBACb;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE;YACpD,IAAM,QAAQ,GAAG,yBAAyB,CAAC;gBACzC,KAAK,EAAE;oBACL,SAAS,EAAE,EAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAC;oBAC5C,KAAK,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,IAAI,EAAE,cAAc;iBAC7C;aACF,EAAE,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC,CAAC;YAEjB,MAAM,CAAC,SAAS,CAAmB,QAAQ,EAAE;gBAC3C,KAAK,EAAE;oBACL,SAAS,EAAE,EAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAC;oBAC5C,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc;iBACnC;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,CAAC,IAAI,CAAC,UAAC,WAAW;YACzF,IAAM,QAAQ,GAAG,yBAAyB,CAAC;gBACzC,KAAK,EAAE;oBACL,SAAS,EAAE,EAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,IAAI,EAAE,cAAc,EAAC;oBAC5E,KAAK,EAAE,KAAK;iBACb;aACF,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,CAAC,CAAC;YAEpB,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3E,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE;gBACzB,KAAK,EAAE,EAAC,KAAK,EAAE,KAAK,EAAC;aACtB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC,CAAC;QAEJ,EAAE,CAAC,2EAA2E,EAAE,GAAG,CAAC,IAAI,CAAC,UAAC,WAAW;YACnG,IAAM,QAAQ,GAAG,yBAAyB,CAAC;gBACzC,KAAK,EAAE;oBACL,SAAS,EAAE,EAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAC;oBAC5C,KAAK,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,IAAI,EAAE,cAAc;iBAC7C;aACF,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,CAAC,CAAC;YAEpB,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3E,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE;gBACzB,KAAK,EAAE;oBACL,SAAS,EAAE,EAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAC;iBAC7C;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qBAAqB,EAAE;QAC9B,EAAE,CAAC,0CAA0C,EAAE;YAC7C,IAAM,KAAK,GAAG,gBAAgB,CAAC;gBAC7B,MAAM,EAAE;oBACN,GAAG,EAAE,CAAC,cAAc,EAAE,YAAY,CAAC;iBACpC;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE;wBACR,CAAC,EAAE,EAAC,KAAK,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,IAAI,EAAE,cAAc,EAAC;qBAClD;iBACF;aACF,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE;YAC7D,IAAM,KAAK,GAAG,gBAAgB,CAAC;gBAC7B,MAAM,EAAE;oBACN,GAAG,EAAE,CAAC,cAAc,EAAE,YAAY,EAAE,cAAc,CAAC;oBACnD,MAAM,EAAE,CAAC,QAAQ,EAAE,cAAc,CAAC;iBACnC;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE;wBACR,CAAC,EAAE,EAAC,KAAK,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,IAAI,EAAE,cAAc,EAAC;wBACjD,CAAC,EAAE,EAAC,KAAK,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAC,EAAE,IAAI,EAAE,SAAS,EAAC;qBAChD;iBACF;aACF,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE;YAC1C,IAAM,KAAK,GAAG,gBAAgB,CAAC;gBAC7B,MAAM,EAAE;oBACN,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;oBACnB,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;iBACvB;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE;wBACR,CAAC,EAAE,EAAC,KAAK,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,EAAE,IAAI,EAAE,cAAc,EAAC;wBACjD,CAAC,EAAE,EAAC,KAAK,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAC,EAAE,IAAI,EAAE,SAAS,EAAC;wBAC/C,KAAK,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAC;qBACvC;iBACF;aACF,CAAC,CAAC;YAEH,KAAK,CAAC,UAAU,EAAE,CAAC;YACnB,IAAM,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAEnD,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAE/C,KAAK,CAAC,WAAW,EAAE,CAAC;YAEpB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE;QAClB,EAAE,CAAC,mBAAmB,EAAE,GAAG,CAAC,IAAI,CAAC,UAAC,WAAW;YAC3C,gBAAgB,CAAC;gBACf,MAAM,EAAE,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,EAAE;iBACb;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE;wBACJ,CAAC,EAAE,QAAQ;qBACZ;iBACF;aACF,CAAC,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC,CAAC;IACN,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\n\nimport {replaceRepeaterInEncoding} from '../../src/compile/repeater';\nimport {Encoding} from '../../src/encoding';\nimport * as log from '../../src/log';\nimport {keys} from '../../src/util';\nimport {parseRepeatModel} from '../util';\n\ndescribe('Repeat', function() {\n describe('resolveRepeat', () => {\n it('should resolve repeated fields', () => {\n const resolved = replaceRepeaterInEncoding({\n x: {field: {repeat: 'row'}, type: 'quantitative'},\n y: {field: 'bar', type: 'quantitative'}\n }, {row: 'foo'});\n\n assert.deepEqual>(resolved, {\n x: {field: 'foo', type: 'quantitative'},\n y: {field: 'bar', type: 'quantitative'}\n });\n });\n\n it('should show warning if repeat in field def cannot be resolved', log.wrap((localLogger) => {\n const resolved = replaceRepeaterInEncoding({\n x: {field: {repeat: 'row'}, type: 'quantitative'},\n y: {field: 'bar', type: 'quantitative'}\n }, {column: 'foo'});\n\n assert.equal(localLogger.warns[0], log.message.noSuchRepeatedValue('row'));\n assert.deepEqual(resolved, {\n y: {field: 'bar', type: 'quantitative'}\n });\n }));\n\n it('should support arrays fo field defs', () => {\n const resolved = replaceRepeaterInEncoding({\n detail: [\n {field: {repeat: 'row'}, type: 'quantitative'},\n {field: 'bar', type: 'quantitative'}\n ]\n }, {row: 'foo'});\n\n assert.deepEqual>(resolved, {\n detail: [{field: 'foo', type: 'quantitative'}, {field: 'bar', type: 'quantitative'}]\n });\n });\n\n it('should replace fields in sort', () => {\n const resolved = replaceRepeaterInEncoding({\n x: {field: 'bar', type: 'quantitative', sort: {field: {repeat: 'row'}, op: 'min'}}\n }, {row: 'foo'});\n\n assert.deepEqual>(resolved, {\n x: {field: 'bar', type: 'quantitative', sort: {field: 'foo', op: 'min'}}\n });\n });\n\n it('should replace fields in conditionals', () => {\n const resolved = replaceRepeaterInEncoding({\n color: {\n condition: {selection: 'test', field: {repeat: 'row'}, type: 'quantitative'},\n value: 'red'\n }\n }, {row: 'foo'});\n\n assert.deepEqual>(resolved, {\n color: {\n condition: {selection: 'test', field: 'foo', type: 'quantitative'},\n value: 'red'\n }\n });\n });\n\n it('should replace fields in reveresed conditionals', () => {\n const resolved = replaceRepeaterInEncoding({\n color: {\n condition: {selection: 'test', value: 'red'},\n field: {repeat: 'row'}, type: 'quantitative'\n }\n }, {row: 'foo'});\n\n assert.deepEqual>(resolved, {\n color: {\n condition: {selection: 'test', value: 'red'},\n field: 'foo', type: 'quantitative'\n }\n });\n });\n\n it('should show warning if repeat in conditional cannot be resolved', log.wrap((localLogger) => {\n const resolved = replaceRepeaterInEncoding({\n color: {\n condition: {selection: 'test', field: {repeat: 'row'}, type: 'quantitative'},\n value: 'red'\n }\n }, {column: 'foo'});\n\n assert.equal(localLogger.warns[0], log.message.noSuchRepeatedValue('row'));\n assert.deepEqual(resolved, {\n color: {value: 'red'}\n });\n }));\n\n it('should show warning if repeat in a condition field def cannot be resolved', log.wrap((localLogger) => {\n const resolved = replaceRepeaterInEncoding({\n color: {\n condition: {selection: 'test', value: 'red'},\n field: {repeat: 'row'}, type: 'quantitative'\n }\n }, {column: 'foo'});\n\n assert.equal(localLogger.warns[0], log.message.noSuchRepeatedValue('row'));\n assert.deepEqual(resolved, {\n color: {\n condition: {selection: 'test', value: 'red'}\n }\n });\n }));\n });\n\n describe('initialize children', () => {\n it('should create a model per repeated value', () => {\n const model = parseRepeatModel({\n repeat: {\n row: ['Acceleration', 'Horsepower']\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: {repeat: 'row'}, type: 'quantitative'}\n }\n }\n });\n\n assert.equal(model.children.length, 2);\n });\n\n it('should create n*m models if row and column are specified', () => {\n const model = parseRepeatModel({\n repeat: {\n row: ['Acceleration', 'Horsepower', 'Displacement'],\n column: ['Origin', 'NumCylinders']\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: {repeat: 'row'}, type: 'quantitative'},\n y: {field: {repeat: 'column'}, type: 'ordinal'}\n }\n }\n });\n\n assert.equal(model.children.length, 6);\n });\n\n it('should union color scales and legends', () => {\n const model = parseRepeatModel({\n repeat: {\n row: ['foo', 'bar'],\n column: ['foo', 'bar']\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: {repeat: 'row'}, type: 'quantitative'},\n y: {field: {repeat: 'column'}, type: 'ordinal'},\n color: {field: 'baz', type: 'nominal'}\n }\n }\n });\n\n model.parseScale();\n const colorScale = model.component.scales['color'];\n\n assert.deepEqual(colorScale.domains.length, 4);\n\n model.parseLegend();\n\n assert.equal(keys(model.component.legends).length, 1);\n });\n });\n\n describe('resolve', () => {\n it('cannot share axes', log.wrap((localLogger) => {\n parseRepeatModel({\n repeat: {},\n spec: {\n mark: 'point',\n encoding: {}\n },\n resolve: {\n axis: {\n x: 'shared'\n }\n }\n });\n assert.equal(localLogger.warns[0], log.message.REPEAT_CANNOT_SHARE_AXIS);\n }));\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/resolve.test.d.ts b/build/test/compile/resolve.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/resolve.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/resolve.test.js b/build/test/compile/resolve.test.js new file mode 100644 index 0000000000..e354fb1f90 --- /dev/null +++ b/build/test/compile/resolve.test.js @@ -0,0 +1,104 @@ +import { assert } from 'chai'; +import { defaultScaleResolve, parseGuideResolve } from '../../src/compile/resolve'; +import * as log from '../../src/log'; +import { parseConcatModel, parseFacetModel, parseLayerModel, parseRepeatModel } from '../util'; +describe('compile/resolve', function () { + describe('defaultScaleResolve', function () { + it('shares scales for layer model by default.', function () { + var model = parseLayerModel({ + layer: [] + }); + assert.equal(defaultScaleResolve('x', model), 'shared'); + }); + it('shares scales for facet model by default.', function () { + var model = parseFacetModel({ + facet: { + row: { field: 'a', type: 'nominal' } + }, + spec: { mark: 'point', encoding: {} } + }); + assert.equal(defaultScaleResolve('x', model), 'shared'); + }); + it('separates xy scales for concat model by default.', function () { + var model = parseConcatModel({ + hconcat: [] + }); + assert.equal(defaultScaleResolve('x', model), 'independent'); + }); + it('shares non-xy scales for concat model by default.', function () { + var model = parseConcatModel({ + hconcat: [] + }); + assert.equal(defaultScaleResolve('color', model), 'shared'); + }); + it('separates xy scales for repeat model by default.', function () { + var model = parseRepeatModel({ + repeat: { + row: ['a', 'b'] + }, + spec: { + mark: 'point', + encoding: { + x: { field: { repeat: 'row' }, type: 'quantitative' }, + color: { field: 'color', type: 'quantitative' } + } + } + }); + assert.equal(defaultScaleResolve('x', model), 'independent'); + }); + it('shares non-xy scales for repeat model by default.', function () { + var model = parseRepeatModel({ + repeat: { + row: ['a', 'b'] + }, + spec: { + mark: 'point', + encoding: { + x: { field: { repeat: 'row' }, type: 'quantitative' }, + color: { field: 'color', type: 'quantitative' } + } + } + }); + assert.equal(defaultScaleResolve('color', model), 'shared'); + }); + }); + describe('parseGuideResolve', function () { + it('shares axis for a shared scale by default', function () { + var axisResolve = parseGuideResolve({ + scale: { x: 'shared' }, + axis: {} + }, 'x'); + assert.equal(axisResolve, 'shared'); + }); + it('separates axis for a shared scale if specified', function () { + var axisResolve = parseGuideResolve({ + scale: { x: 'shared' }, + axis: { x: 'independent' } + }, 'x'); + assert.equal(axisResolve, 'independent'); + }); + it('separates legend for a shared scale if specified', function () { + var legendResolve = parseGuideResolve({ + scale: { color: 'shared' }, + legend: { color: 'independent' } + }, 'color'); + assert.equal(legendResolve, 'independent'); + }); + it('separates axis for an independent scale by default', function () { + var axisResolve = parseGuideResolve({ + scale: { x: 'independent' }, + axis: {} + }, 'x'); + assert.equal(axisResolve, 'independent'); + }); + it('separates axis for an independent scale even "shared" is specified and throw warning', log.wrap(function (localLogger) { + var axisResolve = parseGuideResolve({ + scale: { x: 'independent' }, + axis: { x: 'shared' } + }, 'x'); + assert.equal(axisResolve, 'independent'); + assert.equal(localLogger.warns[0], log.message.independentScaleMeansIndependentGuide('x')); + })); + }); +}); +//# sourceMappingURL=resolve.test.js.map \ No newline at end of file diff --git a/build/test/compile/resolve.test.js.map b/build/test/compile/resolve.test.js.map new file mode 100644 index 0000000000..20f6f3985c --- /dev/null +++ b/build/test/compile/resolve.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"resolve.test.js","sourceRoot":"","sources":["../../../test/compile/resolve.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {defaultScaleResolve, parseGuideResolve} from '../../src/compile/resolve';\nimport * as log from '../../src/log';\nimport {parseConcatModel, parseFacetModel, parseLayerModel, parseRepeatModel} from '../util';\n\ndescribe('compile/resolve', () => {\n describe('defaultScaleResolve', () => {\n it('shares scales for layer model by default.', () => {\n const model = parseLayerModel({\n layer: []\n });\n assert.equal(defaultScaleResolve('x', model), 'shared');\n });\n\n it('shares scales for facet model by default.', () => {\n const model = parseFacetModel({\n facet: {\n row: {field: 'a', type: 'nominal'}\n },\n spec: {mark: 'point', encoding: {}}\n });\n assert.equal(defaultScaleResolve('x', model), 'shared');\n });\n\n it('separates xy scales for concat model by default.', () => {\n const model = parseConcatModel({\n hconcat: []\n });\n assert.equal(defaultScaleResolve('x', model), 'independent');\n });\n\n it('shares non-xy scales for concat model by default.', () => {\n const model = parseConcatModel({\n hconcat: []\n });\n assert.equal(defaultScaleResolve('color', model), 'shared');\n });\n\n it('separates xy scales for repeat model by default.', () => {\n const model = parseRepeatModel({\n repeat: {\n row: ['a', 'b']\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: {repeat: 'row'}, type: 'quantitative'},\n color: {field: 'color', type: 'quantitative'}\n }\n }\n });\n assert.equal(defaultScaleResolve('x', model), 'independent');\n });\n\n it('shares non-xy scales for repeat model by default.', () => {\n const model = parseRepeatModel({\n repeat: {\n row: ['a', 'b']\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: {repeat: 'row'}, type: 'quantitative'},\n color: {field: 'color', type: 'quantitative'}\n }\n }\n });\n assert.equal(defaultScaleResolve('color', model), 'shared');\n });\n });\n\n describe('parseGuideResolve', () => {\n it('shares axis for a shared scale by default', () => {\n const axisResolve = parseGuideResolve({\n scale: {x: 'shared'},\n axis: {}\n }, 'x');\n assert.equal(axisResolve, 'shared');\n });\n\n it('separates axis for a shared scale if specified', () => {\n const axisResolve = parseGuideResolve({\n scale: {x: 'shared'},\n axis: {x: 'independent'}\n }, 'x');\n assert.equal(axisResolve, 'independent');\n });\n\n it('separates legend for a shared scale if specified', () => {\n const legendResolve = parseGuideResolve({\n scale: {color: 'shared'},\n legend: {color: 'independent'}\n }, 'color');\n assert.equal(legendResolve, 'independent');\n });\n\n it('separates axis for an independent scale by default', () => {\n const axisResolve = parseGuideResolve({\n scale: {x: 'independent'},\n axis: {}\n }, 'x');\n assert.equal(axisResolve, 'independent');\n });\n\n it('separates axis for an independent scale even \"shared\" is specified and throw warning', log.wrap((localLogger) => {\n const axisResolve = parseGuideResolve({\n scale: {x: 'independent'},\n axis: {x: 'shared'}\n }, 'x');\n assert.equal(axisResolve, 'independent');\n assert.equal(localLogger.warns[0], log.message.independentScaleMeansIndependentGuide('x'));\n }));\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/scale/assemble.test.d.ts b/build/test/compile/scale/assemble.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/scale/assemble.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/scale/assemble.test.js b/build/test/compile/scale/assemble.test.js new file mode 100644 index 0000000000..99e9fa903f --- /dev/null +++ b/build/test/compile/scale/assemble.test.js @@ -0,0 +1,121 @@ +import { assert } from 'chai'; +import { assembleScaleRange, assembleScales } from '../../../src/compile/scale/assemble'; +import { parseConcatModel, parseFacetModelWithScale, parseLayerModel, parseRepeatModel, parseUnitModel, parseUnitModelWithScale } from '../../util'; +describe('compile/scale/assemble', function () { + describe('assembleScales', function () { + it('includes all scales for concat', function () { + var model = parseConcatModel({ + vconcat: [{ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }, { + mark: 'bar', + encoding: { + x: { field: 'b', type: 'ordinal' }, + y: { field: 'c', type: 'quantitative' } + } + }] + }); + model.parseScale(); + var scales = assembleScales(model); + assert.equal(scales.length, 3); + }); + it('includes all scales from children for layer, both shared and independent', function () { + var model = parseLayerModel({ + layer: [{ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + }, { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + }], + resolve: { + scale: { + x: 'independent' + } + } + }); + model.parseScale(); + var scales = assembleScales(model); + assert.equal(scales.length, 3); // 2 x, 1 y + }); + it('includes all scales for repeat', function () { + var model = parseRepeatModel({ + repeat: { + row: ['Acceleration', 'Horsepower'] + }, + spec: { + mark: 'point', + encoding: { + x: { field: { repeat: 'row' }, type: 'quantitative' } + } + } + }); + model.parseScale(); + var scales = assembleScales(model); + assert.equal(scales.length, 2); + }); + it('includes shared scales, but not independent scales (as they are nested) for facet.', function () { + var model = parseFacetModelWithScale({ + facet: { + column: { field: 'a', type: 'quantitative', format: 'd' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + }, + resolve: { + scale: { x: 'independent' } + } + }); + var scales = assembleScales(model); + assert.equal(scales.length, 1); + assert.equal(scales[0].name, 'y'); + }); + }); + describe('assembleScaleRange', function () { + it('replaces a range step constant with a signal', function () { + var model = parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'x', type: 'nominal' } + } + }); + assert.deepEqual(assembleScaleRange({ step: 21 }, 'x', model, 'x'), { step: { signal: 'x_step' } }); + }); + it('updates width signal when renamed.', function () { + var model = parseUnitModelWithScale({ + mark: 'point', + encoding: { + x: { field: 'x', type: 'quantitative' } + } + }); + // mock renaming + model.renameLayoutSize('width', 'new_width'); + assert.deepEqual(assembleScaleRange([0, { signal: 'width' }], 'x', model, 'x'), [0, { signal: 'new_width' }]); + }); + it('updates height signal when renamed.', function () { + var model = parseUnitModelWithScale({ + mark: 'point', + encoding: { + x: { field: 'y', type: 'quantitative' } + } + }); + // mock renaming + model.renameLayoutSize('height', 'new_height'); + assert.deepEqual(assembleScaleRange([0, { signal: 'height' }], 'x', model, 'x'), [0, { signal: 'new_height' }]); + }); + }); +}); +//# sourceMappingURL=assemble.test.js.map \ No newline at end of file diff --git a/build/test/compile/scale/assemble.test.js.map b/build/test/compile/scale/assemble.test.js.map new file mode 100644 index 0000000000..118dd371d8 --- /dev/null +++ b/build/test/compile/scale/assemble.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"assemble.test.js","sourceRoot":"","sources":["../../../../test/compile/scale/assemble.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {assembleScaleRange, assembleScales} from '../../../src/compile/scale/assemble';\nimport {parseConcatModel, parseFacetModelWithScale, parseLayerModel, parseRepeatModel, parseUnitModel, parseUnitModelWithScale} from '../../util';\n\ndescribe('compile/scale/assemble', () => {\n describe('assembleScales', () => {\n it('includes all scales for concat', () => {\n const model = parseConcatModel({\n vconcat: [{\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal'}\n }\n },{\n mark: 'bar',\n encoding: {\n x: {field: 'b', type: 'ordinal'},\n y: {field: 'c', type: 'quantitative'}\n }\n }]\n });\n\n model.parseScale();\n const scales = assembleScales(model);\n assert.equal(scales.length, 3);\n });\n\n\n it('includes all scales from children for layer, both shared and independent', () => {\n const model = parseLayerModel({\n layer: [{\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n },{\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n }],\n resolve: {\n scale: {\n x: 'independent'\n }\n }\n });\n\n model.parseScale();\n const scales = assembleScales(model);\n assert.equal(scales.length, 3); // 2 x, 1 y\n });\n\n it('includes all scales for repeat', () => {\n const model = parseRepeatModel({\n repeat: {\n row: ['Acceleration', 'Horsepower']\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: {repeat: 'row'}, type: 'quantitative'}\n }\n }\n });\n\n model.parseScale();\n const scales = assembleScales(model);\n assert.equal(scales.length, 2);\n });\n\n it('includes shared scales, but not independent scales (as they are nested) for facet.', () => {\n const model = parseFacetModelWithScale\n ({\n facet: {\n column: {field: 'a', type: 'quantitative', format: 'd'}\n },\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'}\n }\n },\n resolve: {\n scale: {x: 'independent'}\n }\n });\n\n const scales = assembleScales(model);\n assert.equal(scales.length, 1);\n assert.equal(scales[0].name, 'y');\n });\n });\n\n describe('assembleScaleRange', () => {\n it('replaces a range step constant with a signal', () => {\n const model = parseUnitModel({\n mark: 'point',\n encoding: {\n x: {field: 'x', type: 'nominal'}\n }\n });\n\n assert.deepEqual(\n assembleScaleRange({step: 21}, 'x', model, 'x'),\n {step: {signal: 'x_step'}}\n );\n });\n\n it('updates width signal when renamed.', () => {\n const model = parseUnitModelWithScale({\n mark: 'point',\n encoding: {\n x: {field: 'x', type: 'quantitative'}\n }\n });\n\n // mock renaming\n model.renameLayoutSize('width', 'new_width');\n\n\n assert.deepEqual(\n assembleScaleRange([0, {signal: 'width'}], 'x', model, 'x'),\n [0, {signal: 'new_width'}]\n );\n });\n\n it('updates height signal when renamed.', () => {\n const model = parseUnitModelWithScale({\n mark: 'point',\n encoding: {\n x: {field: 'y', type: 'quantitative'}\n }\n });\n\n // mock renaming\n model.renameLayoutSize('height', 'new_height');\n\n assert.deepEqual(\n assembleScaleRange([0, {signal: 'height'}], 'x', model, 'x'),\n [0, {signal: 'new_height'}]\n );\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/scale/domain.test.d.ts b/build/test/compile/scale/domain.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/scale/domain.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/scale/domain.test.js b/build/test/compile/scale/domain.test.js new file mode 100644 index 0000000000..ea76249cac --- /dev/null +++ b/build/test/compile/scale/domain.test.js @@ -0,0 +1,767 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { domainSort, mergeDomains, parseDomainForChannel } from '../../../src/compile/scale/domain'; +import { parseScaleCore } from '../../../src/compile/scale/parse'; +import { MAIN } from '../../../src/data'; +import * as log from '../../../src/log'; +import { ScaleType } from '../../../src/scale'; +import { parseUnitModel } from '../../util'; +describe('compile/scale', function () { + describe('parseDomainForChannel()', function () { + function testParseDomainForChannel(model, channel) { + // Cannot parseDomain before parseScaleCore + parseScaleCore(model); + return parseDomainForChannel(model, channel); + } + it('should have correct domain with x and x2 channel', function () { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'quantitative' }, + x2: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' }, + y2: { field: 'd', type: 'quantitative' } + } + }); + var xDomain = testParseDomainForChannel(model, 'x'); + assert.deepEqual(xDomain, [{ data: 'main', field: 'a' }, { data: 'main', field: 'b' }]); + var yDomain = testParseDomainForChannel(model, 'y'); + assert.deepEqual(yDomain, [{ data: 'main', field: 'c' }, { data: 'main', field: 'd' }]); + }); + it('should have correct domain for color', function () { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + color: { field: 'a', type: 'quantitative' }, + } + }); + var xDomain = testParseDomainForChannel(model, 'color'); + assert.deepEqual(xDomain, [{ data: 'main', field: 'a' }]); + }); + it('should have correct domain for color ConditionField', function () { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + color: { + condition: { selection: 'sel', field: 'a', type: 'quantitative' } + } + } + }); + var xDomain = testParseDomainForChannel(model, 'color'); + assert.deepEqual(xDomain, [{ data: 'main', field: 'a' }]); + }); + it('should return domain for stack', function () { + var model = parseUnitModel({ + mark: "bar", + encoding: { + y: { + aggregate: 'sum', + field: 'origin', + type: 'quantitative' + }, + x: { field: 'x', type: "ordinal" }, + color: { field: 'color', type: "ordinal" } + } + }); + assert.deepEqual(testParseDomainForChannel(model, 'y'), [{ + data: 'main', + field: 'sum_origin_start' + }, { + data: 'main', + field: 'sum_origin_end' + }]); + }); + it('should return normalize domain for stack if specified', function () { + var model = parseUnitModel({ + mark: "bar", + encoding: { + y: { + aggregate: 'sum', + field: 'origin', + type: 'quantitative' + }, + x: { field: 'x', type: "ordinal" }, + color: { field: 'color', type: "ordinal" } + }, + config: { + stack: "normalize" + } + }); + assert.deepEqual(testParseDomainForChannel(model, 'y'), [[0, 1]]); + }); + describe('for quantitative', function () { + it('should return the right domain for binned Q', log.wrap(function (localLogger) { + var fieldDef = { + bin: { maxbins: 15 }, + field: 'origin', + scale: { domain: 'unaggregated' }, + type: 'quantitative' + }; + var model = parseUnitModel({ + mark: "point", + encoding: { + y: fieldDef + } + }); + assert.deepEqual(testParseDomainForChannel(model, 'y'), [{ + data: 'main', + field: 'bin_maxbins_15_origin' + }, { + data: 'main', + field: 'bin_maxbins_15_origin_end' + }]); + assert.equal(localLogger.warns[0], log.message.unaggregateDomainHasNoEffectForRawField(fieldDef)); + })); + it('should follow the custom bin.extent for binned Q', log.wrap(function (localLogger) { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'origin', + type: 'quantitative', + bin: { maxbins: 15, extent: [0, 100] } + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + assert.deepEqual(_domain, [[0, 100]]); + })); + it('should return the unaggregated domain if requested for non-bin, non-sum Q', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'mean', + field: 'acceleration', + scale: { domain: 'unaggregated' }, + type: "quantitative" + } + } + }); + assert.deepEqual(testParseDomainForChannel(model, 'y'), [{ + data: MAIN, + field: 'min_acceleration' + }, { + data: MAIN, + field: 'max_acceleration' + }]); + }); + it('should return the aggregated domain for sum Q', log.wrap(function (localLogger) { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'sum', + field: 'origin', + scale: { domain: 'unaggregated' }, + type: "quantitative" + } + } + }); + testParseDomainForChannel(model, 'y'); + assert.equal(localLogger.warns[0], log.message.unaggregateDomainWithNonSharedDomainOp('sum')); + })); + it('should return the right custom domain', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'horsepower', + type: "quantitative", + scale: { domain: [0, 200] } + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + assert.deepEqual(_domain, [[0, 200]]); + }); + it('should follow the custom domain despite bin', log.wrap(function (localLogger) { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'origin', + type: 'quantitative', + scale: { domain: [0, 200] }, + bin: { maxbins: 15 } + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + assert.deepEqual(_domain, [[0, 200]]); + })); + it('should return the aggregated domain if we do not override it', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'min', + field: 'origin', + type: "quantitative" + } + } + }); + assert.deepEqual(testParseDomainForChannel(model, 'y'), [ + { + data: 'main', + field: 'min_origin' + } + ]); + }); + it('should use the aggregated data for domain if specified in config', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'min', + field: 'acceleration', + type: "quantitative" + } + }, + config: { + scale: { + useUnaggregatedDomain: true + } + } + }); + assert.deepEqual(testParseDomainForChannel(model, 'y'), [{ + data: MAIN, + field: 'min_acceleration' + }, { + data: MAIN, + field: 'max_acceleration' + }]); + }); + }); + describe('for time', function () { + it('should return the correct domain for month T', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'origin', + type: "temporal", + timeUnit: 'month' + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + assert.deepEqual(_domain, [{ data: 'main', field: 'month_origin' }]); + }); + it('should return the correct domain for month O', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'origin', + type: "ordinal", + timeUnit: 'month' + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + assert.deepEqual(_domain, [{ data: 'main', field: 'month_origin', sort: true }]); + }); + it('should return the correct domain for yearmonth T', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'origin', + type: "temporal", + timeUnit: 'yearmonth' + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + assert.deepEqual(_domain, [{ data: 'main', field: 'yearmonth_origin' }]); + }); + it('should return the correct domain for month O when specify sort', function () { + var sortDef = { op: 'mean', field: 'precipitation', order: 'descending' }; + var model = parseUnitModel({ + mark: "bar", + encoding: { + x: { + timeUnit: 'month', + field: 'date', + type: 'ordinal', + sort: sortDef + }, + y: { + aggregate: 'mean', + field: 'precipitation', + type: 'quantitative' + } + } + }); + var _domain = testParseDomainForChannel(model, 'x'); + assert.deepEqual(_domain, [{ + data: 'raw', + field: 'month_date', + sort: sortDef + }]); + }); + it('should return the right custom domain with DateTime objects', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'year', + type: "temporal", + scale: { domain: [{ year: 1970 }, { year: 1980 }] } + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + expect(_domain).toEqual([ + { "signal": "{data: datetime(1970, 0, 1, 0, 0, 0, 0)}" }, + { "signal": "{data: datetime(1980, 0, 1, 0, 0, 0, 0)}" } + ]); + }); + it('should return the right custom domain with date strings', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'year', + type: "temporal", + scale: { domain: ["Jan 1, 2007", "Jan 1, 2009"] } + } + } + }); + var _domain = testParseDomainForChannel(model, 'y'); + expect(_domain).toEqual([ + { "signal": "{data: datetime(\"Jan 1, 2007\")}" }, + { "signal": "{data: datetime(\"Jan 1, 2009\")}" }, + ]); + }); + }); + describe('for ordinal', function () { + it('should have correct domain for binned ordinal color', function () { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + color: { field: 'a', bin: true, type: 'ordinal' }, + } + }); + var xDomain = testParseDomainForChannel(model, 'color'); + assert.deepEqual(xDomain, [{ data: 'main', field: 'bin_maxbins_6_a_range', sort: { field: 'bin_maxbins_6_a', op: 'min' } }]); + }); + }); + describe('for nominal', function () { + it('should return correct domain with the provided sort property', function () { + var sortDef = { op: 'min', field: 'Acceleration' }; + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { field: 'origin', type: "nominal", sort: sortDef } + } + }); + assert.deepEqual(testParseDomainForChannel(model, 'y'), [{ + data: "raw", + field: 'origin', + sort: sortDef + }]); + }); + it('should return correct domain with the provided sort property with order property', function () { + var sortDef = { op: 'min', field: 'Acceleration', order: "descending" }; + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { field: 'origin', type: "nominal", sort: sortDef } + } + }); + assert.deepEqual(testParseDomainForChannel(model, 'y'), [{ + data: "raw", + field: 'origin', + sort: sortDef + }]); + }); + it('should return correct domain without sort if sort is not provided', function () { + var model = parseUnitModel({ + mark: "point", + encoding: { + y: { field: 'origin', type: "nominal" } + } + }); + assert.deepEqual(testParseDomainForChannel(model, 'y'), [{ + data: "main", + field: 'origin', + sort: true + }]); + }); + }); + }); + describe('mergeDomains()', function () { + it('should merge the same domains', function () { + var domain = mergeDomains([{ + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean' } + }, { + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean' } + }]); + assert.deepEqual(domain, { + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean' } + }); + }); + it('should drop field if op is count', function () { + var domain = mergeDomains([{ + data: 'foo', + field: 'a', + sort: { op: 'count', field: 'b' } + }]); + assert.deepEqual(domain, { + data: 'foo', + field: 'a', + sort: { op: 'count' } + }); + }); + it('should sort the output domain if one domain is sorted', function () { + var domain = mergeDomains([{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean', order: 'descending' } + }]); + assert.deepEqual(domain, { + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean', order: 'descending' } + }); + }); + it('should sort the output domain if one domain is sorted with true', function () { + var domain = mergeDomains([{ + data: 'foo', + field: 'a', + sort: true + }, { + data: 'foo', + field: 'b', + }]); + assert.deepEqual(domain, { + data: 'foo', + fields: ['a', 'b'], + sort: true + }); + }); + it('should not sort if no domain is sorted', function () { + var domain = mergeDomains([{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'b', + }]); + assert.deepEqual(domain, { + data: 'foo', + fields: ['a', 'b'] + }); + }); + it('should ignore order ascending as it is the default', function () { + var domain = mergeDomains([{ + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean', order: 'ascending' } + }, { + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean' } + }]); + assert.deepEqual(domain, { + data: 'foo', + field: 'a', + sort: { field: 'b', op: 'mean' } + }); + }); + it('should merge domains with the same data', function () { + var domain = mergeDomains([{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'a' + }]); + assert.deepEqual(domain, { + data: 'foo', + field: 'a' + }); + }); + it('should merge domains with the same data source', function () { + var domain = mergeDomains([{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'b' + }]); + assert.deepEqual(domain, { + data: 'foo', + fields: ['a', 'b'] + }); + }); + it('should merge domains with different data source', function () { + var domain = mergeDomains([{ + data: 'foo', + field: 'a', + sort: true + }, { + data: 'bar', + field: 'a', + sort: true + }]); + assert.deepEqual(domain, { + fields: [{ + data: 'foo', + field: 'a' + }, { + data: 'bar', + field: 'a' + }], + sort: true + }); + }); + it('should merge domains with different data and sort', function () { + var domain = mergeDomains([{ + data: 'foo', + field: 'a', + sort: { + op: 'count' + } + }, { + data: 'bar', + field: 'a' + }]); + assert.deepEqual(domain, { + fields: [{ + data: 'foo', + field: 'a' + }, { + data: 'bar', + field: 'a' + }], + sort: { + op: 'count' + } + }); + }); + it('should merge domains with the same and different data', function () { + var domain = mergeDomains([{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'b' + }, { + data: 'bar', + field: 'a' + }]); + assert.deepEqual(domain, { + fields: [{ + data: 'foo', + field: 'a' + }, { + data: 'foo', + field: 'b' + }, { + data: 'bar', + field: 'a' + }] + }); + }); + it('should merge signal domains', function () { + var domain = mergeDomains([{ + signal: 'foo' + }, { + data: 'bar', + field: 'a' + }]); + assert.deepEqual(domain, { + fields: [{ + signal: 'foo' + }, { + data: 'bar', + field: 'a' + } + ] + }); + }); + it('should warn if sorts conflict', log.wrap(function (localLogger) { + var domain = mergeDomains([{ + data: 'foo', + field: 'a', + sort: { + op: 'count' + } + }, { + data: 'foo', + field: 'b', + sort: true + }]); + assert.deepEqual(domain, { + data: 'foo', + fields: ['a', 'b'], + sort: true + }); + assert.equal(localLogger.warns[0], log.message.MORE_THAN_ONE_SORT); + })); + it('should warn if sorts conflict even if we do not union', log.wrap(function (localLogger) { + var domain = mergeDomains([{ + data: 'foo', + field: 'a', + sort: { + op: 'count' + } + }, { + data: 'foo', + field: 'a', + sort: true + }]); + assert.deepEqual(domain, { + data: 'foo', + field: 'a', + sort: true + }); + assert.equal(localLogger.warns[0], log.message.MORE_THAN_ONE_SORT); + })); + it('should warn if we had to drop complex sort', log.wrap(function (localLogger) { + var domain = mergeDomains([{ + data: 'foo', + field: 'a', + sort: { + op: 'mean', + field: 'c' + } + }, { + data: 'foo', + field: 'b' + }]); + assert.deepEqual(domain, { + data: 'foo', + fields: ['a', 'b'], + sort: true + }); + assert.equal(localLogger.warns[0], log.message.domainSortDropped({ + op: 'mean', + field: 'c' + })); + })); + it('should not sort explicit domains', function () { + var domain = mergeDomains([[1, 2, 3, 4], [3, 4, 5, 6]]); + assert.deepEqual(domain, { + fields: [[1, 2, 3, 4], [3, 4, 5, 6]] + }); + }); + }); + describe('domainSort()', function () { + it('should return undefined for continuous domain', function () { + var model = parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' }, + } + }); + var sort = domainSort(model, 'x', ScaleType.LINEAR); + assert.deepEqual(sort, undefined); + }); + it('should return true by default for discrete domain', function () { + var model = parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' }, + } + }); + var sort = domainSort(model, 'x', ScaleType.ORDINAL); + assert.deepEqual(sort, true); + }); + it('should return true for ascending', function () { + var model = parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative', sort: 'ascending' }, + } + }); + var sort = domainSort(model, 'x', ScaleType.ORDINAL); + assert.deepEqual(sort, true); + }); + it('should return undefined if sort = null', function () { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'quantitative', sort: null }, + } + }); + var sort = domainSort(model, 'x', ScaleType.ORDINAL); + assert.deepEqual(sort, undefined); + }); + it('should return normal sort spec if specified and aggregration is not count', function () { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'nominal', sort: { op: 'sum', field: 'y' } }, + y: { field: 'b', aggregate: 'sum', type: 'quantitative' } + } + }); + var sort = domainSort(model, 'x', ScaleType.ORDINAL); + assert.deepEqual(sort, { op: 'sum', field: 'y' }); + }); + it('should return normal sort spec if aggregration is count and field not specified', function () { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'nominal', sort: { op: 'count' } }, + y: { field: 'b', aggregate: 'sum', type: 'quantitative' } + } + }); + var sort = domainSort(model, 'x', ScaleType.ORDINAL); + assert.deepEqual(sort, { op: 'count' }); + }); + it('should return true if sort is not specified', function () { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'nominal' }, + y: { field: 'b', aggregate: 'sum', type: 'quantitative' } + } + }); + var sort = domainSort(model, 'x', ScaleType.ORDINAL); + assert.deepEqual(sort, true); + }); + it('should return undefined if sort is specified', function () { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'nominal', sort: "descending" }, + y: { field: 'b', aggregate: 'sum', type: 'quantitative' } + } + }); + assert.deepEqual(domainSort(model, 'x', ScaleType.ORDINAL), { op: 'min', field: 'a', order: 'descending' }); + }); + it('should return sort spec using derived sort index', function () { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'ordinal', sort: ['B', 'A', 'C'] }, + y: { field: 'b', type: 'quantitative' } + } + }); + assert.deepEqual(domainSort(model, 'x', ScaleType.ORDINAL), { op: 'min', field: 'x_a_sort_index', order: 'ascending' }); + }); + it('should return sort with flattened field access', function () { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'ordinal', sort: { field: 'foo.bar', op: 'mean' } }, + } + }); + assert.deepEqual(domainSort(model, 'x', ScaleType.ORDINAL), { op: 'mean', field: 'foo\\.bar' }); + }); + }); +}); +//# sourceMappingURL=domain.test.js.map \ No newline at end of file diff --git a/build/test/compile/scale/domain.test.js.map b/build/test/compile/scale/domain.test.js.map new file mode 100644 index 0000000000..5c4dec6ec5 --- /dev/null +++ b/build/test/compile/scale/domain.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"domain.test.js","sourceRoot":"","sources":["../../../../test/compile/scale/domain.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {ScaleChannel} from '../../../src/channel';\nimport {domainSort, mergeDomains, parseDomainForChannel} from '../../../src/compile/scale/domain';\nimport {parseScaleCore} from '../../../src/compile/scale/parse';\nimport {UnitModel} from '../../../src/compile/unit';\nimport {MAIN} from '../../../src/data';\nimport {PositionFieldDef} from '../../../src/fielddef';\nimport * as log from '../../../src/log';\nimport {ScaleType} from '../../../src/scale';\nimport {EncodingSortField} from '../../../src/sort';\nimport {VgDomain, VgSortField} from '../../../src/vega.schema';\nimport {parseUnitModel} from '../../util';\n\ndescribe('compile/scale', () => {\n describe('parseDomainForChannel()', () => {\n function testParseDomainForChannel(model: UnitModel, channel: ScaleChannel) {\n // Cannot parseDomain before parseScaleCore\n parseScaleCore(model);\n return parseDomainForChannel(model, channel);\n }\n\n it('should have correct domain with x and x2 channel', function() {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n x: {field: 'a', type: 'quantitative'},\n x2: {field: 'b', type: 'quantitative'},\n y: {field: 'c', type: 'quantitative'},\n y2: {field: 'd', type: 'quantitative'}\n }\n });\n\n const xDomain = testParseDomainForChannel(model, 'x');\n assert.deepEqual(xDomain, [{data: 'main', field: 'a'}, {data: 'main', field: 'b'}]);\n\n const yDomain = testParseDomainForChannel(model, 'y');\n assert.deepEqual(yDomain, [{data: 'main', field: 'c'}, {data: 'main', field: 'd'}]);\n });\n\n it('should have correct domain for color', function() {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n color: {field: 'a', type: 'quantitative'},\n }\n });\n\n const xDomain = testParseDomainForChannel(model, 'color');\n assert.deepEqual(xDomain, [{data: 'main', field: 'a'}]);\n });\n\n it('should have correct domain for color ConditionField', function() {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n color: {\n condition: {selection: 'sel', field: 'a', type: 'quantitative'}\n }\n }\n });\n\n const xDomain = testParseDomainForChannel(model, 'color');\n assert.deepEqual(xDomain, [{data: 'main', field: 'a'}]);\n });\n\n it('should return domain for stack', function() {\n const model = parseUnitModel({\n mark: \"bar\",\n encoding: {\n y: {\n aggregate: 'sum',\n field: 'origin',\n type: 'quantitative'\n },\n x: {field: 'x', type: \"ordinal\"},\n color: {field: 'color', type: \"ordinal\"}\n }\n });\n\n assert.deepEqual(testParseDomainForChannel(model,'y'), [{\n data: 'main',\n field: 'sum_origin_start'\n }, {\n data: 'main',\n field: 'sum_origin_end'\n }]);\n });\n\n it('should return normalize domain for stack if specified', function() {\n const model = parseUnitModel({\n mark: \"bar\",\n encoding: {\n y: {\n aggregate: 'sum',\n field: 'origin',\n type: 'quantitative'\n },\n x: {field: 'x', type: \"ordinal\"},\n color: {field: 'color', type: \"ordinal\"}\n },\n config: {\n stack: \"normalize\"\n }\n });\n\n assert.deepEqual(testParseDomainForChannel(model,'y'), [[0, 1]]);\n });\n\n describe('for quantitative', function() {\n it('should return the right domain for binned Q', log.wrap((localLogger) => {\n const fieldDef: PositionFieldDef = {\n bin: {maxbins: 15},\n field: 'origin',\n scale: {domain: 'unaggregated'},\n type: 'quantitative'\n };\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: fieldDef\n }\n });\n\n assert.deepEqual(testParseDomainForChannel(model,'y'), [{\n data: 'main',\n field: 'bin_maxbins_15_origin'\n }, {\n data: 'main',\n field: 'bin_maxbins_15_origin_end'\n }]);\n\n assert.equal(localLogger.warns[0], log.message.unaggregateDomainHasNoEffectForRawField(fieldDef));\n }));\n\n it('should follow the custom bin.extent for binned Q', log.wrap((localLogger) => {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n field: 'origin',\n type: 'quantitative',\n bin: {maxbins: 15, extent:[0, 100]}\n }\n }\n });\n const _domain = testParseDomainForChannel(model,'y');\n\n assert.deepEqual(_domain, [[0, 100]]);\n }));\n\n it('should return the unaggregated domain if requested for non-bin, non-sum Q',\n function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n aggregate: 'mean',\n field: 'acceleration',\n scale: {domain: 'unaggregated'},\n type: \"quantitative\"\n }\n }\n });\n\n assert.deepEqual(testParseDomainForChannel(model,'y'), [{\n data: MAIN,\n field: 'min_acceleration'\n }, {\n data: MAIN,\n field: 'max_acceleration'\n }]);\n });\n\n it('should return the aggregated domain for sum Q', log.wrap((localLogger) => {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n aggregate: 'sum',\n field: 'origin',\n scale: {domain: 'unaggregated'},\n type: \"quantitative\"\n }\n }\n });\n testParseDomainForChannel(model,'y');\n assert.equal(\n localLogger.warns[0], log.message.unaggregateDomainWithNonSharedDomainOp('sum')\n );\n }));\n\n it('should return the right custom domain', () => {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n field: 'horsepower',\n type: \"quantitative\",\n scale: {domain: [0,200]}\n }\n }\n });\n const _domain = testParseDomainForChannel(model,'y');\n\n assert.deepEqual(_domain, [[0, 200]]);\n });\n\n it('should follow the custom domain despite bin', log.wrap((localLogger) => {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n field: 'origin',\n type: 'quantitative',\n scale: {domain: [0,200]},\n bin: {maxbins: 15}\n }\n }\n });\n const _domain = testParseDomainForChannel(model,'y');\n\n assert.deepEqual(_domain, [[0, 200]]);\n }));\n\n it('should return the aggregated domain if we do not override it', function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n aggregate: 'min',\n field: 'origin',\n type: \"quantitative\"\n }\n }\n });\n\n assert.deepEqual(testParseDomainForChannel(model,'y'), [\n {\n data: 'main',\n field: 'min_origin'\n }\n ]);\n });\n\n it('should use the aggregated data for domain if specified in config', function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n aggregate: 'min',\n field: 'acceleration',\n type: \"quantitative\"\n }\n },\n config: {\n scale: {\n useUnaggregatedDomain: true\n }\n }\n });\n\n assert.deepEqual(testParseDomainForChannel(model,'y'), [{\n data: MAIN,\n field: 'min_acceleration'\n }, {\n data: MAIN,\n field: 'max_acceleration'\n }]);\n });\n });\n\n describe('for time', function() {\n it('should return the correct domain for month T',\n function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n field: 'origin',\n type: \"temporal\",\n timeUnit: 'month'\n }\n }\n });\n const _domain = testParseDomainForChannel(model,'y');\n assert.deepEqual(_domain, [{data: 'main', field: 'month_origin'}]);\n });\n\n it('should return the correct domain for month O',\n function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n field: 'origin',\n type: \"ordinal\",\n timeUnit: 'month'\n }\n }\n });\n const _domain = testParseDomainForChannel(model,'y');\n assert.deepEqual(_domain, [{data: 'main', field: 'month_origin', sort: true}]);\n });\n\n it('should return the correct domain for yearmonth T',\n function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n field: 'origin',\n type: \"temporal\",\n timeUnit: 'yearmonth'\n }\n }\n });\n const _domain = testParseDomainForChannel(model,'y');\n\n assert.deepEqual(_domain, [{data: 'main', field: 'yearmonth_origin'}]);\n });\n\n\n it('should return the correct domain for month O when specify sort',\n function() {\n const sortDef: EncodingSortField = {op: 'mean', field: 'precipitation', order: 'descending'} ;\n const model = parseUnitModel({\n mark: \"bar\",\n encoding: {\n x: {\n timeUnit: 'month',\n field: 'date',\n type: 'ordinal',\n sort: sortDef\n },\n y: {\n aggregate: 'mean',\n field: 'precipitation',\n type: 'quantitative'\n }\n }\n });\n const _domain = testParseDomainForChannel(model,'x');\n\n assert.deepEqual(_domain, [{\n data: 'raw',\n field: 'month_date',\n sort: sortDef\n }]);\n });\n\n it('should return the right custom domain with DateTime objects', () => {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n field: 'year',\n type: \"temporal\",\n scale: {domain: [{year: 1970}, {year: 1980}]}\n }\n }\n });\n const _domain = testParseDomainForChannel(model, 'y');\n\n expect(_domain).toEqual([\n {\"signal\": \"{data: datetime(1970, 0, 1, 0, 0, 0, 0)}\"},\n {\"signal\": \"{data: datetime(1980, 0, 1, 0, 0, 0, 0)}\"}\n ]);\n });\n\n it('should return the right custom domain with date strings', () => {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {\n field: 'year',\n type: \"temporal\",\n scale: {domain: [\"Jan 1, 2007\", \"Jan 1, 2009\"]}\n }\n }\n });\n const _domain = testParseDomainForChannel(model, 'y');\n\n expect(_domain).toEqual([\n {\"signal\": `{data: datetime(\"Jan 1, 2007\")}`},\n {\"signal\": `{data: datetime(\"Jan 1, 2009\")}`},\n ]);\n });\n });\n\n describe('for ordinal', function() {\n it('should have correct domain for binned ordinal color', function() {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n color: {field: 'a', bin: true, type: 'ordinal'},\n }\n });\n\n const xDomain = testParseDomainForChannel(model, 'color');\n assert.deepEqual(xDomain, [{data: 'main', field: 'bin_maxbins_6_a_range', sort: {field: 'bin_maxbins_6_a', op: 'min'}}]);\n });\n });\n\n describe('for nominal', function() {\n it('should return correct domain with the provided sort property', function() {\n const sortDef: EncodingSortField = {op: 'min' as 'min', field:'Acceleration'};\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {field: 'origin', type: \"nominal\", sort: sortDef}\n }\n });\n assert.deepEqual(testParseDomainForChannel(model,'y'), [{\n data: \"raw\",\n field: 'origin',\n sort: sortDef\n }]);\n });\n\n it('should return correct domain with the provided sort property with order property', function() {\n const sortDef: EncodingSortField = {op: 'min', field:'Acceleration', order: \"descending\"} ;\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {field: 'origin', type: \"nominal\", sort: sortDef}\n }\n });\n\n assert.deepEqual(testParseDomainForChannel(model,'y'), [{\n data: \"raw\",\n field: 'origin',\n sort: sortDef\n }]);\n });\n\n it('should return correct domain without sort if sort is not provided', function() {\n const model = parseUnitModel({\n mark: \"point\",\n encoding: {\n y: {field: 'origin', type: \"nominal\"}\n }\n });\n\n assert.deepEqual(testParseDomainForChannel(model,'y'), [{\n data: \"main\",\n field: 'origin',\n sort: true\n }]);\n });\n });\n });\n\n describe('mergeDomains()', () => {\n it('should merge the same domains', () => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a',\n sort: {field: 'b', op: 'mean'}\n }, {\n data: 'foo',\n field: 'a',\n sort: {field: 'b', op: 'mean'}\n }]);\n\n assert.deepEqual(domain, {\n data: 'foo',\n field: 'a',\n sort: {field: 'b', op: 'mean'}\n });\n });\n\n it('should drop field if op is count', () => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a',\n sort: {op: 'count', field: 'b'}\n }]);\n\n assert.deepEqual(domain, {\n data: 'foo',\n field: 'a',\n sort: {op: 'count'}\n });\n });\n\n it('should sort the output domain if one domain is sorted', () => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a'\n }, {\n data: 'foo',\n field: 'a',\n sort: {field: 'b', op: 'mean', order: 'descending'}\n }]);\n\n assert.deepEqual(domain, {\n data: 'foo',\n field: 'a',\n sort: {field: 'b', op: 'mean', order: 'descending'}\n });\n });\n\n it('should sort the output domain if one domain is sorted with true', () => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a',\n sort: true\n }, {\n data: 'foo',\n field: 'b',\n }]);\n\n assert.deepEqual(domain, {\n data: 'foo',\n fields: ['a', 'b'],\n sort: true\n });\n });\n\n it('should not sort if no domain is sorted', () => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a'\n }, {\n data: 'foo',\n field: 'b',\n }]);\n\n assert.deepEqual(domain, {\n data: 'foo',\n fields: ['a', 'b']\n });\n });\n\n it('should ignore order ascending as it is the default', () => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a',\n sort: {field: 'b', op: 'mean', order: 'ascending'}\n }, {\n data: 'foo',\n field: 'a',\n sort: {field: 'b', op: 'mean'}\n }]);\n\n assert.deepEqual(domain, {\n data: 'foo',\n field: 'a',\n sort: {field: 'b', op: 'mean'}\n });\n });\n\n it('should merge domains with the same data', () => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a'\n }, {\n data: 'foo',\n field: 'a'\n }]);\n\n assert.deepEqual(domain, {\n data: 'foo',\n field: 'a'\n });\n });\n\n it('should merge domains with the same data source', () => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a'\n }, {\n data: 'foo',\n field: 'b'\n }]);\n\n assert.deepEqual(domain, {\n data: 'foo',\n fields: ['a', 'b']\n });\n });\n\n it('should merge domains with different data source', () => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a',\n sort: true\n }, {\n data: 'bar',\n field: 'a',\n sort: true\n }]);\n\n assert.deepEqual(domain, {\n fields: [{\n data: 'foo',\n field: 'a'\n }, {\n data: 'bar',\n field: 'a'\n }],\n sort: true\n });\n });\n\n it('should merge domains with different data and sort', () => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a',\n sort: {\n op: 'count'\n }\n }, {\n data: 'bar',\n field: 'a'\n }]);\n\n assert.deepEqual(domain, {\n fields: [{\n data: 'foo',\n field: 'a'\n }, {\n data: 'bar',\n field: 'a'\n }],\n sort: {\n op: 'count'\n }\n });\n });\n\n it('should merge domains with the same and different data', () => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a'\n }, {\n data: 'foo',\n field: 'b'\n }, {\n data: 'bar',\n field: 'a'\n }]);\n\n assert.deepEqual(domain, {\n fields: [{\n data: 'foo',\n field: 'a'\n }, {\n data: 'foo',\n field: 'b'\n }, {\n data: 'bar',\n field: 'a'\n }]\n });\n });\n\n it('should merge signal domains', () => {\n const domain = mergeDomains([{\n signal: 'foo'\n }, {\n data: 'bar',\n field: 'a'\n }]);\n\n assert.deepEqual(domain, {\n fields: [{\n signal: 'foo'\n }, {\n data: 'bar',\n field: 'a'\n }\n ]\n });\n });\n\n it('should warn if sorts conflict', log.wrap((localLogger) => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a',\n sort: {\n op: 'count'\n }\n }, {\n data: 'foo',\n field: 'b',\n sort: true\n }]);\n\n assert.deepEqual(domain, {\n data: 'foo',\n fields: ['a', 'b'],\n sort: true\n });\n\n assert.equal(localLogger.warns[0], log.message.MORE_THAN_ONE_SORT);\n }));\n\n it('should warn if sorts conflict even if we do not union', log.wrap((localLogger) => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a',\n sort: {\n op: 'count'\n }\n }, {\n data: 'foo',\n field: 'a',\n sort: true\n }]);\n\n assert.deepEqual(domain, {\n data: 'foo',\n field: 'a',\n sort: true\n });\n\n assert.equal(localLogger.warns[0], log.message.MORE_THAN_ONE_SORT);\n }));\n\n it('should warn if we had to drop complex sort', log.wrap((localLogger) => {\n const domain = mergeDomains([{\n data: 'foo',\n field: 'a',\n sort: {\n op: 'mean',\n field: 'c'\n }\n }, {\n data: 'foo',\n field: 'b'\n }]);\n\n assert.deepEqual(domain, {\n data: 'foo',\n fields: ['a', 'b'],\n sort: true\n });\n\n assert.equal(localLogger.warns[0], log.message.domainSortDropped({\n op: 'mean',\n field: 'c'\n }));\n }));\n\n it('should not sort explicit domains', () => {\n const domain = mergeDomains([[1,2,3,4], [3,4,5,6]]);\n\n assert.deepEqual(domain, {\n fields: [[1,2,3,4], [3,4,5,6]]\n });\n });\n });\n\n describe('domainSort()', () => {\n it('should return undefined for continuous domain', () => {\n const model = parseUnitModel({\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'quantitative'},\n }\n });\n const sort = domainSort(model, 'x', ScaleType.LINEAR);\n assert.deepEqual(sort, undefined);\n });\n\n it('should return true by default for discrete domain', () => {\n const model = parseUnitModel({\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal'},\n }\n });\n const sort = domainSort(model, 'x', ScaleType.ORDINAL);\n assert.deepEqual(sort, true);\n });\n\n it('should return true for ascending', () => {\n const model = parseUnitModel({\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'quantitative', sort: 'ascending'},\n }\n });\n const sort = domainSort(model, 'x', ScaleType.ORDINAL);\n assert.deepEqual(sort, true);\n });\n\n it('should return undefined if sort = null', () => {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n x: {field: 'a', type: 'quantitative', sort: null},\n }\n });\n const sort = domainSort(model, 'x', ScaleType.ORDINAL);\n assert.deepEqual(sort, undefined);\n });\n\n it('should return normal sort spec if specified and aggregration is not count', () => {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n x: {field: 'a', type: 'nominal', sort: {op: 'sum', field:'y'}},\n y: {field: 'b', aggregate: 'sum', type: 'quantitative'}\n }\n });\n const sort = domainSort(model, 'x', ScaleType.ORDINAL);\n assert.deepEqual(sort, {op: 'sum', field: 'y'});\n });\n\n it('should return normal sort spec if aggregration is count and field not specified', () => {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n x: {field: 'a', type: 'nominal', sort: {op: 'count'}},\n y: {field: 'b', aggregate: 'sum', type: 'quantitative'}\n }\n });\n const sort = domainSort(model, 'x', ScaleType.ORDINAL);\n assert.deepEqual(sort, {op: 'count'});\n });\n\n it('should return true if sort is not specified', () => {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n x: {field: 'a', type: 'nominal'},\n y: {field: 'b', aggregate: 'sum', type: 'quantitative'}\n }\n });\n const sort = domainSort(model, 'x', ScaleType.ORDINAL);\n assert.deepEqual(sort, true);\n });\n\n it('should return undefined if sort is specified', () => {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n x: {field: 'a', type: 'nominal', sort: \"descending\"},\n y: {field: 'b', aggregate: 'sum', type: 'quantitative'}\n }\n });\n assert.deepEqual(domainSort(model, 'x', ScaleType.ORDINAL), {op: 'min', field: 'a', order: 'descending'});\n });\n\n it('should return sort spec using derived sort index', () => {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n x: {field: 'a', type: 'ordinal', sort: ['B', 'A', 'C']},\n y: {field: 'b', type: 'quantitative'}\n }\n });\n assert.deepEqual(domainSort(model, 'x', ScaleType.ORDINAL), {op: 'min', field: 'x_a_sort_index', order: 'ascending'});\n });\n\n it('should return sort with flattened field access', () => {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n x: {field: 'a', type: 'ordinal', sort: {field: 'foo.bar', op: 'mean'}},\n }\n });\n assert.deepEqual(domainSort(model, 'x', ScaleType.ORDINAL), {op: 'mean', field: 'foo\\\\.bar'});\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/scale/parse.test.d.ts b/build/test/compile/scale/parse.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/scale/parse.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/scale/parse.test.js b/build/test/compile/scale/parse.test.js new file mode 100644 index 0000000000..af43d71edd --- /dev/null +++ b/build/test/compile/scale/parse.test.js @@ -0,0 +1,467 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { toSet } from 'vega-util'; +import { parseScale, parseScaleCore } from '../../../src/compile/scale/parse'; +import { SELECTION_DOMAIN } from '../../../src/compile/selection/selection'; +import * as log from '../../../src/log'; +import { NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES, SCALE_PROPERTIES } from '../../../src/scale'; +import { without } from '../../../src/util'; +import { parseModel, parseModelWithScale, parseUnitModelWithScale } from '../../util'; +describe('src/compile', function () { + it('NON_TYPE_RANGE_SCALE_PROPERTIES should be SCALE_PROPERTIES wihtout type, domain, and range properties', function () { + assert.deepEqual(toSet(NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES), toSet(without(SCALE_PROPERTIES, ['type', 'domain', 'range', 'rangeStep', 'scheme']))); + }); + describe('parseScaleCore', function () { + it('respects explicit scale type', function () { + var model = parseModel({ + "data": { "url": "data/seattle-weather.csv" }, + "layer": [ + { + "mark": "bar", + "encoding": { + "y": { + "aggregate": "mean", + "field": "precipitation", + "type": "quantitative" + } + } + }, + { + "mark": "rule", + "encoding": { + "y": { + "aggregate": "mean", + "field": "precipitation", + "type": "quantitative", + "scale": { "type": "log" } + } + } + } + ] + }); + parseScaleCore(model); + assert.equal(model.getScaleComponent('y').explicit.type, 'log'); + }); + it('respects explicit scale type', function () { + var model = parseModel({ + "data": { "url": "data/seattle-weather.csv" }, + "layer": [ + { + "mark": "bar", + "encoding": { + "y": { + "aggregate": "mean", + "field": "precipitation", + "type": "quantitative", + "scale": { "type": "log" } + } + } + }, + { + "mark": "rule", + "encoding": { + "y": { + "aggregate": "mean", + "field": "precipitation", + "type": "quantitative" + } + } + } + ] + }); + parseScaleCore(model); + assert.equal(model.getScaleComponent('y').explicit.type, 'log'); + }); + // TODO: this actually shouldn't get merged + it('favors the first explicit scale type', log.wrap(function (localLogger) { + var model = parseModel({ + "data": { "url": "data/seattle-weather.csv" }, + "layer": [ + { + "mark": "bar", + "encoding": { + "y": { + "aggregate": "mean", + "field": "precipitation", + "type": "quantitative", + "scale": { "type": "log" } + } + } + }, + { + "mark": "rule", + "encoding": { + "y": { + "aggregate": "mean", + "field": "precipitation", + "type": "quantitative", + "scale": { "type": "pow" } + } + } + } + ] + }); + parseScaleCore(model); + assert.equal(model.getScaleComponent('y').explicit.type, 'log'); + assert.equal(localLogger.warns[0], log.message.mergeConflictingProperty('type', 'scale', 'log', 'pow')); + })); + it('favors the band over point', function () { + var model = parseModel({ + "data": { "url": "data/seattle-weather.csv" }, + "layer": [ + { + "mark": "point", + "encoding": { + "y": { + "aggregate": "mean", + "field": "precipitation", + "type": "quantitative" + }, + "x": { "field": "weather", "type": "nominal" } + } + }, { + "mark": "bar", + "encoding": { + "y": { + "aggregate": "mean", + "field": "precipitation", + "type": "quantitative" + }, + "x": { "field": "weather", "type": "nominal" } + } + }, + ] + }); + parseScaleCore(model); + assert.equal(model.getScaleComponent('x').implicit.type, 'band'); + }); + it('correctly ignores x/y when lon/lat', function () { + var model = parseModel({ + "data": { + "url": "data/zipcodes.csv", + "format": { + "type": "csv" + } + }, + "mark": "point", + "encoding": { + "longitude": { + "field": "longitude", + "type": "quantitative" + }, + "latitude": { + "field": "latitude", + "type": "quantitative" + } + } + }); + parseScaleCore(model); + assert.isUndefined(model.getScaleComponent('x')); + assert.isUndefined(model.getScaleComponent('y')); + }); + it('correctly ignores shape when geojson', function () { + var model = parseModel({ + "mark": "geoshape", + "data": { "url": "data/income.json" }, + "transform": [ + { + "lookup": "id", + "from": { + "data": { + "url": "data/us-10m.json", + "format": { "type": "topojson", "feature": "states" } + }, + "key": "id" + }, + "as": "geo" + } + ], + "encoding": { + "shape": { "field": "geo", "type": "geojson" }, + } + }); + parseScaleCore(model); + assert.isUndefined(model.getScaleComponent('shape')); + }); + }); + describe('parseScale', function () { + it('does not throw warning when two equivalent objects are specified', log.wrap(function (logger) { + var model = parseModel({ + "data": { "url": "data/seattle-weather.csv" }, + "layer": [ + { + "mark": "circle", + "encoding": { + "y": { + "field": "a", + "type": "nominal", + "scale": { "rangeStep": 17 } + } + } + }, + { + "mark": "point", + "encoding": { + "y": { + "field": "a", + "type": "nominal", + "scale": { "rangeStep": 17 } + } + } + } + ] + }); + parseScale(model); + assert.deepEqual(model.getScaleComponent('y').explicit.range, { step: 17 }); + assert.equal(logger.warns.length, 0); + })); + describe('x ordinal point', function () { + it('should create an x point scale with rangeStep and no range', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + x: { field: 'origin', type: "nominal" } + } + }); + var scale = model.getScaleComponent('x'); + assert.equal(scale.implicit.type, 'point'); + assert.deepEqual(scale.implicit.range, { step: 21 }); + }); + }); + it('should output only padding without default paddingInner and paddingOuter if padding is specified for a band scale', function () { + var model = parseUnitModelWithScale({ + mark: 'bar', + encoding: { + x: { field: 'origin', type: "nominal", scale: { type: 'band', padding: 0.6 } } + } + }); + var scale = model.getScaleComponent('x'); + assert.equal(scale.explicit.padding, 0.6); + assert.isUndefined(scale.get('paddingInner')); + assert.isUndefined(scale.get('paddingOuter')); + }); + it('should output default paddingInner and paddingOuter = paddingInner/2 if none of padding properties is specified for a band scale', function () { + var model = parseUnitModelWithScale({ + mark: 'bar', + encoding: { + x: { field: 'origin', type: "nominal", scale: { type: 'band' } } + }, + config: { + scale: { bandPaddingInner: 0.3 } + } + }); + var scale = model.getScaleComponent('x'); + assert.equal(scale.implicit.paddingInner, 0.3); + assert.equal(scale.implicit.paddingOuter, 0.15); + assert.isUndefined(scale.get('padding')); + }); + describe('nominal with color', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: 'origin', type: "nominal" } + } + }); + var scale = model.getScaleComponent('color'); + it('should create correct color scale', function () { + assert.equal(scale.implicit.name, 'color'); + assert.equal(scale.implicit.type, 'ordinal'); + assert.deepEqual(scale.domains, [{ + data: 'main', + field: 'origin', + sort: true + }]); + assert.equal(scale.implicit.range, 'category'); + }); + }); + describe('ordinal with color', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: 'origin', type: "ordinal" } + } + }); + var scale = model.getScaleComponent('color'); + it('should create sequential color scale', function () { + assert.equal(scale.implicit.name, 'color'); + assert.equal(scale.implicit.type, 'ordinal'); + assert.deepEqual(scale.domains, [{ + data: 'main', + field: 'origin', + sort: true + }]); + }); + }); + describe('quantitative with color', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: "origin", type: "quantitative" } + } + }); + var scale = model.getScaleComponent('color'); + it('should create linear color scale', function () { + assert.equal(scale.implicit.name, 'color'); + assert.equal(scale.implicit.type, 'sequential'); + assert.equal(scale.implicit.range, 'ramp'); + assert.deepEqual(scale.domains, [{ + data: 'main', + field: 'origin' + }]); + }); + }); + describe('color with bin', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: "origin", type: "quantitative", bin: true } + } + }); + var scale = model.getScaleComponent('color'); + it('should add correct scales', function () { + assert.equal(scale.implicit.name, 'color'); + assert.equal(scale.implicit.type, 'bin-ordinal'); + }); + }); + describe('ordinal color with bin', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: "origin", type: "ordinal", bin: true } + } + }); + var scale = model.getScaleComponent('color'); + it('should add correct scales', function () { + assert.equal(scale.implicit.name, 'color'); + assert.equal(scale.implicit.type, 'ordinal'); + }); + }); + describe('opacity with bin', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + opacity: { field: "origin", type: "quantitative", bin: true } + } + }); + var scale = model.getScaleComponent('opacity'); + it('should add correct scales', function () { + assert.equal(scale.implicit.name, 'opacity'); + assert.equal(scale.implicit.type, 'bin-linear'); + }); + }); + describe('size with bin', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + size: { field: "origin", type: "quantitative", bin: true } + } + }); + var scale = model.getScaleComponent('size'); + it('should add correct scales', function () { + assert.equal(scale.implicit.name, 'size'); + assert.equal(scale.implicit.type, 'bin-linear'); + }); + }); + describe('color with time unit', function () { + var model = parseUnitModelWithScale({ + mark: "point", + encoding: { + color: { field: 'origin', type: "temporal", timeUnit: "year" } + } + }); + var scale = model.getScaleComponent('color'); + it('should add correct scales', function () { + assert.equal(scale.implicit.name, 'color'); + assert.equal(scale.implicit.type, 'sequential'); + }); + }); + describe('selection domain', function () { + var model = parseUnitModelWithScale({ + mark: "area", + encoding: { + x: { + field: "date", type: "temporal", + scale: { domain: { selection: "brush", encoding: "x" } }, + }, + y: { + field: "date", type: "temporal", + scale: { domain: { selection: "foobar", field: "Miles_per_Gallon" } }, + } + } + }); + var xScale = model.getScaleComponent('x'); + var yscale = model.getScaleComponent('y'); + it('should add a raw selection domain', function () { + assert.property(xScale.explicit, 'domainRaw'); + assert.propertyVal(xScale.explicit.domainRaw, 'signal', SELECTION_DOMAIN + '{"encoding":"x","selection":"brush"}'); + assert.property(yscale.explicit, 'domainRaw'); + assert.propertyVal(yscale.explicit.domainRaw, 'signal', SELECTION_DOMAIN + '{"field":"Miles_per_Gallon","selection":"foobar"}'); + }); + }); + }); + describe('parseScaleDomain', function () { + describe('faceted domains', function () { + it('should use cloned subtree', function () { + var model = parseModelWithScale({ + facet: { + row: { field: "symbol", type: "nominal" } + }, + data: { url: "foo.csv" }, + spec: { + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' }, + } + } + }); + assert.deepEqual(model.component.scales.x.domains, [{ + data: 'scale_child_main', + field: 'a' + }]); + }); + it('should not use cloned subtree if the data is not faceted', function () { + var model = parseModelWithScale({ + facet: { + row: { field: "symbol", type: "nominal" } + }, + data: { url: "foo.csv" }, + spec: { + data: { url: 'foo' }, + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' }, + } + } + }); + assert.deepEqual(model.component.scales.x.domains, [{ + data: 'child_main', + field: 'a' + }]); + }); + it('should not use cloned subtree if the scale is independent', function () { + var model = parseModelWithScale({ + facet: { + row: { field: "symbol", type: "nominal" } + }, + data: { url: "foo.csv" }, + spec: { + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' }, + } + }, + resolve: { + scale: { + x: 'independent' + } + } + }); + assert.deepEqual(model.children[0].component.scales.x.domains, [{ + data: 'child_main', + field: 'a' + }]); + }); + }); + }); +}); +//# sourceMappingURL=parse.test.js.map \ No newline at end of file diff --git a/build/test/compile/scale/parse.test.js.map b/build/test/compile/scale/parse.test.js.map new file mode 100644 index 0000000000..21442b68d8 --- /dev/null +++ b/build/test/compile/scale/parse.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.test.js","sourceRoot":"","sources":["../../../../test/compile/scale/parse.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {toSet} from 'vega-util';\nimport {parseScale, parseScaleCore} from '../../../src/compile/scale/parse';\nimport {SELECTION_DOMAIN} from '../../../src/compile/selection/selection';\nimport * as log from '../../../src/log';\nimport {NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES, SCALE_PROPERTIES} from '../../../src/scale';\nimport {without} from '../../../src/util';\nimport {parseModel, parseModelWithScale, parseUnitModelWithScale} from '../../util';\n\ndescribe('src/compile', function() {\n it('NON_TYPE_RANGE_SCALE_PROPERTIES should be SCALE_PROPERTIES wihtout type, domain, and range properties', () => {\n assert.deepEqual(\n toSet(NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES),\n toSet(without(SCALE_PROPERTIES, ['type', 'domain', 'range', 'rangeStep', 'scheme']))\n );\n });\n\n describe('parseScaleCore', () => {\n it('respects explicit scale type', () => {\n const model = parseModel({\n \"data\": {\"url\": \"data/seattle-weather.csv\"},\n \"layer\": [\n {\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"precipitation\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"precipitation\",\n \"type\": \"quantitative\",\n \"scale\": {\"type\": \"log\"}\n }\n }\n }\n ]\n });\n parseScaleCore(model);\n assert.equal(model.getScaleComponent('y').explicit.type, 'log');\n });\n\n it('respects explicit scale type', () => {\n const model = parseModel({\n \"data\": {\"url\": \"data/seattle-weather.csv\"},\n \"layer\": [\n {\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"precipitation\",\n \"type\": \"quantitative\",\n \"scale\": {\"type\": \"log\"}\n }\n }\n },\n {\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"precipitation\",\n \"type\": \"quantitative\"\n }\n }\n }\n ]\n });\n parseScaleCore(model);\n assert.equal(model.getScaleComponent('y').explicit.type, 'log');\n });\n\n // TODO: this actually shouldn't get merged\n it('favors the first explicit scale type', log.wrap((localLogger) => {\n const model = parseModel({\n \"data\": {\"url\": \"data/seattle-weather.csv\"},\n \"layer\": [\n {\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"precipitation\",\n \"type\": \"quantitative\",\n \"scale\": {\"type\": \"log\"}\n }\n }\n },\n {\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"precipitation\",\n \"type\": \"quantitative\",\n \"scale\": {\"type\": \"pow\"}\n }\n }\n }\n ]\n });\n parseScaleCore(model);\n assert.equal(model.getScaleComponent('y').explicit.type, 'log');\n assert.equal(localLogger.warns[0], log.message.mergeConflictingProperty('type', 'scale', 'log', 'pow'));\n }));\n\n it('favors the band over point', () => {\n const model = parseModel({\n \"data\": {\"url\": \"data/seattle-weather.csv\"},\n \"layer\": [\n {\n \"mark\": \"point\",\n \"encoding\": {\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"precipitation\",\n \"type\": \"quantitative\"\n },\n \"x\": {\"field\": \"weather\", \"type\": \"nominal\"}\n }\n },{\n \"mark\": \"bar\",\n \"encoding\": {\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"precipitation\",\n \"type\": \"quantitative\"\n },\n \"x\": {\"field\": \"weather\", \"type\": \"nominal\"}\n }\n },\n ]\n });\n parseScaleCore(model);\n assert.equal(model.getScaleComponent('x').implicit.type, 'band');\n });\n\n it('correctly ignores x/y when lon/lat', () => {\n const model = parseModel({\n \"data\": {\n \"url\": \"data/zipcodes.csv\",\n \"format\": {\n \"type\": \"csv\"\n }\n },\n \"mark\": \"point\",\n \"encoding\": {\n \"longitude\": {\n \"field\": \"longitude\",\n \"type\": \"quantitative\"\n },\n \"latitude\": {\n \"field\": \"latitude\",\n \"type\": \"quantitative\"\n }\n }\n });\n parseScaleCore(model);\n assert.isUndefined(model.getScaleComponent('x'));\n assert.isUndefined(model.getScaleComponent('y'));\n });\n\n it('correctly ignores shape when geojson', () => {\n const model = parseModel({\n \"mark\": \"geoshape\",\n \"data\": {\"url\": \"data/income.json\"},\n \"transform\": [\n {\n \"lookup\": \"id\",\n \"from\": {\n \"data\": {\n \"url\": \"data/us-10m.json\",\n \"format\": {\"type\": \"topojson\",\"feature\": \"states\"}\n },\n \"key\": \"id\"\n },\n \"as\": \"geo\"\n }\n ],\n \"encoding\": {\n \"shape\": {\"field\": \"geo\",\"type\": \"geojson\"},\n }\n });\n parseScaleCore(model);\n assert.isUndefined(model.getScaleComponent('shape'));\n });\n });\n\n describe('parseScale', () => {\n it('does not throw warning when two equivalent objects are specified', log.wrap((logger) => {\n const model = parseModel({\n \"data\": {\"url\": \"data/seattle-weather.csv\"},\n \"layer\": [\n {\n \"mark\": \"circle\",\n \"encoding\": {\n \"y\": {\n \"field\": \"a\",\n \"type\": \"nominal\",\n \"scale\": {\"rangeStep\": 17}\n }\n }\n },\n {\n \"mark\": \"point\",\n \"encoding\": {\n \"y\": {\n \"field\": \"a\",\n \"type\": \"nominal\",\n \"scale\": {\"rangeStep\": 17}\n }\n }\n }\n ]\n });\n parseScale(model);\n assert.deepEqual(model.getScaleComponent('y').explicit.range, {step: 17});\n assert.equal(logger.warns.length, 0);\n }));\n\n describe('x ordinal point', () => {\n it('should create an x point scale with rangeStep and no range', () => {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n x: {field: 'origin', type: \"nominal\"}\n }\n });\n const scale = model.getScaleComponent('x');\n assert.equal(scale.implicit.type, 'point');\n assert.deepEqual(scale.implicit.range, {step: 21});\n });\n });\n\n it('should output only padding without default paddingInner and paddingOuter if padding is specified for a band scale', () => {\n const model = parseUnitModelWithScale({\n mark: 'bar',\n encoding: {\n x: {field: 'origin', type: \"nominal\", scale: {type: 'band', padding: 0.6}}\n }\n });\n const scale = model.getScaleComponent('x');\n assert.equal(scale.explicit.padding, 0.6);\n assert.isUndefined(scale.get('paddingInner'));\n assert.isUndefined(scale.get('paddingOuter'));\n });\n\n it('should output default paddingInner and paddingOuter = paddingInner/2 if none of padding properties is specified for a band scale', () => {\n const model = parseUnitModelWithScale({\n mark: 'bar',\n encoding: {\n x: {field: 'origin', type: \"nominal\", scale: {type: 'band'}}\n },\n config: {\n scale: {bandPaddingInner: 0.3}\n }\n });\n const scale = model.getScaleComponent('x');\n assert.equal(scale.implicit.paddingInner, 0.3);\n assert.equal(scale.implicit.paddingOuter, 0.15);\n assert.isUndefined(scale.get('padding'));\n });\n\n describe('nominal with color', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n color: {field: 'origin', type: \"nominal\"}\n }\n });\n\n const scale = model.getScaleComponent('color');\n\n it('should create correct color scale', function() {\n assert.equal(scale.implicit.name, 'color');\n assert.equal(scale.implicit.type, 'ordinal');\n assert.deepEqual(scale.domains, [{\n data: 'main',\n field: 'origin',\n sort: true\n }]);\n assert.equal(scale.implicit.range, 'category');\n });\n });\n\n describe('ordinal with color', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n color: {field: 'origin', type: \"ordinal\"}\n }\n });\n\n const scale = model.getScaleComponent('color');\n\n it('should create sequential color scale', function() {\n assert.equal(scale.implicit.name, 'color');\n assert.equal(scale.implicit.type, 'ordinal');\n\n assert.deepEqual(scale.domains, [{\n data: 'main',\n field: 'origin',\n sort: true\n }]);\n });\n });\n\n describe('quantitative with color', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n color: {field: \"origin\", type: \"quantitative\"}\n }\n });\n\n const scale = model.getScaleComponent('color');\n\n it('should create linear color scale', function() {\n assert.equal(scale.implicit.name, 'color');\n assert.equal(scale.implicit.type, 'sequential');\n assert.equal(scale.implicit.range, 'ramp');\n\n assert.deepEqual(scale.domains, [{\n data: 'main',\n field: 'origin'\n }]);\n });\n });\n\n describe('color with bin', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n color: {field: \"origin\", type: \"quantitative\", bin: true}\n }\n });\n\n const scale = model.getScaleComponent('color');\n\n it('should add correct scales', function() {\n assert.equal(scale.implicit.name, 'color');\n assert.equal(scale.implicit.type, 'bin-ordinal');\n });\n });\n\n describe('ordinal color with bin', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n color: {field: \"origin\", type: \"ordinal\", bin: true}\n }\n });\n\n const scale = model.getScaleComponent('color');\n\n it('should add correct scales', function() {\n assert.equal(scale.implicit.name, 'color');\n assert.equal(scale.implicit.type, 'ordinal');\n });\n });\n\n describe('opacity with bin', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n opacity: {field: \"origin\", type: \"quantitative\", bin: true}\n }\n });\n\n const scale = model.getScaleComponent('opacity');\n\n it('should add correct scales', function() {\n assert.equal(scale.implicit.name, 'opacity');\n assert.equal(scale.implicit.type, 'bin-linear');\n });\n });\n\n describe('size with bin', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n size: {field: \"origin\", type: \"quantitative\", bin: true}\n }\n });\n\n const scale = model.getScaleComponent('size');\n\n it('should add correct scales', function() {\n assert.equal(scale.implicit.name, 'size');\n assert.equal(scale.implicit.type, 'bin-linear');\n });\n });\n\n describe('color with time unit', function() {\n const model = parseUnitModelWithScale({\n mark: \"point\",\n encoding: {\n color: {field: 'origin', type: \"temporal\", timeUnit: \"year\"}\n }\n });\n\n const scale = model.getScaleComponent('color');\n\n it('should add correct scales', function() {\n assert.equal(scale.implicit.name, 'color');\n assert.equal(scale.implicit.type, 'sequential');\n });\n });\n\n describe('selection domain', function() {\n const model = parseUnitModelWithScale({\n mark: \"area\",\n encoding: {\n x: {\n field: \"date\", type: \"temporal\",\n scale: {domain: {selection: \"brush\", encoding: \"x\"}},\n },\n y: {\n field: \"date\", type: \"temporal\",\n scale: {domain: {selection: \"foobar\", field: \"Miles_per_Gallon\"}},\n }\n }\n });\n\n const xScale = model.getScaleComponent('x');\n const yscale = model.getScaleComponent('y');\n\n it('should add a raw selection domain', function() {\n assert.property(xScale.explicit, 'domainRaw');\n assert.propertyVal(xScale.explicit.domainRaw, 'signal',\n SELECTION_DOMAIN + '{\"encoding\":\"x\",\"selection\":\"brush\"}');\n\n assert.property(yscale.explicit, 'domainRaw');\n assert.propertyVal(yscale.explicit.domainRaw, 'signal',\n SELECTION_DOMAIN + '{\"field\":\"Miles_per_Gallon\",\"selection\":\"foobar\"}');\n });\n });\n });\n\n describe('parseScaleDomain', function() {\n describe('faceted domains', function() {\n it('should use cloned subtree', function() {\n const model = parseModelWithScale({\n facet: {\n row: {field: \"symbol\", type: \"nominal\"}\n },\n data: {url: \"foo.csv\"},\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'quantitative'},\n }\n }\n });\n\n assert.deepEqual(model.component.scales.x.domains, [{\n data: 'scale_child_main',\n field: 'a'\n }]);\n });\n\n it('should not use cloned subtree if the data is not faceted', function() {\n const model = parseModelWithScale({\n facet: {\n row: {field: \"symbol\", type: \"nominal\"}\n },\n data: {url: \"foo.csv\"},\n spec: {\n data: {url: 'foo'},\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'quantitative'},\n }\n }\n });\n\n assert.deepEqual(model.component.scales.x.domains, [{\n data: 'child_main',\n field: 'a'\n }]);\n });\n\n it('should not use cloned subtree if the scale is independent', function() {\n const model = parseModelWithScale({\n facet: {\n row: {field: \"symbol\", type: \"nominal\"}\n },\n data: {url: \"foo.csv\"},\n spec: {\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'quantitative'},\n }\n },\n resolve: {\n scale: {\n x: 'independent'\n }\n }\n });\n\n assert.deepEqual(model.children[0].component.scales.x.domains, [{\n data: 'child_main',\n field: 'a'\n }]);\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/scale/properties.test.d.ts b/build/test/compile/scale/properties.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/scale/properties.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/scale/properties.test.js b/build/test/compile/scale/properties.test.js new file mode 100644 index 0000000000..fd6040df68 --- /dev/null +++ b/build/test/compile/scale/properties.test.js @@ -0,0 +1,135 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { NONPOSITION_SCALE_CHANNELS } from '../../../src/channel'; +import * as rules from '../../../src/compile/scale/properties'; +import { AREA, BAR, LINE } from '../../../src/mark'; +describe('compile/scale', function () { + describe('nice', function () { + it('should return nice for x and y.', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var c = _a[_i]; + assert.equal(rules.nice('linear', c, { type: 'quantitative' }), true); + } + }); + it('should not return nice for binned x and y.', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var c = _a[_i]; + assert.equal(rules.nice('linear', c, { type: 'quantitative', bin: true }), undefined); + } + }); + it('should not return nice for temporal x and y.', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var c = _a[_i]; + assert.equal(rules.nice('time', c, { type: 'temporal' }), undefined); + } + }); + }); + describe('padding', function () { + it('should be pointPadding for point scale if channel is x or y and padding is not specified.', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var c = _a[_i]; + assert.equal(rules.padding(c, 'point', { pointPadding: 13 }, undefined, undefined, undefined), 13); + } + }); + it('should be continuousBandSize for linear x-scale of vertical bar.', function () { + assert.equal(rules.padding('x', 'linear', {}, { field: 'date', type: 'temporal' }, { type: 'bar', orient: 'vertical' }, { continuousBandSize: 13 }), 13); + }); + it('should be undefined for linear x-scale for binned field of vertical bar.', function () { + assert.equal(rules.padding('x', 'linear', {}, { bin: true, field: 'date', type: 'temporal' }, { type: 'bar', orient: 'vertical' }, { continuousBandSize: 13 }), undefined); + }); + it('should be continuousBandSize for linear y-scale of horizontal bar.', function () { + assert.equal(rules.padding('y', 'linear', {}, { field: 'date', type: 'temporal' }, { type: 'bar', orient: 'horizontal' }, { continuousBandSize: 13 }), 13); + }); + }); + describe('paddingInner', function () { + it('should be undefined if padding is specified.', function () { + assert.equal(rules.paddingInner(10, 'x', {}), undefined); + }); + it('should be bandPaddingInner if channel is x or y and padding is not specified.', function () { + assert.equal(rules.paddingInner(undefined, 'x', { bandPaddingInner: 15 }), 15); + assert.equal(rules.paddingInner(undefined, 'y', { bandPaddingInner: 15 }), 15); + }); + it('should be undefined for non-xy channels.', function () { + for (var _i = 0, NONPOSITION_SCALE_CHANNELS_1 = NONPOSITION_SCALE_CHANNELS; _i < NONPOSITION_SCALE_CHANNELS_1.length; _i++) { + var c = NONPOSITION_SCALE_CHANNELS_1[_i]; + assert.equal(rules.paddingInner(undefined, c, { bandPaddingInner: 15 }), undefined); + } + }); + }); + describe('paddingOuter', function () { + it('should be undefined if padding is specified.', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + assert.equal(rules.paddingOuter(10, 'x', scaleType, 0, {}), undefined); + } + }); + it('should be config.scale.bandPaddingOuter for band scale if channel is x or y and padding is not specified and config.scale.bandPaddingOuter.', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var c = _a[_i]; + assert.equal(rules.paddingOuter(undefined, c, 'band', 0, { bandPaddingOuter: 16 }), 16); + } + }); + it('should be paddingInner/2 for band scale if channel is x or y and padding is not specified and config.scale.bandPaddingOuter.', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var c = _a[_i]; + assert.equal(rules.paddingOuter(undefined, c, 'band', 10, {}), 5); + } + }); + it('should be undefined for non-xy channels.', function () { + for (var _i = 0, NONPOSITION_SCALE_CHANNELS_2 = NONPOSITION_SCALE_CHANNELS; _i < NONPOSITION_SCALE_CHANNELS_2.length; _i++) { + var c = NONPOSITION_SCALE_CHANNELS_2[_i]; + for (var _a = 0, _b = ['point', 'band']; _a < _b.length; _a++) { + var scaleType = _b[_a]; + assert.equal(rules.paddingOuter(undefined, c, scaleType, 0, {}), undefined); + } + } + }); + }); + describe('reverse', function () { + it('should return true for a continuous scale with sort = "descending".', function () { + assert.isTrue(rules.reverse('linear', 'descending')); + }); + it('should return false for a discrete scale with sort = "descending".', function () { + assert.isUndefined(rules.reverse('point', 'descending')); + }); + }); + describe('zero', function () { + it('should return true when mapping a quantitative field to x with scale.domain = "unaggregated"', function () { + assert(rules.zero('x', { field: 'a', type: 'quantitative' }, 'unaggregated', { type: 'point' })); + }); + it('should return true when mapping a quantitative field to size', function () { + assert(rules.zero('size', { field: 'a', type: 'quantitative' }, undefined, { type: 'point' })); + }); + it('should return false when mapping a ordinal field to size', function () { + assert(!rules.zero('size', { field: 'a', type: 'ordinal' }, undefined, { type: 'point' })); + }); + it('should return true when mapping a non-binned quantitative field to x/y of point', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var channel = _a[_i]; + assert(rules.zero(channel, { field: 'a', type: 'quantitative' }, undefined, { type: 'point' })); + } + }); + it('should return false when mapping a quantitative field to dimension axis of bar, line, and area', function () { + for (var _i = 0, _a = [BAR, AREA, LINE]; _i < _a.length; _i++) { + var mark = _a[_i]; + assert.isFalse(rules.zero('x', { field: 'a', type: 'quantitative' }, undefined, { type: mark, orient: 'vertical' })); + assert.isFalse(rules.zero('y', { field: 'a', type: 'quantitative' }, undefined, { type: mark, orient: 'horizontal' })); + } + }); + it('should return false when mapping a binned quantitative field to x/y', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var channel = _a[_i]; + assert(!rules.zero(channel, { bin: true, field: 'a', type: 'quantitative' }, undefined, { type: 'point' })); + } + }); + it('should return false when mapping a non-binned quantitative field with custom domain to x/y', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var channel = _a[_i]; + assert(!rules.zero(channel, { + bin: true, field: 'a', type: 'quantitative' + }, [3, 5], { type: 'point' })); + } + }); + }); +}); +//# sourceMappingURL=properties.test.js.map \ No newline at end of file diff --git a/build/test/compile/scale/properties.test.js.map b/build/test/compile/scale/properties.test.js.map new file mode 100644 index 0000000000..2877ca438d --- /dev/null +++ b/build/test/compile/scale/properties.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"properties.test.js","sourceRoot":"","sources":["../../../../test/compile/scale/properties.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\n\nimport {Channel, NONPOSITION_SCALE_CHANNELS} from '../../../src/channel';\nimport {ScaleType} from '../../../src/scale';\n\nimport * as rules from '../../../src/compile/scale/properties';\nimport {AREA, BAR, LINE} from '../../../src/mark';\n\ndescribe('compile/scale', () => {\n describe('nice', () => {\n it('should return nice for x and y.', () => {\n for (const c of ['x', 'y'] as Channel[]) {\n assert.equal(rules.nice('linear', c, {type: 'quantitative'}), true);\n }\n });\n\n it('should not return nice for binned x and y.', () => {\n for (const c of ['x', 'y'] as Channel[]) {\n assert.equal(rules.nice('linear', c, {type: 'quantitative', bin: true}), undefined);\n }\n });\n\n it('should not return nice for temporal x and y.', () => {\n for (const c of ['x', 'y'] as Channel[]) {\n assert.equal(rules.nice('time', c, {type: 'temporal'}), undefined);\n }\n });\n });\n\n describe('padding', () => {\n it('should be pointPadding for point scale if channel is x or y and padding is not specified.', () => {\n for (const c of ['x', 'y'] as Channel[]) {\n assert.equal(rules.padding(c, 'point', {pointPadding: 13}, undefined, undefined, undefined), 13);\n }\n });\n\n it('should be continuousBandSize for linear x-scale of vertical bar.', () => {\n assert.equal(rules.padding('x', 'linear', {}, {field: 'date', type: 'temporal'}, {type: 'bar', orient: 'vertical'}, {continuousBandSize: 13}), 13);\n });\n\n\n it('should be undefined for linear x-scale for binned field of vertical bar.', () => {\n assert.equal(rules.padding('x', 'linear', {}, {bin: true, field: 'date', type: 'temporal'}, {type: 'bar', orient: 'vertical'}, {continuousBandSize: 13}), undefined);\n });\n\n it('should be continuousBandSize for linear y-scale of horizontal bar.', () => {\n assert.equal(rules.padding('y', 'linear', {}, {field: 'date', type: 'temporal'}, {type: 'bar', orient: 'horizontal'}, {continuousBandSize: 13}), 13);\n });\n });\n\n describe('paddingInner', () => {\n it('should be undefined if padding is specified.', () => {\n assert.equal(rules.paddingInner(10, 'x', {}), undefined);\n });\n\n it('should be bandPaddingInner if channel is x or y and padding is not specified.', () => {\n assert.equal(rules.paddingInner(undefined, 'x', {bandPaddingInner: 15}), 15);\n assert.equal(rules.paddingInner(undefined, 'y', {bandPaddingInner: 15}), 15);\n });\n\n it('should be undefined for non-xy channels.', () => {\n for (const c of NONPOSITION_SCALE_CHANNELS) {\n assert.equal(rules.paddingInner(undefined, c, {bandPaddingInner: 15}), undefined);\n }\n });\n });\n\n describe('paddingOuter', () => {\n it('should be undefined if padding is specified.', () => {\n for (const scaleType of ['point', 'band'] as ScaleType[]) {\n assert.equal(rules.paddingOuter(10, 'x', scaleType, 0, {}), undefined);\n }\n });\n\n it('should be config.scale.bandPaddingOuter for band scale if channel is x or y and padding is not specified and config.scale.bandPaddingOuter.', () => {\n for (const c of ['x', 'y'] as Channel[]) {\n assert.equal(rules.paddingOuter(undefined, c, 'band', 0, {bandPaddingOuter: 16}), 16);\n }\n });\n it('should be paddingInner/2 for band scale if channel is x or y and padding is not specified and config.scale.bandPaddingOuter.', () => {\n for (const c of ['x', 'y'] as Channel[]) {\n assert.equal(rules.paddingOuter(undefined, c, 'band', 10, {}), 5);\n }\n });\n\n it('should be undefined for non-xy channels.', () => {\n for (const c of NONPOSITION_SCALE_CHANNELS) {\n for (const scaleType of ['point', 'band'] as ScaleType[]) {\n assert.equal(rules.paddingOuter(undefined, c, scaleType, 0, {}), undefined);\n }\n }\n });\n });\n\n describe('reverse', () => {\n it('should return true for a continuous scale with sort = \"descending\".', () => {\n assert.isTrue(rules.reverse('linear', 'descending'));\n });\n\n it('should return false for a discrete scale with sort = \"descending\".', () => {\n assert.isUndefined(rules.reverse('point', 'descending'));\n });\n });\n\n describe('zero', () => {\n it('should return true when mapping a quantitative field to x with scale.domain = \"unaggregated\"', () => {\n assert(rules.zero('x', {field: 'a', type: 'quantitative'}, 'unaggregated', {type: 'point'}));\n });\n\n it('should return true when mapping a quantitative field to size', () => {\n assert(rules.zero('size', {field: 'a', type: 'quantitative'}, undefined, {type: 'point'}));\n });\n\n it('should return false when mapping a ordinal field to size', () => {\n assert(!rules.zero('size', {field: 'a', type: 'ordinal'}, undefined, {type: 'point'}));\n });\n\n it('should return true when mapping a non-binned quantitative field to x/y of point', () => {\n for (const channel of ['x', 'y'] as Channel[]) {\n assert(rules.zero(channel, {field: 'a', type: 'quantitative'}, undefined, {type: 'point'}));\n }\n });\n\n it('should return false when mapping a quantitative field to dimension axis of bar, line, and area', () => {\n for (const mark of [BAR, AREA, LINE]) {\n assert.isFalse(rules.zero('x', {field: 'a', type: 'quantitative'}, undefined, {type: mark, orient: 'vertical'}));\n assert.isFalse(rules.zero('y', {field: 'a', type: 'quantitative'}, undefined, {type: mark, orient: 'horizontal'}));\n }\n });\n\n it('should return false when mapping a binned quantitative field to x/y', () => {\n for (const channel of ['x', 'y'] as Channel[]) {\n assert(!rules.zero(channel, {bin: true, field: 'a', type: 'quantitative'}, undefined, {type: 'point'}));\n }\n });\n\n it('should return false when mapping a non-binned quantitative field with custom domain to x/y', () => {\n for (const channel of ['x', 'y'] as Channel[]) {\n assert(!rules.zero(channel, {\n bin: true, field: 'a', type: 'quantitative'\n }, [3, 5], {type: 'point'}));\n }\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/scale/range.test.d.ts b/build/test/compile/scale/range.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/scale/range.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/scale/range.test.js b/build/test/compile/scale/range.test.js new file mode 100644 index 0000000000..46a3c9c87e --- /dev/null +++ b/build/test/compile/scale/range.test.js @@ -0,0 +1,201 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { parseRangeForChannel } from '../../../src/compile/scale/range'; +import { makeExplicit, makeImplicit } from '../../../src/compile/split'; +import { defaultConfig } from '../../../src/config'; +import * as log from '../../../src/log'; +import { CONTINUOUS_TO_CONTINUOUS_SCALES, DISCRETE_DOMAIN_SCALES } from '../../../src/scale'; +import { NOMINAL, ORDINAL, QUANTITATIVE } from '../../../src/type'; +describe('compile/scale', function () { + describe('parseRange()', function () { + describe('position', function () { + it('should return [0, plot_width] for x-continuous scales by default.', function () { + for (var _i = 0, CONTINUOUS_TO_CONTINUOUS_SCALES_1 = CONTINUOUS_TO_CONTINUOUS_SCALES; _i < CONTINUOUS_TO_CONTINUOUS_SCALES_1.length; _i++) { + var scaleType = CONTINUOUS_TO_CONTINUOUS_SCALES_1[_i]; + assert.deepEqual(parseRangeForChannel('x', scaleType, QUANTITATIVE, {}, defaultConfig, true, 'point', false, 'plot_width', []), makeImplicit([0, { signal: 'plot_width' }])); + } + }); + it('should return [plot_height,0] for y-continuous scales by default.', function () { + for (var _i = 0, CONTINUOUS_TO_CONTINUOUS_SCALES_2 = CONTINUOUS_TO_CONTINUOUS_SCALES; _i < CONTINUOUS_TO_CONTINUOUS_SCALES_2.length; _i++) { + var scaleType = CONTINUOUS_TO_CONTINUOUS_SCALES_2[_i]; + assert.deepEqual(parseRangeForChannel('y', scaleType, QUANTITATIVE, {}, defaultConfig, true, 'point', false, 'plot_height', []), makeImplicit([{ signal: 'plot_height' }, 0])); + } + }); + it('should return [0, plot_height] for y-discrete scales with height by default.', function () { + for (var _i = 0, DISCRETE_DOMAIN_SCALES_1 = DISCRETE_DOMAIN_SCALES; _i < DISCRETE_DOMAIN_SCALES_1.length; _i++) { + var scaleType = DISCRETE_DOMAIN_SCALES_1[_i]; + assert.deepEqual(parseRangeForChannel('y', scaleType, QUANTITATIVE, {}, defaultConfig, true, 'point', true, 'plot_height', []), makeImplicit([0, { signal: 'plot_height' }])); + } + }); + it('should support custom range.', log.wrap(function (localLogger) { + assert.deepEqual(parseRangeForChannel('x', 'linear', QUANTITATIVE, { range: [0, 100] }, defaultConfig, true, 'point', false, 'plot_width', []), makeExplicit([0, 100])); + assert.deepEqual(localLogger.warns.length, 0); + })); + it('should return config.scale.rangeStep for band/point scales by default.', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + assert.deepEqual(parseRangeForChannel('x', scaleType, NOMINAL, {}, defaultConfig, undefined, 'point', false, 'plot_width', []), makeImplicit({ step: 21 })); + } + }); + it('should return config.scale.textXRangeStep by default for text mark\'s x band/point scales.', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + assert.deepEqual(parseRangeForChannel('x', scaleType, NOMINAL, {}, { scale: { textXRangeStep: 55 } }, undefined, 'text', false, 'plot_width', []), makeImplicit({ step: 55 })); + } + }); + it('should return specified rangeStep if topLevelSize is undefined for band/point scales', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + assert.deepEqual(parseRangeForChannel('x', scaleType, NOMINAL, { rangeStep: 23 }, defaultConfig, undefined, 'text', false, 'plot_width', []), makeExplicit({ step: 23 })); + } + }); + it('should drop rangeStep if topLevelSize is specified for band/point scales', log.wrap(function (localLogger) { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + assert.deepEqual(parseRangeForChannel('x', scaleType, NOMINAL, { rangeStep: 23 }, defaultConfig, undefined, 'text', true, 'plot_width', []), makeImplicit([0, { signal: 'plot_width' }])); + } + assert.equal(localLogger.warns[0], log.message.rangeStepDropped('x')); + })); + it('should return default topLevelSize if rangeStep is null for band/point scales', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + assert.deepEqual(parseRangeForChannel('x', scaleType, NOMINAL, { rangeStep: null }, defaultConfig, undefined, 'text', false, 'plot_width', []), makeImplicit([0, { signal: 'plot_width' }])); + } + }); + it('should return default topLevelSize if rangeStep config is null', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + assert.deepEqual(parseRangeForChannel('x', scaleType, NOMINAL, {}, { view: { width: 200 }, scale: { rangeStep: null } }, undefined, 'point', false, 'plot_width', []), makeImplicit([0, { signal: 'plot_width' }])); + } + }); + it('should return default topLevelSize for text if textXRangeStep config is null', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + assert.deepEqual(parseRangeForChannel('x', scaleType, NOMINAL, {}, { view: { width: 200 }, scale: { textXRangeStep: null } }, undefined, 'text', false, 'plot_width', []), makeImplicit([0, { signal: 'plot_width' }])); + } + }); + it('should drop rangeStep for continuous scales', function () { + var _loop_1 = function (scaleType) { + log.wrap(function (localLogger) { + assert.deepEqual(parseRangeForChannel('x', scaleType, QUANTITATIVE, { rangeStep: 23 }, defaultConfig, undefined, 'text', true, 'plot_width', []), makeImplicit([0, { signal: 'plot_width' }])); + assert.equal(localLogger.warns[0], log.message.scalePropertyNotWorkWithScaleType(scaleType, 'rangeStep', 'x')); + })(); + }; + for (var _i = 0, CONTINUOUS_TO_CONTINUOUS_SCALES_3 = CONTINUOUS_TO_CONTINUOUS_SCALES; _i < CONTINUOUS_TO_CONTINUOUS_SCALES_3.length; _i++) { + var scaleType = CONTINUOUS_TO_CONTINUOUS_SCALES_3[_i]; + _loop_1(scaleType); + } + }); + }); + describe('color', function () { + it('should use the specified scheme for a nominal color field.', function () { + assert.deepEqual(parseRangeForChannel('color', 'ordinal', NOMINAL, { scheme: 'warm' }, defaultConfig, undefined, 'point', false, 'plot_width', []), makeExplicit({ scheme: 'warm' })); + }); + it('should use the specified scheme with extent for a nominal color field.', function () { + assert.deepEqual(parseRangeForChannel('color', 'ordinal', NOMINAL, { scheme: { name: 'warm', extent: [0.2, 1] } }, defaultConfig, undefined, 'point', false, 'plot_width', []), makeExplicit({ scheme: 'warm', extent: [0.2, 1] })); + }); + it('should use the specified range for a nominal color field.', function () { + assert.deepEqual(parseRangeForChannel('color', 'ordinal', NOMINAL, { range: ['red', 'green', 'blue'] }, defaultConfig, undefined, 'point', false, 'plot_width', []), makeExplicit(['red', 'green', 'blue'])); + }); + it('should use default category range in Vega for a nominal color field.', function () { + assert.deepEqual(parseRangeForChannel('color', 'ordinal', NOMINAL, {}, defaultConfig, undefined, 'point', false, 'plot_width', []), makeImplicit('category')); + }); + it('should use default ordinal range in Vega for an ordinal color field.', function () { + assert.deepEqual(parseRangeForChannel('color', 'ordinal', ORDINAL, {}, defaultConfig, undefined, 'point', false, 'plot_width', []), makeImplicit('ordinal')); + }); + it('should use default ramp range in Vega for a temporal/quantitative color field.', function () { + assert.deepEqual(parseRangeForChannel('color', 'sequential', QUANTITATIVE, {}, defaultConfig, undefined, 'point', false, 'plot_width', []), makeImplicit('ramp')); + }); + it('should use the specified scheme with count for a quantitative color field.', function () { + assert.deepEqual(parseRangeForChannel('color', 'ordinal', QUANTITATIVE, { scheme: { name: 'viridis', count: 3 } }, defaultConfig, undefined, 'point', false, 'plot_width', []), makeExplicit({ scheme: 'viridis', count: 3 })); + }); + }); + describe('opacity', function () { + it('should use default opacityRange as opacity\'s scale range.', function () { + assert.deepEqual(parseRangeForChannel('opacity', 'linear', QUANTITATIVE, {}, defaultConfig, undefined, 'point', false, 'plot_width', []), makeImplicit([defaultConfig.scale.minOpacity, defaultConfig.scale.maxOpacity])); + }); + }); + describe('size', function () { + describe('bar', function () { + it('should return [minBandSize, maxBandSize] if both are specified', function () { + var config = { + scale: { minBandSize: 2, maxBandSize: 9 } + }; + assert.deepEqual(parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, config, undefined, 'bar', false, 'plot_width', []), makeImplicit([2, 9])); + }); + it('should return [continuousBandSize, xRangeStep-1] by default since min/maxSize config are not specified', function () { + assert.deepEqual(parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, undefined, 'bar', false, 'plot_width', []), makeImplicit([2, defaultConfig.scale.rangeStep - 1])); + }); + }); + describe('tick', function () { + it('should return [minBandSize, maxBandSize] if both are specified', function () { + var config = { + scale: { minBandSize: 4, maxBandSize: 9 } + }; + assert.deepEqual(parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, config, undefined, 'tick', false, 'plot_width', []), makeImplicit([4, 9])); + }); + it('should return [(default)minBandSize, rangeStep-1] by default since maxSize config is not specified', function () { + assert.deepEqual(parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, undefined, 'tick', false, 'plot_width', []), makeImplicit([defaultConfig.scale.minBandSize, defaultConfig.scale.rangeStep - 1])); + }); + }); + describe('text', function () { + it('should return [minFontSize, maxFontSize]', function () { + assert.deepEqual(parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, undefined, 'text', false, 'plot_width', []), makeImplicit([defaultConfig.scale.minFontSize, defaultConfig.scale.maxFontSize])); + }); + }); + describe('rule', function () { + it('should return [minStrokeWidth, maxStrokeWidth]', function () { + assert.deepEqual(parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, undefined, 'rule', false, 'plot_width', []), makeImplicit([defaultConfig.scale.minStrokeWidth, defaultConfig.scale.maxStrokeWidth])); + }); + }); + describe('point, square, circle', function () { + it('should return [minSize, maxSize]', function () { + for (var _i = 0, _a = ['point', 'square', 'circle']; _i < _a.length; _i++) { + var m = _a[_i]; + var config = { + scale: { + minSize: 5, + maxSize: 25 + } + }; + assert.deepEqual(parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, config, undefined, m, false, 'plot_width', []), makeImplicit([5, 25])); + } + }); + it('should return [0, (minBandSize-2)^2] if both x and y are discrete and size is quantitative (thus use zero=true, by default)', function () { + for (var _i = 0, _a = ['point', 'square', 'circle']; _i < _a.length; _i++) { + var m = _a[_i]; + assert.deepEqual(parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, true, m, false, 'plot_width', [11, 13] // xyRangeSteps + ), makeImplicit([0, 81])); + } + }); + it('should return [9, (minBandSize-2)^2] if both x and y are discrete and size is not quantitative (thus use zero=false, by default)', function () { + for (var _i = 0, _a = ['point', 'square', 'circle']; _i < _a.length; _i++) { + var m = _a[_i]; + assert.deepEqual(parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, false, m, false, 'plot_width', [11, 13] // xyRangeSteps + ), makeImplicit([9, 81])); + } + }); + it('should return [9, (minBandSize-2)^2] if both x and y are discrete and size is quantitative but use zero=false', function () { + for (var _i = 0, _a = ['point', 'square', 'circle']; _i < _a.length; _i++) { + var m = _a[_i]; + assert.deepEqual(parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, false, m, false, 'plot_width', [11, 13] // xyRangeSteps + ), makeImplicit([9, 81])); + } + }); + it('should return [0, (xRangeStep-2)^2] if x is discrete and y is continuous and size is quantitative (thus use zero=true, by default)', function () { + for (var _i = 0, _a = ['point', 'square', 'circle']; _i < _a.length; _i++) { + var m = _a[_i]; + assert.deepEqual(parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, true, m, false, 'plot_width', [11] // xyRangeSteps only have one value + ), makeImplicit([0, 81])); + } + }); + }); + }); + describe('shape', function () { + it('should use default symbol range in Vega as shape\'s scale range.', function () { + assert.deepEqual(parseRangeForChannel('shape', 'ordinal', QUANTITATIVE, {}, defaultConfig, undefined, 'point', false, 'plot_width', []), makeImplicit('symbol')); + }); + }); + }); +}); +//# sourceMappingURL=range.test.js.map \ No newline at end of file diff --git a/build/test/compile/scale/range.test.js.map b/build/test/compile/scale/range.test.js.map new file mode 100644 index 0000000000..8b48778fa7 --- /dev/null +++ b/build/test/compile/scale/range.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"range.test.js","sourceRoot":"","sources":["../../../../test/compile/scale/range.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAC,oBAAoB,EAAC,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAC,YAAY,EAAE,YAAY,EAAC,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAC,+BAA+B,EAAE,sBAAsB,EAAY,MAAM,oBAAoB,CAAC;AACtG,OAAO,EAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAEjE,QAAQ,CAAC,eAAe,EAAE;IACxB,QAAQ,CAAC,cAAc,EAAE;QACvB,QAAQ,CAAC,UAAU,EAAE;YACnB,EAAE,CAAC,mEAAmE,EAAE;gBACtE,KAAwB,UAA+B,EAA/B,mEAA+B,EAA/B,6CAA+B,EAA/B,IAA+B,EAAE;oBAApD,IAAM,SAAS,wCAAA;oBAClB,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAC7G,YAAY,CAAC,CAAC,CAAC,EAAE,EAAC,MAAM,EAAE,YAAY,EAAC,CAAC,CAAC,CAC1C,CAAC;iBACH;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,mEAAmE,EAAE;gBACtE,KAAwB,UAA+B,EAA/B,mEAA+B,EAA/B,6CAA+B,EAA/B,IAA+B,EAAE;oBAApD,IAAM,SAAS,wCAAA;oBAClB,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,CAAC,EAC9G,YAAY,CAAC,CAAC,EAAC,MAAM,EAAE,aAAa,EAAC,EAAE,CAAC,CAAC,CAAC,CAC3C,CAAC;iBACH;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,8EAA8E,EAAE;gBACjF,KAAwB,UAAsB,EAAtB,iDAAsB,EAAtB,oCAAsB,EAAtB,IAAsB,EAAE;oBAA3C,IAAM,SAAS,+BAAA;oBAClB,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,CAAC,EAC7G,YAAY,CAAC,CAAC,CAAC,EAAE,EAAC,MAAM,EAAE,aAAa,EAAC,CAAC,CAAC,CAC3C,CAAC;iBACH;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,CAAC,IAAI,CAAC,UAAC,WAAW;gBACtD,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAC,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAC,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAC3H,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CACvB,CAAC;gBACF,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC,CAAC;YAEJ,EAAE,CAAC,wEAAwE,EAAE;gBAC3E,KAAwB,UAAgC,EAAhC,KAAA,CAAC,OAAO,EAAE,MAAM,CAAgB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;oBAArD,IAAM,SAAS,SAAA;oBAClB,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAC7G,YAAY,CAAC,EAAC,IAAI,EAAE,EAAE,EAAC,CAAC,CACzB,CAAC;iBACH;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,4FAA4F,EAAE;gBAC/F,KAAwB,UAAgC,EAAhC,KAAA,CAAC,OAAO,EAAE,MAAM,CAAgB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;oBAArD,IAAM,SAAS,SAAA;oBAClB,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,EAAC,KAAK,EAAE,EAAC,cAAc,EAAE,EAAE,EAAC,EAAC,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAC5H,YAAY,CAAC,EAAC,IAAI,EAAE,EAAE,EAAC,CAAC,CACzB,CAAC;iBACH;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,sFAAsF,EAAE;gBACzF,KAAwB,UAAgC,EAAhC,KAAA,CAAC,OAAO,EAAE,MAAM,CAAgB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;oBAArD,IAAM,SAAS,SAAA;oBAClB,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,EAAC,SAAS,EAAE,EAAE,EAAC,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACzH,YAAY,CAAC,EAAC,IAAI,EAAE,EAAE,EAAC,CAAC,CACzB,CAAC;iBACH;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,CAAC,IAAI,CAAC,UAAC,WAAW;gBAClG,KAAwB,UAAgC,EAAhC,KAAA,CAAC,OAAO,EAAE,MAAM,CAAgB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;oBAArD,IAAM,SAAS,SAAA;oBAClB,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,EAAC,SAAS,EAAE,EAAE,EAAC,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,CAAC,EACxH,YAAY,CAAC,CAAC,CAAC,EAAE,EAAC,MAAM,EAAE,YAAY,EAAC,CAAC,CAAC,CAC1C,CAAC;iBACH;gBACD,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC,CAAC;YAEJ,EAAE,CAAC,+EAA+E,EAAE;gBAClF,KAAwB,UAAgC,EAAhC,KAAA,CAAC,OAAO,EAAE,MAAM,CAAgB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;oBAArD,IAAM,SAAS,SAAA;oBAClB,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAC3H,YAAY,CAAC,CAAC,CAAC,EAAE,EAAC,MAAM,EAAE,YAAY,EAAC,CAAC,CAAC,CAC1C,CAAC;iBACH;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,gEAAgE,EAAE;gBACnE,KAAwB,UAAgC,EAAhC,KAAA,CAAC,OAAO,EAAE,MAAM,CAAgB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;oBAArD,IAAM,SAAS,SAAA;oBAClB,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,EAAC,IAAI,EAAE,EAAC,KAAK,EAAE,GAAG,EAAC,EAAE,KAAK,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,EAAC,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAC9I,YAAY,CAAC,CAAC,CAAC,EAAE,EAAC,MAAM,EAAE,YAAY,EAAC,CAAC,CAAC,CAC1C,CAAC;iBACH;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,8EAA8E,EAAE;gBACjF,KAAwB,UAAgC,EAAhC,KAAA,CAAC,OAAO,EAAE,MAAM,CAAgB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;oBAArD,IAAM,SAAS,SAAA;oBAClB,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,EAAC,IAAI,EAAE,EAAC,KAAK,EAAE,GAAG,EAAC,EAAE,KAAK,EAAE,EAAC,cAAc,EAAE,IAAI,EAAC,EAAC,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAClJ,YAAY,CAAC,CAAC,CAAC,EAAE,EAAC,MAAM,EAAE,YAAY,EAAC,CAAC,CAAC,CAC1C,CAAC;iBACH;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,6CAA6C,EAAE;wCACrC,SAAS;oBAClB,GAAG,CAAC,IAAI,CAAC,UAAC,WAAW;wBACnB,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,EAAC,SAAS,EAAE,EAAE,EAAC,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,CAAC,EAC7H,YAAY,CAAC,CAAC,CAAC,EAAE,EAAC,MAAM,EAAE,YAAY,EAAC,CAAC,CAAC,CAC1C,CAAC;wBACF,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,iCAAiC,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;oBACjH,CAAC,CAAC,EAAE,CAAC;gBACP,CAAC;gBARD,KAAwB,UAA+B,EAA/B,mEAA+B,EAA/B,6CAA+B,EAA/B,IAA+B;oBAAlD,IAAM,SAAS,wCAAA;4BAAT,SAAS;iBAQnB;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,OAAO,EAAE;YAChB,EAAE,CAAC,4DAA4D,EAAE;gBAC/D,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAC,MAAM,EAAE,MAAM,EAAC,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAC/H,YAAY,CAAC,EAAC,MAAM,EAAE,MAAM,EAAC,CAAC,CAC/B,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,wEAAwE,EAAE;gBAC3E,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAC,MAAM,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAC,EAAC,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACzJ,YAAY,CAAC,EAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAC,CAAC,CACjD,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,2DAA2D,EAAE;gBAC9D,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAC,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAChJ,YAAY,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CACvC,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,sEAAsE,EAAE;gBACzE,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACjH,YAAY,CAAC,UAAU,CAAC,CACzB,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,sEAAsE,EAAE;gBACzE,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACjH,YAAY,CAAC,SAAS,CAAC,CACxB,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,gFAAgF,EAAE;gBACnF,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACzH,YAAY,CAAC,MAAM,CAAC,CACrB,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,4EAA4E,EAAE;gBAC/E,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,EAAC,MAAM,EAAE,EAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAC,EAAC,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACzJ,YAAY,CAAC,EAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAC,CAAC,CAC5C,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,SAAS,EAAE;YAClB,EAAE,CAAC,4DAA4D,EAAE;gBAC/D,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACvH,YAAY,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,EAAE,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAC/E,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,MAAM,EAAE;YACf,QAAQ,CAAC,KAAK,EAAE;gBACd,EAAE,CAAC,gEAAgE,EAAE;oBACnE,IAAM,MAAM,GAAG;wBACb,KAAK,EAAE,EAAC,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAC;qBACxC,CAAC;oBACF,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAC3G,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CACrB,CAAC;gBACJ,CAAC,CAAC,CAAC;gBAEH,EAAE,CAAC,wGAAwG,EAAE;oBAC3G,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAClH,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CACrD,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,QAAQ,CAAC,MAAM,EAAE;gBACf,EAAE,CAAC,gEAAgE,EAAE;oBACnE,IAAM,MAAM,GAAG;wBACb,KAAK,EAAE,EAAC,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAC;qBACxC,CAAC;oBACF,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAC5G,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CACrB,CAAC;gBACJ,CAAC,CAAC,CAAC;gBAEH,EAAE,CAAC,oGAAoG,EAAE;oBACvG,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACnH,YAAY,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,EAAE,aAAa,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CACnF,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,QAAQ,CAAC,MAAM,EAAE;gBACf,EAAE,CAAC,0CAA0C,EAAE;oBAC7C,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACnH,YAAY,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,EAAE,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CACjF,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,QAAQ,CAAC,MAAM,EAAE;gBACf,EAAE,CAAC,gDAAgD,EAAE;oBACnD,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACnH,YAAY,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,cAAc,EAAE,aAAa,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CACvF,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,QAAQ,CAAC,uBAAuB,EAAE;gBAChC,EAAE,CAAC,kCAAkC,EAAE;oBACrC,KAAgB,UAAuC,EAAvC,KAAA,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAW,EAAvC,cAAuC,EAAvC,IAAuC,EAAE;wBAApD,IAAM,CAAC,SAAA;wBACV,IAAM,MAAM,GAAG;4BACb,KAAK,EAAE;gCACL,OAAO,EAAE,CAAC;gCACV,OAAO,EAAE,EAAE;6BAEZ;yBACF,CAAC;wBAEF,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACvG,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CACtB,CAAC;qBACH;gBACH,CAAC,CAAC,CAAC;gBAEH,EAAE,CAAC,6HAA6H,EAAE;oBAChI,KAAgB,UAAuC,EAAvC,KAAA,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAW,EAAvC,cAAuC,EAAvC,IAAuC,EAAE;wBAApD,IAAM,CAAC,SAAA;wBACV,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAClG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,eAAe;yBACzB,EACD,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CACtB,CAAC;qBACH;gBACH,CAAC,CAAC,CAAC;gBAEH,EAAE,CAAC,kIAAkI,EAAE;oBACrI,KAAgB,UAAuC,EAAvC,KAAA,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAW,EAAvC,cAAuC,EAAvC,IAAuC,EAAE;wBAApD,IAAM,CAAC,SAAA;wBACV,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EACnG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,eAAe;yBACzB,EACD,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CACtB,CAAC;qBACH;gBACH,CAAC,CAAC,CAAC;gBAEH,EAAE,CAAC,+GAA+G,EAAE;oBAClH,KAAgB,UAAuC,EAAvC,KAAA,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAW,EAAvC,cAAuC,EAAvC,IAAuC,EAAE;wBAApD,IAAM,CAAC,SAAA;wBACV,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EACnG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,eAAe;yBACzB,EACD,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CACtB,CAAC;qBACH;gBACH,CAAC,CAAC,CAAC;gBAEH,EAAE,CAAC,oIAAoI,EAAE;oBACrI,KAAgB,UAAuC,EAAvC,KAAA,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAW,EAAvC,cAAuC,EAAvC,IAAuC,EAAE;wBAApD,IAAM,CAAC,SAAA;wBACZ,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAClG,CAAC,EAAE,CAAC,CAAC,mCAAmC;yBACzC,EACD,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CACtB,CAAC;qBACH;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,OAAO,EAAE;YAChB,EAAE,CAAC,kEAAkE,EAAE;gBACrE,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EACtH,YAAY,CAAC,QAAQ,CAAC,CACvB,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\n\nimport {parseRangeForChannel} from '../../../src/compile/scale/range';\nimport {makeExplicit, makeImplicit} from '../../../src/compile/split';\nimport {defaultConfig} from '../../../src/config';\nimport * as log from '../../../src/log';\nimport {Mark} from '../../../src/mark';\nimport {CONTINUOUS_TO_CONTINUOUS_SCALES, DISCRETE_DOMAIN_SCALES, ScaleType} from '../../../src/scale';\nimport {NOMINAL, ORDINAL, QUANTITATIVE} from '../../../src/type';\n\ndescribe('compile/scale', () => {\n describe('parseRange()', function() {\n describe('position', () => {\n it('should return [0, plot_width] for x-continuous scales by default.', () => {\n for (const scaleType of CONTINUOUS_TO_CONTINUOUS_SCALES) {\n assert.deepEqual(\n parseRangeForChannel('x', scaleType, QUANTITATIVE, {}, defaultConfig, true, 'point', false, 'plot_width', []),\n makeImplicit([0, {signal: 'plot_width'}])\n );\n }\n });\n\n it('should return [plot_height,0] for y-continuous scales by default.', () => {\n for (const scaleType of CONTINUOUS_TO_CONTINUOUS_SCALES) {\n assert.deepEqual(\n parseRangeForChannel('y', scaleType, QUANTITATIVE, {}, defaultConfig, true, 'point', false, 'plot_height', []),\n makeImplicit([{signal: 'plot_height'}, 0])\n );\n }\n });\n\n it('should return [0, plot_height] for y-discrete scales with height by default.', () => {\n for (const scaleType of DISCRETE_DOMAIN_SCALES) {\n assert.deepEqual(\n parseRangeForChannel('y', scaleType, QUANTITATIVE, {}, defaultConfig, true, 'point', true, 'plot_height', []),\n makeImplicit([0, {signal: 'plot_height'}])\n );\n }\n });\n\n it('should support custom range.', log.wrap((localLogger) => {\n assert.deepEqual(\n parseRangeForChannel('x', 'linear', QUANTITATIVE, {range: [0, 100]}, defaultConfig, true, 'point', false, 'plot_width', []),\n makeExplicit([0, 100])\n );\n assert.deepEqual(localLogger.warns.length, 0);\n }));\n\n it('should return config.scale.rangeStep for band/point scales by default.', () => {\n for (const scaleType of ['point', 'band'] as ScaleType[]) {\n assert.deepEqual(\n parseRangeForChannel('x', scaleType, NOMINAL, {}, defaultConfig, undefined, 'point', false, 'plot_width', []),\n makeImplicit({step: 21})\n );\n }\n });\n\n it('should return config.scale.textXRangeStep by default for text mark\\'s x band/point scales.', () => {\n for (const scaleType of ['point', 'band'] as ScaleType[]) {\n assert.deepEqual(\n parseRangeForChannel('x', scaleType, NOMINAL, {}, {scale: {textXRangeStep: 55}}, undefined, 'text', false, 'plot_width', []),\n makeImplicit({step: 55})\n );\n }\n });\n\n it('should return specified rangeStep if topLevelSize is undefined for band/point scales', () => {\n for (const scaleType of ['point', 'band'] as ScaleType[]) {\n assert.deepEqual(\n parseRangeForChannel('x', scaleType, NOMINAL, {rangeStep: 23}, defaultConfig, undefined, 'text', false, 'plot_width', []),\n makeExplicit({step: 23})\n );\n }\n });\n\n it('should drop rangeStep if topLevelSize is specified for band/point scales', log.wrap((localLogger) => {\n for (const scaleType of ['point', 'band'] as ScaleType[]) {\n assert.deepEqual(\n parseRangeForChannel('x', scaleType, NOMINAL, {rangeStep: 23}, defaultConfig, undefined, 'text', true, 'plot_width', []),\n makeImplicit([0, {signal: 'plot_width'}])\n );\n }\n assert.equal(localLogger.warns[0], log.message.rangeStepDropped('x'));\n }));\n\n it('should return default topLevelSize if rangeStep is null for band/point scales', () => {\n for (const scaleType of ['point', 'band'] as ScaleType[]) {\n assert.deepEqual(\n parseRangeForChannel('x', scaleType, NOMINAL, {rangeStep: null}, defaultConfig, undefined, 'text', false, 'plot_width', []),\n makeImplicit([0, {signal: 'plot_width'}])\n );\n }\n });\n\n it('should return default topLevelSize if rangeStep config is null', () => {\n for (const scaleType of ['point', 'band'] as ScaleType[]) {\n assert.deepEqual(\n parseRangeForChannel('x', scaleType, NOMINAL, {}, {view: {width: 200}, scale: {rangeStep: null}}, undefined, 'point', false, 'plot_width', []),\n makeImplicit([0, {signal: 'plot_width'}])\n );\n }\n });\n\n it('should return default topLevelSize for text if textXRangeStep config is null', () => {\n for (const scaleType of ['point', 'band'] as ScaleType[]) {\n assert.deepEqual(\n parseRangeForChannel('x', scaleType, NOMINAL, {}, {view: {width: 200}, scale: {textXRangeStep: null}}, undefined, 'text', false, 'plot_width', []),\n makeImplicit([0, {signal: 'plot_width'}])\n );\n }\n });\n\n it('should drop rangeStep for continuous scales', () => {\n for (const scaleType of CONTINUOUS_TO_CONTINUOUS_SCALES) {\n log.wrap((localLogger) => {\n assert.deepEqual(\n parseRangeForChannel('x', scaleType, QUANTITATIVE, {rangeStep: 23}, defaultConfig, undefined, 'text', true, 'plot_width', []),\n makeImplicit([0, {signal: 'plot_width'}])\n );\n assert.equal(localLogger.warns[0], log.message.scalePropertyNotWorkWithScaleType(scaleType, 'rangeStep', 'x'));\n })();\n }\n });\n });\n\n describe('color', function() {\n it('should use the specified scheme for a nominal color field.', () => {\n assert.deepEqual(\n parseRangeForChannel('color', 'ordinal', NOMINAL, {scheme: 'warm'}, defaultConfig, undefined, 'point', false, 'plot_width', []),\n makeExplicit({scheme: 'warm'})\n );\n });\n\n it('should use the specified scheme with extent for a nominal color field.', () => {\n assert.deepEqual(\n parseRangeForChannel('color', 'ordinal', NOMINAL, {scheme: {name: 'warm', extent: [0.2, 1]}}, defaultConfig, undefined, 'point', false, 'plot_width', []),\n makeExplicit({scheme: 'warm', extent: [0.2, 1]})\n );\n });\n\n it('should use the specified range for a nominal color field.', () => {\n assert.deepEqual(\n parseRangeForChannel('color', 'ordinal', NOMINAL, {range: ['red', 'green', 'blue']}, defaultConfig, undefined, 'point', false, 'plot_width', []),\n makeExplicit(['red', 'green', 'blue'])\n );\n });\n\n it('should use default category range in Vega for a nominal color field.', () => {\n assert.deepEqual(\n parseRangeForChannel('color', 'ordinal', NOMINAL, {}, defaultConfig, undefined, 'point', false, 'plot_width', []),\n makeImplicit('category')\n );\n });\n\n it('should use default ordinal range in Vega for an ordinal color field.', () => {\n assert.deepEqual(\n parseRangeForChannel('color', 'ordinal', ORDINAL, {}, defaultConfig, undefined, 'point', false, 'plot_width', []),\n makeImplicit('ordinal')\n );\n });\n\n it('should use default ramp range in Vega for a temporal/quantitative color field.', () => {\n assert.deepEqual(\n parseRangeForChannel('color', 'sequential', QUANTITATIVE, {}, defaultConfig, undefined, 'point', false, 'plot_width', []),\n makeImplicit('ramp')\n );\n });\n\n it('should use the specified scheme with count for a quantitative color field.', () => {\n assert.deepEqual(\n parseRangeForChannel('color', 'ordinal', QUANTITATIVE, {scheme: {name: 'viridis', count: 3}}, defaultConfig, undefined, 'point', false, 'plot_width', []),\n makeExplicit({scheme: 'viridis', count: 3})\n );\n });\n });\n\n describe('opacity', function() {\n it('should use default opacityRange as opacity\\'s scale range.', () => {\n assert.deepEqual(\n parseRangeForChannel('opacity', 'linear', QUANTITATIVE, {}, defaultConfig, undefined, 'point', false, 'plot_width', []),\n makeImplicit([defaultConfig.scale.minOpacity, defaultConfig.scale.maxOpacity])\n );\n });\n });\n\n describe('size', function() {\n describe('bar', function() {\n it('should return [minBandSize, maxBandSize] if both are specified', () => {\n const config = {\n scale: {minBandSize: 2, maxBandSize: 9}\n };\n assert.deepEqual(\n parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, config, undefined, 'bar', false, 'plot_width', []),\n makeImplicit([2, 9])\n );\n });\n\n it('should return [continuousBandSize, xRangeStep-1] by default since min/maxSize config are not specified', () => {\n assert.deepEqual(\n parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, undefined, 'bar', false, 'plot_width', []),\n makeImplicit([2, defaultConfig.scale.rangeStep - 1])\n );\n });\n });\n\n describe('tick', function() {\n it('should return [minBandSize, maxBandSize] if both are specified', () => {\n const config = {\n scale: {minBandSize: 4, maxBandSize: 9}\n };\n assert.deepEqual(\n parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, config, undefined, 'tick', false, 'plot_width', []),\n makeImplicit([4, 9])\n );\n });\n\n it('should return [(default)minBandSize, rangeStep-1] by default since maxSize config is not specified', () => {\n assert.deepEqual(\n parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, undefined, 'tick', false, 'plot_width', []),\n makeImplicit([defaultConfig.scale.minBandSize, defaultConfig.scale.rangeStep - 1])\n );\n });\n });\n\n describe('text', function() {\n it('should return [minFontSize, maxFontSize]', () => {\n assert.deepEqual(\n parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, undefined, 'text', false, 'plot_width', []),\n makeImplicit([defaultConfig.scale.minFontSize, defaultConfig.scale.maxFontSize])\n );\n });\n });\n\n describe('rule', function() {\n it('should return [minStrokeWidth, maxStrokeWidth]', () => {\n assert.deepEqual(\n parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, undefined, 'rule', false, 'plot_width', []),\n makeImplicit([defaultConfig.scale.minStrokeWidth, defaultConfig.scale.maxStrokeWidth])\n );\n });\n });\n\n describe('point, square, circle', function() {\n it('should return [minSize, maxSize]', () => {\n for (const m of ['point', 'square', 'circle'] as Mark[]) {\n const config = {\n scale: {\n minSize: 5,\n maxSize: 25\n\n }\n };\n\n assert.deepEqual(\n parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, config, undefined, m, false, 'plot_width', []),\n makeImplicit([5, 25])\n );\n }\n });\n\n it('should return [0, (minBandSize-2)^2] if both x and y are discrete and size is quantitative (thus use zero=true, by default)', () => {\n for (const m of ['point', 'square', 'circle'] as Mark[]) {\n assert.deepEqual(\n parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, true, m, false, 'plot_width',\n [11, 13] // xyRangeSteps\n ),\n makeImplicit([0, 81])\n );\n }\n });\n\n it('should return [9, (minBandSize-2)^2] if both x and y are discrete and size is not quantitative (thus use zero=false, by default)', () => {\n for (const m of ['point', 'square', 'circle'] as Mark[]) {\n assert.deepEqual(\n parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, false, m, false, 'plot_width',\n [11, 13] // xyRangeSteps\n ),\n makeImplicit([9, 81])\n );\n }\n });\n\n it('should return [9, (minBandSize-2)^2] if both x and y are discrete and size is quantitative but use zero=false', () => {\n for (const m of ['point', 'square', 'circle'] as Mark[]) {\n assert.deepEqual(\n parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, false, m, false, 'plot_width',\n [11, 13] // xyRangeSteps\n ),\n makeImplicit([9, 81])\n );\n }\n });\n\n it('should return [0, (xRangeStep-2)^2] if x is discrete and y is continuous and size is quantitative (thus use zero=true, by default)', () => {\n for (const m of ['point', 'square', 'circle'] as Mark[]) {\n assert.deepEqual(\n parseRangeForChannel('size', 'linear', QUANTITATIVE, {}, defaultConfig, true, m, false, 'plot_width',\n [11] // xyRangeSteps only have one value\n ),\n makeImplicit([0, 81])\n );\n }\n });\n });\n });\n\n describe('shape', function() {\n it('should use default symbol range in Vega as shape\\'s scale range.', () => {\n assert.deepEqual(\n parseRangeForChannel('shape', 'ordinal', QUANTITATIVE, {}, defaultConfig, undefined, 'point', false, 'plot_width', []),\n makeImplicit('symbol')\n );\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/scale/type.test.d.ts b/build/test/compile/scale/type.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/scale/type.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/scale/type.test.js b/build/test/compile/scale/type.test.js new file mode 100644 index 0000000000..83d2e55f9f --- /dev/null +++ b/build/test/compile/scale/type.test.js @@ -0,0 +1,158 @@ +import { assert } from 'chai'; +import { rangeType, SCALE_CHANNELS, X, Y } from '../../../src/channel'; +import { scaleType } from '../../../src/compile/scale/type'; +import { defaultConfig } from '../../../src/config'; +import * as log from '../../../src/log'; +import { PRIMITIVE_MARKS } from '../../../src/mark'; +import { ScaleType } from '../../../src/scale'; +import { TIMEUNITS } from '../../../src/timeunit'; +import { NOMINAL, ORDINAL } from '../../../src/type'; +import * as util from '../../../src/util'; +var defaultScaleConfig = defaultConfig.scale; +describe('compile/scale', function () { + describe('type()', function () { + it('should return null for channel without scale', function () { + assert.deepEqual(scaleType(undefined, 'detail', { type: 'temporal', timeUnit: 'yearmonth' }, 'point', defaultScaleConfig), null); + }); + it('should show warning if users try to override the scale and use bin', log.wrap(function (localLogger) { + assert.deepEqual(scaleType('point', 'color', { type: 'quantitative', bin: true }, 'point', defaultScaleConfig), ScaleType.BIN_ORDINAL); + assert.equal(localLogger.warns[0], log.message.scaleTypeNotWorkWithFieldDef(ScaleType.POINT, ScaleType.BIN_ORDINAL)); + })); + describe('nominal/ordinal', function () { + describe('color', function () { + it('should return ordinal scale for nominal data by default.', function () { + assert.equal(scaleType(undefined, 'color', { type: 'nominal' }, 'point', defaultScaleConfig), ScaleType.ORDINAL); + }); + it('should return ordinal scale for ordinal data.', function () { + assert.equal(scaleType(undefined, 'color', { type: 'nominal' }, 'point', defaultScaleConfig), ScaleType.ORDINAL); + }); + }); + describe('discrete channel (shape)', function () { + it('should return ordinal for nominal field', function () { + assert.deepEqual(scaleType(undefined, 'shape', { type: 'nominal' }, 'point', defaultScaleConfig), ScaleType.ORDINAL); + }); + it('should return ordinal even if other type is specified', log.wrap(function (localLogger) { + [ScaleType.LINEAR, ScaleType.BAND, ScaleType.POINT].forEach(function (badScaleType) { + assert.deepEqual(scaleType(badScaleType, 'shape', { type: 'nominal' }, 'point', defaultScaleConfig), ScaleType.ORDINAL); + var warns = localLogger.warns; + assert.equal(warns[warns.length - 1], log.message.scaleTypeNotWorkWithChannel('shape', badScaleType, 'ordinal')); + }); + })); + it('should return ordinal for an ordinal field and throw a warning.', log.wrap(function (localLogger) { + assert.deepEqual(scaleType(undefined, 'shape', { type: 'ordinal' }, 'point', defaultScaleConfig), ScaleType.ORDINAL); + assert.equal(localLogger.warns[0], log.message.discreteChannelCannotEncode('shape', 'ordinal')); + })); + }); + describe('continuous', function () { + it('should return point scale for ordinal X,Y for marks others than rect, rule, and bar', function () { + PRIMITIVE_MARKS.forEach(function (mark) { + if (util.contains(['bar', 'rule', 'rect'], mark)) { + return; + } + [ORDINAL, NOMINAL].forEach(function (t) { + [X, Y].forEach(function (channel) { + assert.equal(scaleType(undefined, channel, { type: t }, mark, defaultScaleConfig), ScaleType.POINT); + }); + }); + }); + }); + it('should return band scale for ordinal X,Y when mark is rect, rule, bar', function () { + [ORDINAL, NOMINAL].forEach(function (t) { + [X, Y].forEach(function (channel) { + ['bar', 'rule', 'rect'].forEach(function (mark) { + assert.equal(scaleType(undefined, channel, { type: t }, 'rect', defaultScaleConfig), ScaleType.BAND); + }); + }); + }); + }); + it('should return point scale for X,Y when mark is point', function () { + [ORDINAL, NOMINAL].forEach(function (t) { + [X, Y].forEach(function (channel) { + assert.equal(scaleType(undefined, channel, { type: t }, 'point', defaultScaleConfig), ScaleType.POINT); + }); + }); + }); + it('should return point scale for X,Y when mark is point when ORDINAL SCALE TYPE is specified and throw warning', log.wrap(function (localLogger) { + [ORDINAL, NOMINAL].forEach(function (t) { + [X, Y].forEach(function (channel) { + assert.equal(scaleType('ordinal', channel, { type: t }, 'point', defaultScaleConfig), ScaleType.POINT); + var warns = localLogger.warns; + assert.equal(warns[warns.length - 1], log.message.scaleTypeNotWorkWithChannel(channel, 'ordinal', 'point')); + }); + }); + })); + it('should return point scale for ordinal/nominal fields for continuous channels other than x and y.', function () { + var OTHER_CONTINUOUS_CHANNELS = SCALE_CHANNELS.filter(function (c) { return rangeType(c) === 'continuous' && !util.contains([X, Y], c); }); + PRIMITIVE_MARKS.forEach(function (mark) { + [ORDINAL, NOMINAL].forEach(function (t) { + OTHER_CONTINUOUS_CHANNELS.forEach(function (channel) { + assert.equal(scaleType(undefined, channel, { type: t }, mark, defaultScaleConfig), ScaleType.POINT, channel + ", " + mark + ", " + t + " " + scaleType(undefined, channel, { type: t }, mark, defaultScaleConfig)); + }); + }); + }); + }); + }); + }); + describe('temporal', function () { + it('should return sequential scale for temporal color field by default.', function () { + assert.equal(scaleType(undefined, 'color', { type: 'temporal' }, 'point', defaultScaleConfig), ScaleType.SEQUENTIAL); + }); + it('should return ordinal for temporal field and throw a warning.', log.wrap(function (localLogger) { + assert.deepEqual(scaleType(undefined, 'shape', { type: 'temporal', timeUnit: 'yearmonth' }, 'point', defaultScaleConfig), ScaleType.ORDINAL); + assert.equal(localLogger.warns[0], log.message.discreteChannelCannotEncode('shape', 'temporal')); + })); + it('should return time for all time units.', function () { + for (var _i = 0, TIMEUNITS_1 = TIMEUNITS; _i < TIMEUNITS_1.length; _i++) { + var timeUnit = TIMEUNITS_1[_i]; + assert.deepEqual(scaleType(undefined, Y, { type: 'temporal', timeUnit: timeUnit }, 'point', defaultScaleConfig), ScaleType.TIME); + } + }); + }); + describe('quantitative', function () { + it('should return sequential scale for quantitative color field by default.', function () { + assert.equal(scaleType(undefined, 'color', { type: 'quantitative' }, 'point', defaultScaleConfig), ScaleType.SEQUENTIAL); + }); + it('should return ordinal bin scale for quantitative color field with binning.', function () { + assert.equal(scaleType(undefined, 'color', { type: 'quantitative', bin: true }, 'point', defaultScaleConfig), ScaleType.BIN_ORDINAL); + }); + it('should return ordinal for encoding quantitative field with a discrete channel and throw a warning.', log.wrap(function (localLogger) { + assert.deepEqual(scaleType(undefined, 'shape', { type: 'quantitative' }, 'point', defaultScaleConfig), ScaleType.ORDINAL); + assert.equal(localLogger.warns[0], log.message.discreteChannelCannotEncode('shape', 'quantitative')); + })); + it('should return linear scale for quantitative by default.', function () { + assert.equal(scaleType(undefined, 'x', { type: 'quantitative' }, 'point', defaultScaleConfig), ScaleType.LINEAR); + }); + it('should return bin linear scale for quantitative by default.', function () { + assert.equal(scaleType(undefined, 'opacity', { type: 'quantitative', bin: true }, 'point', defaultScaleConfig), ScaleType.BIN_LINEAR); + }); + it('should return linear scale for quantitative x and y.', function () { + assert.equal(scaleType(undefined, 'x', { type: 'quantitative', bin: true }, 'point', defaultScaleConfig), ScaleType.LINEAR); + }); + }); + describe('dataTypeMatchScaleType()', function () { + it('should return specified value if datatype is ordinal or nominal and specified scale type is the ordinal or nominal', function () { + assert.equal(scaleType(ScaleType.ORDINAL, 'shape', { type: 'ordinal' }, 'point', defaultScaleConfig), ScaleType.ORDINAL); + }); + it('should return default scale type if data type is temporal but specified scale type is not time or utc', function () { + assert.equal(scaleType(ScaleType.LINEAR, 'x', { type: 'temporal', timeUnit: 'year' }, 'point', defaultScaleConfig), ScaleType.TIME); + assert.equal(scaleType(ScaleType.LINEAR, 'color', { type: 'temporal', timeUnit: 'year' }, 'point', defaultScaleConfig), ScaleType.SEQUENTIAL); + }); + it('should return time if data type is temporal but specified scale type is discrete', function () { + assert.equal(scaleType(ScaleType.POINT, 'x', { type: 'temporal', timeUnit: 'year' }, 'point', defaultScaleConfig), ScaleType.TIME); + }); + it('should return default scale type if data type is temporal but specified scale type is time or utc or any discrete type', function () { + assert.equal(scaleType(ScaleType.LINEAR, 'x', { type: 'temporal', timeUnit: 'year' }, 'point', defaultScaleConfig), ScaleType.TIME); + }); + it('should return default scale type if data type is quantative but scale type do not support quantative', function () { + assert.equal(scaleType(ScaleType.TIME, 'color', { type: 'quantitative' }, 'point', defaultScaleConfig), ScaleType.SEQUENTIAL); + }); + it('should return default scale type if data type is quantative and scale type supports quantative', function () { + assert.equal(scaleType(ScaleType.TIME, 'x', { type: 'quantitative' }, 'point', defaultScaleConfig), ScaleType.LINEAR); + }); + it('should return default scale type if data type is quantative and scale type supports quantative', function () { + assert.equal(scaleType(ScaleType.TIME, 'x', { type: 'temporal' }, 'point', defaultScaleConfig), ScaleType.TIME); + }); + }); + }); +}); +//# sourceMappingURL=type.test.js.map \ No newline at end of file diff --git a/build/test/compile/scale/type.test.js.map b/build/test/compile/scale/type.test.js.map new file mode 100644 index 0000000000..7c5f9ca00d --- /dev/null +++ b/build/test/compile/scale/type.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"type.test.js","sourceRoot":"","sources":["../../../../test/compile/scale/type.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {rangeType, SCALE_CHANNELS, X, Y} from '../../../src/channel';\nimport {scaleType} from '../../../src/compile/scale/type';\nimport {defaultConfig} from '../../../src/config';\nimport * as log from '../../../src/log';\nimport {PRIMITIVE_MARKS} from '../../../src/mark';\nimport {ScaleType} from '../../../src/scale';\nimport {TIMEUNITS} from '../../../src/timeunit';\nimport {NOMINAL, ORDINAL} from '../../../src/type';\nimport * as util from '../../../src/util';\n\nconst defaultScaleConfig = defaultConfig.scale;\n\ndescribe('compile/scale', () => {\n describe('type()', () => {\n it('should return null for channel without scale', function() {\n assert.deepEqual(\n scaleType(undefined, 'detail', {type: 'temporal', timeUnit: 'yearmonth'}, 'point', defaultScaleConfig),\n null\n );\n });\n\n it('should show warning if users try to override the scale and use bin', log.wrap((localLogger) => {\n assert.deepEqual(\n scaleType('point', 'color', {type: 'quantitative', bin: true}, 'point', defaultScaleConfig),\n ScaleType.BIN_ORDINAL\n );\n assert.equal(localLogger.warns[0], log.message.scaleTypeNotWorkWithFieldDef(ScaleType.POINT, ScaleType.BIN_ORDINAL));\n }));\n\n describe('nominal/ordinal', () => {\n describe('color', () => {\n it('should return ordinal scale for nominal data by default.', () => {\n assert.equal(\n scaleType(undefined, 'color', {type: 'nominal'}, 'point', defaultScaleConfig),\n ScaleType.ORDINAL\n );\n });\n\n it('should return ordinal scale for ordinal data.', () => {\n assert.equal(\n scaleType(undefined, 'color', {type: 'nominal'}, 'point', defaultScaleConfig),\n ScaleType.ORDINAL\n );\n });\n });\n\n describe('discrete channel (shape)', () => {\n it('should return ordinal for nominal field', function() {\n assert.deepEqual(\n scaleType(undefined, 'shape', {type: 'nominal'}, 'point', defaultScaleConfig),\n ScaleType.ORDINAL\n );\n });\n\n it('should return ordinal even if other type is specified', log.wrap((localLogger) => {\n [ScaleType.LINEAR, ScaleType.BAND, ScaleType.POINT].forEach((badScaleType) => {\n assert.deepEqual(\n scaleType(badScaleType, 'shape', {type: 'nominal'}, 'point', defaultScaleConfig),\n ScaleType.ORDINAL\n );\n const warns = localLogger.warns;\n assert.equal(warns[warns.length-1], log.message.scaleTypeNotWorkWithChannel('shape', badScaleType, 'ordinal'));\n });\n }));\n\n it('should return ordinal for an ordinal field and throw a warning.', log.wrap((localLogger) => {\n assert.deepEqual(\n scaleType(undefined, 'shape', {type: 'ordinal'}, 'point', defaultScaleConfig),\n ScaleType.ORDINAL\n );\n assert.equal(localLogger.warns[0], log.message.discreteChannelCannotEncode('shape', 'ordinal'));\n }));\n });\n\n describe('continuous', () => {\n it('should return point scale for ordinal X,Y for marks others than rect, rule, and bar', () => {\n PRIMITIVE_MARKS.forEach((mark) => {\n if (util.contains(['bar', 'rule', 'rect'], mark)) {\n return;\n }\n\n [ORDINAL, NOMINAL].forEach((t) => {\n [X, Y].forEach((channel) => {\n assert.equal(\n scaleType(undefined, channel, {type: t}, mark, defaultScaleConfig),\n ScaleType.POINT\n );\n });\n });\n });\n });\n\n it('should return band scale for ordinal X,Y when mark is rect, rule, bar', () => {\n [ORDINAL, NOMINAL].forEach((t) => {\n [X, Y].forEach((channel) => {\n ['bar', 'rule', 'rect'].forEach((mark) => {\n assert.equal(\n scaleType(undefined, channel, {type: t}, 'rect', defaultScaleConfig),\n ScaleType.BAND\n );\n });\n });\n });\n });\n\n it('should return point scale for X,Y when mark is point', () => {\n [ORDINAL, NOMINAL].forEach((t) => {\n [X, Y].forEach((channel) => {\n assert.equal(scaleType(undefined, channel, {type: t}, 'point', defaultScaleConfig), ScaleType.POINT);\n });\n });\n });\n\n it('should return point scale for X,Y when mark is point when ORDINAL SCALE TYPE is specified and throw warning', log.wrap((localLogger) => {\n [ORDINAL, NOMINAL].forEach((t) => {\n [X, Y].forEach((channel) => {\n assert.equal(scaleType('ordinal', channel, {type: t}, 'point', defaultScaleConfig), ScaleType.POINT);\n const warns = localLogger.warns;\n assert.equal(warns[warns.length-1], log.message.scaleTypeNotWorkWithChannel(channel, 'ordinal', 'point'));\n });\n });\n }));\n\n it('should return point scale for ordinal/nominal fields for continuous channels other than x and y.', () => {\n const OTHER_CONTINUOUS_CHANNELS = SCALE_CHANNELS.filter((c) => rangeType(c) === 'continuous' && !util.contains([X, Y], c));\n PRIMITIVE_MARKS.forEach((mark) => {\n [ORDINAL, NOMINAL].forEach((t) => {\n OTHER_CONTINUOUS_CHANNELS.forEach((channel) => {\n assert.equal(\n scaleType(undefined, channel, {type: t}, mark, defaultScaleConfig),\n ScaleType.POINT,\n `${channel}, ${mark}, ${t} ` + scaleType(undefined, channel, {type: t}, mark, defaultScaleConfig)\n );\n });\n });\n });\n });\n });\n });\n\n describe('temporal', () => {\n it('should return sequential scale for temporal color field by default.', () => {\n assert.equal(\n scaleType(undefined, 'color', {type: 'temporal'}, 'point', defaultScaleConfig),\n ScaleType.SEQUENTIAL\n );\n });\n\n it('should return ordinal for temporal field and throw a warning.', log.wrap((localLogger) => {\n assert.deepEqual(\n scaleType(undefined, 'shape', {type: 'temporal', timeUnit: 'yearmonth'}, 'point', defaultScaleConfig),\n ScaleType.ORDINAL\n );\n assert.equal(localLogger.warns[0], log.message.discreteChannelCannotEncode('shape', 'temporal'));\n }));\n\n it('should return time for all time units.', function() {\n for (const timeUnit of TIMEUNITS) {\n assert.deepEqual(\n scaleType(undefined, Y, {type: 'temporal', timeUnit: timeUnit}, 'point', defaultScaleConfig),\n ScaleType.TIME\n );\n }\n });\n });\n describe('quantitative', () => {\n it('should return sequential scale for quantitative color field by default.', () => {\n assert.equal(\n scaleType(undefined, 'color', {type: 'quantitative'}, 'point', defaultScaleConfig),\n ScaleType.SEQUENTIAL\n );\n });\n\n it('should return ordinal bin scale for quantitative color field with binning.', () => {\n assert.equal(\n scaleType(undefined, 'color', {type: 'quantitative', bin: true}, 'point', defaultScaleConfig),\n ScaleType.BIN_ORDINAL\n );\n });\n\n it('should return ordinal for encoding quantitative field with a discrete channel and throw a warning.', log.wrap((localLogger) => {\n assert.deepEqual(\n scaleType(undefined, 'shape', {type: 'quantitative'}, 'point', defaultScaleConfig),\n ScaleType.ORDINAL\n );\n assert.equal(localLogger.warns[0], log.message.discreteChannelCannotEncode('shape', 'quantitative'));\n }));\n\n it('should return linear scale for quantitative by default.', () => {\n assert.equal(\n scaleType(undefined, 'x', {type: 'quantitative'}, 'point', defaultScaleConfig),\n ScaleType.LINEAR\n );\n });\n\n it('should return bin linear scale for quantitative by default.', () => {\n assert.equal(\n scaleType(undefined, 'opacity', {type: 'quantitative', bin: true}, 'point', defaultScaleConfig),\n ScaleType.BIN_LINEAR\n );\n });\n\n it('should return linear scale for quantitative x and y.', () => {\n assert.equal(\n scaleType(undefined, 'x', {type: 'quantitative', bin: true}, 'point', defaultScaleConfig),\n ScaleType.LINEAR\n );\n });\n });\n\n describe('dataTypeMatchScaleType()', () => {\n it('should return specified value if datatype is ordinal or nominal and specified scale type is the ordinal or nominal', () => {\n assert.equal(\n scaleType(ScaleType.ORDINAL, 'shape', {type: 'ordinal'}, 'point', defaultScaleConfig),\n ScaleType.ORDINAL\n );\n });\n\n it('should return default scale type if data type is temporal but specified scale type is not time or utc', () => {\n assert.equal(\n scaleType(ScaleType.LINEAR, 'x', {type: 'temporal', timeUnit: 'year'}, 'point', defaultScaleConfig),\n ScaleType.TIME\n );\n\n assert.equal(\n scaleType(ScaleType.LINEAR, 'color', {type: 'temporal', timeUnit: 'year'}, 'point', defaultScaleConfig),\n ScaleType.SEQUENTIAL\n );\n });\n\n it('should return time if data type is temporal but specified scale type is discrete', () => {\n assert.equal(\n scaleType(ScaleType.POINT, 'x', {type: 'temporal', timeUnit: 'year'}, 'point', defaultScaleConfig),\n ScaleType.TIME\n );\n });\n\n it('should return default scale type if data type is temporal but specified scale type is time or utc or any discrete type', () => {\n assert.equal(\n scaleType(ScaleType.LINEAR, 'x', {type: 'temporal', timeUnit: 'year'}, 'point', defaultScaleConfig),\n ScaleType.TIME\n );\n });\n\n it('should return default scale type if data type is quantative but scale type do not support quantative', () => {\n assert.equal(\n scaleType(ScaleType.TIME, 'color', {type: 'quantitative'}, 'point', defaultScaleConfig),\n ScaleType.SEQUENTIAL\n );\n });\n\n it('should return default scale type if data type is quantative and scale type supports quantative', () => {\n assert.equal(\n scaleType(ScaleType.TIME, 'x', {type: 'quantitative'}, 'point', defaultScaleConfig),\n ScaleType.LINEAR\n );\n });\n\n it('should return default scale type if data type is quantative and scale type supports quantative', () => {\n assert.equal(\n scaleType(ScaleType.TIME, 'x', {type: 'temporal'}, 'point', defaultScaleConfig),\n ScaleType.TIME\n );\n });\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/facets.test.d.ts b/build/test/compile/selection/facets.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/facets.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/facets.test.js b/build/test/compile/selection/facets.test.js new file mode 100644 index 0000000000..c6b755c179 --- /dev/null +++ b/build/test/compile/selection/facets.test.js @@ -0,0 +1,49 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import * as selection from '../../../src/compile/selection/selection'; +import { parseModel } from '../../util'; +describe('Faceted Selections', function () { + var model = parseModel({ + "data": { "url": "data/anscombe.json" }, + "facet": { + "column": { "field": "Series", "type": "nominal" }, + "row": { "field": "X", "type": "nominal", "bin": true }, + }, + "spec": { + "layer": [{ + "mark": "rule", + "encoding": { "y": { "value": 10 } } + }, { + "selection": { + "one": { "type": "single" }, + "twp": { "type": "multi" }, + "three": { "type": "interval" } + }, + "mark": "rule", + "encoding": { + "x": { "value": 10 } + } + }] + } + }); + model.parse(); + var unit = model.children[0].children[1]; + it('should assemble a facet signal', function () { + assert.includeDeepMembers(selection.assembleUnitSelectionSignals(unit, []), [ + { + "name": "facet", + "value": {}, + "on": [ + { + "events": [{ "source": "scope", "type": "mousemove" }], + "update": "isTuple(facet) ? facet : group(\"cell\").datum" + } + ] + } + ]); + }); + it('should name the unit with the facet keys', function () { + assert.equal(selection.unitName(unit), "\"child_layer_1\" + '_' + (facet[\"bin_maxbins_6_X\"]) + '_' + (facet[\"Series\"])"); + }); +}); +//# sourceMappingURL=facets.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/facets.test.js.map b/build/test/compile/selection/facets.test.js.map new file mode 100644 index 0000000000..feed985c36 --- /dev/null +++ b/build/test/compile/selection/facets.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"facets.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/facets.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,SAAS,MAAM,0CAA0C,CAAC;AAEtE,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAC;AAEtC,QAAQ,CAAC,oBAAoB,EAAE;IAC7B,IAAM,KAAK,GAAG,UAAU,CAAC;QACvB,MAAM,EAAE,EAAC,KAAK,EAAE,oBAAoB,EAAC;QACrC,OAAO,EAAE;YACP,QAAQ,EAAE,EAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC;YAChD,KAAK,EAAE,EAAC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAC;SACtD;QACD,MAAM,EAAE;YACN,OAAO,EAAE,CAAC;oBACR,MAAM,EAAE,MAAM;oBACd,UAAU,EAAE,EAAC,GAAG,EAAE,EAAC,OAAO,EAAE,EAAE,EAAC,EAAC;iBACjC,EAAE;oBACD,WAAW,EAAE;wBACX,KAAK,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAC;wBACzB,KAAK,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC;wBACxB,OAAO,EAAE,EAAC,MAAM,EAAE,UAAU,EAAC;qBAC9B;oBACD,MAAM,EAAE,MAAM;oBACd,UAAU,EAAE;wBACV,GAAG,EAAE,EAAC,OAAO,EAAE,EAAE,EAAC;qBACnB;iBACF,CAAC;SACH;KACF,CAAC,CAAC;IAEH,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,IAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAc,CAAC;IAExD,EAAE,CAAC,gCAAgC,EAAE;QACnC,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,4BAA4B,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE;YAC1E;gBACE,MAAM,EAAE,OAAO;gBACf,OAAO,EAAE,EAAE;gBACX,IAAI,EAAE;oBACJ;wBACE,QAAQ,EAAE,CAAC,EAAC,QAAQ,EAAE,OAAO,EAAC,MAAM,EAAE,WAAW,EAAC,CAAC;wBACnD,QAAQ,EAAE,gDAAgD;qBAC3D;iBACF;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE;QAC7C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EACnC,oFAA8E,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport * as selection from '../../../src/compile/selection/selection';\nimport {UnitModel} from '../../../src/compile/unit';\nimport {parseModel} from '../../util';\n\ndescribe('Faceted Selections', function() {\n const model = parseModel({\n \"data\": {\"url\": \"data/anscombe.json\"},\n \"facet\": {\n \"column\": {\"field\": \"Series\", \"type\": \"nominal\"},\n \"row\": {\"field\": \"X\", \"type\": \"nominal\", \"bin\": true},\n },\n \"spec\": {\n \"layer\": [{\n \"mark\": \"rule\",\n \"encoding\": {\"y\": {\"value\": 10}}\n }, {\n \"selection\": {\n \"one\": {\"type\": \"single\"},\n \"twp\": {\"type\": \"multi\"},\n \"three\": {\"type\": \"interval\"}\n },\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"value\": 10}\n }\n }]\n }\n });\n\n model.parse();\n const unit = model.children[0].children[1] as UnitModel;\n\n it('should assemble a facet signal', function() {\n assert.includeDeepMembers(selection.assembleUnitSelectionSignals(unit, []), [\n {\n \"name\": \"facet\",\n \"value\": {},\n \"on\": [\n {\n \"events\": [{\"source\": \"scope\",\"type\": \"mousemove\"}],\n \"update\": \"isTuple(facet) ? facet : group(\\\"cell\\\").datum\"\n }\n ]\n }\n ]);\n });\n\n it('should name the unit with the facet keys', function() {\n assert.equal(selection.unitName(unit),\n `\"child_layer_1\" + '_' + (facet[\"bin_maxbins_6_X\"]) + '_' + (facet[\"Series\"])`);\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/identifier.test.d.ts b/build/test/compile/selection/identifier.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/identifier.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/identifier.test.js b/build/test/compile/selection/identifier.test.js new file mode 100644 index 0000000000..658aa36511 --- /dev/null +++ b/build/test/compile/selection/identifier.test.js @@ -0,0 +1,70 @@ +import * as tslib_1 from "tslib"; +import { assert } from 'chai'; +import { assembleRootData } from '../../../src/compile/data/assemble'; +import { optimizeDataflow } from '../../../src/compile/data/optimize'; +import { parseModel } from '../../util'; +/* tslint:disable:quotemark */ +function getVgData(selection, x, y, mark, enc, transform) { + var model = parseModel({ + data: { url: 'data/cars.json' }, + transform: transform, + selection: selection, + mark: mark || 'circle', + encoding: tslib_1.__assign({ x: tslib_1.__assign({ field: 'Horsepower', type: 'quantitative' }, x), y: tslib_1.__assign({ field: 'Miles-per-Gallon', type: 'quantitative' }, y), color: { field: 'Origin', type: 'nominal' } }, enc) + }); + model.parse(); + optimizeDataflow(model.component.data); + return assembleRootData(model.component.data, {}); +} +describe('Identifier transform', function () { + it('is not unnecessarily added', function () { + function test(selDef) { + var data = getVgData(selDef); + for (var _i = 0, data_1 = data; _i < data_1.length; _i++) { + var d = data_1[_i]; + assert.isNotTrue(d.transform && d.transform.some(function (t) { return t.type === 'identifier'; })); + } + } + test(); + for (var _i = 0, _a = ['single', 'multi']; _i < _a.length; _i++) { + var type = _a[_i]; + test({ pt: { type: type, encodings: ['x'] } }); + } + }); + it('is added for default point selections', function () { + for (var _i = 0, _a = ['single', 'multi']; _i < _a.length; _i++) { + var type = _a[_i]; + var url = getVgData({ pt: { type: type } }); + assert.equal(url[0].transform[0].type, 'identifier'); + } + }); + it('is added immediately after aggregate transforms', function () { + function test(transform) { + var aggr = -1; + transform.some(function (t, i) { return (aggr = i, t.type === 'aggregate'); }); + assert.isAtLeast(aggr, 0); + assert.equal(transform[aggr + 1].type, 'identifier'); + } + for (var _i = 0, _a = ['single', 'multi']; _i < _a.length; _i++) { + var type = _a[_i]; + var sel = { pt: { type: type } }; + var data = getVgData(sel, { bin: true }, { aggregate: 'count' }); + test(data[0].transform); + data = getVgData(sel, { aggregate: 'sum' }, null, 'bar', { column: { field: 'Cylinders', type: 'ordinal' } }); + test(data[0].transform); + } + }); + it('is added before any user-specified transforms', function () { + var _loop_1 = function (type) { + var data = getVgData({ pt: { type: type } }, null, null, null, null, [{ calculate: 'datum.Horsepower * 2', as: 'foo' }]); + var calc = -1; + data[0].transform.some(function (t, i) { return (calc = i, t.type === 'formula' && t.as === 'foo'); }); + assert.equal(data[0].transform[calc - 1].type, 'identifier'); + }; + for (var _i = 0, _a = ['single', 'multi']; _i < _a.length; _i++) { + var type = _a[_i]; + _loop_1(type); + } + }); +}); +//# sourceMappingURL=identifier.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/identifier.test.js.map b/build/test/compile/selection/identifier.test.js.map new file mode 100644 index 0000000000..0481a2d504 --- /dev/null +++ b/build/test/compile/selection/identifier.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"identifier.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/identifier.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {assembleRootData} from '../../../src/compile/data/assemble';\nimport {optimizeDataflow} from '../../../src/compile/data/optimize';\nimport {Mark} from '../../../src/mark';\nimport {VgTransform} from '../../../src/vega.schema';\nimport {parseModel} from '../../util';\n\n/* tslint:disable:quotemark */\n\nfunction getVgData(selection: any, x?: any, y?: any, mark?: Mark, enc?: any, transform?: any) {\n const model = parseModel({\n data: {url: 'data/cars.json'},\n transform,\n selection,\n mark: mark || 'circle',\n encoding: {\n x: {field: 'Horsepower', type: 'quantitative', ...x},\n y: {field: 'Miles-per-Gallon', type: 'quantitative', ...y},\n color: {field: 'Origin', type: 'nominal'},\n ...enc\n }\n });\n model.parse();\n optimizeDataflow(model.component.data);\n return assembleRootData(model.component.data, {});\n}\n\ndescribe('Identifier transform', function() {\n it('is not unnecessarily added', function() {\n function test(selDef?: any) {\n const data = getVgData(selDef);\n for (const d of data) {\n assert.isNotTrue(d.transform && d.transform.some((t) => t.type === 'identifier'));\n }\n }\n\n test();\n for (const type of ['single', 'multi']) {\n test({pt: {type, encodings: ['x']}});\n }\n });\n\n it('is added for default point selections', function() {\n for (const type of ['single', 'multi']) {\n const url = getVgData({pt: {type}});\n assert.equal(url[0].transform[0].type, 'identifier');\n }\n });\n\n it('is added immediately after aggregate transforms', function() {\n function test(transform: VgTransform[]) {\n let aggr = -1;\n transform.some((t, i) => (aggr = i, t.type === 'aggregate'));\n assert.isAtLeast(aggr, 0);\n assert.equal(transform[aggr + 1].type, 'identifier');\n }\n\n for (const type of ['single', 'multi']) {\n const sel = {pt: {type}};\n let data = getVgData(sel, {bin: true}, {aggregate: 'count'});\n test(data[0].transform);\n\n data = getVgData(sel, {aggregate: 'sum'}, null, 'bar',\n {column: {field: 'Cylinders', type: 'ordinal'}});\n test(data[0].transform);\n }\n });\n\n it('is added before any user-specified transforms', function() {\n for (const type of ['single', 'multi']) {\n const data = getVgData({pt: {type}}, null, null, null, null,\n [{calculate: 'datum.Horsepower * 2', as: 'foo'}]);\n let calc = -1;\n data[0].transform.some((t, i) => (calc = i, t.type === 'formula' && t.as === 'foo'));\n assert.equal(data[0].transform[calc - 1].type, 'identifier');\n }\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/inputs.test.d.ts b/build/test/compile/selection/inputs.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/inputs.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/inputs.test.js b/build/test/compile/selection/inputs.test.js new file mode 100644 index 0000000000..a0c690188f --- /dev/null +++ b/build/test/compile/selection/inputs.test.js @@ -0,0 +1,147 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import * as selection from '../../../src/compile/selection/selection'; +import inputs from '../../../src/compile/selection/transforms/inputs'; +import { parseUnitModel } from '../../util'; +describe('Inputs Selection Transform', function () { + var model = parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" } + } + }); + model.parseScale(); + var selCmpts = selection.parseUnitSelection(model, { + "one": { + "type": "single", + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + }, + "two": { + "type": "single", + "fields": ["Cylinders", "Horsepower"], + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + }, + "three": { + "type": "single", "nearest": true, + "fields": ["Cylinders", "Origin"], + "bind": { + "Horsepower": { "input": "range", "min": 0, "max": 10, "step": 1 }, + "Origin": { "input": "select", "options": ["Japan", "USA", "Europe"] } + } + }, + "four": { + "type": "single", "bind": null + }, + "six": { + "type": "interval", + "bind": "scales" + } + }); + it('identifies transform invocation', function () { + assert.isNotFalse(inputs.has(selCmpts['one'])); + assert.isNotFalse(inputs.has(selCmpts['two'])); + assert.isNotFalse(inputs.has(selCmpts['three'])); + assert.isNotTrue(inputs.has(selCmpts['four'])); + assert.isNotTrue(inputs.has(selCmpts['six'])); + }); + it('adds widget binding for default projection', function () { + model.component.selection = { one: selCmpts['one'] }; + assert.includeDeepMembers(selection.assembleUnitSelectionSignals(model, []), [ + { + "name": "one_tuple", + "update": "one__vgsid_ ? {fields: [\"_vgsid_\"], values: [one__vgsid_]} : null" + } + ]); + assert.includeDeepMembers(selection.assembleTopLevelSignals(model, []), [ + { + "name": "one__vgsid_", + "value": "", + "on": [ + { + "events": [{ "source": "scope", "type": "click" }], + "update": "datum && item().mark.marktype !== 'group' ? datum[\"_vgsid_\"] : null" + } + ], + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + } + ]); + }); + it('adds single widget binding for compound projection', function () { + model.component.selection = { two: selCmpts['two'] }; + assert.includeDeepMembers(selection.assembleUnitSelectionSignals(model, []), [ + { + "name": "two_tuple", + "update": "two_Cylinders && two_Horsepower ? {fields: [\"Cylinders\", \"Horsepower\"], values: [two_Cylinders, two_Horsepower]} : null" + } + ]); + assert.includeDeepMembers(selection.assembleTopLevelSignals(model, []), [ + { + "name": "two_Horsepower", + "value": "", + "on": [ + { + "events": [{ "source": "scope", "type": "click" }], + "update": "datum && item().mark.marktype !== 'group' ? datum[\"Horsepower\"] : null" + } + ], + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + }, + { + "name": "two_Cylinders", + "value": "", + "on": [ + { + "events": [{ "source": "scope", "type": "click" }], + "update": "datum && item().mark.marktype !== 'group' ? datum[\"Cylinders\"] : null" + } + ], + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + } + ]); + }); + it('adds projection-specific widget bindings', function () { + model.component.selection = { three: selCmpts['three'] }; + assert.includeDeepMembers(selection.assembleUnitSelectionSignals(model, []), [ + { + "name": "three_tuple", + "update": "three_Cylinders && three_Origin ? {fields: [\"Cylinders\", \"Origin\"], values: [three_Cylinders, three_Origin]} : null" + } + ]); + assert.includeDeepMembers(selection.assembleTopLevelSignals(model, []), [ + { + "name": "three_Origin", + "value": "", + "on": [ + { + "events": [{ "source": "scope", "type": "click" }], + "update": "datum && item().mark.marktype !== 'group' ? (item().isVoronoi ? datum.datum : datum)[\"Origin\"] : null" + } + ], + "bind": { + "input": "select", + "options": ["Japan", "USA", "Europe"] + } + }, + { + "name": "three_Cylinders", + "value": "", + "on": [ + { + "events": [{ "source": "scope", "type": "click" }], + "update": "datum && item().mark.marktype !== 'group' ? (item().isVoronoi ? datum.datum : datum)[\"Cylinders\"] : null" + } + ], + "bind": { + "Horsepower": { "input": "range", "min": 0, "max": 10, "step": 1 }, + "Origin": { + "input": "select", + "options": ["Japan", "USA", "Europe"] + } + } + } + ]); + }); +}); +//# sourceMappingURL=inputs.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/inputs.test.js.map b/build/test/compile/selection/inputs.test.js.map new file mode 100644 index 0000000000..a4c0d61129 --- /dev/null +++ b/build/test/compile/selection/inputs.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"inputs.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/inputs.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport * as selection from '../../../src/compile/selection/selection';\nimport inputs from '../../../src/compile/selection/transforms/inputs';\nimport {parseUnitModel} from '../../util';\n\ndescribe('Inputs Selection Transform', function() {\n const model = parseUnitModel({\n \"mark\": \"circle\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\"},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n });\n\n model.parseScale();\n const selCmpts = selection.parseUnitSelection(model, {\n \"one\": {\n \"type\": \"single\",\n \"bind\": {\"input\": \"range\", \"min\": 0, \"max\": 10, \"step\": 1}\n },\n \"two\": {\n \"type\": \"single\",\n \"fields\": [\"Cylinders\", \"Horsepower\"],\n \"bind\": {\"input\": \"range\", \"min\": 0, \"max\": 10, \"step\": 1}\n },\n \"three\": {\n \"type\": \"single\", \"nearest\": true,\n \"fields\": [\"Cylinders\", \"Origin\"],\n \"bind\": {\n \"Horsepower\": {\"input\": \"range\", \"min\": 0, \"max\": 10, \"step\": 1},\n \"Origin\": {\"input\": \"select\", \"options\": [\"Japan\", \"USA\", \"Europe\"]}\n }\n },\n \"four\": {\n \"type\": \"single\", \"bind\": null\n },\n \"six\": {\n \"type\": \"interval\",\n \"bind\": \"scales\"\n }\n });\n\n it('identifies transform invocation', function() {\n assert.isNotFalse(inputs.has(selCmpts['one']));\n assert.isNotFalse(inputs.has(selCmpts['two']));\n assert.isNotFalse(inputs.has(selCmpts['three']));\n assert.isNotTrue(inputs.has(selCmpts['four']));\n assert.isNotTrue(inputs.has(selCmpts['six']));\n });\n\n it('adds widget binding for default projection', function() {\n model.component.selection = {one: selCmpts['one']};\n assert.includeDeepMembers(selection.assembleUnitSelectionSignals(model, []), [\n {\n \"name\": \"one_tuple\",\n \"update\": \"one__vgsid_ ? {fields: [\\\"_vgsid_\\\"], values: [one__vgsid_]} : null\"\n }\n ]);\n\n assert.includeDeepMembers(selection.assembleTopLevelSignals(model, []), [\n {\n \"name\": \"one__vgsid_\",\n \"value\": \"\",\n \"on\": [\n {\n \"events\": [{\"source\": \"scope\",\"type\": \"click\"}],\n \"update\": \"datum && item().mark.marktype !== 'group' ? datum[\\\"_vgsid_\\\"] : null\"\n }\n ],\n \"bind\": {\"input\": \"range\",\"min\": 0,\"max\": 10,\"step\": 1}\n }\n ]);\n });\n\n it('adds single widget binding for compound projection', function() {\n model.component.selection = {two: selCmpts['two']};\n assert.includeDeepMembers(selection.assembleUnitSelectionSignals(model, []), [\n {\n \"name\": \"two_tuple\",\n \"update\": \"two_Cylinders && two_Horsepower ? {fields: [\\\"Cylinders\\\", \\\"Horsepower\\\"], values: [two_Cylinders, two_Horsepower]} : null\"\n }\n ]);\n\n assert.includeDeepMembers(selection.assembleTopLevelSignals(model, []), [\n {\n \"name\": \"two_Horsepower\",\n \"value\": \"\",\n \"on\": [\n {\n \"events\": [{\"source\": \"scope\",\"type\": \"click\"}],\n \"update\": \"datum && item().mark.marktype !== 'group' ? datum[\\\"Horsepower\\\"] : null\"\n }\n ],\n \"bind\": {\"input\": \"range\",\"min\": 0,\"max\": 10,\"step\": 1}\n },\n {\n \"name\": \"two_Cylinders\",\n \"value\": \"\",\n \"on\": [\n {\n \"events\": [{\"source\": \"scope\",\"type\": \"click\"}],\n \"update\": \"datum && item().mark.marktype !== 'group' ? datum[\\\"Cylinders\\\"] : null\"\n }\n ],\n \"bind\": {\"input\": \"range\",\"min\": 0,\"max\": 10,\"step\": 1}\n }\n ]);\n });\n\n it('adds projection-specific widget bindings', function() {\n model.component.selection = {three: selCmpts['three']};\n assert.includeDeepMembers(selection.assembleUnitSelectionSignals(model, []), [\n {\n \"name\": \"three_tuple\",\n \"update\": \"three_Cylinders && three_Origin ? {fields: [\\\"Cylinders\\\", \\\"Origin\\\"], values: [three_Cylinders, three_Origin]} : null\"\n }\n ]);\n\n assert.includeDeepMembers(selection.assembleTopLevelSignals(model, []), [\n {\n \"name\": \"three_Origin\",\n \"value\": \"\",\n \"on\": [\n {\n \"events\": [{\"source\": \"scope\",\"type\": \"click\"}],\n \"update\": \"datum && item().mark.marktype !== 'group' ? (item().isVoronoi ? datum.datum : datum)[\\\"Origin\\\"] : null\"\n }\n ],\n \"bind\": {\n \"input\": \"select\",\n \"options\": [\"Japan\",\"USA\",\"Europe\"]\n }\n },\n {\n \"name\": \"three_Cylinders\",\n \"value\": \"\",\n \"on\": [\n {\n \"events\": [{\"source\": \"scope\",\"type\": \"click\"}],\n \"update\": \"datum && item().mark.marktype !== 'group' ? (item().isVoronoi ? datum.datum : datum)[\\\"Cylinders\\\"] : null\"\n }\n ],\n \"bind\": {\n \"Horsepower\": {\"input\": \"range\",\"min\": 0,\"max\": 10,\"step\": 1},\n \"Origin\": {\n \"input\": \"select\",\n \"options\": [\"Japan\",\"USA\",\"Europe\"]\n }\n }\n }\n ]);\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/interval.test.d.ts b/build/test/compile/selection/interval.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/interval.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/interval.test.js b/build/test/compile/selection/interval.test.js new file mode 100644 index 0000000000..c9e6bac425 --- /dev/null +++ b/build/test/compile/selection/interval.test.js @@ -0,0 +1,448 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { selector as parseSelector } from 'vega-event-selector'; +import interval from '../../../src/compile/selection/interval'; +import * as selection from '../../../src/compile/selection/selection'; +import { parseUnitModel } from '../../util'; +describe('Interval Selections', function () { + var model = parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles-per-Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" } + } + }); + model.parseScale(); + var selCmpts = model.component.selection = selection.parseUnitSelection(model, { + "one": { "type": "interval", "encodings": ["x"], "translate": false, "zoom": false }, + "two": { + "type": "interval", + "encodings": ["y"], + "bind": "scales", + "translate": false, + "zoom": false + }, + "thr-ee": { + "type": "interval", + "on": "[mousedown, mouseup] > mousemove, [keydown, keyup] > keypress", + "translate": false, + "zoom": false, + "resolve": "intersect", + "mark": { + "fill": "red", + "fillOpacity": 0.75, + "stroke": "black", + "strokeWidth": 4, + "strokeDash": [10, 5], + "strokeDashOffset": 3, + "strokeOpacity": 0.25 + } + } + }); + describe('Tuple Signals', function () { + it('builds projection signals', function () { + var oneSg = interval.signals(model, selCmpts['one']); + assert.includeDeepMembers(oneSg, [{ + "name": "one_x", + "value": [], + "on": [ + { + "events": parseSelector('mousedown', 'scope')[0], + "update": "[x(unit), x(unit)]" + }, + { + "events": parseSelector('[mousedown, window:mouseup] > window:mousemove!', 'scope')[0], + "update": "[one_x[0], clamp(x(unit), 0, width)]" + }, + { + "events": { "signal": "one_scale_trigger" }, + "update": "[scale(\"x\", one_Horsepower[0]), scale(\"x\", one_Horsepower[1])]" + } + ] + }, { + "name": "one_Horsepower", + "on": [{ + "events": { "signal": "one_x" }, + "update": "one_x[0] === one_x[1] ? null : invert(\"x\", one_x)" + }] + }, { + "name": "one_scale_trigger", + "update": "(!isArray(one_Horsepower) || (+invert(\"x\", one_x)[0] === +one_Horsepower[0] && +invert(\"x\", one_x)[1] === +one_Horsepower[1])) ? one_scale_trigger : {}" + }]); + var twoSg = interval.signals(model, selCmpts['two']); + assert.includeDeepMembers(twoSg, [{ + "name": "two_Miles_per_Gallon", + "on": [] + }]); + var threeSg = interval.signals(model, selCmpts['thr_ee']); + assert.includeDeepMembers(threeSg, [ + { + "name": "thr_ee_x", + "value": [], + "on": [ + { + "events": parseSelector('mousedown', 'scope')[0], + "update": "[x(unit), x(unit)]" + }, + { + "events": parseSelector('[mousedown, mouseup] > mousemove', 'scope')[0], + "update": "[thr_ee_x[0], clamp(x(unit), 0, width)]" + }, + { + "events": parseSelector('keydown', 'scope')[0], + "update": "[x(unit), x(unit)]" + }, + { + "events": parseSelector('[keydown, keyup] > keypress', 'scope')[0], + "update": "[thr_ee_x[0], clamp(x(unit), 0, width)]" + }, + { + "events": { "signal": "thr_ee_scale_trigger" }, + "update": "[scale(\"x\", thr_ee_Horsepower[0]), scale(\"x\", thr_ee_Horsepower[1])]" + } + ] + }, + { + "name": "thr_ee_Horsepower", + "on": [{ + "events": { "signal": "thr_ee_x" }, + "update": "thr_ee_x[0] === thr_ee_x[1] ? null : invert(\"x\", thr_ee_x)" + }] + }, + { + "name": "thr_ee_y", + "value": [], + "on": [ + { + "events": parseSelector('mousedown', 'scope')[0], + "update": "[y(unit), y(unit)]" + }, + { + "events": parseSelector('[mousedown, mouseup] > mousemove', 'scope')[0], + "update": "[thr_ee_y[0], clamp(y(unit), 0, height)]" + }, + { + "events": parseSelector('keydown', 'scope')[0], + "update": "[y(unit), y(unit)]" + }, + { + "events": parseSelector('[keydown, keyup] > keypress', 'scope')[0], + "update": "[thr_ee_y[0], clamp(y(unit), 0, height)]" + }, + { + "events": { "signal": "thr_ee_scale_trigger" }, + "update": "[scale(\"y\", thr_ee_Miles_per_Gallon[0]), scale(\"y\", thr_ee_Miles_per_Gallon[1])]" + } + ] + }, + { + "name": "thr_ee_Miles_per_Gallon", + "on": [{ + "events": { "signal": "thr_ee_y" }, + "update": "thr_ee_y[0] === thr_ee_y[1] ? null : invert(\"y\", thr_ee_y)" + }] + }, + { + "name": "thr_ee_scale_trigger", + "update": "(!isArray(thr_ee_Horsepower) || (+invert(\"x\", thr_ee_x)[0] === +thr_ee_Horsepower[0] && +invert(\"x\", thr_ee_x)[1] === +thr_ee_Horsepower[1])) && (!isArray(thr_ee_Miles_per_Gallon) || (+invert(\"y\", thr_ee_y)[0] === +thr_ee_Miles_per_Gallon[0] && +invert(\"y\", thr_ee_y)[1] === +thr_ee_Miles_per_Gallon[1])) ? thr_ee_scale_trigger : {}" + } + ]); + }); + it('builds trigger signals', function () { + var oneSg = interval.signals(model, selCmpts['one']); + assert.includeDeepMembers(oneSg, [ + { + "name": "one_tuple", + "on": [{ + "events": [{ "signal": "one_Horsepower" }], + "update": "one_Horsepower ? {unit: \"\", intervals: [{encoding: \"x\", field: \"Horsepower\", extent: one_Horsepower}]} : null" + }] + } + ]); + var twoSg = interval.signals(model, selCmpts['two']); + assert.includeDeepMembers(twoSg, [ + { + "name": "two_tuple", + "on": [{ + "events": [{ "signal": "two_Miles_per_Gallon" }], + "update": "two_Miles_per_Gallon ? {unit: \"\", intervals: [{encoding: \"y\", field: \"Miles-per-Gallon\", extent: two_Miles_per_Gallon}]} : null" + }] + } + ]); + var threeSg = interval.signals(model, selCmpts['thr_ee']); + assert.includeDeepMembers(threeSg, [ + { + "name": "thr_ee_tuple", + "on": [{ + "events": [{ "signal": "thr_ee_Horsepower" }, { "signal": "thr_ee_Miles_per_Gallon" }], + "update": "thr_ee_Horsepower && thr_ee_Miles_per_Gallon ? {unit: \"\", intervals: [{encoding: \"x\", field: \"Horsepower\", extent: thr_ee_Horsepower}, {encoding: \"y\", field: \"Miles-per-Gallon\", extent: thr_ee_Miles_per_Gallon}]} : null" + }] + } + ]); + }); + it('namespaces signals when encoding/fields collide', function () { + var model2 = parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "x", "type": "quantitative" }, + "y": { "field": "y", "type": "quantitative" } + } + }); + var selCmpts2 = model2.component.selection = selection.parseUnitSelection(model2, { + "one": { + "type": "interval", + "encodings": ["x"], + "translate": false, "zoom": false + } + }); + var sg = interval.signals(model, selCmpts2['one']); + assert.equal(sg[0].name, 'one_x'); + assert.equal(sg[1].name, 'one_x_1'); + }); + }); + it('builds modify signals', function () { + var oneExpr = interval.modifyExpr(model, selCmpts['one']); + assert.equal(oneExpr, 'one_tuple, true'); + var twoExpr = interval.modifyExpr(model, selCmpts['two']); + assert.equal(twoExpr, 'two_tuple, true'); + var threeExpr = interval.modifyExpr(model, selCmpts['thr_ee']); + assert.equal(threeExpr, 'thr_ee_tuple, {unit: \"\"}'); + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, [ + { + "name": "one_modify", + "on": [ + { + "events": { "signal": "one_tuple" }, + "update": "modify(\"one_store\", " + oneExpr + ")" + } + ] + }, + { + "name": "two_modify", + "on": [ + { + "events": { "signal": "two_tuple" }, + "update": "modify(\"two_store\", " + twoExpr + ")" + } + ] + }, + { + "name": "thr_ee_modify", + "on": [ + { + "events": { "signal": "thr_ee_tuple" }, + "update": "modify(\"thr_ee_store\", " + threeExpr + ")" + } + ] + } + ]); + }); + it('builds brush mark', function () { + var marks = [{ hello: "world" }]; + assert.sameDeepMembers(interval.marks(model, selCmpts['one'], marks), [ + { + "name": "one_brush_bg", + "type": "rect", + "clip": true, + "encode": { + "enter": { + "fill": { "value": "#333" }, + "fillOpacity": { "value": 0.125 } + }, + "update": { + "x": [ + { + "test": "data(\"one_store\").length && data(\"one_store\")[0].unit === \"\"", + "signal": "one_x[0]" + }, + { + "value": 0 + } + ], + "y": [ + { + "test": "data(\"one_store\").length && data(\"one_store\")[0].unit === \"\"", + "value": 0 + }, + { + "value": 0 + } + ], + "x2": [ + { + "test": "data(\"one_store\").length && data(\"one_store\")[0].unit === \"\"", + "signal": "one_x[1]" + }, + { + "value": 0 + } + ], + "y2": [ + { + "test": "data(\"one_store\").length && data(\"one_store\")[0].unit === \"\"", + "field": { + "group": "height" + } + }, + { + "value": 0 + } + ] + } + } + }, + { "hello": "world" }, + { + "name": "one_brush", + "type": "rect", + "clip": true, + "encode": { + "enter": { + "fill": { "value": "transparent" } + }, + "update": { + "stroke": [ + { + "test": "one_x[0] !== one_x[1]", + "value": "white" + }, + { + "value": null + } + ], + "x": [ + { + "test": "data(\"one_store\").length && data(\"one_store\")[0].unit === \"\"", + "signal": "one_x[0]" + }, + { + "value": 0 + } + ], + "y": [ + { + "test": "data(\"one_store\").length && data(\"one_store\")[0].unit === \"\"", + "value": 0 + }, + { + "value": 0 + } + ], + "x2": [ + { + "test": "data(\"one_store\").length && data(\"one_store\")[0].unit === \"\"", + "signal": "one_x[1]" + }, + { + "value": 0 + } + ], + "y2": [ + { + "test": "data(\"one_store\").length && data(\"one_store\")[0].unit === \"\"", + "field": { + "group": "height" + } + }, + { + "value": 0 + } + ] + } + } + } + ]); + // Scale-bound interval selections should not add a brush mark. + assert.sameDeepMembers(interval.marks(model, selCmpts['two'], marks), marks); + assert.sameDeepMembers(interval.marks(model, selCmpts['thr_ee'], marks), [ + { + "name": "thr_ee_brush_bg", + "type": "rect", + "clip": true, + "encode": { + "enter": { + "fill": { "value": "red" }, + "fillOpacity": { "value": 0.75 } + }, + "update": { + "x": { + "signal": "thr_ee_x[0]" + }, + "y": { + "signal": "thr_ee_y[0]" + }, + "x2": { + "signal": "thr_ee_x[1]" + }, + "y2": { + "signal": "thr_ee_y[1]" + } + } + } + }, + { "hello": "world" }, + { + "name": "thr_ee_brush", + "type": "rect", + "clip": true, + "encode": { + "enter": { + "fill": { "value": "transparent" } + }, + "update": { + "stroke": [ + { + "test": "thr_ee_x[0] !== thr_ee_x[1] && thr_ee_y[0] !== thr_ee_y[1]", + "value": "black" + }, + { "value": null } + ], + "strokeWidth": [ + { + "test": "thr_ee_x[0] !== thr_ee_x[1] && thr_ee_y[0] !== thr_ee_y[1]", + "value": 4 + }, + { "value": null } + ], + "strokeDash": [ + { + "test": "thr_ee_x[0] !== thr_ee_x[1] && thr_ee_y[0] !== thr_ee_y[1]", + "value": [10, 5] + }, + { "value": null } + ], + "strokeDashOffset": [ + { + "test": "thr_ee_x[0] !== thr_ee_x[1] && thr_ee_y[0] !== thr_ee_y[1]", + "value": 3 + }, + { "value": null } + ], + "strokeOpacity": [ + { + "test": "thr_ee_x[0] !== thr_ee_x[1] && thr_ee_y[0] !== thr_ee_y[1]", + "value": 0.25 + }, + { "value": null } + ], + "x": { + "signal": "thr_ee_x[0]" + }, + "y": { + "signal": "thr_ee_y[0]" + }, + "x2": { + "signal": "thr_ee_x[1]" + }, + "y2": { + "signal": "thr_ee_y[1]" + } + } + } + } + ]); + }); +}); +//# sourceMappingURL=interval.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/interval.test.js.map b/build/test/compile/selection/interval.test.js.map new file mode 100644 index 0000000000..05394e479a --- /dev/null +++ b/build/test/compile/selection/interval.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"interval.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/interval.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport {selector as parseSelector} from 'vega-event-selector';\n\nimport interval from '../../../src/compile/selection/interval';\nimport * as selection from '../../../src/compile/selection/selection';\nimport {parseUnitModel} from '../../util';\n\ndescribe('Interval Selections', function() {\n const model = parseUnitModel({\n \"mark\": \"circle\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles-per-Gallon\",\"type\": \"quantitative\"},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n });\n model.parseScale();\n\n const selCmpts = model.component.selection = selection.parseUnitSelection(model, {\n \"one\": {\"type\": \"interval\", \"encodings\": [\"x\"], \"translate\": false, \"zoom\": false},\n \"two\": {\n \"type\": \"interval\",\n \"encodings\": [\"y\"],\n \"bind\": \"scales\",\n \"translate\": false,\n \"zoom\": false\n },\n \"thr-ee\": {\n \"type\": \"interval\",\n \"on\": \"[mousedown, mouseup] > mousemove, [keydown, keyup] > keypress\",\n \"translate\": false,\n \"zoom\": false,\n \"resolve\": \"intersect\",\n \"mark\": {\n \"fill\": \"red\",\n \"fillOpacity\": 0.75,\n \"stroke\": \"black\",\n \"strokeWidth\": 4,\n \"strokeDash\": [10, 5],\n \"strokeDashOffset\": 3,\n \"strokeOpacity\": 0.25\n }\n }\n });\n\n describe('Tuple Signals', function() {\n it('builds projection signals', function() {\n const oneSg = interval.signals(model, selCmpts['one']);\n assert.includeDeepMembers(oneSg, [{\n \"name\": \"one_x\",\n \"value\": [],\n \"on\": [\n {\n \"events\": parseSelector('mousedown', 'scope')[0],\n \"update\": \"[x(unit), x(unit)]\"\n },\n {\n \"events\": parseSelector('[mousedown, window:mouseup] > window:mousemove!', 'scope')[0],\n \"update\": \"[one_x[0], clamp(x(unit), 0, width)]\"\n },\n {\n \"events\": {\"signal\": \"one_scale_trigger\"},\n \"update\": \"[scale(\\\"x\\\", one_Horsepower[0]), scale(\\\"x\\\", one_Horsepower[1])]\"\n }\n ]\n }, {\n \"name\": \"one_Horsepower\",\n \"on\": [{\n \"events\": {\"signal\": \"one_x\"},\n \"update\": \"one_x[0] === one_x[1] ? null : invert(\\\"x\\\", one_x)\"\n }]\n }, {\n \"name\": \"one_scale_trigger\",\n \"update\": \"(!isArray(one_Horsepower) || (+invert(\\\"x\\\", one_x)[0] === +one_Horsepower[0] && +invert(\\\"x\\\", one_x)[1] === +one_Horsepower[1])) ? one_scale_trigger : {}\"\n }]);\n\n const twoSg = interval.signals(model, selCmpts['two']);\n assert.includeDeepMembers(twoSg, [{\n \"name\": \"two_Miles_per_Gallon\",\n \"on\": []\n }]);\n\n const threeSg = interval.signals(model, selCmpts['thr_ee']);\n assert.includeDeepMembers(threeSg, [\n {\n \"name\": \"thr_ee_x\",\n \"value\": [],\n \"on\": [\n {\n \"events\": parseSelector('mousedown', 'scope')[0],\n \"update\": \"[x(unit), x(unit)]\"\n },\n {\n \"events\": parseSelector('[mousedown, mouseup] > mousemove', 'scope')[0],\n \"update\": \"[thr_ee_x[0], clamp(x(unit), 0, width)]\"\n },\n {\n \"events\": parseSelector('keydown', 'scope')[0],\n \"update\": \"[x(unit), x(unit)]\"\n },\n {\n \"events\": parseSelector('[keydown, keyup] > keypress', 'scope')[0],\n \"update\": \"[thr_ee_x[0], clamp(x(unit), 0, width)]\"\n },\n {\n \"events\": {\"signal\": \"thr_ee_scale_trigger\"},\n \"update\": \"[scale(\\\"x\\\", thr_ee_Horsepower[0]), scale(\\\"x\\\", thr_ee_Horsepower[1])]\"\n }\n ]\n },\n {\n \"name\": \"thr_ee_Horsepower\",\n \"on\": [{\n \"events\": {\"signal\": \"thr_ee_x\"},\n \"update\": \"thr_ee_x[0] === thr_ee_x[1] ? null : invert(\\\"x\\\", thr_ee_x)\"\n }]\n },\n {\n \"name\": \"thr_ee_y\",\n \"value\": [],\n \"on\": [\n {\n \"events\": parseSelector('mousedown', 'scope')[0],\n \"update\": \"[y(unit), y(unit)]\"\n },\n {\n \"events\": parseSelector('[mousedown, mouseup] > mousemove', 'scope')[0],\n \"update\": \"[thr_ee_y[0], clamp(y(unit), 0, height)]\"\n },\n {\n \"events\": parseSelector('keydown', 'scope')[0],\n \"update\": \"[y(unit), y(unit)]\"\n },\n {\n \"events\": parseSelector('[keydown, keyup] > keypress', 'scope')[0],\n \"update\": \"[thr_ee_y[0], clamp(y(unit), 0, height)]\"\n },\n {\n \"events\": {\"signal\": \"thr_ee_scale_trigger\"},\n \"update\": \"[scale(\\\"y\\\", thr_ee_Miles_per_Gallon[0]), scale(\\\"y\\\", thr_ee_Miles_per_Gallon[1])]\"\n }\n ]\n },\n {\n \"name\": \"thr_ee_Miles_per_Gallon\",\n \"on\": [{\n \"events\": {\"signal\": \"thr_ee_y\"},\n \"update\": \"thr_ee_y[0] === thr_ee_y[1] ? null : invert(\\\"y\\\", thr_ee_y)\"\n }]\n },\n {\n \"name\": \"thr_ee_scale_trigger\",\n \"update\": \"(!isArray(thr_ee_Horsepower) || (+invert(\\\"x\\\", thr_ee_x)[0] === +thr_ee_Horsepower[0] && +invert(\\\"x\\\", thr_ee_x)[1] === +thr_ee_Horsepower[1])) && (!isArray(thr_ee_Miles_per_Gallon) || (+invert(\\\"y\\\", thr_ee_y)[0] === +thr_ee_Miles_per_Gallon[0] && +invert(\\\"y\\\", thr_ee_y)[1] === +thr_ee_Miles_per_Gallon[1])) ? thr_ee_scale_trigger : {}\"\n }\n ]);\n });\n\n it('builds trigger signals', function() {\n const oneSg = interval.signals(model, selCmpts['one']);\n assert.includeDeepMembers(oneSg, [\n {\n \"name\": \"one_tuple\",\n \"on\": [{\n \"events\": [{\"signal\": \"one_Horsepower\"}],\n \"update\": \"one_Horsepower ? {unit: \\\"\\\", intervals: [{encoding: \\\"x\\\", field: \\\"Horsepower\\\", extent: one_Horsepower}]} : null\"\n }]\n }\n ]);\n\n const twoSg = interval.signals(model, selCmpts['two']);\n assert.includeDeepMembers(twoSg, [\n {\n \"name\": \"two_tuple\",\n \"on\": [{\n \"events\": [{\"signal\": \"two_Miles_per_Gallon\"}],\n \"update\": \"two_Miles_per_Gallon ? {unit: \\\"\\\", intervals: [{encoding: \\\"y\\\", field: \\\"Miles-per-Gallon\\\", extent: two_Miles_per_Gallon}]} : null\"\n }]\n }\n ]);\n\n const threeSg = interval.signals(model, selCmpts['thr_ee']);\n assert.includeDeepMembers(threeSg, [\n {\n \"name\": \"thr_ee_tuple\",\n \"on\": [{\n \"events\": [{\"signal\": \"thr_ee_Horsepower\"}, {\"signal\": \"thr_ee_Miles_per_Gallon\"}],\n \"update\": \"thr_ee_Horsepower && thr_ee_Miles_per_Gallon ? {unit: \\\"\\\", intervals: [{encoding: \\\"x\\\", field: \\\"Horsepower\\\", extent: thr_ee_Horsepower}, {encoding: \\\"y\\\", field: \\\"Miles-per-Gallon\\\", extent: thr_ee_Miles_per_Gallon}]} : null\"\n }]\n }\n ]);\n });\n\n it('namespaces signals when encoding/fields collide', function() {\n const model2 = parseUnitModel({\n \"mark\": \"circle\",\n \"encoding\": {\n \"x\": {\"field\": \"x\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"y\", \"type\": \"quantitative\"}\n }\n });\n\n const selCmpts2 = model2.component.selection = selection.parseUnitSelection(model2, {\n \"one\": {\n \"type\": \"interval\",\n \"encodings\": [\"x\"],\n \"translate\": false, \"zoom\": false\n }\n });\n\n const sg = interval.signals(model, selCmpts2['one']);\n assert.equal(sg[0].name, 'one_x');\n assert.equal(sg[1].name, 'one_x_1');\n });\n });\n\n it('builds modify signals', function() {\n const oneExpr = interval.modifyExpr(model, selCmpts['one']);\n assert.equal(oneExpr, 'one_tuple, true');\n\n const twoExpr = interval.modifyExpr(model, selCmpts['two']);\n assert.equal(twoExpr, 'two_tuple, true');\n\n const threeExpr = interval.modifyExpr(model, selCmpts['thr_ee']);\n assert.equal(threeExpr, 'thr_ee_tuple, {unit: \\\"\\\"}');\n\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, [\n {\n \"name\": \"one_modify\",\n \"on\": [\n {\n \"events\": {\"signal\": \"one_tuple\"},\n \"update\": `modify(\\\"one_store\\\", ${oneExpr})`\n }\n ]\n },\n {\n \"name\": \"two_modify\",\n \"on\": [\n {\n \"events\": {\"signal\": \"two_tuple\"},\n \"update\": `modify(\\\"two_store\\\", ${twoExpr})`\n }\n ]\n },\n {\n \"name\": \"thr_ee_modify\",\n \"on\": [\n {\n \"events\": {\"signal\": \"thr_ee_tuple\"},\n \"update\": `modify(\\\"thr_ee_store\\\", ${threeExpr})`\n }\n ]\n }\n ]);\n });\n\n it('builds brush mark', function() {\n const marks: any[] = [{hello: \"world\"}];\n assert.sameDeepMembers(interval.marks(model, selCmpts['one'], marks), [\n {\n \"name\": \"one_brush_bg\",\n \"type\": \"rect\",\n \"clip\": true,\n \"encode\": {\n \"enter\": {\n \"fill\": {\"value\": \"#333\"},\n \"fillOpacity\": {\"value\": 0.125}\n },\n \"update\": {\n \"x\": [\n {\n \"test\": \"data(\\\"one_store\\\").length && data(\\\"one_store\\\")[0].unit === \\\"\\\"\",\n \"signal\": \"one_x[0]\"\n },\n {\n \"value\": 0\n }\n ],\n \"y\": [\n {\n \"test\": \"data(\\\"one_store\\\").length && data(\\\"one_store\\\")[0].unit === \\\"\\\"\",\n \"value\": 0\n },\n {\n \"value\": 0\n }\n ],\n \"x2\": [\n {\n \"test\": \"data(\\\"one_store\\\").length && data(\\\"one_store\\\")[0].unit === \\\"\\\"\",\n \"signal\": \"one_x[1]\"\n },\n {\n \"value\": 0\n }\n ],\n \"y2\": [\n {\n \"test\": \"data(\\\"one_store\\\").length && data(\\\"one_store\\\")[0].unit === \\\"\\\"\",\n \"field\": {\n \"group\": \"height\"\n }\n },\n {\n \"value\": 0\n }\n ]\n }\n }\n },\n {\"hello\": \"world\"},\n {\n \"name\": \"one_brush\",\n \"type\": \"rect\",\n \"clip\": true,\n \"encode\": {\n \"enter\": {\n \"fill\": {\"value\": \"transparent\"}\n },\n \"update\": {\n \"stroke\": [\n {\n \"test\": \"one_x[0] !== one_x[1]\",\n \"value\": \"white\"\n },\n {\n \"value\": null\n }\n ],\n \"x\": [\n {\n \"test\": \"data(\\\"one_store\\\").length && data(\\\"one_store\\\")[0].unit === \\\"\\\"\",\n \"signal\": \"one_x[0]\"\n },\n {\n \"value\": 0\n }\n ],\n \"y\": [\n {\n \"test\": \"data(\\\"one_store\\\").length && data(\\\"one_store\\\")[0].unit === \\\"\\\"\",\n \"value\": 0\n },\n {\n \"value\": 0\n }\n ],\n \"x2\": [\n {\n \"test\": \"data(\\\"one_store\\\").length && data(\\\"one_store\\\")[0].unit === \\\"\\\"\",\n \"signal\": \"one_x[1]\"\n },\n {\n \"value\": 0\n }\n ],\n \"y2\": [\n {\n \"test\": \"data(\\\"one_store\\\").length && data(\\\"one_store\\\")[0].unit === \\\"\\\"\",\n \"field\": {\n \"group\": \"height\"\n }\n },\n {\n \"value\": 0\n }\n ]\n }\n }\n }\n ]);\n\n // Scale-bound interval selections should not add a brush mark.\n assert.sameDeepMembers(interval.marks(model, selCmpts['two'], marks), marks);\n\n assert.sameDeepMembers(interval.marks(model, selCmpts['thr_ee'], marks), [\n {\n \"name\": \"thr_ee_brush_bg\",\n \"type\": \"rect\",\n \"clip\": true,\n \"encode\": {\n \"enter\": {\n \"fill\": {\"value\": \"red\"},\n \"fillOpacity\": {\"value\": 0.75}\n },\n \"update\": {\n \"x\": {\n \"signal\": \"thr_ee_x[0]\"\n },\n \"y\": {\n \"signal\": \"thr_ee_y[0]\"\n },\n \"x2\": {\n \"signal\": \"thr_ee_x[1]\"\n },\n \"y2\": {\n \"signal\": \"thr_ee_y[1]\"\n }\n }\n }\n },\n {\"hello\": \"world\"},\n {\n \"name\": \"thr_ee_brush\",\n \"type\": \"rect\",\n \"clip\": true,\n \"encode\": {\n \"enter\": {\n \"fill\": {\"value\": \"transparent\"}\n },\n \"update\": {\n \"stroke\": [\n {\n \"test\": \"thr_ee_x[0] !== thr_ee_x[1] && thr_ee_y[0] !== thr_ee_y[1]\",\n \"value\": \"black\"\n },\n {\"value\": null}\n ],\n \"strokeWidth\": [\n {\n \"test\": \"thr_ee_x[0] !== thr_ee_x[1] && thr_ee_y[0] !== thr_ee_y[1]\",\n \"value\": 4\n },\n {\"value\": null}\n ],\n \"strokeDash\": [\n {\n \"test\": \"thr_ee_x[0] !== thr_ee_x[1] && thr_ee_y[0] !== thr_ee_y[1]\",\n \"value\": [10, 5]\n },\n {\"value\": null}\n ],\n \"strokeDashOffset\": [\n {\n \"test\": \"thr_ee_x[0] !== thr_ee_x[1] && thr_ee_y[0] !== thr_ee_y[1]\",\n \"value\": 3\n },\n {\"value\": null}\n ],\n \"strokeOpacity\": [\n {\n \"test\": \"thr_ee_x[0] !== thr_ee_x[1] && thr_ee_y[0] !== thr_ee_y[1]\",\n \"value\": 0.25\n },\n {\"value\": null}\n ],\n \"x\": {\n \"signal\": \"thr_ee_x[0]\"\n },\n \"y\": {\n \"signal\": \"thr_ee_y[0]\"\n },\n \"x2\": {\n \"signal\": \"thr_ee_x[1]\"\n },\n \"y2\": {\n \"signal\": \"thr_ee_y[1]\"\n }\n }\n }\n }\n ]);\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/layers.test.d.ts b/build/test/compile/selection/layers.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/layers.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/layers.test.js b/build/test/compile/selection/layers.test.js new file mode 100644 index 0000000000..412df270a5 --- /dev/null +++ b/build/test/compile/selection/layers.test.js @@ -0,0 +1,218 @@ +/* tslint:disable quotemark */ +import * as tslib_1 from "tslib"; +import { assert } from 'chai'; +import * as selection from '../../../src/compile/selection/selection'; +import { parseLayerModel } from '../../util'; +describe('Layered Selections', function () { + var layers = parseLayerModel({ + layer: [{ + "selection": { + "brush": { "type": "interval" } + }, + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" } + } + }, { + "selection": { + "grid": { "type": "interval", "bind": "scales" } + }, + "mark": "square", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" } + } + }] + }); + layers.parse(); + it('should appropriately name the unit', function () { + var unit = layers.children[0]; + assert.equal(selection.unitName(unit), '"layer_0"'); + }); + // Selections should augment layered marks together, rather than each + // mark individually. This ensures correct interleaving of brush marks + // (i.e., that the brush mark appears above all layers and thus can be + // moved around). + it('should pass through unit mark assembly', function () { + assert.sameDeepMembers(layers.children[0].assembleMarks(), [{ + "name": "layer_0_marks", + "type": "symbol", + "style": ["circle"], + "from": { + "data": "layer_0_main" + }, + "clip": true, + "encode": { + "update": { + "x": { + "scale": "x", + "field": "Horsepower" + }, + "y": { + "scale": "y", + "field": "Miles_per_Gallon" + }, + "fill": { + "scale": "color", + "field": "Origin" + }, + "shape": { + "value": "circle" + }, + "opacity": { + "value": 0.7 + } + } + } + }]); + assert.sameDeepMembers(layers.children[1].assembleMarks(), [{ + "name": "layer_1_marks", + "type": "symbol", + "style": ["square"], + "from": { + "data": "layer_1_main" + }, + "clip": true, + "encode": { + "update": { + "x": { + "scale": "x", + "field": "Horsepower" + }, + "y": { + "scale": "y", + "field": "Miles_per_Gallon" + }, + "fill": { + "scale": "color", + "field": "Origin" + }, + "shape": { + "value": "square" + }, + "opacity": { + "value": 0.7 + } + } + } + }]); + }); + it('should assemble selection marks across layers', function () { + var child0 = layers.children[0].assembleMarks()[0]; + var child1 = layers.children[1].assembleMarks()[0]; + assert.sameDeepMembers(layers.assembleMarks(), [ + // Background brush mark for "brush" selection. + { + "name": "brush_brush_bg", + "type": "rect", + "clip": true, + "encode": { + "enter": { + "fill": { "value": "#333" }, + "fillOpacity": { "value": 0.125 } + }, + "update": { + "x": [ + { + "test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"layer_0\"", + "signal": "brush_x[0]" + }, + { + "value": 0 + } + ], + "y": [ + { + "test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"layer_0\"", + "signal": "brush_y[0]" + }, + { + "value": 0 + } + ], + "x2": [ + { + "test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"layer_0\"", + "signal": "brush_x[1]" + }, + { + "value": 0 + } + ], + "y2": [ + { + "test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"layer_0\"", + "signal": "brush_y[1]" + }, + { + "value": 0 + } + ] + } + } + }, + tslib_1.__assign({}, child0, { clip: true }), + tslib_1.__assign({}, child1, { clip: true }), + // Foreground brush mark for "brush" selection. + { + "name": "brush_brush", + "type": "rect", + "clip": true, + "encode": { + "enter": { + "fill": { "value": "transparent" } + }, + "update": { + "stroke": [ + { + "test": "brush_x[0] !== brush_x[1] && brush_y[0] !== brush_y[1]", + "value": "white" + }, + { "value": null } + ], + "x": [ + { + "test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"layer_0\"", + "signal": "brush_x[0]" + }, + { + "value": 0 + } + ], + "y": [ + { + "test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"layer_0\"", + "signal": "brush_y[0]" + }, + { + "value": 0 + } + ], + "x2": [ + { + "test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"layer_0\"", + "signal": "brush_x[1]" + }, + { + "value": 0 + } + ], + "y2": [ + { + "test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"layer_0\"", + "signal": "brush_y[1]" + }, + { + "value": 0 + } + ] + } + } + } + ]); + }); +}); +//# sourceMappingURL=layers.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/layers.test.js.map b/build/test/compile/selection/layers.test.js.map new file mode 100644 index 0000000000..2531f63276 --- /dev/null +++ b/build/test/compile/selection/layers.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"layers.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/layers.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport * as selection from '../../../src/compile/selection/selection';\nimport {UnitModel} from '../../../src/compile/unit';\nimport {parseLayerModel} from '../../util';\n\ndescribe('Layered Selections', function() {\n const layers = parseLayerModel({\n layer: [{\n \"selection\": {\n \"brush\": {\"type\": \"interval\"}\n },\n \"mark\": \"circle\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\"},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n }, {\n \"selection\": {\n \"grid\": {\"type\": \"interval\", \"bind\": \"scales\"}\n },\n \"mark\": \"square\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\"},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n }]\n });\n\n layers.parse();\n\n it('should appropriately name the unit', function() {\n const unit = layers.children[0] as UnitModel;\n assert.equal(selection.unitName(unit), '\"layer_0\"');\n });\n\n // Selections should augment layered marks together, rather than each\n // mark individually. This ensures correct interleaving of brush marks\n // (i.e., that the brush mark appears above all layers and thus can be\n // moved around).\n it('should pass through unit mark assembly', function() {\n assert.sameDeepMembers(layers.children[0].assembleMarks(), [{\n \"name\": \"layer_0_marks\",\n \"type\": \"symbol\",\n \"style\": [\"circle\"],\n \"from\": {\n \"data\": \"layer_0_main\"\n },\n \"clip\": true,\n \"encode\": {\n \"update\": {\n \"x\": {\n \"scale\": \"x\",\n \"field\": \"Horsepower\"\n },\n \"y\": {\n \"scale\": \"y\",\n \"field\": \"Miles_per_Gallon\"\n },\n \"fill\": {\n \"scale\": \"color\",\n \"field\": \"Origin\"\n },\n \"shape\": {\n \"value\": \"circle\"\n },\n \"opacity\": {\n \"value\": 0.7\n }\n }\n }\n }]);\n\n assert.sameDeepMembers(layers.children[1].assembleMarks(), [{\n \"name\": \"layer_1_marks\",\n \"type\": \"symbol\",\n \"style\": [\"square\"],\n \"from\": {\n \"data\": \"layer_1_main\"\n },\n \"clip\": true,\n \"encode\": {\n \"update\": {\n \"x\": {\n \"scale\": \"x\",\n \"field\": \"Horsepower\"\n },\n \"y\": {\n \"scale\": \"y\",\n \"field\": \"Miles_per_Gallon\"\n },\n \"fill\": {\n \"scale\": \"color\",\n \"field\": \"Origin\"\n },\n \"shape\": {\n \"value\": \"square\"\n },\n \"opacity\": {\n \"value\": 0.7\n }\n }\n }\n }]);\n });\n\n it('should assemble selection marks across layers', function() {\n const child0 = layers.children[0].assembleMarks()[0];\n const child1 = layers.children[1].assembleMarks()[0];\n\n assert.sameDeepMembers(layers.assembleMarks(), [\n // Background brush mark for \"brush\" selection.\n {\n \"name\": \"brush_brush_bg\",\n \"type\": \"rect\",\n \"clip\": true,\n \"encode\": {\n \"enter\": {\n \"fill\": {\"value\": \"#333\"},\n \"fillOpacity\": {\"value\": 0.125}\n },\n \"update\": {\n \"x\": [\n {\n \"test\": \"data(\\\"brush_store\\\").length && data(\\\"brush_store\\\")[0].unit === \\\"layer_0\\\"\",\n \"signal\": \"brush_x[0]\"\n },\n {\n \"value\": 0\n }\n ],\n \"y\": [\n {\n \"test\": \"data(\\\"brush_store\\\").length && data(\\\"brush_store\\\")[0].unit === \\\"layer_0\\\"\",\n \"signal\": \"brush_y[0]\"\n },\n {\n \"value\": 0\n }\n ],\n \"x2\": [\n {\n \"test\": \"data(\\\"brush_store\\\").length && data(\\\"brush_store\\\")[0].unit === \\\"layer_0\\\"\",\n \"signal\": \"brush_x[1]\"\n },\n {\n \"value\": 0\n }\n ],\n \"y2\": [\n {\n \"test\": \"data(\\\"brush_store\\\").length && data(\\\"brush_store\\\")[0].unit === \\\"layer_0\\\"\",\n \"signal\": \"brush_y[1]\"\n },\n {\n \"value\": 0\n }\n ]\n }\n }\n },\n // Layer marks\n {...child0, clip: true}, {...child1, clip: true},\n // Foreground brush mark for \"brush\" selection.\n {\n \"name\": \"brush_brush\",\n \"type\": \"rect\",\n \"clip\": true,\n \"encode\": {\n \"enter\": {\n \"fill\": {\"value\": \"transparent\"}\n },\n \"update\": {\n \"stroke\": [\n {\n \"test\": \"brush_x[0] !== brush_x[1] && brush_y[0] !== brush_y[1]\",\n \"value\": \"white\"\n },\n {\"value\": null}\n ],\n \"x\": [\n {\n \"test\": \"data(\\\"brush_store\\\").length && data(\\\"brush_store\\\")[0].unit === \\\"layer_0\\\"\",\n \"signal\": \"brush_x[0]\"\n },\n {\n \"value\": 0\n }\n ],\n \"y\": [\n {\n \"test\": \"data(\\\"brush_store\\\").length && data(\\\"brush_store\\\")[0].unit === \\\"layer_0\\\"\",\n \"signal\": \"brush_y[0]\"\n },\n {\n \"value\": 0\n }\n ],\n \"x2\": [\n {\n \"test\": \"data(\\\"brush_store\\\").length && data(\\\"brush_store\\\")[0].unit === \\\"layer_0\\\"\",\n \"signal\": \"brush_x[1]\"\n },\n {\n \"value\": 0\n }\n ],\n \"y2\": [\n {\n \"test\": \"data(\\\"brush_store\\\").length && data(\\\"brush_store\\\")[0].unit === \\\"layer_0\\\"\",\n \"signal\": \"brush_y[1]\"\n },\n {\n \"value\": 0\n }\n ]\n }\n }\n }\n ]);\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/multi.test.d.ts b/build/test/compile/selection/multi.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/multi.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/multi.test.js b/build/test/compile/selection/multi.test.js new file mode 100644 index 0000000000..3f39699a68 --- /dev/null +++ b/build/test/compile/selection/multi.test.js @@ -0,0 +1,58 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import multi from '../../../src/compile/selection/multi'; +import * as selection from '../../../src/compile/selection/selection'; +import { parseUnitModelWithScale } from '../../util'; +describe('Multi Selection', function () { + var model = parseUnitModelWithScale({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative", "bin": true }, + "color": { "field": "Origin", "type": "nominal" } + } + }); + var selCmpts = model.component.selection = selection.parseUnitSelection(model, { + "one": { "type": "multi" }, + "two": { + "type": "multi", "nearest": true, + "on": "mouseover", "toggle": "event.ctrlKey", "encodings": ["y", "color"] + } + }); + it('builds tuple signals', function () { + var oneSg = multi.signals(model, selCmpts['one']); + assert.sameDeepMembers(oneSg, [{ + name: 'one_tuple', + value: {}, + on: [{ + events: selCmpts['one'].events, + update: "datum && item().mark.marktype !== 'group' ? {unit: \"\", encodings: [], fields: [\"_vgsid_\"], values: [datum[\"_vgsid_\"]]} : null", + force: true + }] + }]); + var twoSg = multi.signals(model, selCmpts['two']); + assert.sameDeepMembers(twoSg, [{ + name: 'two_tuple', + value: {}, + on: [{ + events: selCmpts['two'].events, + update: "datum && item().mark.marktype !== 'group' ? {unit: \"\", encodings: [\"y\", \"color\"], fields: [\"Miles_per_Gallon\", \"Origin\"], values: [[(item().isVoronoi ? datum.datum : datum)[\"bin_maxbins_10_Miles_per_Gallon\"], (item().isVoronoi ? datum.datum : datum)[\"bin_maxbins_10_Miles_per_Gallon_end\"]], (item().isVoronoi ? datum.datum : datum)[\"Origin\"]], \"bin_Miles_per_Gallon\": 1} : null", + force: true + }] + }]); + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, oneSg.concat(twoSg)); + }); + it('builds unit datasets', function () { + var data = []; + assert.sameDeepMembers(selection.assembleUnitSelectionData(model, data), [ + { name: 'one_store' }, { name: 'two_store' } + ]); + }); + it('leaves marks alone', function () { + var marks = []; + model.component.selection = { one: selCmpts['one'] }; + assert.equal(selection.assembleUnitSelectionMarks(model, marks), marks); + }); +}); +//# sourceMappingURL=multi.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/multi.test.js.map b/build/test/compile/selection/multi.test.js.map new file mode 100644 index 0000000000..ff0f14d2df --- /dev/null +++ b/build/test/compile/selection/multi.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"multi.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/multi.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,MAAM,sCAAsC,CAAC;AACzD,OAAO,KAAK,SAAS,MAAM,0CAA0C,CAAC;AACtE,OAAO,EAAC,uBAAuB,EAAC,MAAM,YAAY,CAAC;AAEnD,QAAQ,CAAC,iBAAiB,EAAE;IAC1B,IAAM,KAAK,GAAG,uBAAuB,CAAC;QACpC,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE;YACV,GAAG,EAAE,EAAC,OAAO,EAAE,YAAY,EAAC,MAAM,EAAE,cAAc,EAAC;YACnD,GAAG,EAAE,EAAC,OAAO,EAAE,kBAAkB,EAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAC;YACtE,OAAO,EAAE,EAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC;SAChD;KACF,CAAC,CAAC;IAEH,IAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE;QAC/E,KAAK,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC;QACxB,KAAK,EAAE;YACL,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI;YAChC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC;SAC1E;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;gBAC7B,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,EAAE;gBACT,EAAE,EAAE,CAAC;wBACH,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM;wBAC9B,MAAM,EAAE,qIAAqI;wBAC7I,KAAK,EAAE,IAAI;qBACZ,CAAC;aACH,CAAC,CAAC,CAAC;QAEJ,IAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;gBAC7B,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,EAAE;gBACT,EAAE,EAAE,CAAC;wBACH,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM;wBAC9B,MAAM,EAAE,6YAA6Y;wBACrZ,KAAK,EAAE,IAAI;qBACZ,CAAC;aACH,CAAC,CAAC,CAAC;QAEJ,IAAM,OAAO,GAAG,SAAS,CAAC,4BAA4B,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAM,IAAI,GAAU,EAAE,CAAC;QACvB,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,yBAAyB,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE;YACvE,EAAC,IAAI,EAAE,WAAW,EAAC,EAAE,EAAC,IAAI,EAAE,WAAW,EAAC;SACzC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oBAAoB,EAAE;QACvB,IAAM,KAAK,GAAU,EAAE,CAAC;QACxB,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,EAAC,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable quotemark */\nimport {assert} from 'chai';\n\nimport multi from '../../../src/compile/selection/multi';\nimport * as selection from '../../../src/compile/selection/selection';\nimport {parseUnitModelWithScale} from '../../util';\n\ndescribe('Multi Selection', function() {\n const model = parseUnitModelWithScale({\n \"mark\": \"circle\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\", \"bin\": true},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n });\n\n const selCmpts = model.component.selection = selection.parseUnitSelection(model, {\n \"one\": {\"type\": \"multi\"},\n \"two\": {\n \"type\": \"multi\", \"nearest\": true,\n \"on\": \"mouseover\", \"toggle\": \"event.ctrlKey\", \"encodings\": [\"y\", \"color\"]\n }\n });\n\n it('builds tuple signals', function() {\n const oneSg = multi.signals(model, selCmpts['one']);\n assert.sameDeepMembers(oneSg, [{\n name: 'one_tuple',\n value: {},\n on: [{\n events: selCmpts['one'].events,\n update: \"datum && item().mark.marktype !== 'group' ? {unit: \\\"\\\", encodings: [], fields: [\\\"_vgsid_\\\"], values: [datum[\\\"_vgsid_\\\"]]} : null\",\n force: true\n }]\n }]);\n\n const twoSg = multi.signals(model, selCmpts['two']);\n assert.sameDeepMembers(twoSg, [{\n name: 'two_tuple',\n value: {},\n on: [{\n events: selCmpts['two'].events,\n update: \"datum && item().mark.marktype !== 'group' ? {unit: \\\"\\\", encodings: [\\\"y\\\", \\\"color\\\"], fields: [\\\"Miles_per_Gallon\\\", \\\"Origin\\\"], values: [[(item().isVoronoi ? datum.datum : datum)[\\\"bin_maxbins_10_Miles_per_Gallon\\\"], (item().isVoronoi ? datum.datum : datum)[\\\"bin_maxbins_10_Miles_per_Gallon_end\\\"]], (item().isVoronoi ? datum.datum : datum)[\\\"Origin\\\"]], \\\"bin_Miles_per_Gallon\\\": 1} : null\",\n force: true\n }]\n }]);\n\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, oneSg.concat(twoSg));\n });\n\n it('builds unit datasets', function() {\n const data: any[] = [];\n assert.sameDeepMembers(selection.assembleUnitSelectionData(model, data), [\n {name: 'one_store'}, {name: 'two_store'}\n ]);\n });\n\n it('leaves marks alone', function() {\n const marks: any[] = [];\n model.component.selection = {one: selCmpts['one']};\n assert.equal(selection.assembleUnitSelectionMarks(model, marks), marks);\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/nearest.test.d.ts b/build/test/compile/selection/nearest.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/nearest.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/nearest.test.js b/build/test/compile/selection/nearest.test.js new file mode 100644 index 0000000000..2163293a56 --- /dev/null +++ b/build/test/compile/selection/nearest.test.js @@ -0,0 +1,97 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import * as selection from '../../../src/compile/selection/selection'; +import nearest from '../../../src/compile/selection/transforms/nearest'; +import * as log from '../../../src/log'; +import { duplicate } from '../../../src/util'; +import { parseUnitModel } from '../../util'; +function getModel(markType) { + var model = parseUnitModel({ + "mark": markType, + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" } + } + }); + model.parseScale(); + model.parseMarkGroup(); + model.component.selection = selection.parseUnitSelection(model, { + "one": { "type": "single", "nearest": true }, + "two": { "type": "multi", "nearest": true }, + "three": { "type": "interval" }, + "four": { "type": "single", "nearest": false }, + "five": { "type": "multi" }, + "six": { "type": "multi", "nearest": null }, + "seven": { "type": "single", "nearest": true, "encodings": ["x"] }, + "eight": { "type": "single", "nearest": true, "encodings": ["y"] }, + "nine": { "type": "single", "nearest": true, "encodings": ["color"] } + }); + return model; +} +function voronoiMark(x, y) { + return [ + { hello: "world" }, + { + "name": "voronoi", + "type": "path", + "from": { "data": "marks" }, + "encode": { + "enter": { + "fill": { "value": "transparent" }, + "strokeWidth": { "value": 0.35 }, + "stroke": { "value": "transparent" }, + "isVoronoi": { "value": true } + } + }, + "transform": [ + { + "type": "voronoi", + "x": x || { "expr": "datum.datum.x || 0" }, + "y": y || { "expr": "datum.datum.y || 0" }, + "size": [{ "signal": "width" }, { "signal": "height" }] + } + ] + } + ]; +} +describe('Nearest Selection Transform', function () { + it('identifies transform invocation', function () { + var selCmpts = getModel('circle').component.selection; + assert.isNotFalse(nearest.has(selCmpts['one'])); + assert.isNotFalse(nearest.has(selCmpts['two'])); + assert.isNotTrue(nearest.has(selCmpts['three'])); + assert.isNotTrue(nearest.has(selCmpts['four'])); + assert.isNotTrue(nearest.has(selCmpts['five'])); + assert.isNotTrue(nearest.has(selCmpts['six'])); + }); + it('adds voronoi for non-path marks', function () { + var model = getModel('circle'); + var selCmpts = model.component.selection; + var marks = [{ hello: "world" }]; + assert.sameDeepMembers(nearest.marks(model, selCmpts['one'], marks), voronoiMark()); + }); + it('should warn for path marks', log.wrap(function (localLogger) { + var model = getModel('line'); + var selCmpts = model.component.selection; + var marks = []; + assert.equal(nearest.marks(model, selCmpts['one'], marks), marks); + assert.equal(localLogger.warns[0], log.message.nearestNotSupportForContinuous('line')); + })); + it('limits to a single voronoi per unit', function () { + var model = getModel('circle'); + var selCmpts = model.component.selection; + var marks = [{ hello: "world" }]; + var marks2 = nearest.marks(model, selCmpts['one'], marks); + assert.sameDeepMembers(nearest.marks(model, selCmpts['two'], marks2), voronoiMark()); + }); + it('supports 1D voronoi', function () { + var model = getModel('circle'); + var selCmpts = model.component.selection; + var marks = [{ hello: "world" }]; + assert.sameDeepMembers(nearest.marks(model, selCmpts['seven'], duplicate(marks)), voronoiMark(null, { "expr": "0" })); + assert.sameDeepMembers(nearest.marks(model, selCmpts['eight'], duplicate(marks)), voronoiMark({ "expr": "0" })); + assert.sameDeepMembers(nearest.marks(model, selCmpts['nine'], duplicate(marks)), voronoiMark()); + }); +}); +//# sourceMappingURL=nearest.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/nearest.test.js.map b/build/test/compile/selection/nearest.test.js.map new file mode 100644 index 0000000000..5dabe04aa9 --- /dev/null +++ b/build/test/compile/selection/nearest.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"nearest.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/nearest.test.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,SAAS,MAAM,0CAA0C,CAAC;AACtE,OAAO,OAAO,MAAM,mDAAmD,CAAC;AACxE,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAE1C,kBAAkB,QAAa;IAC7B,IAAM,KAAK,GAAG,cAAc,CAAC;QAC3B,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE;YACV,GAAG,EAAE,EAAC,OAAO,EAAE,YAAY,EAAC,MAAM,EAAE,cAAc,EAAC;YACnD,GAAG,EAAE,EAAC,OAAO,EAAE,kBAAkB,EAAC,MAAM,EAAE,cAAc,EAAC;YACzD,OAAO,EAAE,EAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC;SAChD;KACF,CAAC,CAAC;IACH,KAAK,CAAC,UAAU,EAAE,CAAC;IACnB,KAAK,CAAC,cAAc,EAAE,CAAC;IACvB,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE;QAC9D,KAAK,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAC;QAC1C,KAAK,EAAE,EAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAC;QACzC,OAAO,EAAE,EAAC,MAAM,EAAE,UAAU,EAAC;QAC7B,MAAM,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAC;QAC5C,MAAM,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC;QACzB,KAAK,EAAE,EAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAC;QACzC,OAAO,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,EAAC;QAChE,OAAO,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,EAAC;QAChE,MAAM,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,OAAO,CAAC,EAAC;KACpE,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,qBAAqB,CAA2B,EAAE,CAA2B;IAC3E,OAAO;QACL,EAAC,KAAK,EAAE,OAAO,EAAC;QAChB;YACE,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC;YACzB,QAAQ,EAAE;gBACR,OAAO,EAAE;oBACP,MAAM,EAAE,EAAC,OAAO,EAAE,aAAa,EAAC;oBAChC,aAAa,EAAE,EAAC,OAAO,EAAE,IAAI,EAAC;oBAC9B,QAAQ,EAAE,EAAC,OAAO,EAAE,aAAa,EAAC;oBAClC,WAAW,EAAE,EAAC,OAAO,EAAE,IAAI,EAAC;iBAC7B;aACF;YACD,WAAW,EAAE;gBACX;oBACE,MAAM,EAAE,SAAS;oBACjB,GAAG,EAAE,CAAC,IAAI,EAAC,MAAM,EAAE,oBAAoB,EAAC;oBACxC,GAAG,EAAE,CAAC,IAAI,EAAC,MAAM,EAAE,oBAAoB,EAAC;oBACxC,MAAM,EAAE,CAAC,EAAC,QAAQ,EAAE,OAAO,EAAC,EAAC,EAAC,QAAQ,EAAE,QAAQ,EAAC,CAAC;iBACnD;aACF;SACF;KACF,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,6BAA6B,EAAE;IACtC,EAAE,CAAC,iCAAiC,EAAE;QACpC,IAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC;QACxD,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE;QACpC,IAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC;QAC3C,IAAM,KAAK,GAAU,CAAC,EAAC,KAAK,EAAE,OAAO,EAAC,CAAC,CAAC;QAExC,MAAM,CAAC,eAAe,CACpB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,CAAC,IAAI,CAAC,UAAC,WAAW;QACpD,IAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC;QAC3C,IAAM,KAAK,GAAU,EAAE,CAAC;QACxB,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QAClE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC,CAAC;IAEJ,EAAE,CAAC,qCAAqC,EAAE;QACxC,IAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC;QAC3C,IAAM,KAAK,GAAU,CAAC,EAAC,KAAK,EAAE,OAAO,EAAC,CAAC,CAAC;QAExC,IAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QAC5D,MAAM,CAAC,eAAe,CACpB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE;QACxB,IAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC;QAC3C,IAAM,KAAK,GAAU,CAAC,EAAC,KAAK,EAAE,OAAO,EAAC,CAAC,CAAC;QAExC,MAAM,CAAC,eAAe,CACpB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,EACzD,WAAW,CAAC,IAAI,EAAE,EAAC,MAAM,EAAE,GAAG,EAAC,CAAC,CAAC,CAAC;QAEpC,MAAM,CAAC,eAAe,CACpB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,EACzD,WAAW,CAAC,EAAC,MAAM,EAAE,GAAG,EAAC,CAAC,CAAC,CAAC;QAE9B,MAAM,CAAC,eAAe,CACpB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,EACxD,WAAW,EAAE,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport * as selection from '../../../src/compile/selection/selection';\nimport nearest from '../../../src/compile/selection/transforms/nearest';\nimport * as log from '../../../src/log';\nimport {duplicate} from '../../../src/util';\nimport {parseUnitModel} from '../../util';\n\nfunction getModel(markType: any) {\n const model = parseUnitModel({\n \"mark\": markType,\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\"},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n });\n model.parseScale();\n model.parseMarkGroup();\n model.component.selection = selection.parseUnitSelection(model, {\n \"one\": {\"type\": \"single\", \"nearest\": true},\n \"two\": {\"type\": \"multi\", \"nearest\": true},\n \"three\": {\"type\": \"interval\"},\n \"four\": {\"type\": \"single\", \"nearest\": false},\n \"five\": {\"type\": \"multi\"},\n \"six\": {\"type\": \"multi\", \"nearest\": null},\n \"seven\": {\"type\": \"single\", \"nearest\": true, \"encodings\": [\"x\"]},\n \"eight\": {\"type\": \"single\", \"nearest\": true, \"encodings\": [\"y\"]},\n \"nine\": {\"type\": \"single\", \"nearest\": true, \"encodings\": [\"color\"]}\n });\n\n return model;\n}\n\nfunction voronoiMark(x?: string | {expr: string}, y?: string | {expr: string}) {\n return [\n {hello: \"world\"},\n {\n \"name\": \"voronoi\",\n \"type\": \"path\",\n \"from\": {\"data\": \"marks\"},\n \"encode\": {\n \"enter\": {\n \"fill\": {\"value\": \"transparent\"},\n \"strokeWidth\": {\"value\": 0.35},\n \"stroke\": {\"value\": \"transparent\"},\n \"isVoronoi\": {\"value\": true}\n }\n },\n \"transform\": [\n {\n \"type\": \"voronoi\",\n \"x\": x || {\"expr\": \"datum.datum.x || 0\"},\n \"y\": y || {\"expr\": \"datum.datum.y || 0\"},\n \"size\": [{\"signal\": \"width\"},{\"signal\": \"height\"}]\n }\n ]\n }\n ];\n}\n\ndescribe('Nearest Selection Transform', function() {\n it('identifies transform invocation', function() {\n const selCmpts = getModel('circle').component.selection;\n assert.isNotFalse(nearest.has(selCmpts['one']));\n assert.isNotFalse(nearest.has(selCmpts['two']));\n assert.isNotTrue(nearest.has(selCmpts['three']));\n assert.isNotTrue(nearest.has(selCmpts['four']));\n assert.isNotTrue(nearest.has(selCmpts['five']));\n assert.isNotTrue(nearest.has(selCmpts['six']));\n });\n\n it('adds voronoi for non-path marks', function() {\n const model = getModel('circle');\n const selCmpts = model.component.selection;\n const marks: any[] = [{hello: \"world\"}];\n\n assert.sameDeepMembers(\n nearest.marks(model, selCmpts['one'], marks), voronoiMark());\n });\n\n it('should warn for path marks', log.wrap((localLogger) => {\n const model = getModel('line');\n const selCmpts = model.component.selection;\n const marks: any[] = [];\n assert.equal(nearest.marks(model, selCmpts['one'], marks), marks);\n assert.equal(localLogger.warns[0], log.message.nearestNotSupportForContinuous('line'));\n }));\n\n it('limits to a single voronoi per unit', function() {\n const model = getModel('circle');\n const selCmpts = model.component.selection;\n const marks: any[] = [{hello: \"world\"}];\n\n const marks2 = nearest.marks(model, selCmpts['one'], marks);\n assert.sameDeepMembers(\n nearest.marks(model, selCmpts['two'], marks2), voronoiMark());\n });\n\n it('supports 1D voronoi', function() {\n const model = getModel('circle');\n const selCmpts = model.component.selection;\n const marks: any[] = [{hello: \"world\"}];\n\n assert.sameDeepMembers(\n nearest.marks(model, selCmpts['seven'], duplicate(marks)),\n voronoiMark(null, {\"expr\": \"0\"}));\n\n assert.sameDeepMembers(\n nearest.marks(model, selCmpts['eight'], duplicate(marks)),\n voronoiMark({\"expr\": \"0\"}));\n\n assert.sameDeepMembers(\n nearest.marks(model, selCmpts['nine'], duplicate(marks)),\n voronoiMark());\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/parse.test.d.ts b/build/test/compile/selection/parse.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/parse.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/parse.test.js b/build/test/compile/selection/parse.test.js new file mode 100644 index 0000000000..b40f1a17c2 --- /dev/null +++ b/build/test/compile/selection/parse.test.js @@ -0,0 +1,105 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { selector as parseSelector } from 'vega-event-selector'; +import * as selection from '../../../src/compile/selection/selection'; +import { keys } from '../../../src/util'; +import { parseUnitModel } from '../../util'; +describe('Selection', function () { + var model = parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" } + } + }); + it('parses default selection definitions', function () { + var component = selection.parseUnitSelection(model, { + "one": { "type": "single" }, + "two": { "type": "multi" }, + "three": { "type": "interval" } + }); + assert.sameMembers(keys(component), ['one', 'two', 'three']); + assert.equal(component.one.name, 'one'); + assert.equal(component.one.type, 'single'); + assert.sameDeepMembers(component['one'].project, [{ field: '_vgsid_', channel: null }]); + assert.sameDeepMembers(component['one'].events, parseSelector('click', 'scope')); + assert.equal(component.two.name, 'two'); + assert.equal(component.two.type, 'multi'); + assert.equal(component.two.toggle, 'event.shiftKey'); + assert.sameDeepMembers(component['two'].project, [{ field: '_vgsid_', channel: null }]); + assert.sameDeepMembers(component['two'].events, parseSelector('click', 'scope')); + assert.equal(component.three.name, 'three'); + assert.equal(component.three.type, 'interval'); + assert.equal(component.three.translate, '[mousedown, window:mouseup] > window:mousemove!'); + assert.equal(component.three.zoom, 'wheel!'); + assert.sameDeepMembers(component['three'].project, [{ field: 'Horsepower', channel: 'x' }, { field: 'Miles_per_Gallon', channel: 'y' }]); + assert.sameDeepMembers(component['three'].events, parseSelector('[mousedown, window:mouseup] > window:mousemove!', 'scope')); + }); + it('supports inline default overrides', function () { + var component = selection.parseUnitSelection(model, { + "one": { + "type": "single", + "on": "dblclick", "fields": ["Cylinders"] + }, + "two": { + "type": "multi", + "on": "mouseover", "toggle": "event.ctrlKey", "encodings": ["color"] + }, + "three": { + "type": "interval", + "on": "[mousedown[!event.shiftKey], mouseup] > mousemove", + "encodings": ["y"], "translate": false, "zoom": "wheel[event.altKey]" + } + }); + assert.sameMembers(keys(component), ['one', 'two', 'three']); + assert.equal(component.one.name, 'one'); + assert.equal(component.one.type, 'single'); + assert.sameDeepMembers(component['one'].project, [{ field: 'Cylinders', channel: null }]); + assert.sameDeepMembers(component['one'].events, parseSelector('dblclick', 'scope')); + assert.equal(component.two.name, 'two'); + assert.equal(component.two.type, 'multi'); + assert.equal(component.two.toggle, 'event.ctrlKey'); + assert.sameDeepMembers(component['two'].project, [{ field: 'Origin', channel: 'color' }]); + assert.sameDeepMembers(component['two'].events, parseSelector('mouseover', 'scope')); + assert.equal(component.three.name, 'three'); + assert.equal(component.three.type, 'interval'); + assert.equal(component.three.translate, false); + assert.equal(component.three.zoom, 'wheel[event.altKey]'); + assert.sameDeepMembers(component['three'].project, [{ field: 'Miles_per_Gallon', channel: 'y' }]); + assert.sameDeepMembers(component['three'].events, parseSelector('[mousedown[!event.shiftKey], mouseup] > mousemove', 'scope')); + }); + it('respects selection configs', function () { + model.config.selection = { + single: { on: 'dblclick', fields: ['Cylinders'] }, + multi: { on: 'mouseover', encodings: ['color'], toggle: 'event.ctrlKey' }, + interval: { + on: '[mousedown[!event.shiftKey], mouseup] > mousemove', + encodings: ['y'], + zoom: 'wheel[event.altKey]' + } + }; + var component = selection.parseUnitSelection(model, { + "one": { "type": "single" }, + "two": { "type": "multi" }, + "three": { "type": "interval" } + }); + assert.sameMembers(keys(component), ['one', 'two', 'three']); + assert.equal(component.one.name, 'one'); + assert.equal(component.one.type, 'single'); + assert.sameDeepMembers(component['one'].project, [{ field: 'Cylinders', channel: null }]); + assert.sameDeepMembers(component['one'].events, parseSelector('dblclick', 'scope')); + assert.equal(component.two.name, 'two'); + assert.equal(component.two.type, 'multi'); + assert.equal(component.two.toggle, 'event.ctrlKey'); + assert.sameDeepMembers(component['two'].project, [{ field: 'Origin', channel: 'color' }]); + assert.sameDeepMembers(component['two'].events, parseSelector('mouseover', 'scope')); + assert.equal(component.three.name, 'three'); + assert.equal(component.three.type, 'interval'); + assert(!component.three.translate); + assert.equal(component.three.zoom, 'wheel[event.altKey]'); + assert.sameDeepMembers(component['three'].project, [{ field: 'Miles_per_Gallon', channel: 'y' }]); + assert.sameDeepMembers(component['three'].events, parseSelector('[mousedown[!event.shiftKey], mouseup] > mousemove', 'scope')); + }); +}); +//# sourceMappingURL=parse.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/parse.test.js.map b/build/test/compile/selection/parse.test.js.map new file mode 100644 index 0000000000..9fef881af8 --- /dev/null +++ b/build/test/compile/selection/parse.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parse.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/parse.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport {selector as parseSelector} from 'vega-event-selector';\nimport * as selection from '../../../src/compile/selection/selection';\nimport {keys} from '../../../src/util';\nimport {parseUnitModel} from '../../util';\n\ndescribe('Selection', function() {\n const model = parseUnitModel({\n \"mark\": \"circle\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\"},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n });\n\n it('parses default selection definitions', function() {\n const component = selection.parseUnitSelection(model, {\n \"one\": {\"type\": \"single\"},\n \"two\": {\"type\": \"multi\"},\n \"three\": {\"type\": \"interval\"}\n });\n\n assert.sameMembers(keys(component), ['one', 'two', 'three']);\n\n assert.equal(component.one.name, 'one');\n assert.equal(component.one.type, 'single');\n assert.sameDeepMembers(component['one'].project, [{field: '_vgsid_', channel: null}]);\n assert.sameDeepMembers(component['one'].events, parseSelector('click', 'scope'));\n\n assert.equal(component.two.name, 'two');\n assert.equal(component.two.type, 'multi');\n assert.equal(component.two.toggle, 'event.shiftKey');\n assert.sameDeepMembers(component['two'].project, [{field: '_vgsid_', channel: null}]);\n assert.sameDeepMembers(component['two'].events, parseSelector('click', 'scope'));\n\n assert.equal(component.three.name, 'three');\n assert.equal(component.three.type, 'interval');\n assert.equal(component.three.translate, '[mousedown, window:mouseup] > window:mousemove!');\n assert.equal(component.three.zoom, 'wheel!');\n assert.sameDeepMembers(component['three'].project, [{field: 'Horsepower', channel: 'x'}, {field: 'Miles_per_Gallon', channel: 'y'}]);\n assert.sameDeepMembers(component['three'].events, parseSelector('[mousedown, window:mouseup] > window:mousemove!', 'scope'));\n });\n\n it('supports inline default overrides', function() {\n const component = selection.parseUnitSelection(model, {\n \"one\": {\n \"type\": \"single\",\n \"on\": \"dblclick\", \"fields\": [\"Cylinders\"]\n },\n \"two\": {\n \"type\": \"multi\",\n \"on\": \"mouseover\", \"toggle\": \"event.ctrlKey\", \"encodings\": [\"color\"]\n },\n \"three\": {\n \"type\": \"interval\",\n \"on\": \"[mousedown[!event.shiftKey], mouseup] > mousemove\",\n \"encodings\": [\"y\"], \"translate\": false, \"zoom\": \"wheel[event.altKey]\"\n }\n });\n\n assert.sameMembers(keys(component), ['one', 'two', 'three']);\n\n assert.equal(component.one.name, 'one');\n assert.equal(component.one.type, 'single');\n assert.sameDeepMembers(component['one'].project, [{field: 'Cylinders', channel: null}]);\n assert.sameDeepMembers(component['one'].events, parseSelector('dblclick', 'scope'));\n\n assert.equal(component.two.name, 'two');\n assert.equal(component.two.type, 'multi');\n assert.equal(component.two.toggle, 'event.ctrlKey');\n assert.sameDeepMembers(component['two'].project, [{field: 'Origin', channel: 'color'}]);\n assert.sameDeepMembers(component['two'].events, parseSelector('mouseover', 'scope'));\n\n assert.equal(component.three.name, 'three');\n assert.equal(component.three.type, 'interval');\n assert.equal(component.three.translate, false);\n assert.equal(component.three.zoom, 'wheel[event.altKey]');\n assert.sameDeepMembers(component['three'].project, [{field: 'Miles_per_Gallon', channel: 'y'}]);\n assert.sameDeepMembers(component['three'].events, parseSelector('[mousedown[!event.shiftKey], mouseup] > mousemove', 'scope'));\n });\n\n it('respects selection configs', function() {\n model.config.selection = {\n single: {on: 'dblclick', fields: ['Cylinders']},\n multi: {on: 'mouseover', encodings: ['color'], toggle: 'event.ctrlKey'},\n interval: {\n on: '[mousedown[!event.shiftKey], mouseup] > mousemove',\n encodings: ['y'],\n zoom: 'wheel[event.altKey]'\n }\n };\n\n const component = selection.parseUnitSelection(model, {\n \"one\": {\"type\": \"single\"},\n \"two\": {\"type\": \"multi\"},\n \"three\": {\"type\": \"interval\"}\n });\n\n assert.sameMembers(keys(component), ['one', 'two', 'three']);\n\n assert.equal(component.one.name, 'one');\n assert.equal(component.one.type, 'single');\n assert.sameDeepMembers(component['one'].project, [{field: 'Cylinders', channel: null}]);\n assert.sameDeepMembers(component['one'].events, parseSelector('dblclick', 'scope'));\n\n assert.equal(component.two.name, 'two');\n assert.equal(component.two.type, 'multi');\n assert.equal(component.two.toggle, 'event.ctrlKey');\n assert.sameDeepMembers(component['two'].project, [{field: 'Origin', channel: 'color'}]);\n assert.sameDeepMembers(component['two'].events, parseSelector('mouseover', 'scope'));\n\n assert.equal(component.three.name, 'three');\n assert.equal(component.three.type, 'interval');\n assert(!component.three.translate);\n assert.equal(component.three.zoom, 'wheel[event.altKey]');\n assert.sameDeepMembers(component['three'].project, [{field: 'Miles_per_Gallon', channel: 'y'}]);\n assert.sameDeepMembers(component['three'].events, parseSelector('[mousedown[!event.shiftKey], mouseup] > mousemove', 'scope'));\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/predicate.test.d.ts b/build/test/compile/selection/predicate.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/predicate.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/predicate.test.js b/build/test/compile/selection/predicate.test.js new file mode 100644 index 0000000000..286521a668 --- /dev/null +++ b/build/test/compile/selection/predicate.test.js @@ -0,0 +1,93 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { nonPosition } from '../../../src/compile/mark/mixins'; +import * as selection from '../../../src/compile/selection/selection'; +import { expression } from '../../../src/predicate'; +import { parseUnitModel } from '../../util'; +var predicate = selection.selectionPredicate; +describe('Selection Predicate', function () { + var model = parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { + "field": "Cylinders", "type": "ordinal", + "condition": { + "selection": "one", + "value": "grey" + } + }, + "opacity": { + "field": "Origin", "type": "nominal", + "condition": { + "selection": { "or": ["one", { "and": ["two", { "not": "thr-ee" }] }] }, + "value": 0.5 + } + } + } + }); + model.parseScale(); + model.component.selection = selection.parseUnitSelection(model, { + "one": { "type": "single" }, + "two": { "type": "multi", "resolve": "union" }, + "thr-ee": { "type": "interval", "resolve": "intersect" }, + "four": { "type": "single", "empty": "none" } + }); + it('generates the predicate expression', function () { + assert.equal(predicate(model, "one"), '!(length(data("one_store"))) || (vlSingle("one_store", datum))'); + assert.equal(predicate(model, "four"), '(vlSingle("four_store", datum))'); + assert.equal(predicate(model, { "not": "one" }), '!(length(data("one_store"))) || (!(vlSingle("one_store", datum)))'); + assert.equal(predicate(model, { "not": { "and": ["one", "two"] } }), '!(length(data("one_store")) || length(data("two_store"))) || ' + + '(!((vlSingle("one_store", datum)) && ' + + '(vlMulti("two_store", datum, "union"))))'); + assert.equal(predicate(model, { "not": { "and": ["one", "four"] } }), '!(length(data("one_store"))) || ' + + '(!((vlSingle("one_store", datum)) && ' + + '(vlSingle("four_store", datum))))'); + assert.equal(predicate(model, { "and": ["one", "two", { "not": "thr-ee" }] }), '!(length(data("one_store")) || length(data("two_store")) || length(data("thr_ee_store"))) || ' + + '((vlSingle("one_store", datum)) && ' + + '(vlMulti("two_store", datum, "union")) && ' + + '(!(vlInterval("thr_ee_store", datum, "intersect"))))'); + assert.equal(predicate(model, { "or": ["one", { "and": ["two", { "not": "thr-ee" }] }] }), '!(length(data("one_store")) || length(data("two_store")) || length(data("thr_ee_store"))) || ' + + '((vlSingle("one_store", datum)) || ' + + '((vlMulti("two_store", datum, "union")) && ' + + '(!(vlInterval("thr_ee_store", datum, "intersect")))))'); + }); + it('generates Vega production rules', function () { + assert.deepEqual(nonPosition('color', model, { vgChannel: 'fill' }), { + fill: [ + { test: '!(length(data("one_store"))) || (vlSingle("one_store", datum))', value: "grey" }, + { scale: "color", field: "Cylinders" } + ] + }); + assert.deepEqual(nonPosition('opacity', model), { + opacity: [ + { test: '!(length(data("one_store")) || length(data("two_store")) || length(data("thr_ee_store"))) || ' + + '((vlSingle("one_store", datum)) || ' + + '((vlMulti("two_store", datum, "union")) && ' + + '(!(vlInterval("thr_ee_store", datum, "intersect")))))', + value: 0.5 }, + { scale: "opacity", field: "Origin" } + ] + }); + }); + it('generates a selection filter', function () { + assert.equal(expression(model, { "selection": "one" }), '!(length(data("one_store"))) || (vlSingle("one_store", datum))'); + assert.equal(expression(model, { "selection": { "not": "one" } }), '!(length(data("one_store"))) || (!(vlSingle("one_store", datum)))'); + assert.equal(expression(model, { "selection": { "not": { "and": ["one", "two"] } } }), '!(length(data("one_store")) || length(data("two_store"))) || ' + + '(!((vlSingle("one_store", datum)) && ' + + '(vlMulti("two_store", datum, "union"))))'); + assert.equal(expression(model, { "selection": { "and": ["one", "two", { "not": "thr-ee" }] } }), '!(length(data("one_store")) || length(data("two_store")) || length(data("thr_ee_store"))) || ' + + '((vlSingle("one_store", datum)) && ' + + '(vlMulti("two_store", datum, "union")) && ' + + '(!(vlInterval("thr_ee_store", datum, "intersect"))))'); + assert.equal(expression(model, { "selection": { "or": ["one", { "and": ["two", { "not": "thr-ee" }] }] } }), '!(length(data("one_store")) || length(data("two_store")) || length(data("thr_ee_store"))) || ' + + '((vlSingle("one_store", datum)) || ' + + '((vlMulti("two_store", datum, "union")) && ' + + '(!(vlInterval("thr_ee_store", datum, "intersect")))))'); + }); + it('throws an error for unknown selections', function () { + assert.throws(function () { return predicate(model, 'helloworld'); }, 'Cannot find a selection named "helloworld"'); + }); +}); +//# sourceMappingURL=predicate.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/predicate.test.js.map b/build/test/compile/selection/predicate.test.js.map new file mode 100644 index 0000000000..5c0cbd043d --- /dev/null +++ b/build/test/compile/selection/predicate.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"predicate.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/predicate.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport {nonPosition} from '../../../src/compile/mark/mixins';\nimport * as selection from '../../../src/compile/selection/selection';\nimport {expression} from '../../../src/predicate';\nimport {VgEncodeEntry} from '../../../src/vega.schema';\nimport {parseUnitModel} from '../../util';\n\nconst predicate = selection.selectionPredicate;\n\ndescribe('Selection Predicate', function() {\n const model = parseUnitModel({\n \"mark\": \"circle\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\"},\n \"color\": {\n \"field\": \"Cylinders\", \"type\": \"ordinal\",\n \"condition\": {\n \"selection\": \"one\",\n \"value\": \"grey\"\n }\n },\n \"opacity\": {\n \"field\": \"Origin\", \"type\": \"nominal\",\n \"condition\": {\n \"selection\": {\"or\": [\"one\", {\"and\": [\"two\", {\"not\": \"thr-ee\"}]}]},\n \"value\": 0.5\n }\n }\n }\n });\n\n model.parseScale();\n\n model.component.selection = selection.parseUnitSelection(model, {\n \"one\": {\"type\": \"single\"},\n \"two\": {\"type\": \"multi\", \"resolve\": \"union\"},\n \"thr-ee\": {\"type\": \"interval\", \"resolve\": \"intersect\"},\n \"four\": {\"type\": \"single\", \"empty\": \"none\"}\n });\n\n it('generates the predicate expression', function() {\n assert.equal(predicate(model, \"one\"),\n '!(length(data(\"one_store\"))) || (vlSingle(\"one_store\", datum))');\n\n assert.equal(predicate(model, \"four\"), '(vlSingle(\"four_store\", datum))');\n\n assert.equal(predicate(model, {\"not\": \"one\"}),\n '!(length(data(\"one_store\"))) || (!(vlSingle(\"one_store\", datum)))');\n\n assert.equal(predicate(model, {\"not\": {\"and\": [\"one\", \"two\"]}}),\n '!(length(data(\"one_store\")) || length(data(\"two_store\"))) || ' +\n '(!((vlSingle(\"one_store\", datum)) && ' +\n '(vlMulti(\"two_store\", datum, \"union\"))))');\n\n assert.equal(predicate(model, {\"not\": {\"and\": [\"one\", \"four\"]}}),\n '!(length(data(\"one_store\"))) || ' +\n '(!((vlSingle(\"one_store\", datum)) && ' +\n '(vlSingle(\"four_store\", datum))))');\n\n assert.equal(predicate(model, {\"and\": [\"one\", \"two\", {\"not\": \"thr-ee\"}]}),\n '!(length(data(\"one_store\")) || length(data(\"two_store\")) || length(data(\"thr_ee_store\"))) || ' +\n '((vlSingle(\"one_store\", datum)) && ' +\n '(vlMulti(\"two_store\", datum, \"union\")) && ' +\n '(!(vlInterval(\"thr_ee_store\", datum, \"intersect\"))))');\n\n assert.equal(predicate(model, {\"or\": [\"one\", {\"and\": [\"two\", {\"not\": \"thr-ee\"}]}]}),\n '!(length(data(\"one_store\")) || length(data(\"two_store\")) || length(data(\"thr_ee_store\"))) || ' +\n '((vlSingle(\"one_store\", datum)) || ' +\n '((vlMulti(\"two_store\", datum, \"union\")) && ' +\n '(!(vlInterval(\"thr_ee_store\", datum, \"intersect\")))))');\n });\n\n it('generates Vega production rules', function() {\n assert.deepEqual(nonPosition('color', model, {vgChannel: 'fill'}), {\n fill: [\n {test: '!(length(data(\"one_store\"))) || (vlSingle(\"one_store\", datum))', value: \"grey\"},\n {scale: \"color\", field: \"Cylinders\"}\n ]\n });\n\n assert.deepEqual(nonPosition('opacity', model), {\n opacity: [\n {test: '!(length(data(\"one_store\")) || length(data(\"two_store\")) || length(data(\"thr_ee_store\"))) || ' +\n '((vlSingle(\"one_store\", datum)) || ' +\n '((vlMulti(\"two_store\", datum, \"union\")) && ' +\n '(!(vlInterval(\"thr_ee_store\", datum, \"intersect\")))))',\n value: 0.5},\n {scale: \"opacity\", field: \"Origin\"}\n ]\n });\n });\n\n it('generates a selection filter', function() {\n assert.equal(expression(model, {\"selection\": \"one\"}),\n '!(length(data(\"one_store\"))) || (vlSingle(\"one_store\", datum))');\n\n assert.equal(expression(model, {\"selection\": {\"not\": \"one\"}}),\n '!(length(data(\"one_store\"))) || (!(vlSingle(\"one_store\", datum)))');\n\n assert.equal(expression(model, {\"selection\": {\"not\": {\"and\": [\"one\", \"two\"]}}}),\n '!(length(data(\"one_store\")) || length(data(\"two_store\"))) || ' +\n '(!((vlSingle(\"one_store\", datum)) && ' +\n '(vlMulti(\"two_store\", datum, \"union\"))))');\n\n assert.equal(expression(model, {\"selection\": {\"and\": [\"one\", \"two\", {\"not\": \"thr-ee\"}]}}),\n '!(length(data(\"one_store\")) || length(data(\"two_store\")) || length(data(\"thr_ee_store\"))) || ' +\n '((vlSingle(\"one_store\", datum)) && ' +\n '(vlMulti(\"two_store\", datum, \"union\")) && ' +\n '(!(vlInterval(\"thr_ee_store\", datum, \"intersect\"))))');\n\n assert.equal(expression(model, {\"selection\": {\"or\": [\"one\", {\"and\": [\"two\", {\"not\": \"thr-ee\"}]}]}}),\n '!(length(data(\"one_store\")) || length(data(\"two_store\")) || length(data(\"thr_ee_store\"))) || ' +\n '((vlSingle(\"one_store\", datum)) || ' +\n '((vlMulti(\"two_store\", datum, \"union\")) && ' +\n '(!(vlInterval(\"thr_ee_store\", datum, \"intersect\")))))');\n });\n\n it('throws an error for unknown selections', function() {\n assert.throws(() => predicate(model, 'helloworld'), 'Cannot find a selection named \"helloworld\"');\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/scales.test.d.ts b/build/test/compile/selection/scales.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/scales.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/scales.test.js b/build/test/compile/selection/scales.test.js new file mode 100644 index 0000000000..c7e78b8f9f --- /dev/null +++ b/build/test/compile/selection/scales.test.js @@ -0,0 +1,141 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { assembleScalesForModel } from '../../../src/compile/scale/assemble'; +import { parseConcatModel, parseRepeatModel } from '../../util'; +describe('Selection + Scales', function () { + it('assembles domainRaw from selection parameter', function () { + var model = parseConcatModel({ + vconcat: [ + { + mark: "area", + selection: { + brush: { type: "interval", encodings: ["x"] }, + brush2: { type: "multi", fields: ["price"], resolve: "intersect" } + }, + encoding: { + x: { field: "date", type: "temporal" }, + y: { field: "price", type: "quantitative" } + } + }, + { + selection: { + brush3: { type: "interval" } + }, + mark: "area", + encoding: { + x: { + field: "date", type: "temporal", + scale: { domain: { selection: "brush", encoding: "x" } } + }, + y: { + field: "price", type: "quantitative", + scale: { domain: { selection: "brush2", field: "price" } } + }, + color: { + field: "symbol", type: "nominal", + scale: { domain: { selection: "brush2" } } + }, + opacity: { + field: "symbol", type: "nominal", + scale: { domain: { selection: "brush3" } } + } + } + } + ], + resolve: { + scale: { + color: 'independent', + opacity: 'independent' + } + } + }); + model.parseScale(); + model.parseSelection(); + var scales = assembleScalesForModel(model.children[1]); + var xscale = scales[0]; + var yscale = scales[1]; + var cscale = scales[2]; + var oscale = scales[3]; + assert.isObject(xscale.domain); + assert.property(xscale, 'domainRaw'); + assert.propertyVal(xscale.domainRaw, 'signal', "vlIntervalDomain(\"brush_store\", \"x\", null)"); + assert.isObject(yscale.domain); + assert.property(yscale, 'domainRaw'); + assert.deepPropertyVal(yscale.domainRaw, 'signal', "vlMultiDomain(\"brush2_store\", null, \"price\", \"intersect\")"); + assert.isObject(cscale.domain); + assert.property(cscale, 'domainRaw'); + assert.propertyVal(cscale.domainRaw, 'signal', "vlMultiDomain(\"brush2_store\", null, \"price\", \"intersect\")"); + assert.isObject(oscale.domain); + assert.property(oscale, 'domainRaw'); + assert.propertyVal(oscale.domainRaw, 'signal', 'null'); + }); + it('should bind both scales in diagonal repeated views', function () { + var model = parseRepeatModel({ + repeat: { + row: ["Horsepower", "Acceleration"], + column: ["Miles_per_Gallon", "Acceleration"] + }, + spec: { + data: { url: "data/cars.json" }, + mark: "point", + selection: { + grid: { + type: "interval", + resolve: "global", + bind: "scales" + } + }, + encoding: { + x: { field: { repeat: "column" }, type: "quantitative" }, + y: { field: { repeat: "row" }, type: "quantitative" }, + color: { field: "Origin", type: "nominal" } + } + } + }); + model.parseScale(); + model.parseSelection(); + var scales = assembleScalesForModel(model.children[3]); + assert.isTrue(scales.length === 2); + assert.property(scales[0], 'domainRaw'); + assert.property(scales[1], 'domainRaw'); + assert.propertyVal(scales[0].domainRaw, 'signal', 'grid_Acceleration'); + assert.propertyVal(scales[1].domainRaw, 'signal', 'grid_Acceleration'); + }); + it('should merge domainRaw for layered views', function () { + var model = parseConcatModel({ + data: { url: "data/sp500.csv" }, + vconcat: [ + { + layer: [ + { + mark: "point", + encoding: { + x: { + field: "date", type: "temporal", + scale: { domain: { selection: "brush" } } + }, + y: { field: "price", type: "quantitative" } + } + } + ] + }, + { + mark: "area", + selection: { + brush: { type: "interval", encodings: ["x"] } + }, + encoding: { + x: { field: "date", type: "temporal" }, + y: { field: "price", type: "quantitative" } + } + } + ] + }); + model.parseScale(); + model.parseSelection(); + var scales = assembleScalesForModel(model.children[0]); + assert.property(scales[0], 'domainRaw'); + assert.propertyVal(scales[0].domainRaw, 'signal', 'vlIntervalDomain("brush_store", null, "date")'); + }); +}); +//# sourceMappingURL=scales.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/scales.test.js.map b/build/test/compile/selection/scales.test.js.map new file mode 100644 index 0000000000..207708d579 --- /dev/null +++ b/build/test/compile/selection/scales.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scales.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/scales.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {assembleScalesForModel} from '../../../src/compile/scale/assemble';\nimport {Domain} from '../../../src/scale';\nimport {parseConcatModel, parseRepeatModel} from '../../util';\n\ndescribe('Selection + Scales', function() {\n it('assembles domainRaw from selection parameter', function() {\n const model = parseConcatModel({\n vconcat: [\n {\n mark: \"area\",\n selection: {\n brush: {type: \"interval\", encodings: [\"x\"]},\n brush2: {type: \"multi\", fields: [\"price\"], resolve: \"intersect\"}\n },\n encoding: {\n x: {field: \"date\", type: \"temporal\"},\n y: {field: \"price\", type: \"quantitative\"}\n }\n },\n {\n selection: {\n brush3: {type: \"interval\"}\n },\n mark: \"area\",\n encoding: {\n x: {\n field: \"date\", type: \"temporal\",\n scale: {domain: {selection: \"brush\", encoding: \"x\"}}\n },\n y: {\n field: \"price\", type: \"quantitative\",\n scale: {domain: {selection: \"brush2\", field: \"price\"}}\n },\n color: {\n field: \"symbol\", type: \"nominal\",\n scale: {domain: {selection: \"brush2\"} as Domain}\n },\n opacity: {\n field: \"symbol\", type: \"nominal\",\n scale: {domain: {selection: \"brush3\"} as Domain}\n }\n }\n }\n ],\n resolve: {\n scale: {\n color: 'independent',\n opacity: 'independent'\n }\n }\n });\n\n model.parseScale();\n model.parseSelection();\n\n const scales = assembleScalesForModel(model.children[1]);\n const xscale = scales[0];\n const yscale = scales[1];\n const cscale = scales[2];\n const oscale = scales[3];\n\n assert.isObject(xscale.domain);\n assert.property(xscale, 'domainRaw');\n assert.propertyVal(xscale.domainRaw, 'signal',\n \"vlIntervalDomain(\\\"brush_store\\\", \\\"x\\\", null)\");\n\n assert.isObject(yscale.domain);\n assert.property(yscale, 'domainRaw');\n assert.deepPropertyVal(yscale.domainRaw, 'signal',\n \"vlMultiDomain(\\\"brush2_store\\\", null, \\\"price\\\", \\\"intersect\\\")\");\n\n assert.isObject(cscale.domain);\n assert.property(cscale, 'domainRaw');\n assert.propertyVal(cscale.domainRaw, 'signal',\n \"vlMultiDomain(\\\"brush2_store\\\", null, \\\"price\\\", \\\"intersect\\\")\");\n\n assert.isObject(oscale.domain);\n assert.property(oscale, 'domainRaw');\n assert.propertyVal(oscale.domainRaw, 'signal', 'null');\n });\n\n it('should bind both scales in diagonal repeated views', function() {\n const model = parseRepeatModel({\n repeat: {\n row: [\"Horsepower\", \"Acceleration\"],\n column: [\"Miles_per_Gallon\", \"Acceleration\"]\n },\n spec: {\n data: {url: \"data/cars.json\"},\n mark: \"point\",\n selection: {\n grid: {\n type: \"interval\",\n resolve: \"global\",\n bind: \"scales\"\n }\n },\n encoding: {\n x: {field: {repeat: \"column\"}, type: \"quantitative\"},\n y: {field: {repeat: \"row\"}, type: \"quantitative\"},\n color: {field: \"Origin\", type: \"nominal\"}\n }\n }\n });\n\n model.parseScale();\n model.parseSelection();\n\n const scales = assembleScalesForModel(model.children[3]);\n assert.isTrue(scales.length === 2);\n assert.property(scales[0], 'domainRaw');\n assert.property(scales[1], 'domainRaw');\n assert.propertyVal(scales[0].domainRaw, 'signal', 'grid_Acceleration');\n assert.propertyVal(scales[1].domainRaw, 'signal', 'grid_Acceleration');\n });\n\n it('should merge domainRaw for layered views', function() {\n const model = parseConcatModel({\n data: {url: \"data/sp500.csv\"},\n vconcat: [\n {\n layer: [\n {\n mark: \"point\",\n encoding: {\n x: {\n field: \"date\", type: \"temporal\",\n scale: {domain: {selection: \"brush\"}}\n },\n y: {field: \"price\", type: \"quantitative\"}\n }\n }\n ]\n },\n {\n mark: \"area\",\n selection: {\n brush: {type: \"interval\", encodings: [\"x\"]}\n },\n encoding: {\n x: {field: \"date\", type: \"temporal\"},\n y: {field: \"price\", type: \"quantitative\"}\n }\n }\n ]\n });\n\n model.parseScale();\n model.parseSelection();\n const scales = assembleScalesForModel(model.children[0]);\n assert.property(scales[0], 'domainRaw');\n assert.propertyVal(scales[0].domainRaw, 'signal', 'vlIntervalDomain(\"brush_store\", null, \"date\")');\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/single.test.d.ts b/build/test/compile/selection/single.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/single.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/single.test.js b/build/test/compile/selection/single.test.js new file mode 100644 index 0000000000..1f7698e918 --- /dev/null +++ b/build/test/compile/selection/single.test.js @@ -0,0 +1,103 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import * as selection from '../../../src/compile/selection/selection'; +import single from '../../../src/compile/selection/single'; +import { parseUnitModelWithScale } from '../../util'; +describe('Single Selection', function () { + var model = parseUnitModelWithScale({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative", "bin": true }, + "color": { "field": "Origin", "type": "nominal" } + } + }); + var selCmpts = model.component.selection = selection.parseUnitSelection(model, { + "one": { "type": "single" }, + "two": { + "type": "single", "nearest": true, + "on": "mouseover", "encodings": ["y", "color"] + } + }); + it('builds tuple signals', function () { + var oneSg = single.signals(model, selCmpts['one']); + assert.sameDeepMembers(oneSg, [{ + name: 'one_tuple', + value: {}, + on: [{ + events: selCmpts['one'].events, + update: "datum && item().mark.marktype !== 'group' ? {unit: \"\", encodings: [], fields: [\"_vgsid_\"], values: [datum[\"_vgsid_\"]]} : null", + force: true + }] + }]); + var twoSg = single.signals(model, selCmpts['two']); + assert.sameDeepMembers(twoSg, [{ + name: 'two_tuple', + value: {}, + on: [{ + events: selCmpts['two'].events, + update: "datum && item().mark.marktype !== 'group' ? {unit: \"\", encodings: [\"y\", \"color\"], fields: [\"Miles_per_Gallon\", \"Origin\"], values: [[(item().isVoronoi ? datum.datum : datum)[\"bin_maxbins_10_Miles_per_Gallon\"], (item().isVoronoi ? datum.datum : datum)[\"bin_maxbins_10_Miles_per_Gallon_end\"]], (item().isVoronoi ? datum.datum : datum)[\"Origin\"]], \"bin_Miles_per_Gallon\": 1} : null", + force: true + }] + }]); + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, oneSg.concat(twoSg)); + }); + it('builds modify signals', function () { + var oneExpr = single.modifyExpr(model, selCmpts['one']); + assert.equal(oneExpr, 'one_tuple, true'); + var twoExpr = single.modifyExpr(model, selCmpts['two']); + assert.equal(twoExpr, 'two_tuple, true'); + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, [ + { + "name": "one_modify", + "on": [ + { + "events": { "signal": "one_tuple" }, + "update": "modify(\"one_store\", " + oneExpr + ")" + } + ] + }, + { + "name": "two_modify", + "on": [ + { + "events": { "signal": "two_tuple" }, + "update": "modify(\"two_store\", " + twoExpr + ")" + } + ] + } + ]); + }); + it('builds top-level signals', function () { + var oneSg = single.topLevelSignals(model, selCmpts['one'], []); + assert.sameDeepMembers(oneSg, [{ + name: 'one', update: 'data(\"one_store\").length && {_vgsid_: data(\"one_store\")[0].values[0]}' + }]); + var twoSg = single.topLevelSignals(model, selCmpts['two'], []); + assert.sameDeepMembers(twoSg, [{ + name: 'two', update: 'data(\"two_store\").length && {Miles_per_Gallon: data(\"two_store\")[0].values[0], Origin: data(\"two_store\")[0].values[1]}' + }]); + var signals = selection.assembleTopLevelSignals(model, []); + assert.deepEqual(signals, [ + { + name: 'unit', + value: {}, + on: [{ events: 'mousemove', update: 'isTuple(group()) ? group() : unit' }] + } + ].concat(oneSg, twoSg)); + }); + it('builds unit datasets', function () { + var data = []; + assert.sameDeepMembers(selection.assembleUnitSelectionData(model, data), [ + { name: 'one_store' }, { name: 'two_store' } + ]); + }); + it('leaves marks alone', function () { + var marks = []; + model.component.selection = { one: selCmpts['one'] }; + assert.equal(selection.assembleUnitSelectionMarks(model, marks), marks); + }); +}); +//# sourceMappingURL=single.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/single.test.js.map b/build/test/compile/selection/single.test.js.map new file mode 100644 index 0000000000..53cbe88dd4 --- /dev/null +++ b/build/test/compile/selection/single.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"single.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/single.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\nimport {assert} from 'chai';\n\nimport * as selection from '../../../src/compile/selection/selection';\nimport single from '../../../src/compile/selection/single';\nimport {parseUnitModelWithScale} from '../../util';\n\n\ndescribe('Single Selection', function() {\n const model = parseUnitModelWithScale({\n \"mark\": \"circle\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\", \"bin\": true},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n });\n\n const selCmpts = model.component.selection = selection.parseUnitSelection(model, {\n \"one\": {\"type\": \"single\"},\n \"two\": {\n \"type\": \"single\", \"nearest\": true,\n \"on\": \"mouseover\", \"encodings\": [\"y\", \"color\"]\n }\n });\n\n it('builds tuple signals', function() {\n const oneSg = single.signals(model, selCmpts['one']);\n assert.sameDeepMembers(oneSg, [{\n name: 'one_tuple',\n value: {},\n on: [{\n events: selCmpts['one'].events,\n update: \"datum && item().mark.marktype !== 'group' ? {unit: \\\"\\\", encodings: [], fields: [\\\"_vgsid_\\\"], values: [datum[\\\"_vgsid_\\\"]]} : null\",\n force: true\n }]\n }]);\n\n const twoSg = single.signals(model, selCmpts['two']);\n assert.sameDeepMembers(twoSg, [{\n name: 'two_tuple',\n value: {},\n on: [{\n events: selCmpts['two'].events,\n update: \"datum && item().mark.marktype !== 'group' ? {unit: \\\"\\\", encodings: [\\\"y\\\", \\\"color\\\"], fields: [\\\"Miles_per_Gallon\\\", \\\"Origin\\\"], values: [[(item().isVoronoi ? datum.datum : datum)[\\\"bin_maxbins_10_Miles_per_Gallon\\\"], (item().isVoronoi ? datum.datum : datum)[\\\"bin_maxbins_10_Miles_per_Gallon_end\\\"]], (item().isVoronoi ? datum.datum : datum)[\\\"Origin\\\"]], \\\"bin_Miles_per_Gallon\\\": 1} : null\",\n force: true\n }]\n }]);\n\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, oneSg.concat(twoSg));\n });\n\n it('builds modify signals', function() {\n const oneExpr = single.modifyExpr(model, selCmpts['one']);\n assert.equal(oneExpr, 'one_tuple, true');\n\n const twoExpr = single.modifyExpr(model, selCmpts['two']);\n assert.equal(twoExpr, 'two_tuple, true');\n\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, [\n {\n \"name\": \"one_modify\",\n \"on\": [\n {\n \"events\": {\"signal\": \"one_tuple\"},\n \"update\": `modify(\\\"one_store\\\", ${oneExpr})`\n }\n ]\n },\n {\n \"name\": \"two_modify\",\n \"on\": [\n {\n \"events\": {\"signal\": \"two_tuple\"},\n \"update\": `modify(\\\"two_store\\\", ${twoExpr})`\n }\n ]\n }\n ]);\n });\n\n it('builds top-level signals', function() {\n const oneSg = single.topLevelSignals(model, selCmpts['one'], []);\n assert.sameDeepMembers(oneSg, [{\n name: 'one', update: 'data(\\\"one_store\\\").length && {_vgsid_: data(\\\"one_store\\\")[0].values[0]}'\n }]);\n\n const twoSg = single.topLevelSignals(model, selCmpts['two'], []);\n assert.sameDeepMembers(twoSg, [{\n name: 'two', update: 'data(\\\"two_store\\\").length && {Miles_per_Gallon: data(\\\"two_store\\\")[0].values[0], Origin: data(\\\"two_store\\\")[0].values[1]}'\n }]);\n\n const signals = selection.assembleTopLevelSignals(model, []);\n assert.deepEqual(signals, [\n {\n name: 'unit',\n value: {},\n on: [{events: 'mousemove', update: 'isTuple(group()) ? group() : unit'}]\n }\n ].concat(oneSg, twoSg));\n });\n\n it('builds unit datasets', function() {\n const data: any[] = [];\n assert.sameDeepMembers(selection.assembleUnitSelectionData(model, data), [\n {name: 'one_store'}, {name: 'two_store'}\n ]);\n });\n\n it('leaves marks alone', function() {\n const marks: any[] = [];\n model.component.selection = {one: selCmpts['one']};\n assert.equal(selection.assembleUnitSelectionMarks(model, marks), marks);\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/timeunit.test.d.ts b/build/test/compile/selection/timeunit.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/timeunit.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/timeunit.test.js b/build/test/compile/selection/timeunit.test.js new file mode 100644 index 0000000000..ac0f343ae3 --- /dev/null +++ b/build/test/compile/selection/timeunit.test.js @@ -0,0 +1,121 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { assembleRootData } from '../../../src/compile/data/assemble'; +import { optimizeDataflow } from '../../../src/compile/data/optimize'; +import { TimeUnitNode } from '../../../src/compile/data/timeunit'; +import * as selection from '../../../src/compile/selection/selection'; +import { parseModel, parseUnitModel } from '../../util'; +function getData(model) { + optimizeDataflow(model.component.data); + return assembleRootData(model.component.data, {}); +} +function getModel(unit2) { + var model = parseModel({ + "data": { "values": [ + { "date": "Sun, 01 Jan 2012 23:00:01", "price": 150 }, + { "date": "Sun, 02 Jan 2012 00:10:02", "price": 100 }, + { "date": "Sun, 02 Jan 2012 01:20:03", "price": 170 }, + { "date": "Sun, 02 Jan 2012 02:30:04", "price": 165 }, + { "date": "Sun, 02 Jan 2012 03:40:05", "price": 200 } + ] }, + "hconcat": [{ + "mark": "point", + "selection": { + "two": { "type": "single", "encodings": ["x", "y"] } + }, + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "timeUnit": "seconds" + }, + "y": { "field": "price", "type": "quantitative" } + } + }, unit2] + }); + model.parse(); + return model; +} +describe('Selection time unit', function () { + it('dataflow nodes are constructed', function () { + var model = parseUnitModel({ + "mark": "point", + "encoding": { + "x": { "field": "date", "type": "temporal", "timeUnit": "seconds" }, + "y": { "field": "date", "type": "temporal", "timeUnit": "minutes" } + } + }); + var selCmpts = model.component.selection = selection.parseUnitSelection(model, { + "one": { "type": "single" }, + "two": { "type": "single", "encodings": ["x", "y"] } + }); + assert.isUndefined(selCmpts['one'].timeUnit); + assert.instanceOf(selCmpts['two'].timeUnit, TimeUnitNode); + var as = selCmpts['two'].timeUnit.assemble().map(function (tx) { return tx.as; }); + assert.sameDeepMembers(as, ['seconds_date', 'minutes_date']); + }); + it('is added with conditional encodings', function () { + var model = getModel({ + "mark": "point", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "timeUnit": "minutes" + }, + "y": { "field": "price", "type": "quantitative" }, + "color": { + "condition": { "selection": "two", "value": "goldenrod" }, + "value": "steelblue" + } + } + }); + var data2 = getData(model).filter(function (d) { return d.name === 'data_2'; })[0].transform; + assert.equal(data2.filter(function (tx) { return tx.type === 'formula' && tx.as === 'seconds_date'; }).length, 1); + }); + it('is added before selection filters', function () { + var model = getModel({ + "transform": [{ "filter": { "selection": "two" } }], + "mark": "point", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "timeUnit": "minutes" + }, + "y": { "field": "price", "type": "quantitative" } + } + }); + var data2 = getData(model).filter(function (d) { return d.name === 'data_2'; })[0].transform; + var tuIdx = -1; + var selIdx = -1; + data2.forEach(function (tx, idx) { + if (tx.type === 'formula' && tx.as === 'seconds_date') { + tuIdx = idx; + } + else if (tx.type === 'filter' && tx.expr.indexOf('vlSingle') >= 0) { + selIdx = idx; + } + }); + assert.notEqual(tuIdx, -1); + assert.notEqual(selIdx, -1); + assert.isAbove(selIdx, tuIdx); + }); + it('removes duplicate time unit formulae', function () { + var model = getModel({ + "transform": [{ "filter": { "selection": "two" } }], + "mark": "point", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "timeUnit": "seconds" + }, + "y": { "field": "price", "type": "quantitative" } + } + }); + var data2 = getData(model).filter(function (d) { return d.name === 'data_2'; })[0].transform; + assert.equal(data2.filter(function (tx) { return tx.type === 'formula' && tx.as === 'seconds_date'; }).length, 1); + }); +}); +//# sourceMappingURL=timeunit.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/timeunit.test.js.map b/build/test/compile/selection/timeunit.test.js.map new file mode 100644 index 0000000000..8644062fc3 --- /dev/null +++ b/build/test/compile/selection/timeunit.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"timeunit.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/timeunit.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\n\nimport {assert} from 'chai';\nimport {assembleRootData} from '../../../src/compile/data/assemble';\nimport {optimizeDataflow} from '../../../src/compile/data/optimize';\nimport {TimeUnitNode} from '../../../src/compile/data/timeunit';\nimport {Model} from '../../../src/compile/model';\nimport * as selection from '../../../src/compile/selection/selection';\nimport {NormalizedUnitSpec} from '../../../src/spec';\nimport {parseModel, parseUnitModel} from '../../util';\n\nfunction getData(model: Model) {\n optimizeDataflow(model.component.data);\n return assembleRootData(model.component.data, {});\n}\n\nfunction getModel(unit2: NormalizedUnitSpec) {\n const model = parseModel({\n \"data\": {\"values\": [\n {\"date\": \"Sun, 01 Jan 2012 23:00:01\",\"price\": 150},\n {\"date\": \"Sun, 02 Jan 2012 00:10:02\",\"price\": 100},\n {\"date\": \"Sun, 02 Jan 2012 01:20:03\",\"price\": 170},\n {\"date\": \"Sun, 02 Jan 2012 02:30:04\",\"price\": 165},\n {\"date\": \"Sun, 02 Jan 2012 03:40:05\",\"price\": 200}\n ]},\n \"hconcat\": [{\n \"mark\": \"point\",\n \"selection\": {\n \"two\": {\"type\": \"single\", \"encodings\": [\"x\", \"y\"]}\n },\n \"encoding\": {\n \"x\": {\n \"field\": \"date\",\n \"type\": \"temporal\",\n \"timeUnit\": \"seconds\"\n },\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"}\n }\n }, unit2]\n });\n model.parse();\n return model;\n}\n\ndescribe('Selection time unit', function() {\n it('dataflow nodes are constructed', function() {\n const model = parseUnitModel({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\", \"timeUnit\": \"seconds\"},\n \"y\": {\"field\": \"date\", \"type\": \"temporal\", \"timeUnit\": \"minutes\"}\n }\n });\n const selCmpts = model.component.selection = selection.parseUnitSelection(model, {\n \"one\": {\"type\": \"single\"},\n \"two\": {\"type\": \"single\", \"encodings\": [\"x\", \"y\"]}\n });\n\n assert.isUndefined(selCmpts['one'].timeUnit);\n assert.instanceOf(selCmpts['two'].timeUnit, TimeUnitNode);\n\n const as = selCmpts['two'].timeUnit.assemble().map((tx) => tx.as);\n assert.sameDeepMembers(as, ['seconds_date', 'minutes_date']);\n });\n\n it('is added with conditional encodings', function() {\n const model = getModel({\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\n \"field\": \"date\",\n \"type\": \"temporal\",\n \"timeUnit\": \"minutes\"\n },\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"},\n \"color\": {\n \"condition\": {\"selection\": \"two\", \"value\": \"goldenrod\"},\n \"value\": \"steelblue\"\n }\n }\n });\n\n const data2 = getData(model).filter((d) => d.name === 'data_2')[0].transform;\n assert.equal(data2.filter((tx) => tx.type === 'formula' && tx.as === 'seconds_date').length, 1);\n });\n\n it('is added before selection filters', function() {\n const model = getModel({\n \"transform\": [{\"filter\": {\"selection\": \"two\"}}],\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\n \"field\": \"date\",\n \"type\": \"temporal\",\n \"timeUnit\": \"minutes\"\n },\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"}\n }\n });\n\n const data2 = getData(model).filter((d) => d.name === 'data_2')[0].transform;\n let tuIdx = -1;\n let selIdx = -1;\n\n data2.forEach((tx, idx) => {\n if (tx.type === 'formula' && tx.as === 'seconds_date') {\n tuIdx = idx;\n } else if (tx.type === 'filter' && tx.expr.indexOf('vlSingle') >= 0) {\n selIdx = idx;\n }\n });\n\n assert.notEqual(tuIdx, -1);\n assert.notEqual(selIdx, -1);\n assert.isAbove(selIdx, tuIdx);\n });\n\n it('removes duplicate time unit formulae', function() {\n const model = getModel({\n \"transform\": [{\"filter\": {\"selection\": \"two\"}}],\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\n \"field\": \"date\",\n \"type\": \"temporal\",\n \"timeUnit\": \"seconds\"\n },\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"}\n }\n });\n\n const data2 = getData(model).filter((d) => d.name === 'data_2')[0].transform;\n assert.equal(data2.filter((tx) => tx.type === 'formula' && tx.as === 'seconds_date').length, 1);\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/toggle.test.d.ts b/build/test/compile/selection/toggle.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/toggle.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/toggle.test.js b/build/test/compile/selection/toggle.test.js new file mode 100644 index 0000000000..901832924e --- /dev/null +++ b/build/test/compile/selection/toggle.test.js @@ -0,0 +1,85 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import * as selection from '../../../src/compile/selection/selection'; +import toggle from '../../../src/compile/selection/transforms/toggle'; +import { parseUnitModel } from '../../util'; +describe('Toggle Selection Transform', function () { + var model = parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" } + } + }); + model.parseScale(); + var selCmpts = model.component.selection = selection.parseUnitSelection(model, { + "one": { "type": "multi" }, + "two": { + "type": "multi", "resolve": "union", + "on": "mouseover", "toggle": "event.ctrlKey", "encodings": ["y", "color"] + }, + "three": { "type": "multi", "toggle": false }, + "four": { "type": "multi", "toggle": null }, + "five": { "type": "single" }, + "six": { "type": "interval" } + }); + it('identifies transform invocation', function () { + assert.isNotFalse(toggle.has(selCmpts['one'])); + assert.isNotFalse(toggle.has(selCmpts['two'])); + assert.isNotTrue(toggle.has(selCmpts['three'])); + assert.isNotTrue(toggle.has(selCmpts['four'])); + assert.isNotTrue(toggle.has(selCmpts['five'])); + assert.isNotTrue(toggle.has(selCmpts['six'])); + }); + it('builds toggle signals', function () { + var oneSg = toggle.signals(model, selCmpts['one'], []); + assert.sameDeepMembers(oneSg, [{ + name: 'one_toggle', + value: false, + on: [{ + events: selCmpts['one'].events, + update: 'event.shiftKey' + }] + }]); + var twoSg = toggle.signals(model, selCmpts['two'], []); + assert.sameDeepMembers(twoSg, [{ + name: 'two_toggle', + value: false, + on: [{ + events: selCmpts['two'].events, + update: 'event.ctrlKey' + }] + }]); + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, oneSg.concat(twoSg)); + }); + it('builds modify expr', function () { + var oneExpr = toggle.modifyExpr(model, selCmpts['one'], ''); + assert.equal(oneExpr, 'one_toggle ? null : one_tuple, one_toggle ? null : true, one_toggle ? one_tuple : null'); + var twoExpr = toggle.modifyExpr(model, selCmpts['two'], ''); + assert.equal(twoExpr, 'two_toggle ? null : two_tuple, two_toggle ? null : {unit: \"\"}, two_toggle ? two_tuple : null'); + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, [ + { + "name": "one_modify", + "on": [ + { + "events": { "signal": "one_tuple" }, + "update": "modify(\"one_store\", " + oneExpr + ")" + } + ] + }, + { + "name": "two_modify", + "on": [ + { + "events": { "signal": "two_tuple" }, + "update": "modify(\"two_store\", " + twoExpr + ")" + } + ] + } + ]); + }); +}); +//# sourceMappingURL=toggle.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/toggle.test.js.map b/build/test/compile/selection/toggle.test.js.map new file mode 100644 index 0000000000..bd319077fb --- /dev/null +++ b/build/test/compile/selection/toggle.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"toggle.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/toggle.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport * as selection from '../../../src/compile/selection/selection';\nimport toggle from '../../../src/compile/selection/transforms/toggle';\nimport {parseUnitModel} from '../../util';\n\ndescribe('Toggle Selection Transform', function() {\n const model = parseUnitModel({\n \"mark\": \"circle\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\"},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n });\n\n model.parseScale();\n const selCmpts = model.component.selection = selection.parseUnitSelection(model, {\n \"one\": {\"type\": \"multi\"},\n \"two\": {\n \"type\": \"multi\", \"resolve\": \"union\",\n \"on\": \"mouseover\", \"toggle\": \"event.ctrlKey\", \"encodings\": [\"y\", \"color\"]\n },\n \"three\": {\"type\": \"multi\", \"toggle\": false},\n \"four\": {\"type\": \"multi\", \"toggle\": null},\n \"five\": {\"type\": \"single\"},\n \"six\": {\"type\": \"interval\"}\n });\n\n it('identifies transform invocation', function() {\n assert.isNotFalse(toggle.has(selCmpts['one']));\n assert.isNotFalse(toggle.has(selCmpts['two']));\n assert.isNotTrue(toggle.has(selCmpts['three']));\n assert.isNotTrue(toggle.has(selCmpts['four']));\n assert.isNotTrue(toggle.has(selCmpts['five']));\n assert.isNotTrue(toggle.has(selCmpts['six']));\n });\n\n it('builds toggle signals', function() {\n const oneSg = toggle.signals(model, selCmpts['one'], []);\n assert.sameDeepMembers(oneSg, [{\n name: 'one_toggle',\n value: false,\n on: [{\n events: selCmpts['one'].events,\n update: 'event.shiftKey'\n }]\n }]);\n\n const twoSg = toggle.signals(model, selCmpts['two'], []);\n assert.sameDeepMembers(twoSg, [{\n name: 'two_toggle',\n value: false,\n on: [{\n events: selCmpts['two'].events,\n update: 'event.ctrlKey'\n }]\n }]);\n\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, oneSg.concat(twoSg));\n });\n\n it('builds modify expr', function() {\n const oneExpr = toggle.modifyExpr(model, selCmpts['one'], '');\n assert.equal(oneExpr, 'one_toggle ? null : one_tuple, one_toggle ? null : true, one_toggle ? one_tuple : null');\n\n const twoExpr = toggle.modifyExpr(model, selCmpts['two'], '');\n assert.equal(twoExpr, 'two_toggle ? null : two_tuple, two_toggle ? null : {unit: \\\"\\\"}, two_toggle ? two_tuple : null');\n\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, [\n {\n \"name\": \"one_modify\",\n \"on\": [\n {\n \"events\": {\"signal\": \"one_tuple\"},\n \"update\": `modify(\\\"one_store\\\", ${oneExpr})`\n }\n ]\n },\n {\n \"name\": \"two_modify\",\n \"on\": [\n {\n \"events\": {\"signal\": \"two_tuple\"},\n \"update\": `modify(\\\"two_store\\\", ${twoExpr})`\n }\n ]\n }\n ]);\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/translate.test.d.ts b/build/test/compile/selection/translate.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/translate.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/translate.test.js b/build/test/compile/selection/translate.test.js new file mode 100644 index 0000000000..23ce221fcc --- /dev/null +++ b/build/test/compile/selection/translate.test.js @@ -0,0 +1,207 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { selector as parseSelector } from 'vega-event-selector'; +import * as selection from '../../../src/compile/selection/selection'; +import translate from '../../../src/compile/selection/transforms/translate'; +import { parseUnitModel } from '../../util'; +function getModel(xscale, yscale) { + var model = parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative", "scale": { "type": xscale || "linear" } }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative", "scale": { "type": yscale || "linear" } }, + "color": { "field": "Origin", "type": "nominal" } + } + }); + model.parseScale(); + var selCmpts = selection.parseUnitSelection(model, { + "one": { + "type": "single" + }, + "two": { + "type": "multi" + }, + "three": { + "type": "interval", + "translate": false + }, + "four": { + "type": "interval" + }, + "five": { + "type": "interval", + "translate": "[mousedown, mouseup] > mousemove, [keydown, keyup] > touchmove" + }, + "six": { + "type": "interval", + "bind": "scales" + }, + "seven": { + "type": "interval", + "translate": null + } + }); + return { model: model, selCmpts: selCmpts }; +} +describe('Translate Selection Transform', function () { + it('identifies transform invocation', function () { + var _a = getModel(), _model = _a.model, selCmpts = _a.selCmpts; + assert.isNotTrue(translate.has(selCmpts['one'])); + assert.isNotTrue(translate.has(selCmpts['two'])); + assert.isNotTrue(translate.has(selCmpts['three'])); + assert.isNotFalse(translate.has(selCmpts['four'])); + assert.isNotFalse(translate.has(selCmpts['five'])); + assert.isNotFalse(translate.has(selCmpts['six'])); + assert.isNotTrue(translate.has(selCmpts['seven'])); + }); + describe('Anchor/Delta signals', function () { + var _a = getModel(), model = _a.model, selCmpts = _a.selCmpts; + it('builds them for default invocation', function () { + model.component.selection = { four: selCmpts['four'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, [ + { + "name": "four_translate_anchor", + "value": {}, + "on": [ + { + "events": parseSelector('@four_brush:mousedown', 'scope'), + "update": "{x: x(unit), y: y(unit), extent_x: slice(four_x), extent_y: slice(four_y)}" + } + ] + }, + { + "name": "four_translate_delta", + "value": {}, + "on": [ + { + "events": parseSelector('[@four_brush:mousedown, window:mouseup] > window:mousemove!', 'scope'), + "update": "{x: four_translate_anchor.x - x(unit), y: four_translate_anchor.y - y(unit)}" + } + ] + } + ]); + }); + it('builds them for custom events', function () { + model.component.selection = { five: selCmpts['five'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, [ + { + "name": "five_translate_anchor", + "value": {}, + "on": [ + { + "events": parseSelector('@five_brush:mousedown, @five_brush:keydown', 'scope'), + "update": "{x: x(unit), y: y(unit), extent_x: slice(five_x), extent_y: slice(five_y)}" + } + ] + }, + { + "name": "five_translate_delta", + "value": {}, + "on": [ + { + "events": parseSelector('[@five_brush:mousedown, mouseup] > mousemove, [@five_brush:keydown, keyup] > touchmove', 'scope'), + "update": "{x: five_translate_anchor.x - x(unit), y: five_translate_anchor.y - y(unit)}" + } + ] + } + ]); + }); + it('builds them for scale-bound intervals', function () { + model.component.selection = { six: selCmpts['six'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, [ + { + "name": "six_translate_anchor", + "value": {}, + "on": [ + { + "events": parseSelector('mousedown', 'scope'), + "update": "{x: x(unit), y: y(unit), extent_x: domain(\"x\"), extent_y: domain(\"y\")}" + } + ] + }, + { + "name": "six_translate_delta", + "value": {}, + "on": [ + { + "events": parseSelector('[mousedown, window:mouseup] > window:mousemove!', 'scope'), + "update": "{x: six_translate_anchor.x - x(unit), y: six_translate_anchor.y - y(unit)}" + } + ] + } + ]); + }); + }); + describe('Translate Signal', function () { + it('always builds panLinear exprs for brushes', function () { + var _a = getModel(), model = _a.model, selCmpts = _a.selCmpts; + model.component.selection = { four: selCmpts['four'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_x'; })[0].on, [ + { + "events": { "signal": "four_translate_delta" }, + "update": "clampRange(panLinear(four_translate_anchor.extent_x, four_translate_delta.x / span(four_translate_anchor.extent_x)), 0, width)" + } + ]); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_y'; })[0].on, [ + { + "events": { "signal": "four_translate_delta" }, + "update": "clampRange(panLinear(four_translate_anchor.extent_y, four_translate_delta.y / span(four_translate_anchor.extent_y)), 0, height)" + } + ]); + var model2 = getModel('log', 'pow').model; + model2.component.selection = { four: selCmpts['four'] }; + signals = selection.assembleUnitSelectionSignals(model2, []); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_x'; })[0].on, [ + { + "events": { "signal": "four_translate_delta" }, + "update": "clampRange(panLinear(four_translate_anchor.extent_x, four_translate_delta.x / span(four_translate_anchor.extent_x)), 0, width)" + } + ]); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_y'; })[0].on, [ + { + "events": { "signal": "four_translate_delta" }, + "update": "clampRange(panLinear(four_translate_anchor.extent_y, four_translate_delta.y / span(four_translate_anchor.extent_y)), 0, height)" + } + ]); + }); + it('builds panLinear exprs for scale-bound intervals', function () { + var _a = getModel(), model = _a.model, selCmpts = _a.selCmpts; + model.component.selection = { six: selCmpts['six'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_Horsepower'; })[0].on, [ + { + "events": { "signal": "six_translate_delta" }, + "update": "panLinear(six_translate_anchor.extent_x, -six_translate_delta.x / width)" + } + ]); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_Miles_per_Gallon'; })[0].on, [ + { + "events": { "signal": "six_translate_delta" }, + "update": "panLinear(six_translate_anchor.extent_y, six_translate_delta.y / height)" + } + ]); + }); + it('builds panLog/panPow exprs for scale-bound intervals', function () { + var _a = getModel('log', 'pow'), model = _a.model, selCmpts = _a.selCmpts; + model.component.selection = { six: selCmpts['six'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_Horsepower'; })[0].on, [ + { + "events": { "signal": "six_translate_delta" }, + "update": "panLog(six_translate_anchor.extent_x, -six_translate_delta.x / width)" + } + ]); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_Miles_per_Gallon'; })[0].on, [ + { + "events": { "signal": "six_translate_delta" }, + "update": "panPow(six_translate_anchor.extent_y, six_translate_delta.y / height, 1)" + } + ]); + }); + }); +}); +//# sourceMappingURL=translate.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/translate.test.js.map b/build/test/compile/selection/translate.test.js.map new file mode 100644 index 0000000000..96b6ccd687 --- /dev/null +++ b/build/test/compile/selection/translate.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"translate.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/translate.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport {selector as parseSelector} from 'vega-event-selector';\nimport * as selection from '../../../src/compile/selection/selection';\nimport translate from '../../../src/compile/selection/transforms/translate';\nimport {ScaleType} from '../../../src/scale';\nimport {parseUnitModel} from '../../util';\n\nfunction getModel(xscale?: ScaleType, yscale?: ScaleType) {\n const model = parseUnitModel({\n \"mark\": \"circle\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\", \"scale\": {\"type\": xscale || \"linear\"}},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\", \"scale\": {\"type\": yscale || \"linear\"}},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n });\n\n model.parseScale();\n const selCmpts = selection.parseUnitSelection(model, {\n \"one\": {\n \"type\": \"single\"\n },\n \"two\": {\n \"type\": \"multi\"\n },\n \"three\": {\n \"type\": \"interval\",\n \"translate\": false\n },\n \"four\": {\n \"type\": \"interval\"\n },\n \"five\": {\n \"type\": \"interval\",\n \"translate\": \"[mousedown, mouseup] > mousemove, [keydown, keyup] > touchmove\"\n },\n \"six\": {\n \"type\": \"interval\",\n \"bind\": \"scales\"\n },\n \"seven\": {\n \"type\": \"interval\",\n \"translate\": null\n }\n });\n\n return {model, selCmpts};\n}\n\ndescribe('Translate Selection Transform', function() {\n it('identifies transform invocation', function() {\n const {model: _model, selCmpts} = getModel();\n assert.isNotTrue(translate.has(selCmpts['one']));\n assert.isNotTrue(translate.has(selCmpts['two']));\n assert.isNotTrue(translate.has(selCmpts['three']));\n assert.isNotFalse(translate.has(selCmpts['four']));\n assert.isNotFalse(translate.has(selCmpts['five']));\n assert.isNotFalse(translate.has(selCmpts['six']));\n assert.isNotTrue(translate.has(selCmpts['seven']));\n });\n\n describe('Anchor/Delta signals', function() {\n const {model, selCmpts} = getModel();\n\n it('builds them for default invocation', function() {\n model.component.selection = {four: selCmpts['four']};\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, [\n {\n \"name\": \"four_translate_anchor\",\n \"value\": {},\n \"on\": [\n {\n \"events\": parseSelector('@four_brush:mousedown', 'scope'),\n \"update\": \"{x: x(unit), y: y(unit), extent_x: slice(four_x), extent_y: slice(four_y)}\"\n }\n ]\n },\n {\n \"name\": \"four_translate_delta\",\n \"value\": {},\n \"on\": [\n {\n \"events\": parseSelector('[@four_brush:mousedown, window:mouseup] > window:mousemove!', 'scope'),\n \"update\": \"{x: four_translate_anchor.x - x(unit), y: four_translate_anchor.y - y(unit)}\"\n }\n ]\n }\n ]);\n });\n\n it('builds them for custom events', function() {\n model.component.selection = {five: selCmpts['five']};\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, [\n {\n \"name\": \"five_translate_anchor\",\n \"value\": {},\n \"on\": [\n {\n \"events\": parseSelector('@five_brush:mousedown, @five_brush:keydown', 'scope'),\n \"update\": \"{x: x(unit), y: y(unit), extent_x: slice(five_x), extent_y: slice(five_y)}\"\n }\n ]\n },\n {\n \"name\": \"five_translate_delta\",\n \"value\": {},\n \"on\": [\n {\n \"events\": parseSelector('[@five_brush:mousedown, mouseup] > mousemove, [@five_brush:keydown, keyup] > touchmove', 'scope'),\n \"update\": \"{x: five_translate_anchor.x - x(unit), y: five_translate_anchor.y - y(unit)}\"\n }\n ]\n }\n ]);\n });\n\n it('builds them for scale-bound intervals', function() {\n model.component.selection = {six: selCmpts['six']};\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, [\n {\n \"name\": \"six_translate_anchor\",\n \"value\": {},\n \"on\": [\n {\n \"events\": parseSelector('mousedown', 'scope'),\n \"update\": \"{x: x(unit), y: y(unit), extent_x: domain(\\\"x\\\"), extent_y: domain(\\\"y\\\")}\"\n }\n ]\n },\n {\n \"name\": \"six_translate_delta\",\n \"value\": {},\n \"on\": [\n {\n \"events\": parseSelector('[mousedown, window:mouseup] > window:mousemove!', 'scope'),\n \"update\": \"{x: six_translate_anchor.x - x(unit), y: six_translate_anchor.y - y(unit)}\"\n }\n ]\n }\n ]);\n });\n });\n\n describe('Translate Signal', function() {\n it('always builds panLinear exprs for brushes', function() {\n const {model, selCmpts} = getModel();\n model.component.selection = {four: selCmpts['four']};\n let signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals.filter((s) => s.name === 'four_x')[0].on, [\n {\n \"events\": {\"signal\": \"four_translate_delta\"},\n \"update\": \"clampRange(panLinear(four_translate_anchor.extent_x, four_translate_delta.x / span(four_translate_anchor.extent_x)), 0, width)\"\n }\n ]);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'four_y')[0].on, [\n {\n \"events\": {\"signal\": \"four_translate_delta\"},\n \"update\": \"clampRange(panLinear(four_translate_anchor.extent_y, four_translate_delta.y / span(four_translate_anchor.extent_y)), 0, height)\"\n }\n ]);\n\n const model2 = getModel('log', 'pow').model;\n model2.component.selection = {four: selCmpts['four']};\n signals = selection.assembleUnitSelectionSignals(model2, []);\n assert.includeDeepMembers(signals.filter((s) => s.name === 'four_x')[0].on, [\n {\n \"events\": {\"signal\": \"four_translate_delta\"},\n \"update\": \"clampRange(panLinear(four_translate_anchor.extent_x, four_translate_delta.x / span(four_translate_anchor.extent_x)), 0, width)\"\n }\n ]);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'four_y')[0].on, [\n {\n \"events\": {\"signal\": \"four_translate_delta\"},\n \"update\": \"clampRange(panLinear(four_translate_anchor.extent_y, four_translate_delta.y / span(four_translate_anchor.extent_y)), 0, height)\"\n }\n ]);\n });\n\n it('builds panLinear exprs for scale-bound intervals', function() {\n const {model, selCmpts} = getModel();\n model.component.selection = {six: selCmpts['six']};\n const signals = selection.assembleUnitSelectionSignals(model, []);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'six_Horsepower')[0].on, [\n {\n \"events\": {\"signal\": \"six_translate_delta\"},\n \"update\": \"panLinear(six_translate_anchor.extent_x, -six_translate_delta.x / width)\"\n }\n ]);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'six_Miles_per_Gallon')[0].on, [\n {\n \"events\": {\"signal\": \"six_translate_delta\"},\n \"update\": \"panLinear(six_translate_anchor.extent_y, six_translate_delta.y / height)\"\n }\n ]);\n });\n\n it('builds panLog/panPow exprs for scale-bound intervals', function() {\n const {model, selCmpts} = getModel('log', 'pow');\n model.component.selection = {six: selCmpts['six']};\n const signals = selection.assembleUnitSelectionSignals(model, []);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'six_Horsepower')[0].on, [\n {\n \"events\": {\"signal\": \"six_translate_delta\"},\n \"update\": \"panLog(six_translate_anchor.extent_x, -six_translate_delta.x / width)\"\n }\n ]);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'six_Miles_per_Gallon')[0].on, [\n {\n \"events\": {\"signal\": \"six_translate_delta\"},\n \"update\": \"panPow(six_translate_anchor.extent_y, six_translate_delta.y / height, 1)\"\n }\n ]);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/selection/zoom.test.d.ts b/build/test/compile/selection/zoom.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/selection/zoom.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/selection/zoom.test.js b/build/test/compile/selection/zoom.test.js new file mode 100644 index 0000000000..32aff0e206 --- /dev/null +++ b/build/test/compile/selection/zoom.test.js @@ -0,0 +1,206 @@ +/* tslint:disable quotemark */ +import { assert } from 'chai'; +import { selector as parseSelector } from 'vega-event-selector'; +import * as selection from '../../../src/compile/selection/selection'; +import zoom from '../../../src/compile/selection/transforms/zoom'; +import { parseUnitModel } from '../../util'; +function getModel(xscale, yscale) { + var model = parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative", "scale": { "type": xscale || "linear" } }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative", "scale": { "type": yscale || "linear" } }, + "color": { "field": "Origin", "type": "nominal" } + } + }); + model.parseScale(); + var selCmpts = selection.parseUnitSelection(model, { + "one": { + "type": "single" + }, + "two": { + "type": "multi" + }, + "three": { + "type": "interval", + "zoom": false + }, + "four": { + "type": "interval" + }, + "five": { + "type": "interval", + "zoom": "wheel, pinch" + }, + "six": { + "type": "interval", + "bind": "scales" + }, + "seven": { + "type": "interval", + "zoom": null + } + }); + return { model: model, selCmpts: selCmpts }; +} +describe('Zoom Selection Transform', function () { + it('identifies transform invocation', function () { + var _a = getModel(), _model = _a.model, selCmpts = _a.selCmpts; + assert.isNotTrue(zoom.has(selCmpts['one'])); + assert.isNotTrue(zoom.has(selCmpts['two'])); + assert.isNotTrue(zoom.has(selCmpts['three'])); + assert.isNotFalse(zoom.has(selCmpts['four'])); + assert.isNotFalse(zoom.has(selCmpts['five'])); + assert.isNotFalse(zoom.has(selCmpts['six'])); + assert.isNotTrue(zoom.has(selCmpts['seven'])); + }); + describe('Anchor/Delta signals', function () { + it('builds then for default invocation', function () { + var _a = getModel(), model = _a.model, selCmpts = _a.selCmpts; + model.component.selection = { four: selCmpts['four'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, [ + { + "name": "four_zoom_anchor", + "on": [ + { + "events": parseSelector('@four_brush:wheel!', 'scope'), + "update": "{x: x(unit), y: y(unit)}" + } + ] + }, + { + "name": "four_zoom_delta", + "on": [ + { + "events": parseSelector('@four_brush:wheel!', 'scope'), + "force": true, + "update": "pow(1.001, event.deltaY * pow(16, event.deltaMode))" + } + ] + } + ]); + }); + it('builds them for custom events', function () { + var _a = getModel(), model = _a.model, selCmpts = _a.selCmpts; + model.component.selection = { five: selCmpts['five'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, [ + { + "name": "five_zoom_anchor", + "on": [ + { + "events": parseSelector('@five_brush:wheel, @five_brush:pinch', 'scope'), + "update": "{x: x(unit), y: y(unit)}" + } + ] + }, + { + "name": "five_zoom_delta", + "on": [ + { + "events": parseSelector('@five_brush:wheel, @five_brush:pinch', 'scope'), + "force": true, + "update": "pow(1.001, event.deltaY * pow(16, event.deltaMode))" + } + ] + } + ]); + }); + it('builds them for scale-bound zoom', function () { + var _a = getModel(), model = _a.model, selCmpts = _a.selCmpts; + model.component.selection = { six: selCmpts['six'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals, [ + { + "name": "six_zoom_anchor", + "on": [ + { + "events": parseSelector('wheel!', 'scope'), + "update": "{x: invert(\"x\", x(unit)), y: invert(\"y\", y(unit))}" + } + ] + }, + { + "name": "six_zoom_delta", + "on": [ + { + "events": parseSelector('wheel!', 'scope'), + "force": true, + "update": "pow(1.001, event.deltaY * pow(16, event.deltaMode))" + } + ] + } + ]); + }); + }); + describe('Zoom Signal', function () { + it('always builds zoomLinear exprs for brushes', function () { + var _a = getModel(), model = _a.model, selCmpts = _a.selCmpts; + model.component.selection = { four: selCmpts['four'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_x'; })[0].on, [ + { + "events": { "signal": "four_zoom_delta" }, + "update": "clampRange(zoomLinear(four_x, four_zoom_anchor.x, four_zoom_delta), 0, width)" + } + ]); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_y'; })[0].on, [ + { + "events": { "signal": "four_zoom_delta" }, + "update": "clampRange(zoomLinear(four_y, four_zoom_anchor.y, four_zoom_delta), 0, height)" + } + ]); + var model2 = getModel('log', 'pow').model; + model2.component.selection = { four: selCmpts['four'] }; + signals = selection.assembleUnitSelectionSignals(model2, []); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_x'; })[0].on, [ + { + "events": { "signal": "four_zoom_delta" }, + "update": "clampRange(zoomLinear(four_x, four_zoom_anchor.x, four_zoom_delta), 0, width)" + } + ]); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_y'; })[0].on, [ + { + "events": { "signal": "four_zoom_delta" }, + "update": "clampRange(zoomLinear(four_y, four_zoom_anchor.y, four_zoom_delta), 0, height)" + } + ]); + }); + it('builds zoomLinear exprs for scale-bound zoom', function () { + var _a = getModel(), model = _a.model, selCmpts = _a.selCmpts; + model.component.selection = { six: selCmpts['six'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_Horsepower'; })[0].on, [ + { + "events": { "signal": "six_zoom_delta" }, + "update": "zoomLinear(domain(\"x\"), six_zoom_anchor.x, six_zoom_delta)" + } + ]); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_Miles_per_Gallon'; })[0].on, [ + { + "events": { "signal": "six_zoom_delta" }, + "update": "zoomLinear(domain(\"y\"), six_zoom_anchor.y, six_zoom_delta)" + } + ]); + }); + it('builds zoomLog/Pow exprs for scale-bound zoom', function () { + var _a = getModel('log', 'pow'), model = _a.model, selCmpts = _a.selCmpts; + model.component.selection = { six: selCmpts['six'] }; + var signals = selection.assembleUnitSelectionSignals(model, []); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_Horsepower'; })[0].on, [ + { + "events": { "signal": "six_zoom_delta" }, + "update": "zoomLog(domain(\"x\"), six_zoom_anchor.x, six_zoom_delta)" + } + ]); + assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_Miles_per_Gallon'; })[0].on, [ + { + "events": { "signal": "six_zoom_delta" }, + "update": "zoomPow(domain(\"y\"), six_zoom_anchor.y, six_zoom_delta, 1)" + } + ]); + }); + }); +}); +//# sourceMappingURL=zoom.test.js.map \ No newline at end of file diff --git a/build/test/compile/selection/zoom.test.js.map b/build/test/compile/selection/zoom.test.js.map new file mode 100644 index 0000000000..9286b84a3e --- /dev/null +++ b/build/test/compile/selection/zoom.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"zoom.test.js","sourceRoot":"","sources":["../../../../test/compile/selection/zoom.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable quotemark */\n\nimport {assert} from 'chai';\nimport {selector as parseSelector} from 'vega-event-selector';\nimport * as selection from '../../../src/compile/selection/selection';\nimport zoom from '../../../src/compile/selection/transforms/zoom';\nimport {ScaleType} from '../../../src/scale';\nimport {parseUnitModel} from '../../util';\n\nfunction getModel(xscale?: ScaleType, yscale?: ScaleType) {\n const model = parseUnitModel({\n \"mark\": \"circle\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\", \"scale\": {\"type\": xscale || \"linear\"}},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\", \"scale\": {\"type\": yscale || \"linear\"}},\n \"color\": {\"field\": \"Origin\", \"type\": \"nominal\"}\n }\n });\n\n model.parseScale();\n const selCmpts = selection.parseUnitSelection(model, {\n \"one\": {\n \"type\": \"single\"\n },\n \"two\": {\n \"type\": \"multi\"\n },\n \"three\": {\n \"type\": \"interval\",\n \"zoom\": false\n },\n \"four\": {\n \"type\": \"interval\"\n },\n \"five\": {\n \"type\": \"interval\",\n \"zoom\": \"wheel, pinch\"\n },\n \"six\": {\n \"type\": \"interval\",\n \"bind\": \"scales\"\n },\n \"seven\": {\n \"type\": \"interval\",\n \"zoom\": null\n }\n });\n\n return {model, selCmpts};\n}\n\ndescribe('Zoom Selection Transform', function() {\n\n it('identifies transform invocation', function() {\n const {model: _model, selCmpts} = getModel();\n assert.isNotTrue(zoom.has(selCmpts['one']));\n assert.isNotTrue(zoom.has(selCmpts['two']));\n assert.isNotTrue(zoom.has(selCmpts['three']));\n assert.isNotFalse(zoom.has(selCmpts['four']));\n assert.isNotFalse(zoom.has(selCmpts['five']));\n assert.isNotFalse(zoom.has(selCmpts['six']));\n assert.isNotTrue(zoom.has(selCmpts['seven']));\n });\n\n describe('Anchor/Delta signals', function() {\n it('builds then for default invocation', function() {\n const {model, selCmpts} = getModel();\n model.component.selection = {four: selCmpts['four']};\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, [\n {\n \"name\": \"four_zoom_anchor\",\n \"on\": [\n {\n \"events\": parseSelector('@four_brush:wheel!', 'scope'),\n \"update\": \"{x: x(unit), y: y(unit)}\"\n }\n ]\n },\n {\n \"name\": \"four_zoom_delta\",\n \"on\": [\n {\n \"events\": parseSelector('@four_brush:wheel!', 'scope'),\n \"force\": true,\n \"update\": \"pow(1.001, event.deltaY * pow(16, event.deltaMode))\"\n }\n ]\n }\n ]);\n });\n\n it('builds them for custom events', function() {\n const {model, selCmpts} = getModel();\n model.component.selection = {five: selCmpts['five']};\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, [\n {\n \"name\": \"five_zoom_anchor\",\n \"on\": [\n {\n \"events\": parseSelector('@five_brush:wheel, @five_brush:pinch', 'scope'),\n \"update\": \"{x: x(unit), y: y(unit)}\"\n }\n ]\n },\n {\n \"name\": \"five_zoom_delta\",\n \"on\": [\n {\n \"events\": parseSelector('@five_brush:wheel, @five_brush:pinch', 'scope'),\n \"force\": true,\n \"update\": \"pow(1.001, event.deltaY * pow(16, event.deltaMode))\"\n }\n ]\n }\n ]);\n });\n\n it('builds them for scale-bound zoom', function() {\n const {model, selCmpts} = getModel();\n model.component.selection = {six: selCmpts['six']};\n const signals = selection.assembleUnitSelectionSignals(model, []);\n assert.includeDeepMembers(signals, [\n {\n \"name\": \"six_zoom_anchor\",\n \"on\": [\n {\n \"events\": parseSelector('wheel!', 'scope'),\n \"update\": \"{x: invert(\\\"x\\\", x(unit)), y: invert(\\\"y\\\", y(unit))}\"\n }\n ]\n },\n {\n \"name\": \"six_zoom_delta\",\n \"on\": [\n {\n \"events\": parseSelector('wheel!', 'scope'),\n \"force\": true,\n \"update\": \"pow(1.001, event.deltaY * pow(16, event.deltaMode))\"\n }\n ]\n }\n ]);\n });\n });\n\n describe('Zoom Signal', function() {\n it('always builds zoomLinear exprs for brushes', function() {\n const {model, selCmpts} = getModel();\n model.component.selection = {four: selCmpts['four']};\n let signals = selection.assembleUnitSelectionSignals(model, []);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'four_x')[0].on, [\n {\n \"events\": {\"signal\": \"four_zoom_delta\"},\n \"update\": \"clampRange(zoomLinear(four_x, four_zoom_anchor.x, four_zoom_delta), 0, width)\"\n }\n ]);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'four_y')[0].on, [\n {\n \"events\": {\"signal\": \"four_zoom_delta\"},\n \"update\": \"clampRange(zoomLinear(four_y, four_zoom_anchor.y, four_zoom_delta), 0, height)\"\n }\n ]);\n\n const model2 = getModel('log', 'pow').model;\n model2.component.selection = {four: selCmpts['four']};\n signals = selection.assembleUnitSelectionSignals(model2, []);\n assert.includeDeepMembers(signals.filter((s) => s.name === 'four_x')[0].on, [\n {\n \"events\": {\"signal\": \"four_zoom_delta\"},\n \"update\": \"clampRange(zoomLinear(four_x, four_zoom_anchor.x, four_zoom_delta), 0, width)\"\n }\n ]);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'four_y')[0].on, [\n {\n \"events\": {\"signal\": \"four_zoom_delta\"},\n \"update\": \"clampRange(zoomLinear(four_y, four_zoom_anchor.y, four_zoom_delta), 0, height)\"\n }\n ]);\n });\n\n it('builds zoomLinear exprs for scale-bound zoom', function() {\n const {model, selCmpts} = getModel();\n model.component.selection = {six: selCmpts['six']};\n const signals = selection.assembleUnitSelectionSignals(model, []);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'six_Horsepower')[0].on, [\n {\n \"events\": {\"signal\": \"six_zoom_delta\"},\n \"update\": \"zoomLinear(domain(\\\"x\\\"), six_zoom_anchor.x, six_zoom_delta)\"\n }\n ]);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'six_Miles_per_Gallon')[0].on, [\n {\n \"events\": {\"signal\": \"six_zoom_delta\"},\n \"update\": \"zoomLinear(domain(\\\"y\\\"), six_zoom_anchor.y, six_zoom_delta)\"\n }\n ]);\n });\n\n it('builds zoomLog/Pow exprs for scale-bound zoom', function() {\n const {model, selCmpts} = getModel('log', 'pow');\n model.component.selection = {six: selCmpts['six']};\n const signals = selection.assembleUnitSelectionSignals(model, []);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'six_Horsepower')[0].on, [\n {\n \"events\": {\"signal\": \"six_zoom_delta\"},\n \"update\": \"zoomLog(domain(\\\"x\\\"), six_zoom_anchor.x, six_zoom_delta)\"\n }\n ]);\n\n assert.includeDeepMembers(signals.filter((s) => s.name === 'six_Miles_per_Gallon')[0].on, [\n {\n \"events\": {\"signal\": \"six_zoom_delta\"},\n \"update\": \"zoomPow(domain(\\\"y\\\"), six_zoom_anchor.y, six_zoom_delta, 1)\"\n }\n ]);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compile/unit.test.d.ts b/build/test/compile/unit.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compile/unit.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compile/unit.test.js b/build/test/compile/unit.test.js new file mode 100644 index 0000000000..69b7e4f310 --- /dev/null +++ b/build/test/compile/unit.test.js @@ -0,0 +1,78 @@ +import { assert } from 'chai'; +import { DETAIL, SHAPE, X } from '../../src/channel'; +import * as log from '../../src/log'; +import { BAR } from '../../src/mark'; +import { QUANTITATIVE } from '../../src/type'; +import { parseUnitModel } from '../util'; +describe('UnitModel', function () { + describe('initEncoding', function () { + it('should drop unsupported channel and throws warning', log.wrap(function (localLogger) { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + shape: { field: 'a', type: 'quantitative' } + } + }); + assert.equal(model.encoding.shape, undefined); + assert.equal(localLogger.warns[0], log.message.incompatibleChannel(SHAPE, BAR)); + })); + it('should drop invalid channel and throws warning', log.wrap(function (localLogger) { + var _model = parseUnitModel({ + mark: 'bar', + encoding: { + _y: { type: 'quantitative' } + } + }); // To make parseUnitModel accept the model with invalid encoding channel + assert.equal(localLogger.warns[0], log.message.invalidEncodingChannel('_y')); + })); + it('should drop channel without field and value and throws warning', log.wrap(function (localLogger) { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + x: { type: 'quantitative' } + } + }); + assert.equal(model.encoding.x, undefined); + assert.equal(localLogger.warns[0], log.message.emptyFieldDef({ type: QUANTITATIVE }, X)); + })); + it('should drop a fieldDef without field and value from the channel def list and throws warning', log.wrap(function (localLogger) { + var model = parseUnitModel({ + mark: 'bar', + encoding: { + detail: [ + { field: 'a', type: 'ordinal' }, + { type: 'quantitative' } + ] + } + }); + assert.deepEqual(model.encoding.detail, [ + { field: 'a', type: 'ordinal' } + ]); + assert.equal(localLogger.warns[0], log.message.emptyFieldDef({ type: QUANTITATIVE }, DETAIL)); + })); + }); + describe('initAxes', function () { + it('should not include properties of non-VlOnlyAxisConfig in config.axis', function () { + var model = parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' }, + y: { field: 'b', type: 'ordinal' } + }, + config: { axis: { domainWidth: 123 } } + }); + assert.equal(model.axis(X)['domainWidth'], undefined); + }); + it('it should have axis.offset = encode.x.axis.offset', function () { + var model = parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', axis: { offset: 345 } }, + y: { field: 'b', type: 'ordinal' } + } + }); + assert.equal(model.axis(X).offset, 345); + }); + }); +}); +//# sourceMappingURL=unit.test.js.map \ No newline at end of file diff --git a/build/test/compile/unit.test.js.map b/build/test/compile/unit.test.js.map new file mode 100644 index 0000000000..ef47372e9d --- /dev/null +++ b/build/test/compile/unit.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"unit.test.js","sourceRoot":"","sources":["../../../test/compile/unit.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {DETAIL, SHAPE, X} from '../../src/channel';\nimport {FieldDef} from '../../src/fielddef';\nimport * as log from '../../src/log';\nimport {BAR} from '../../src/mark';\nimport {QUANTITATIVE} from '../../src/type';\nimport {parseUnitModel} from '../util';\n\ndescribe('UnitModel', function() {\n describe('initEncoding', () => {\n it('should drop unsupported channel and throws warning', log.wrap((localLogger) => {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n shape: {field: 'a', type: 'quantitative'}\n }\n });\n assert.equal(model.encoding.shape, undefined);\n assert.equal(localLogger.warns[0], log.message.incompatibleChannel(SHAPE, BAR));\n }));\n\n it('should drop invalid channel and throws warning', log.wrap((localLogger) => {\n const _model = parseUnitModel({\n mark: 'bar',\n encoding: {\n _y: {type: 'quantitative'}\n }\n } as any); // To make parseUnitModel accept the model with invalid encoding channel\n assert.equal(localLogger.warns[0], log.message.invalidEncodingChannel('_y'));\n }));\n\n it('should drop channel without field and value and throws warning', log.wrap((localLogger) => {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n x: {type: 'quantitative'}\n }\n });\n assert.equal(model.encoding.x, undefined);\n assert.equal(localLogger.warns[0], log.message.emptyFieldDef({type: QUANTITATIVE}, X));\n }));\n\n it('should drop a fieldDef without field and value from the channel def list and throws warning', log.wrap((localLogger) => {\n const model = parseUnitModel({\n mark: 'bar',\n encoding: {\n detail: [\n {field: 'a', type: 'ordinal'},\n {type: 'quantitative'}\n ]\n }\n });\n assert.deepEqual | FieldDef[]>(model.encoding.detail, [\n {field: 'a', type: 'ordinal'}\n ]);\n assert.equal(localLogger.warns[0], log.message.emptyFieldDef({type: QUANTITATIVE}, DETAIL));\n }));\n\n });\n\n describe('initAxes', () => {\n it('should not include properties of non-VlOnlyAxisConfig in config.axis', () => {\n const model = parseUnitModel({\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal'},\n y: {field: 'b', type: 'ordinal'}\n },\n config: {axis: {domainWidth: 123}}\n });\n\n assert.equal(model.axis(X)['domainWidth'], undefined);\n });\n\n it('it should have axis.offset = encode.x.axis.offset', () => {\n const model = parseUnitModel({\n mark: 'point',\n encoding: {\n x: {field: 'a', type: 'ordinal', axis: {offset: 345}},\n y: {field: 'b', type: 'ordinal'}\n }\n });\n\n assert.equal(model.axis(X).offset, 345);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compositemark/boxplot.test.d.ts b/build/test/compositemark/boxplot.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compositemark/boxplot.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compositemark/boxplot.test.js b/build/test/compositemark/boxplot.test.js new file mode 100644 index 0000000000..f0a2cc0133 --- /dev/null +++ b/build/test/compositemark/boxplot.test.js @@ -0,0 +1,1808 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import * as log from '../../src/log'; +import { normalize } from '../../src/spec'; +import { defaultConfig } from '.././../src/config'; +describe("normalizeBoxMinMax", function () { + it("should produce an error if both axes have aggregate boxplot", function () { + assert.throws(function () { + normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "x": { "aggregate": "box-plot", "field": "people", "type": "quantitative" }, + "y": { + "aggregate": "box-plot", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig); + }, Error, 'Both x and y cannot have aggregate'); + }); + it("should produce correct layered specs for vertical boxplot with two quantitative axes and use default orientation", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "lower_whisker_people" + }, + { + "op": "max", + "field": "people", + "as": "upper_whisker_people" + } + ], + "groupby": ["age"] + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "upper_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 5 } + } + } + ] + }); + }); + it("should produce an error if neither the x axis or y axis is specified", function () { + assert.throws(function () { + normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig); + }, Error, 'Need a valid continuous axis for boxplots'); + }); + it("should produce a warning if continuous axis has aggregate property", log.wrap(function (localLogger) { + normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig); + assert.equal(localLogger.warns[0], 'Continuous axis should not have customized aggregation function min'); + })); + it("should produce an error if build 1D boxplot with a discrete axis", function () { + assert.throws(function () { + normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: "box-plot", + encoding: { + "x": { "field": "age", "type": "ordinal" } + } + }, defaultConfig); + }, Error, 'Need a valid continuous axis for boxplots'); + }); + it("should produce an error if both axes are discrete", function () { + assert.throws(function () { + normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "field": "age", + "type": "ordinal", + "axis": { "title": "age" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig); + }, Error, 'Need a valid continuous axis for boxplots'); + }); + it("should produce an error if in 2D boxplot both axes are not valid field definitions", function () { + assert.throws(function () { + normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "type": "ordinal", + "axis": { "title": "age" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig); + }, Error, 'Need a valid continuous axis for boxplots'); + }); + it("should produce an error if 1D boxplot only axis is discrete", function () { + assert.throws(function () { + normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: "box-plot", + encoding: { + "x": { "field": "age", "type": "ordinal" }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig); + }, Error, 'Need a valid continuous axis for boxplots'); + }); + it("should produce correct layered specs for vertical boxplot with two quantitative axes and specify orientation with orient", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + orient: "vertical", + extent: "min-max" + }, + encoding: { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "lower_whisker_people" + }, + { + "op": "max", + "field": "people", + "as": "upper_whisker_people" + } + ], + "groupby": ["age"] + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "upper_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 5 } + } + } + ] + }); + }); + it("should produce correct layered specs for horizontal boxplot with two quantitative axes and specify orientation with orient", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + orient: "horizontal", + extent: "min-max" + }, + encoding: { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "lower_whisker_people" + }, + { + "op": "max", + "field": "people", + "as": "upper_whisker_people" + } + ], + "groupby": ["age"] + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "x2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "upper_box_people", + "type": "quantitative" + }, + "x2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "lower_box_people", + "type": "quantitative" + }, + "x2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 5 }, + } + } + ] + }); + }); + it("should produce correct layered specs for vertical boxplot with two quantitative axes and specify orientation with aggregate", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "people", + "type": "quantitative", + "aggregate": "box-plot", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "lower_whisker_people" + }, + { + "op": "max", + "field": "people", + "as": "upper_whisker_people" + } + ], + "groupby": ["age"] + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "upper_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 5 } + } + } + ] + }); + }); + it("should produce correct layered specs for horizontal boxplot with two quantitative axes and specify orientation with aggregate", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "people", + "type": "quantitative", + "aggregate": "box-plot", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "lower_whisker_people" + }, + { + "op": "max", + "field": "people", + "as": "upper_whisker_people" + } + ], + "groupby": ["age"] + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "x2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "upper_box_people", + "type": "quantitative" + }, + "x2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "lower_box_people", + "type": "quantitative" + }, + "x2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "y": { "field": "age", "type": "quantitative" }, + "x": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 5 }, + } + } + ] + }); + }); + it("should produce correct layered specs for vertical boxplot with min and max", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "lower_whisker_people" + }, + { + "op": "max", + "field": "people", + "as": "upper_whisker_people" + } + ], + "groupby": ["age"] + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "field": "upper_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "field": "lower_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 5 } + } + } + ] + }); + }); + it("should produce correct layered specs for horizontal boxplot with min and max", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "lower_whisker_people" + }, + { + "op": "max", + "field": "people", + "as": "upper_whisker_people" + } + ], + "groupby": ["age"] + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "x2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "upper_box_people", + "type": "quantitative" + }, + "x2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "lower_box_people", + "type": "quantitative" + }, + "x2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 5 }, + } + } + ] + }); + }); + it("should produce correct layered specs for horizontal with no nonpositional encoding properties boxplot with min and max", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "lower_whisker_people" + }, + { + "op": "max", + "field": "people", + "as": "upper_whisker_people" + } + ], + "groupby": ["age"] + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "x2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "upper_box_people", + "type": "quantitative" + }, + "x2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "lower_box_people", + "type": "quantitative" + }, + "x2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 14 } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 14 } + } + } + ] + }); + }); + it("should produce correct layered specs for 1D boxplot with only x", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "x": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "lower_whisker_people" + }, + { + "op": "max", + "field": "people", + "as": "upper_whisker_people" + } + ], + "groupby": [] + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "x2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { + "field": "upper_box_people", + "type": "quantitative" + }, + "x2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "x": { + "field": "lower_box_people", + "type": "quantitative" + }, + "x2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 14 } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "x": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 14 } + } + } + ] + }); + }); + it("should produce correct layered specs for 1D boxplot with only y", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + type: "box-plot", + extent: "min-max" + }, + encoding: { + "y": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "lower_whisker_people" + }, + { + "op": "max", + "field": "people", + "as": "upper_whisker_people" + } + ], + "groupby": [] + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "y": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "y": { + "field": "upper_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "y": { + "field": "lower_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 14 } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "y": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 14 } + } + } + ] + }); + }); +}); +describe("normalizeBoxIQR", function () { + it("should produce correct layered specs for vertical boxplot with two quantitative axes and use default orientation for a 1.5 * IQR whiskers with boxplot mark type", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: "box-plot", + encoding: { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "min_people" + }, + { + "op": "max", + "field": "people", + "as": "max_people" + } + ], + "groupby": ["age"] + }, + { + calculate: 'datum.upper_box_people - datum.lower_box_people', + as: 'iqr_people' + }, + { + "calculate": "min(datum.upper_box_people + datum.iqr_people * " + defaultConfig.box.extent + ", datum.max_people)", + "as": "upper_whisker_people" + }, + { + "calculate": "max(datum.lower_box_people - datum.iqr_people * " + defaultConfig.box.extent + ", datum.min_people)", + "as": "lower_whisker_people" + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "upper_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 5 } + } + } + ] + }); + }); + it("should produce correct layered specs for vertical boxplot with two quantitative axes and use default orientation for a 1.5 * IQR whiskers", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + "type": "box-plot", + "extent": 1.5 + }, + encoding: { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "min_people" + }, + { + "op": "max", + "field": "people", + "as": "max_people" + } + ], + "groupby": ["age"] + }, + { + calculate: 'datum.upper_box_people - datum.lower_box_people', + as: 'iqr_people' + }, + { + "calculate": "min(datum.upper_box_people + datum.iqr_people * 1.5, datum.max_people)", + "as": "upper_whisker_people" + }, + { + "calculate": "max(datum.lower_box_people - datum.iqr_people * 1.5, datum.min_people)", + "as": "lower_whisker_people" + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "upper_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 5 }, + "color": { "value": "skyblue" } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 5 } + } + } + ] + }); + }); + it("should produce correct layered specs for vertical IQR boxplot where color encodes the mean of the people field", function () { + assert.deepEqual(normalize({ + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + mark: { + "type": "box-plot", + "extent": 1.5 + }, + encoding: { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 }, + "color": { + "aggregate": "mean", + "field": "people", + "type": "quantitative" + } + } + }, defaultConfig), { + "description": "A box plot showing median, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [ + { + "aggregate": [ + { + "op": "q1", + "field": "people", + "as": "lower_box_people" + }, + { + "op": "q3", + "field": "people", + "as": "upper_box_people" + }, + { + "op": "median", + "field": "people", + "as": "mid_box_people" + }, + { + "op": "min", + "field": "people", + "as": "min_people" + }, + { + "op": "max", + "field": "people", + "as": "max_people" + }, + { + "op": "mean", + "field": "people", + "as": "mean_people" + } + ], + "groupby": ["age"] + }, + { + calculate: 'datum.upper_box_people - datum.lower_box_people', + as: 'iqr_people' + }, + { + "calculate": "min(datum.upper_box_people + datum.iqr_people * 1.5, datum.max_people)", + "as": "upper_whisker_people" + }, + { + "calculate": "max(datum.lower_box_people - datum.iqr_people * 1.5, datum.min_people)", + "as": "lower_whisker_people" + } + ], + "layer": [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_whisker_people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "field": "lower_box_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "upper_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_whisker_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'bar', + style: 'box' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "lower_box_people", + "type": "quantitative" + }, + "y2": { + "field": "upper_box_people", + "type": "quantitative" + }, + "size": { "value": 5 }, + "color": { + "field": "mean_people", + "type": "quantitative" + } + } + }, + { + mark: { + type: 'tick', + style: 'boxMid' + }, + "encoding": { + "x": { "field": "age", "type": "quantitative" }, + "y": { + "field": "mid_box_people", + "type": "quantitative" + }, + "color": { "value": "white" }, + "size": { "value": 5 } + } + } + ] + }); + }); +}); +//# sourceMappingURL=boxplot.test.js.map \ No newline at end of file diff --git a/build/test/compositemark/boxplot.test.js.map b/build/test/compositemark/boxplot.test.js.map new file mode 100644 index 0000000000..cffb3d6996 --- /dev/null +++ b/build/test/compositemark/boxplot.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"boxplot.test.js","sourceRoot":"","sources":["../../../test/compositemark/boxplot.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\nimport {assert} from 'chai';\n\nimport * as log from '../../src/log';\nimport {normalize} from '../../src/spec';\nimport {defaultConfig} from '.././../src/config';\n\n\ndescribe(\"normalizeBoxMinMax\", () => {\n it(\"should produce an error if both axes have aggregate boxplot\", () => {\n assert.throws(() => {\n normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"x\": {\"aggregate\": \"box-plot\", \"field\": \"people\",\"type\": \"quantitative\"},\n \"y\": {\n \"aggregate\": \"box-plot\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig);\n }, Error, 'Both x and y cannot have aggregate');\n });\n\nit(\"should produce correct layered specs for vertical boxplot with two quantitative axes and use default orientation\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"lower_whisker_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"upper_whisker_people\"\n }\n ],\n \"groupby\": [\"age\"]\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 5}\n }\n }\n ]\n });\n });\n\n it(\"should produce an error if neither the x axis or y axis is specified\", () => {\n assert.throws(() => {\n normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig);\n }, Error, 'Need a valid continuous axis for boxplots');\n });\n\n it(\"should produce a warning if continuous axis has aggregate property\", log.wrap((localLogger) => {\n normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"min\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig);\n\n assert.equal(localLogger.warns[0], 'Continuous axis should not have customized aggregation function min');\n }));\n\n it(\"should produce an error if build 1D boxplot with a discrete axis\", () => {\n assert.throws(() => {\n normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: \"box-plot\",\n encoding: {\n \"x\": {\"field\": \"age\", \"type\": \"ordinal\"}\n }\n }, defaultConfig);\n }, Error, 'Need a valid continuous axis for boxplots');\n });\n\n it(\"should produce an error if both axes are discrete\", () => {\n assert.throws(() => {\n normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"field\": \"age\",\n \"type\": \"ordinal\",\n \"axis\": {\"title\": \"age\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig);\n }, Error, 'Need a valid continuous axis for boxplots');\n });\n\n it(\"should produce an error if in 2D boxplot both axes are not valid field definitions\", () => {\n assert.throws(() => {\n normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"type\": \"ordinal\",\n \"axis\": {\"title\": \"age\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig);\n }, Error, 'Need a valid continuous axis for boxplots');\n });\n\n it(\"should produce an error if 1D boxplot only axis is discrete\", () => {\n assert.throws(() => {\n normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: \"box-plot\",\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig);\n }, Error, 'Need a valid continuous axis for boxplots');\n });\n\n it(\"should produce correct layered specs for vertical boxplot with two quantitative axes and specify orientation with orient\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n orient: \"vertical\",\n extent: \"min-max\"\n },\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"lower_whisker_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"upper_whisker_people\"\n }\n ],\n \"groupby\": [\"age\"]\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 5}\n }\n }\n ]\n });\n });\n\n it(\"should produce correct layered specs for horizontal boxplot with two quantitative axes and specify orientation with orient\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n orient: \"horizontal\",\n extent: \"min-max\"\n },\n encoding: {\n \"y\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"x\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"lower_whisker_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"upper_whisker_people\"\n }\n ],\n \"groupby\": [\"age\"]\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"x\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"x2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"x\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"x2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"x\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"x2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"x\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 5},\n }\n }\n ]\n });\n });\n\n it(\"should produce correct layered specs for vertical boxplot with two quantitative axes and specify orientation with aggregate\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"aggregate\": \"box-plot\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"lower_whisker_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"upper_whisker_people\"\n }\n ],\n \"groupby\": [\"age\"]\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 5}\n }\n }\n ]\n });\n });\n\n it(\"should produce correct layered specs for horizontal boxplot with two quantitative axes and specify orientation with aggregate\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"y\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"x\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"aggregate\": \"box-plot\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"lower_whisker_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"upper_whisker_people\"\n }\n ],\n \"groupby\": [\"age\"]\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"x\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"x2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"x\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"x2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"x\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"x2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"x\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 5},\n }\n }\n ]\n });\n });\n\n it(\"should produce correct layered specs for vertical boxplot with min and max\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"lower_whisker_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"upper_whisker_people\"\n }\n ],\n \"groupby\": [\"age\"]\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 5}\n }\n }\n ]\n });\n });\n\n it(\"should produce correct layered specs for horizontal boxplot with min and max\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"lower_whisker_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"upper_whisker_people\"\n }\n ],\n \"groupby\": [\"age\"]\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"x2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"x2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"x2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 5},\n }\n }\n ]\n });\n });\n\n it(\"should produce correct layered specs for horizontal with no nonpositional encoding properties boxplot with min and max\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n }\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"lower_whisker_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"upper_whisker_people\"\n }\n ],\n \"groupby\": [\"age\"]\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"x2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"x2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"x2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 14}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 14}\n }\n }\n ]\n });\n });\n\n it(\"should produce correct layered specs for 1D boxplot with only x\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"x\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n }\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"lower_whisker_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"upper_whisker_people\"\n }\n ],\n \"groupby\": []\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"x2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"x2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"x\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"x2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 14}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"x\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 14}\n }\n }\n ]\n });\n });\n\n it(\"should produce correct layered specs for 1D boxplot with only y\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n type: \"box-plot\",\n extent: \"min-max\"\n },\n encoding: {\n \"y\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n }\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"lower_whisker_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"upper_whisker_people\"\n }\n ],\n \"groupby\": []\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"y\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"y\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"y\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 14}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"y\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 14}\n }\n }\n ]\n });\n });\n});\n\n\ndescribe(\"normalizeBoxIQR\", () => {\n\n it(\"should produce correct layered specs for vertical boxplot with two quantitative axes and use default orientation for a 1.5 * IQR whiskers with boxplot mark type\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: \"box-plot\",\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"min_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"max_people\"\n }\n ],\n \"groupby\": [\"age\"]\n },\n {\n calculate: 'datum.upper_box_people - datum.lower_box_people',\n as: 'iqr_people'\n },\n {\n \"calculate\": `min(datum.upper_box_people + datum.iqr_people * ${defaultConfig.box.extent}, datum.max_people)`,\n \"as\": \"upper_whisker_people\"\n },\n {\n \"calculate\": `max(datum.lower_box_people - datum.iqr_people * ${defaultConfig.box.extent}, datum.min_people)`,\n \"as\": \"lower_whisker_people\"\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 5}\n }\n }\n ]\n });\n });\n\n it(\"should produce correct layered specs for vertical boxplot with two quantitative axes and use default orientation for a 1.5 * IQR whiskers\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n \"type\": \"box-plot\",\n \"extent\": 1.5\n },\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"min_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"max_people\"\n }\n ],\n \"groupby\": [\"age\"]\n },\n {\n calculate: 'datum.upper_box_people - datum.lower_box_people',\n as: 'iqr_people'\n },\n {\n \"calculate\": \"min(datum.upper_box_people + datum.iqr_people * 1.5, datum.max_people)\",\n \"as\": \"upper_whisker_people\"\n },\n {\n \"calculate\": \"max(datum.lower_box_people - datum.iqr_people * 1.5, datum.min_people)\",\n \"as\": \"lower_whisker_people\"\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5},\n \"color\": {\"value\" : \"skyblue\"}\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 5}\n }\n }\n ]\n });\n });\n\n it(\"should produce correct layered specs for vertical IQR boxplot where color encodes the mean of the people field\", () => {\n assert.deepEqual(normalize({\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n mark: {\n \"type\": \"box-plot\",\n \"extent\": 1.5\n },\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5},\n \"color\": {\n \"aggregate\": \"mean\",\n \"field\": \"people\",\n \"type\": \"quantitative\"\n }\n }\n }, defaultConfig), {\n \"description\": \"A box plot showing median, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"q1\",\n \"field\": \"people\",\n \"as\": \"lower_box_people\"\n },\n {\n \"op\": \"q3\",\n \"field\": \"people\",\n \"as\": \"upper_box_people\"\n },\n {\n \"op\": \"median\",\n \"field\": \"people\",\n \"as\": \"mid_box_people\"\n },\n {\n \"op\": \"min\",\n \"field\": \"people\",\n \"as\": \"min_people\"\n },\n {\n \"op\": \"max\",\n \"field\": \"people\",\n \"as\": \"max_people\"\n },\n {\n \"op\": \"mean\",\n \"field\": \"people\",\n \"as\": \"mean_people\"\n }\n ],\n \"groupby\": [\"age\"]\n },\n {\n calculate: 'datum.upper_box_people - datum.lower_box_people',\n as: 'iqr_people'\n },\n {\n \"calculate\": \"min(datum.upper_box_people + datum.iqr_people * 1.5, datum.max_people)\",\n \"as\": \"upper_whisker_people\"\n },\n {\n \"calculate\": \"max(datum.lower_box_people - datum.iqr_people * 1.5, datum.min_people)\",\n \"as\": \"lower_whisker_people\"\n }\n ],\n \"layer\": [\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_whisker_people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_whisker_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'bar',\n style: 'box'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"lower_box_people\",\n \"type\": \"quantitative\"\n },\n \"y2\": {\n \"field\": \"upper_box_people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5},\n \"color\": {\n \"field\": \"mean_people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"quantitative\"},\n \"y\": {\n \"field\": \"mid_box_people\",\n \"type\": \"quantitative\"\n },\n \"color\": {\"value\": \"white\"},\n \"size\": {\"value\": 5}\n }\n }\n ]\n });\n });\n\n});\n"]} \ No newline at end of file diff --git a/build/test/compositemark/errorband.test.d.ts b/build/test/compositemark/errorband.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compositemark/errorband.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compositemark/errorband.test.js b/build/test/compositemark/errorband.test.js new file mode 100644 index 0000000000..91ab4568f7 --- /dev/null +++ b/build/test/compositemark/errorband.test.js @@ -0,0 +1,128 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { isMarkDef } from '../../src/mark'; +import { isLayerSpec, isUnitSpec, normalize } from '../../src/spec'; +import { some } from '../../src/util'; +import { defaultConfig } from '.././../src/config'; +describe('normalizeErrorBand', function () { + it('should produce correct layered specs for mean point and vertical error band', function () { + assert.deepEqual(normalize({ + "data": { + "url": "data/population.json" + }, + mark: "errorband", + encoding: { + "x": { + "field": "age", + "type": "ordinal" + }, + "y": { + "field": "people", + "type": "quantitative" + } + } + }, defaultConfig), { + "data": { + "url": "data/population.json" + }, + "transform": [ + { + "aggregate": [ + { + "op": "stderr", + "field": "people", + "as": "extent_people" + }, + { + "op": "mean", + "field": "people", + "as": "center_people" + } + ], + "groupby": [ + "age" + ] + }, + { + "calculate": "datum.center_people + datum.extent_people", + "as": "upper_people" + }, + { + "calculate": "datum.center_people - datum.extent_people", + "as": "lower_people" + } + ], + "layer": [ + { + "mark": { + "opacity": 0.3, + "type": "area", + "style": "errorband-band" + }, + "encoding": { + "y": { + "field": "lower_people", + "type": "quantitative", + "title": "people" + }, + "y2": { + "field": "upper_people", + "type": "quantitative" + }, + "x": { + "field": "age", + "type": "ordinal", + "title": "age" + } + } + } + ] + }); + }); + it('should produce correct layered specs with rect + rule, instead of area + line, in 1D error band', function () { + var outputSpec = normalize({ + "data": { "url": "data/population.json" }, + "mark": { "type": "errorband", "borders": true }, + "encoding": { "y": { "field": "people", "type": "quantitative" } } + }, defaultConfig); + var layer = isLayerSpec(outputSpec) && outputSpec.layer; + if (layer) { + assert.isTrue(some(layer, function (unitSpec) { + return isUnitSpec(unitSpec) && isMarkDef(unitSpec.mark) && + unitSpec.mark.type === "rect"; + })); + assert.isTrue(some(layer, function (unitSpec) { + return isUnitSpec(unitSpec) && isMarkDef(unitSpec.mark) && + unitSpec.mark.type === "rule"; + })); + } + else { + assert.fail(!layer, false, 'layer should be a part of the spec'); + } + }); + it('should produce correct layered specs with area + line, in 2D error band', function () { + var outputSpec = normalize({ + "data": { "url": "data/population.json" }, + "mark": { "type": "errorband", "borders": true }, + "encoding": { + "y": { "field": "people", "type": "quantitative" }, + "x": { "field": "age", "type": "ordinal" } + } + }, defaultConfig); + var layer = isLayerSpec(outputSpec) && outputSpec.layer; + if (layer) { + assert.isTrue(some(layer, function (unitSpec) { + return isUnitSpec(unitSpec) && isMarkDef(unitSpec.mark) && + unitSpec.mark.type === "area"; + })); + assert.isTrue(some(layer, function (unitSpec) { + return isUnitSpec(unitSpec) && isMarkDef(unitSpec.mark) && + unitSpec.mark.type === "line"; + })); + } + else { + assert.fail(!layer, false, 'layer should be a part of the spec'); + } + }); +}); +//# sourceMappingURL=errorband.test.js.map \ No newline at end of file diff --git a/build/test/compositemark/errorband.test.js.map b/build/test/compositemark/errorband.test.js.map new file mode 100644 index 0000000000..5aaef3b996 --- /dev/null +++ b/build/test/compositemark/errorband.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"errorband.test.js","sourceRoot":"","sources":["../../../test/compositemark/errorband.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\nimport {assert} from 'chai';\n\nimport {isMarkDef} from '../../src/mark';\nimport {isLayerSpec, isUnitSpec, normalize} from '../../src/spec';\nimport {some} from '../../src/util';\nimport {defaultConfig} from '.././../src/config';\n\ndescribe('normalizeErrorBand', () => {\n it('should produce correct layered specs for mean point and vertical error band', () => {\n assert.deepEqual(normalize({\n \"data\": {\n \"url\": \"data/population.json\"\n },\n mark: \"errorband\",\n encoding: {\n \"x\": {\n \"field\": \"age\",\n \"type\": \"ordinal\"\n },\n \"y\": {\n \"field\": \"people\",\n \"type\": \"quantitative\"\n }\n }\n }, defaultConfig), {\n \"data\": {\n \"url\": \"data/population.json\"\n },\n \"transform\": [\n {\n \"aggregate\": [\n {\n \"op\": \"stderr\",\n \"field\": \"people\",\n \"as\": \"extent_people\"\n },\n {\n \"op\": \"mean\",\n \"field\": \"people\",\n \"as\": \"center_people\"\n }\n ],\n \"groupby\": [\n \"age\"\n ]\n },\n {\n \"calculate\": \"datum.center_people + datum.extent_people\",\n \"as\": \"upper_people\"\n },\n {\n \"calculate\": \"datum.center_people - datum.extent_people\",\n \"as\": \"lower_people\"\n }\n ],\n \"layer\": [\n {\n \"mark\": {\n \"opacity\": 0.3,\n \"type\": \"area\",\n \"style\": \"errorband-band\"\n },\n \"encoding\": {\n \"y\": {\n \"field\": \"lower_people\",\n \"type\": \"quantitative\",\n \"title\": \"people\"\n },\n \"y2\": {\n \"field\": \"upper_people\",\n \"type\": \"quantitative\"\n },\n \"x\": {\n \"field\": \"age\",\n \"type\": \"ordinal\",\n \"title\": \"age\"\n }\n }\n }\n ]\n });\n });\n\n it('should produce correct layered specs with rect + rule, instead of area + line, in 1D error band', () => {\n const outputSpec = normalize({\n \"data\": {\"url\": \"data/population.json\"},\n \"mark\": {\"type\": \"errorband\", \"borders\": true},\n \"encoding\": {\"y\": {\"field\": \"people\", \"type\": \"quantitative\"}}\n }, defaultConfig);\n\n const layer = isLayerSpec(outputSpec) && outputSpec.layer;\n if (layer) {\n assert.isTrue(some(layer, (unitSpec) => {\n return isUnitSpec(unitSpec) && isMarkDef(unitSpec.mark) &&\n unitSpec.mark.type === \"rect\";\n }));\n assert.isTrue(some(layer, (unitSpec) => {\n return isUnitSpec(unitSpec) && isMarkDef(unitSpec.mark) &&\n unitSpec.mark.type === \"rule\";\n }));\n } else {\n assert.fail(!layer, false, 'layer should be a part of the spec');\n }\n });\n\n it('should produce correct layered specs with area + line, in 2D error band', () => {\n const outputSpec = normalize({\n \"data\": {\"url\": \"data/population.json\"},\n \"mark\": {\"type\": \"errorband\", \"borders\": true},\n \"encoding\": {\n \"y\": {\"field\": \"people\", \"type\": \"quantitative\"},\n \"x\": {\"field\": \"age\", \"type\": \"ordinal\"}\n }\n }, defaultConfig);\n\n const layer = isLayerSpec(outputSpec) && outputSpec.layer;\n if (layer) {\n assert.isTrue(some(layer, (unitSpec) => {\n return isUnitSpec(unitSpec) && isMarkDef(unitSpec.mark) &&\n unitSpec.mark.type === \"area\";\n }));\n assert.isTrue(some(layer, (unitSpec) => {\n return isUnitSpec(unitSpec) && isMarkDef(unitSpec.mark) &&\n unitSpec.mark.type === \"line\";\n }));\n } else {\n assert.fail(!layer, false, 'layer should be a part of the spec');\n }\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/compositemark/errorbar.test.d.ts b/build/test/compositemark/errorbar.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/compositemark/errorbar.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/compositemark/errorbar.test.js b/build/test/compositemark/errorbar.test.js new file mode 100644 index 0000000000..2b820c2387 --- /dev/null +++ b/build/test/compositemark/errorbar.test.js @@ -0,0 +1,92 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { normalize } from '../../src/spec'; +import { defaultConfig } from '.././../src/config'; +describe("normalizeErrorBar", function () { + it("should produce correct layered specs for horizontal error bar", function () { + assert.deepEqual(normalize({ + "data": { "url": "data/population.json" }, + mark: "error-bar", + encoding: { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "x2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + }, + "size": { "value": 5 } + } + }, defaultConfig), { + "data": { "url": "data/population.json" }, + "layer": [ + { + "mark": "rule", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "x2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + } + } + }, + { + "mark": "tick", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 } + } + }, + { + "mark": "tick", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "aggregate": "max", + "field": "people", + "type": "quantitative", + }, + "size": { "value": 5 } + } + } + ] + }); + }); + it("should throw error when missing x2 and y2", function () { + assert.throws(function () { + normalize({ + "data": { "url": "data/population.json" }, + mark: "error-bar", + encoding: { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 } + } + }, defaultConfig); + }, Error, 'Neither x2 or y2 provided'); + }); +}); +//# sourceMappingURL=errorbar.test.js.map \ No newline at end of file diff --git a/build/test/compositemark/errorbar.test.js.map b/build/test/compositemark/errorbar.test.js.map new file mode 100644 index 0000000000..a7d1b08b6f --- /dev/null +++ b/build/test/compositemark/errorbar.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"errorbar.test.js","sourceRoot":"","sources":["../../../test/compositemark/errorbar.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\nimport {assert} from 'chai';\n\nimport {normalize} from '../../src/spec';\nimport {defaultConfig} from '.././../src/config';\n\n\ndescribe(\"normalizeErrorBar\", () => {\n\n it(\"should produce correct layered specs for horizontal error bar\", () => {\n assert.deepEqual(normalize({\n \"data\": {\"url\": \"data/population.json\"},\n mark: \"error-bar\",\n encoding: {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"aggregate\": \"min\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"x2\": {\n \"aggregate\": \"max\",\n \"field\": \"people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5}\n }\n }, defaultConfig), {\n \"data\": {\"url\": \"data/population.json\"},\n \"layer\": [\n {\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"aggregate\": \"min\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"x2\": {\n \"aggregate\": \"max\",\n \"field\": \"people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n \"mark\": \"tick\",\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"aggregate\": \"min\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5}\n }\n },\n {\n \"mark\": \"tick\",\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"aggregate\": \"max\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n // \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5}\n }\n }\n ]\n });\n });\n\n it(\"should throw error when missing x2 and y2\", () => {\n assert.throws(() => {\n normalize({\n \"data\": {\"url\": \"data/population.json\"},\n mark: \"error-bar\",\n encoding: {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\n \"aggregate\": \"min\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5}\n }\n }, defaultConfig);\n }, Error, 'Neither x2 or y2 provided');\n });\n });\n"]} \ No newline at end of file diff --git a/build/test/config.test.d.ts b/build/test/config.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/config.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/config.test.js b/build/test/config.test.js new file mode 100644 index 0000000000..2548856681 --- /dev/null +++ b/build/test/config.test.js @@ -0,0 +1,44 @@ +import * as tslib_1 from "tslib"; +import { assert } from 'chai'; +import { defaultConfig, stripAndRedirectConfig } from '../src/config'; +import { PRIMITIVE_MARKS } from '../src/mark'; +import { duplicate } from '../src/util'; +describe('config', function () { + describe('stripAndRedirectConfig', function () { + var config = tslib_1.__assign({}, defaultConfig, { mark: tslib_1.__assign({}, defaultConfig.mark, { opacity: 0.3 }), bar: tslib_1.__assign({ opacity: 0.5 }, defaultConfig.bar), view: { + fill: '#eee' + }, title: { + color: 'red', + fontWeight: 'bold' + } }); + var copy = duplicate(config); + var output = stripAndRedirectConfig(config); + it('should not cause side-effect to the input', function () { + assert.deepEqual(config, copy); + }); + it('should remove VL only mark config but keep Vega mark config', function () { + assert.isUndefined(output.mark.color); + assert.equal(output.mark.opacity, 0.3); + }); + it('should redirect mark config to style and remove VL only mark-specific config', function () { + for (var _i = 0, PRIMITIVE_MARKS_1 = PRIMITIVE_MARKS; _i < PRIMITIVE_MARKS_1.length; _i++) { + var mark = PRIMITIVE_MARKS_1[_i]; + assert.isUndefined(output[mark], mark + " config should be redirected"); + } + assert.isUndefined(output.style.bar['binSpacing'], "VL only Bar config should be removed"); + assert.isUndefined(output.style.cell['width'], "VL only cell config should be removed"); + assert.isUndefined(output.style.cell['height'], "VL only cell config should be removed"); + assert.equal(output.style.cell['fill'], '#eee', "config.view should be redirect to config.style.cell"); + assert.deepEqual(output.style.bar.opacity, 0.5, 'Bar config should be redirected to config.style.bar'); + }); + it('should redirect config.title to config.style.group-title and rename color to fill', function () { + assert.deepEqual(output.title, undefined); + assert.deepEqual(output.style['group-title'].fontWeight, 'bold'); + assert.deepEqual(output.style['group-title'].fill, 'red'); + }); + it('should remove empty config object', function () { + assert.isUndefined(output.axisTop); + }); + }); +}); +//# sourceMappingURL=config.test.js.map \ No newline at end of file diff --git a/build/test/config.test.js.map b/build/test/config.test.js.map new file mode 100644 index 0000000000..c59dcb8167 --- /dev/null +++ b/build/test/config.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../test/config.test.ts"],"names":[],"mappings":";AACA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAS,aAAa,EAAE,sBAAsB,EAAC,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAC,eAAe,EAAC,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAEtC,QAAQ,CAAC,QAAQ,EAAE;IACjB,QAAQ,CAAC,wBAAwB,EAAE;QACjC,IAAM,MAAM,wBACP,aAAa,IAChB,IAAI,uBACC,aAAa,CAAC,IAAI,IACrB,OAAO,EAAE,GAAG,KAEd,GAAG,qBACD,OAAO,EAAE,GAAG,IACT,aAAa,CAAC,GAAG,GAEtB,IAAI,EAAE;gBACJ,IAAI,EAAE,MAAM;aACb,EACD,KAAK,EAAE;gBACL,KAAK,EAAE,KAAK;gBACZ,UAAU,EAAE,MAAM;aACnB,GACF,CAAC;QACF,IAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAE9C,EAAE,CAAC,2CAA2C,EAAE;YAC9C,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6DAA6D,EAAE;YAChE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8EAA8E,EAAE;YACjF,KAAmB,UAAe,EAAf,mCAAe,EAAf,6BAAe,EAAf,IAAe,EAAE;gBAA/B,IAAM,IAAI,wBAAA;gBACb,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAK,IAAI,iCAA8B,CAAC,CAAC;aACzE;YACD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,sCAAsC,CAAC,CAAC;YAC3F,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,uCAAuC,CAAC,CAAC;YACxF,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,uCAAuC,CAAC,CAAC;YACzF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,qDAAqD,CAAC,CAAC;YAEvG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,qDAAqD,CAAC,CAAC;QACzG,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mFAAmF,EAAE;YACtF,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAC1C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACjE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE;YACtC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["\nimport {assert} from 'chai';\nimport {Config, defaultConfig, stripAndRedirectConfig} from '../src/config';\nimport {PRIMITIVE_MARKS} from '../src/mark';\nimport {duplicate} from '../src/util';\n\ndescribe('config', () => {\n describe('stripAndRedirectConfig', () => {\n const config: Config = {\n ...defaultConfig,\n mark: {\n ...defaultConfig.mark,\n opacity: 0.3,\n },\n bar: {\n opacity: 0.5,\n ...defaultConfig.bar\n },\n view: {\n fill: '#eee'\n },\n title: {\n color: 'red',\n fontWeight: 'bold'\n }\n };\n const copy = duplicate(config);\n const output = stripAndRedirectConfig(config);\n\n it('should not cause side-effect to the input', () => {\n assert.deepEqual(config, copy);\n });\n\n it('should remove VL only mark config but keep Vega mark config', () => {\n assert.isUndefined(output.mark.color);\n assert.equal(output.mark.opacity, 0.3);\n });\n\n it('should redirect mark config to style and remove VL only mark-specific config', () => {\n for (const mark of PRIMITIVE_MARKS) {\n assert.isUndefined(output[mark], `${mark} config should be redirected`);\n }\n assert.isUndefined(output.style.bar['binSpacing'], `VL only Bar config should be removed`);\n assert.isUndefined(output.style.cell['width'], `VL only cell config should be removed`);\n assert.isUndefined(output.style.cell['height'], `VL only cell config should be removed`);\n assert.equal(output.style.cell['fill'], '#eee', `config.view should be redirect to config.style.cell`);\n\n assert.deepEqual(output.style.bar.opacity, 0.5, 'Bar config should be redirected to config.style.bar');\n });\n\n it('should redirect config.title to config.style.group-title and rename color to fill', () => {\n assert.deepEqual(output.title, undefined);\n assert.deepEqual(output.style['group-title'].fontWeight, 'bold');\n assert.deepEqual(output.style['group-title'].fill, 'red');\n });\n\n it('should remove empty config object', () => {\n assert.isUndefined(output.axisTop);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/datetime.test.d.ts b/build/test/datetime.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/datetime.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/datetime.test.js b/build/test/datetime.test.js new file mode 100644 index 0000000000..47f876d366 --- /dev/null +++ b/build/test/datetime.test.js @@ -0,0 +1,96 @@ +import { assert } from 'chai'; +import { dateTimeExpr } from '../src/datetime'; +import * as log from '../src/log'; +describe('datetime', function () { + describe('dateTimeExpr', function () { + it('should drop day if day is combined with year/month/date', log.wrap(function (localLogger) { + var d = { + year: 2007, + day: 'monday' + }; + var expr = dateTimeExpr(d, true); + assert.equal(expr, 'datetime(2007, 0, 1, 0, 0, 0, 0)'); + assert.equal(localLogger.warns[0], log.message.droppedDay(d)); + })); + it('should normalize numeric quarter correctly', function () { + var expr = dateTimeExpr({ + quarter: 2 + }, true); + assert.equal(expr, 'datetime(0, 1*3, 1, 0, 0, 0, 0)'); + }); + it('should log warning for quarter > 4', log.wrap(function (localLogger) { + assert.equal(dateTimeExpr({ + quarter: 5 + }, true), 'datetime(0, 4*3, 1, 0, 0, 0, 0)'); + assert.equal(localLogger.warns[0], log.message.invalidTimeUnit('quarter', 5)); + })); + it('should throw error for invalid quarter', function () { + assert.throws(function () { + dateTimeExpr({ quarter: 'Q' }, true); + }, Error, log.message.invalidTimeUnit('quarter', 'Q')); + }); + it('should normalize numeric month correctly', function () { + var expr = dateTimeExpr({ + month: 1 + }, true); + assert.equal(expr, 'datetime(0, 0, 1, 0, 0, 0, 0)'); + }); + it('should normalize month name correctly', function () { + assert.equal(dateTimeExpr({ + month: 'January' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + assert.equal(dateTimeExpr({ + month: 'january' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + assert.equal(dateTimeExpr({ + month: 'Jan' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + assert.equal(dateTimeExpr({ + month: 'jan' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + }); + it('should throw error for invalid month', function () { + assert.throws(function () { + dateTimeExpr({ month: 'J' }, true); + }, Error, log.message.invalidTimeUnit('month', 'J')); + }); + it('should normalize numeric day (of week) correctly', function () { + assert.equal(dateTimeExpr({ + day: 0 + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + assert.equal(dateTimeExpr({ + day: 7 + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + }); + it('should normalize day name correctly and use year 2006 to ensure correct', function () { + assert.equal(dateTimeExpr({ + day: 'Sunday' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + assert.equal(dateTimeExpr({ + day: 'sunday' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + assert.equal(dateTimeExpr({ + day: 'Sun' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + assert.equal(dateTimeExpr({ + day: 'sun' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + }); + it('should throw error for invalid day', function () { + assert.throws(function () { + dateTimeExpr({ day: 'S' }, true); + }, Error, log.message.invalidTimeUnit('day', 'S')); + }); + it('should use utc expression if utc is specified', function () { + var d = { + year: 2007, + day: 'monday', + utc: true + }; + var expr = dateTimeExpr(d, true); + assert.equal(expr, 'utc(2007, 0, 1, 0, 0, 0, 0)'); + }); + // Note: Other part of coverage handled by timeUnit.fieldExpr's test + }); +}); +//# sourceMappingURL=datetime.test.js.map \ No newline at end of file diff --git a/build/test/datetime.test.js.map b/build/test/datetime.test.js.map new file mode 100644 index 0000000000..ecba735459 --- /dev/null +++ b/build/test/datetime.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"datetime.test.js","sourceRoot":"","sources":["../../test/datetime.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {dateTimeExpr} from '../src/datetime';\nimport * as log from '../src/log';\n\ndescribe('datetime', () => {\n describe('dateTimeExpr', () => {\n it('should drop day if day is combined with year/month/date', log.wrap((localLogger) => {\n const d = {\n year: 2007,\n day: 'monday'\n };\n const expr = dateTimeExpr(d, true);\n assert.equal(expr, 'datetime(2007, 0, 1, 0, 0, 0, 0)');\n assert.equal(localLogger.warns[0], log.message.droppedDay(d));\n }));\n\n it('should normalize numeric quarter correctly', () => {\n const expr = dateTimeExpr({\n quarter: 2\n }, true);\n assert.equal(expr, 'datetime(0, 1*3, 1, 0, 0, 0, 0)');\n });\n\n it('should log warning for quarter > 4', log.wrap((localLogger) => {\n assert.equal(dateTimeExpr({\n quarter: 5\n }, true), 'datetime(0, 4*3, 1, 0, 0, 0, 0)');\n assert.equal(localLogger.warns[0], log.message.invalidTimeUnit('quarter', 5));\n }));\n\n it('should throw error for invalid quarter', () => {\n assert.throws(() => {\n dateTimeExpr({quarter: 'Q'}, true);\n }, Error, log.message.invalidTimeUnit('quarter', 'Q'));\n });\n\n it('should normalize numeric month correctly', () => {\n const expr = dateTimeExpr({\n month: 1\n }, true);\n assert.equal(expr, 'datetime(0, 0, 1, 0, 0, 0, 0)');\n });\n\n it('should normalize month name correctly', () => {\n assert.equal(dateTimeExpr({\n month: 'January'\n }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)');\n assert.equal(dateTimeExpr({\n month: 'january'\n }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)');\n assert.equal(dateTimeExpr({\n month: 'Jan'\n }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)');\n assert.equal(dateTimeExpr({\n month: 'jan'\n }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)');\n });\n\n it('should throw error for invalid month', () => {\n assert.throws(() => {\n dateTimeExpr({month: 'J'}, true);\n }, Error, log.message.invalidTimeUnit('month', 'J'));\n });\n\n it('should normalize numeric day (of week) correctly', () => {\n assert.equal(dateTimeExpr({\n day: 0\n }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)');\n assert.equal(dateTimeExpr({\n day: 7\n }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)');\n });\n\n it('should normalize day name correctly and use year 2006 to ensure correct', () => {\n assert.equal(dateTimeExpr({\n day: 'Sunday'\n }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)');\n assert.equal(dateTimeExpr({\n day: 'sunday'\n }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)');\n assert.equal(dateTimeExpr({\n day: 'Sun'\n }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)');\n assert.equal(dateTimeExpr({\n day: 'sun'\n }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)');\n });\n\n it('should throw error for invalid day', () => {\n assert.throws(() => {\n dateTimeExpr({day: 'S'}, true);\n }, Error, log.message.invalidTimeUnit('day', 'S'));\n });\n\n it('should use utc expression if utc is specified', () => {\n const d = {\n year: 2007,\n day: 'monday',\n utc: true\n };\n const expr = dateTimeExpr(d, true);\n assert.equal(expr, 'utc(2007, 0, 1, 0, 0, 0, 0)');\n });\n\n // Note: Other part of coverage handled by timeUnit.fieldExpr's test\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/encoding.test.d.ts b/build/test/encoding.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/encoding.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/encoding.test.js b/build/test/encoding.test.js new file mode 100644 index 0000000000..3b2d0fd0ad --- /dev/null +++ b/build/test/encoding.test.js @@ -0,0 +1,42 @@ +import { assert } from 'chai'; +import { normalizeEncoding } from '../src/encoding'; +import * as log from '../src/log'; +describe('axis', function () { + describe('normalizeEncoding', function () { + it('should convert lat and long type to channels', function () { + var encoding = normalizeEncoding({ + x: { field: 'a', type: 'longitude' }, + y: { field: 'b', type: 'latitude' }, + x2: { field: 'a2', type: 'longitude' }, + y2: { field: 'b2', type: 'latitude' } + }, 'rule'); + assert.deepEqual(encoding, { + longitude: { field: 'a', type: 'quantitative' }, + latitude: { field: 'b', type: 'quantitative' }, + longitude2: { field: 'a2', type: 'quantitative' }, + latitude2: { field: 'b2', type: 'quantitative' } + }); + }); + it('should drop color channel if fill is specified', log.wrap(function (logger) { + var encoding = normalizeEncoding({ + color: { field: 'a', type: 'quantitative' }, + fill: { field: 'b', type: 'quantitative' } + }, 'rule'); + assert.deepEqual(encoding, { + fill: { field: 'b', type: 'quantitative' } + }); + assert.equal(logger.warns[0], log.message.droppingColor('encoding', { fill: true })); + })); + it('should drop color channel if stroke is specified', log.wrap(function (logger) { + var encoding = normalizeEncoding({ + color: { field: 'a', type: 'quantitative' }, + stroke: { field: 'b', type: 'quantitative' } + }, 'rule'); + assert.deepEqual(encoding, { + stroke: { field: 'b', type: 'quantitative' } + }); + assert.equal(logger.warns[0], log.message.droppingColor('encoding', { stroke: true })); + })); + }); +}); +//# sourceMappingURL=encoding.test.js.map \ No newline at end of file diff --git a/build/test/encoding.test.js.map b/build/test/encoding.test.js.map new file mode 100644 index 0000000000..62486ebaa5 --- /dev/null +++ b/build/test/encoding.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"encoding.test.js","sourceRoot":"","sources":["../../test/encoding.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAElC,QAAQ,CAAC,MAAM,EAAE;IACf,QAAQ,CAAC,mBAAmB,EAAE;QAC5B,EAAE,CAAC,8CAA8C,EAAE;YACjD,IAAM,QAAQ,GAAG,iBAAiB,CAAC;gBACjC,CAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAC;gBAClC,CAAC,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAC;gBACjC,EAAE,EAAE,EAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAC;gBACpC,EAAE,EAAE,EAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAC;aACpC,EAAE,MAAM,CAAC,CAAC;YAEX,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE;gBACzB,SAAS,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC;gBAC7C,QAAQ,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC;gBAC5C,UAAU,EAAE,EAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAC;gBAC/C,SAAS,EAAE,EAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAC;aAC/C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,CAAC,IAAI,CAAC,UAAC,MAAM;YACnE,IAAM,QAAQ,GAAG,iBAAiB,CAAC;gBACjC,KAAK,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC;gBACzC,IAAI,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC;aACzC,EAAE,MAAM,CAAC,CAAC;YAEX,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE;gBACzB,IAAI,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC;aACzC,CAAC,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,UAAU,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC;QACrF,CAAC,CAAC,CAAC,CAAC;QAEJ,EAAE,CAAC,kDAAkD,EAAE,GAAG,CAAC,IAAI,CAAC,UAAC,MAAM;YACrE,IAAM,QAAQ,GAAG,iBAAiB,CAAC;gBACjC,KAAK,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC;gBACzC,MAAM,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC;aAC3C,EAAE,MAAM,CAAC,CAAC;YAEX,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE;gBACzB,MAAM,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAC;aAC3C,CAAC,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,UAAU,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC;QACvF,CAAC,CAAC,CAAC,CAAC;IACN,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\nimport {normalizeEncoding} from '../src/encoding';\nimport * as log from '../src/log';\n\ndescribe('axis', () => {\n describe('normalizeEncoding', () => {\n it('should convert lat and long type to channels', () => {\n const encoding = normalizeEncoding({\n x: {field: 'a', type: 'longitude'},\n y: {field: 'b', type: 'latitude'},\n x2: {field: 'a2', type: 'longitude'},\n y2: {field: 'b2', type: 'latitude'}\n }, 'rule');\n\n assert.deepEqual(encoding, {\n longitude: {field: 'a', type: 'quantitative'},\n latitude: {field: 'b', type: 'quantitative'},\n longitude2: {field: 'a2', type: 'quantitative'},\n latitude2: {field: 'b2', type: 'quantitative'}\n });\n });\n\n it('should drop color channel if fill is specified', log.wrap((logger) => {\n const encoding = normalizeEncoding({\n color: {field: 'a', type: 'quantitative'},\n fill: {field: 'b', type: 'quantitative'}\n }, 'rule');\n\n assert.deepEqual(encoding, {\n fill: {field: 'b', type: 'quantitative'}\n });\n assert.equal(logger.warns[0], log.message.droppingColor('encoding', {fill: true}));\n }));\n\n it('should drop color channel if stroke is specified', log.wrap((logger) => {\n const encoding = normalizeEncoding({\n color: {field: 'a', type: 'quantitative'},\n stroke: {field: 'b', type: 'quantitative'}\n }, 'rule');\n\n assert.deepEqual(encoding, {\n stroke: {field: 'b', type: 'quantitative'}\n });\n assert.equal(logger.warns[0], log.message.droppingColor('encoding', {stroke: true}));\n }));\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/fielddef.test.d.ts b/build/test/fielddef.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/fielddef.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/fielddef.test.js b/build/test/fielddef.test.js new file mode 100644 index 0000000000..02a9436c94 --- /dev/null +++ b/build/test/fielddef.test.js @@ -0,0 +1,182 @@ +import { assert } from 'chai'; +import { COUNTING_OPS } from '../src/aggregate'; +import { channelCompatibility, defaultType, normalize, title, vgField } from '../src/fielddef'; +import * as log from '../src/log'; +import { TimeUnit } from '../src/timeunit'; +import { QUANTITATIVE, TEMPORAL } from '../src/type'; +describe('fieldDef', function () { + describe('vgField()', function () { + it('should access flattened fields', function () { + assert.deepEqual(vgField({ field: 'foo.bar\\.baz' }), 'foo\\.bar\\.baz'); + }); + it('should access flattened fields in expression', function () { + assert.deepEqual(vgField({ field: 'foo.bar\\.baz' }, { expr: 'datum' }), 'datum["foo.bar.baz"]'); + }); + }); + describe('defaultType()', function () { + it('should return temporal if there is timeUnit', function () { + assert.equal(defaultType({ timeUnit: 'month', field: 'a' }, 'x'), 'temporal'); + }); + it('should return quantitative if there is bin', function () { + assert.equal(defaultType({ bin: true, field: 'a' }, 'x'), 'quantitative'); + }); + it('should return quantitative for a channel that supports measure', function () { + for (var _i = 0, _a = ['x', 'y', 'size', 'opacity', 'order']; _i < _a.length; _i++) { + var c = _a[_i]; + assert.equal(defaultType({ field: 'a' }, c), 'quantitative', c); + } + }); + it('should return nominal for a channel that does not support measure', function () { + for (var _i = 0, _a = ['color', 'shape', 'row', 'column']; _i < _a.length; _i++) { + var c = _a[_i]; + assert.equal(defaultType({ field: 'a' }, c), 'nominal', c); + } + }); + }); + describe('normalize()', function () { + it('should convert primitive type to value def', log.wrap(function (localLogger) { + assert.deepEqual(normalize(5, 'x'), { value: 5 }); + assert.equal(localLogger.warns.length, 1); + })); + it('should return fieldDef with full type name.', function () { + var fieldDef = { field: 'a', type: 'q' }; + assert.deepEqual(normalize(fieldDef, 'x'), { field: 'a', type: 'quantitative' }); + }); + it('normalizes yearmonthday to become yearmonthdate.', log.wrap(function (localLogger) { + var fieldDef = { + timeUnit: 'yearmonthday', + field: 'a', + type: 'temporal' + }; + assert.deepEqual(normalize(fieldDef, 'x'), { timeUnit: 'yearmonthdate', field: 'a', type: 'temporal' }); + assert.equal(localLogger.warns[0], log.message.dayReplacedWithDate('yearmonthday')); + })); + it('should replace other type with quantitative for a field with counting aggregate.', log.wrap(function (localLogger) { + for (var _i = 0, COUNTING_OPS_1 = COUNTING_OPS; _i < COUNTING_OPS_1.length; _i++) { + var aggregate = COUNTING_OPS_1[_i]; + var fieldDef = { aggregate: aggregate, field: 'a', type: 'nominal' }; + assert.deepEqual(normalize(fieldDef, 'x'), { aggregate: aggregate, field: 'a', type: 'quantitative' }); + } + assert.equal(localLogger.warns.length, 4); + })); + it('should return fieldDef with default type and throw warning if type is missing.', log.wrap(function (localLogger) { + var fieldDef = { field: 'a' }; + assert.deepEqual(normalize(fieldDef, 'x'), { field: 'a', type: 'quantitative' }); + assert.equal(localLogger.warns[0], log.message.emptyOrInvalidFieldType(undefined, 'x', 'quantitative')); + })); + it('should drop invalid aggregate ops and throw warning.', log.wrap(function (localLogger) { + var fieldDef = { aggregate: 'box-plot', field: 'a', type: 'quantitative' }; + assert.deepEqual(normalize(fieldDef, 'x'), { field: 'a', type: 'quantitative' }); + assert.equal(localLogger.warns[0], log.message.invalidAggregate('box-plot')); + })); + }); + describe('channelCompatability', function () { + describe('row/column', function () { + it('is incompatible with continuous field', function () { + for (var _i = 0, _a = ['row', 'column']; _i < _a.length; _i++) { + var channel = _a[_i]; + assert(!channelCompatibility({ field: 'a', type: 'quantitative' }, channel).compatible); + } + }); + it('is compatible with discrete field', function () { + for (var _i = 0, _a = ['row', 'column']; _i < _a.length; _i++) { + var channel = _a[_i]; + assert(channelCompatibility({ field: 'a', type: 'nominal' }, channel).compatible); + } + }); + }); + describe('x/y/color/text/detail', function () { + it('is compatible with continuous field', function () { + for (var _i = 0, _a = ['x', 'y', 'color', 'text', 'detail']; _i < _a.length; _i++) { + var channel = _a[_i]; + assert(channelCompatibility({ field: 'a', type: 'quantitative' }, channel).compatible); + } + }); + it('is compatible with discrete field', function () { + for (var _i = 0, _a = ['x', 'y', 'color', 'text', 'detail']; _i < _a.length; _i++) { + var channel = _a[_i]; + assert(channelCompatibility({ field: 'a', type: 'nominal' }, channel).compatible); + } + }); + }); + describe('opacity/size/x2/y2', function () { + it('is compatible with continuous field', function () { + for (var _i = 0, _a = ['opacity', 'size', 'x2', 'y2']; _i < _a.length; _i++) { + var channel = _a[_i]; + assert(channelCompatibility({ field: 'a', type: 'quantitative' }, channel).compatible); + } + }); + it('is compatible with binned field', function () { + for (var _i = 0, _a = ['opacity', 'size', 'x2', 'y2']; _i < _a.length; _i++) { + var channel = _a[_i]; + assert(channelCompatibility({ bin: true, field: 'a', type: 'quantitative' }, channel).compatible); + } + }); + it('is incompatible with nominal field', function () { + for (var _i = 0, _a = ['opacity', 'size', 'x2', 'y2']; _i < _a.length; _i++) { + var channel = _a[_i]; + assert(!channelCompatibility({ field: 'a', type: 'nominal' }, channel).compatible); + } + }); + }); + describe('shape', function () { + it('is compatible with nominal field', function () { + assert(channelCompatibility({ field: 'a', type: 'nominal' }, 'shape').compatible); + }); + it('is incompatible with ordinal field', function () { + assert(!channelCompatibility({ field: 'a', type: 'ordinal' }, 'shape').compatible); + }); + it('is incompatible with quantitative field', function () { + assert(!channelCompatibility({ field: 'a', type: 'quantitative' }, 'shape').compatible); + }); + }); + describe('order', function () { + it('is incompatible with nominal field', function () { + assert(!channelCompatibility({ field: 'a', type: 'nominal' }, 'order').compatible); + }); + it('is compatible with ordinal field', function () { + assert(channelCompatibility({ field: 'a', type: 'ordinal' }, 'order').compatible); + }); + it('is compatible with quantitative field', function () { + assert(channelCompatibility({ field: 'a', type: 'quantitative' }, 'order').compatible); + }); + }); + }); + describe('title()', function () { + it('should return correct title for aggregate', function () { + assert.equal(title({ field: 'f', aggregate: 'mean' }, {}), 'Mean of f'); + }); + it('should return correct title for count', function () { + assert.equal(title({ aggregate: 'count' }, { countTitle: 'baz!' }), 'baz!'); + }); + it('should return correct title for bin', function () { + var fieldDef = { field: 'f', type: QUANTITATIVE, bin: true }; + assert.equal(title(fieldDef, {}), 'f (binned)'); + }); + it('should return correct title for bin', function () { + var fieldDef = { field: 'f', type: QUANTITATIVE, bin: true }; + assert.equal(title(fieldDef, { fieldTitle: 'functional' }), 'BIN(f)'); + }); + it('should return correct title for timeUnit', function () { + var fieldDef = { field: 'f', type: TEMPORAL, timeUnit: TimeUnit.MONTH }; + assert.equal(title(fieldDef, {}), 'f (month)'); + }); + it('should return correct title for timeUnit', function () { + var fieldDef = { field: 'f', type: TEMPORAL, timeUnit: TimeUnit.YEARMONTHDATE }; + assert.equal(title(fieldDef, {}), 'f (year-month-date)'); + }); + it('should return correct title for timeUnit', function () { + var fieldDef = { field: 'f', type: TEMPORAL, timeUnit: TimeUnit.DAY }; + assert.equal(title(fieldDef, {}), 'f (day)'); + }); + it('should return correct title for timeUnit', function () { + var fieldDef = { field: 'f', type: TEMPORAL, timeUnit: TimeUnit.YEARQUARTER }; + assert.equal(title(fieldDef, {}), 'f (year-quarter)'); + }); + it('should return correct title for raw field', function () { + var fieldDef = { field: 'f', type: TEMPORAL }; + assert.equal(title(fieldDef, {}), 'f'); + }); + }); +}); +//# sourceMappingURL=fielddef.test.js.map \ No newline at end of file diff --git a/build/test/fielddef.test.js.map b/build/test/fielddef.test.js.map new file mode 100644 index 0000000000..bf4997f8f5 --- /dev/null +++ b/build/test/fielddef.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fielddef.test.js","sourceRoot":"","sources":["../../test/fielddef.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\n\nimport {COUNTING_OPS} from '../src/aggregate';\nimport {Channel} from '../src/channel';\nimport {channelCompatibility, ChannelDef, defaultType, FieldDef, normalize, title, vgField} from '../src/fielddef';\nimport * as log from '../src/log';\nimport {TimeUnit} from '../src/timeunit';\nimport {QUANTITATIVE, TEMPORAL} from '../src/type';\n\ndescribe('fieldDef', () => {\n describe('vgField()', () => {\n it ('should access flattened fields', () => {\n assert.deepEqual(vgField({field: 'foo.bar\\\\.baz'}), 'foo\\\\.bar\\\\.baz');\n });\n\n it ('should access flattened fields in expression', () => {\n assert.deepEqual(vgField({field: 'foo.bar\\\\.baz'}, {expr: 'datum'}), 'datum[\"foo.bar.baz\"]');\n });\n });\n\n describe('defaultType()', () => {\n it('should return temporal if there is timeUnit', () => {\n assert.equal(defaultType({timeUnit: 'month', field: 'a'} as FieldDef, 'x'), 'temporal');\n });\n\n it('should return quantitative if there is bin', () => {\n assert.equal(defaultType({bin: true, field: 'a'} as FieldDef, 'x'), 'quantitative');\n });\n\n it('should return quantitative for a channel that supports measure', () => {\n for (const c of ['x', 'y', 'size', 'opacity', 'order'] as Channel[]) {\n assert.equal(defaultType({field: 'a'} as FieldDef, c), 'quantitative', c);\n }\n });\n\n it('should return nominal for a channel that does not support measure', () => {\n for (const c of ['color', 'shape', 'row', 'column'] as Channel[]) {\n assert.equal(defaultType({field: 'a'} as FieldDef, c), 'nominal', c);\n }\n });\n });\n\n describe('normalize()', () => {\n it('should convert primitive type to value def', log.wrap((localLogger) => {\n assert.deepEqual>(normalize(5 as any, 'x'), {value: 5});\n assert.equal(localLogger.warns.length, 1);\n }));\n\n it('should return fieldDef with full type name.', () => {\n const fieldDef: FieldDef = {field: 'a', type: 'q' as any};\n assert.deepEqual>(normalize(fieldDef, 'x'), {field: 'a', type: 'quantitative'});\n });\n\n it('normalizes yearmonthday to become yearmonthdate.', log.wrap((localLogger) => {\n const fieldDef: FieldDef = {\n timeUnit: 'yearmonthday' as TimeUnit, // Need to cast here as this is intentionally wrong\n field: 'a',\n type: 'temporal'\n };\n assert.deepEqual>(normalize(fieldDef, 'x'), {timeUnit: 'yearmonthdate', field: 'a', type: 'temporal'});\n assert.equal(localLogger.warns[0], log.message.dayReplacedWithDate('yearmonthday'));\n }));\n\n it('should replace other type with quantitative for a field with counting aggregate.', log.wrap((localLogger) => {\n for (const aggregate of COUNTING_OPS) {\n const fieldDef: FieldDef = {aggregate, field: 'a', type: 'nominal'};\n assert.deepEqual>(normalize(fieldDef, 'x'), {aggregate, field: 'a', type: 'quantitative'});\n }\n assert.equal(localLogger.warns.length, 4);\n }));\n\n it('should return fieldDef with default type and throw warning if type is missing.', log.wrap((localLogger) => {\n const fieldDef = {field: 'a'} as FieldDef;\n assert.deepEqual>(normalize(fieldDef, 'x'), {field: 'a', type: 'quantitative'});\n assert.equal(localLogger.warns[0], log.message.emptyOrInvalidFieldType(undefined, 'x', 'quantitative'));\n }));\n\n it('should drop invalid aggregate ops and throw warning.', log.wrap((localLogger) => {\n const fieldDef: FieldDef = {aggregate: 'box-plot', field: 'a', type: 'quantitative'};\n assert.deepEqual>(normalize(fieldDef, 'x'), {field: 'a', type: 'quantitative'});\n assert.equal(localLogger.warns[0], log.message.invalidAggregate('box-plot'));\n }));\n });\n\n describe('channelCompatability', () => {\n describe('row/column', () => {\n it('is incompatible with continuous field', () => {\n for (const channel of ['row', 'column'] as Channel[]) {\n assert(!channelCompatibility({field: 'a', type: 'quantitative'}, channel).compatible);\n }\n });\n it('is compatible with discrete field', () => {\n for (const channel of ['row', 'column'] as Channel[]) {\n assert(channelCompatibility({field: 'a', type: 'nominal'}, channel).compatible);\n }\n });\n });\n\n describe('x/y/color/text/detail', () => {\n it('is compatible with continuous field', () => {\n for (const channel of ['x', 'y', 'color', 'text', 'detail'] as Channel[]) {\n assert(channelCompatibility({field: 'a', type: 'quantitative'}, channel).compatible);\n }\n });\n it('is compatible with discrete field', () => {\n for (const channel of ['x', 'y', 'color', 'text', 'detail'] as Channel[]) {\n assert(channelCompatibility({field: 'a', type: 'nominal'}, channel).compatible);\n }\n });\n });\n\n describe('opacity/size/x2/y2', () => {\n it('is compatible with continuous field', () => {\n for (const channel of ['opacity', 'size', 'x2', 'y2'] as Channel[]) {\n assert(channelCompatibility({field: 'a', type: 'quantitative'}, channel).compatible);\n }\n });\n\n it('is compatible with binned field', () => {\n for (const channel of ['opacity', 'size', 'x2', 'y2'] as Channel[]) {\n assert(channelCompatibility({bin: true, field: 'a', type: 'quantitative'}, channel).compatible);\n }\n });\n\n it('is incompatible with nominal field', () => {\n for (const channel of ['opacity', 'size', 'x2', 'y2'] as Channel[]) {\n assert(!channelCompatibility({field: 'a', type: 'nominal'}, channel).compatible);\n }\n });\n });\n\n describe('shape', () => {\n it('is compatible with nominal field', () => {\n assert(channelCompatibility({field: 'a', type: 'nominal'}, 'shape').compatible);\n });\n it('is incompatible with ordinal field', () => {\n assert(!channelCompatibility({field: 'a', type: 'ordinal'}, 'shape').compatible);\n });\n it('is incompatible with quantitative field', () => {\n assert(!channelCompatibility({field: 'a', type: 'quantitative'}, 'shape').compatible);\n });\n });\n\n describe('order', () => {\n it('is incompatible with nominal field', () => {\n assert(!channelCompatibility({field: 'a', type: 'nominal'}, 'order').compatible);\n });\n it('is compatible with ordinal field', () => {\n assert(channelCompatibility({field: 'a', type: 'ordinal'}, 'order').compatible);\n });\n it('is compatible with quantitative field', () => {\n assert(channelCompatibility({field: 'a', type: 'quantitative'}, 'order').compatible);\n });\n });\n });\n\n describe('title()', () => {\n it('should return correct title for aggregate', () => {\n assert.equal(title({field: 'f', aggregate: 'mean'}, {}), 'Mean of f');\n });\n\n it('should return correct title for count', () => {\n assert.equal(title({aggregate: 'count'}, {countTitle: 'baz!'}), 'baz!');\n });\n\n it('should return correct title for bin', () => {\n const fieldDef = {field: 'f', type: QUANTITATIVE, bin: true};\n assert.equal(title(fieldDef,{}), 'f (binned)');\n });\n\n it('should return correct title for bin', () => {\n const fieldDef = {field: 'f', type: QUANTITATIVE, bin: true};\n assert.equal(title(fieldDef,{fieldTitle: 'functional'}), 'BIN(f)');\n });\n\n it('should return correct title for timeUnit', () => {\n const fieldDef = {field: 'f', type: TEMPORAL, timeUnit: TimeUnit.MONTH};\n assert.equal(title(fieldDef,{}), 'f (month)');\n });\n\n it('should return correct title for timeUnit', () => {\n const fieldDef = {field: 'f', type: TEMPORAL, timeUnit: TimeUnit.YEARMONTHDATE};\n assert.equal(title(fieldDef,{}), 'f (year-month-date)');\n });\n\n it('should return correct title for timeUnit', () => {\n const fieldDef = {field: 'f', type: TEMPORAL, timeUnit: TimeUnit.DAY};\n assert.equal(title(fieldDef,{}), 'f (day)');\n });\n\n it('should return correct title for timeUnit', () => {\n const fieldDef = {field: 'f', type: TEMPORAL, timeUnit: TimeUnit.YEARQUARTER};\n assert.equal(title(fieldDef,{}), 'f (year-quarter)');\n });\n\n it('should return correct title for raw field', () => {\n const fieldDef = {field: 'f', type: TEMPORAL};\n assert.equal(title(fieldDef,{}), 'f');\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/predicate.test.d.ts b/build/test/predicate.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/predicate.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/predicate.test.js b/build/test/predicate.test.js new file mode 100644 index 0000000000..2b23fd712e --- /dev/null +++ b/build/test/predicate.test.js @@ -0,0 +1,176 @@ +import { assert } from 'chai'; +import { expression, fieldFilterExpression, isFieldEqualPredicate, isFieldLTEPredicate, isFieldOneOfPredicate, isFieldRangePredicate } from '../src/predicate'; +import { TimeUnit } from '../src/timeunit'; +describe('filter', function () { + var equalFilter = { field: 'color', equal: 'red' }; + var oneOfFilter = { field: 'color', oneOf: ['red', 'yellow'] }; + var rangeFilter = { field: 'x', range: [0, 5] }; + var exprFilter = 'datum["x"]===5'; + var lessThanEqualsFilter = { field: 'x', lte: 'z' }; + describe('isEqualFilter', function () { + it('should return true for an equal filter', function () { + assert.isTrue(isFieldEqualPredicate(equalFilter)); + }); + it('should return false for other filters', function () { + [oneOfFilter, rangeFilter, exprFilter].forEach(function (filter) { + assert.isFalse(isFieldEqualPredicate(filter)); + }); + }); + }); + describe('islessThanEqualsFilter', function () { + it('should return true for less than equals to filter', function () { + assert.isTrue(isFieldLTEPredicate(lessThanEqualsFilter)); + }); + it('should return false for other filters', function () { + [equalFilter, oneOfFilter, rangeFilter, exprFilter].forEach(function (filter) { + assert.isFalse(isFieldLTEPredicate(filter)); + }); + }); + }); + describe('isOneOfFilter', function () { + it('should return true for an in filter', function () { + assert.isTrue(isFieldOneOfPredicate(oneOfFilter)); + }); + it('should return false for other filters', function () { + [equalFilter, rangeFilter, exprFilter].forEach(function (filter) { + assert.isFalse(isFieldOneOfPredicate(filter)); + }); + }); + }); + describe('isRangeFilter', function () { + it('should return true for a range filter', function () { + assert.isTrue(isFieldRangePredicate(rangeFilter)); + }); + it('should return false for other filters', function () { + [oneOfFilter, equalFilter, exprFilter].forEach(function (filter) { + assert.isFalse(isFieldRangePredicate(filter)); + }); + }); + }); + describe('expression', function () { + it('should return a correct expression for an EqualFilter', function () { + var expr = expression(null, { field: 'color', equal: 'red' }); + assert.equal(expr, 'datum["color"]==="red"'); + }); + it('should return correct expression for lessThan', function () { + var expr = expression(null, { field: 'x', lt: 1 }); + assert.equal(expr, 'datum["x"]<1'); + }); + it('should return correct expression for greaterThan', function () { + var expr = expression(null, { field: 'x', gt: 'aardvark' }); + assert.equal(expr, 'datum["x"]>"aardvark"'); + }); + it('should return correct expression for lessThanEquals', function () { + var expr = expression(null, { field: 'x', lte: 'zyzzyva' }); + assert.equal(expr, 'datum["x"]<="zyzzyva"'); + }); + it('should return correct expression for greaterThanEquals', function () { + var expr = expression(null, { field: 'x', gte: 1 }); + assert.equal(expr, 'datum["x"]>=1'); + }); + it('should return a correct expression for an EqualFilter with datetime object', function () { + var expr = expression(null, { + field: 'date', + equal: { + month: 'January' + } + }); + assert.equal(expr, 'datum["date"]===time(datetime(0, 0, 1, 0, 0, 0, 0))'); + }); + it('should return a correct expression for an EqualFilter with time unit and datetime object', function () { + var expr = expression(null, { + timeUnit: TimeUnit.MONTH, + field: 'date', + equal: { + month: 'January' + } + }); + assert.equal(expr, 'time(datetime(0, month(datum["date"]), 1, 0, 0, 0, 0))===time(datetime(0, 0, 1, 0, 0, 0, 0))'); + }); + it('should return a correct expression for an EqualFilter with datetime object', function () { + var expr = expression(null, { + timeUnit: TimeUnit.MONTH, + field: 'date', + equal: 'January' + }); + assert.equal(expr, 'time(datetime(0, month(datum["date"]), 1, 0, 0, 0, 0))===time(datetime(0, 0, 1, 0, 0, 0, 0))'); + }); + it('should return a correct expression for an lessThanFilter with datetime object', function () { + var expr = expression(null, { + field: 'date', + lt: { + month: 'February' + } + }); + assert.equal(expr, 'datum["date"]time(datetime(0, 0, 1, 0, 0, 0, 0))'); + }); + it('should return a correct expression for an greaterThanEqualsFilter with datetime object', function () { + var expr = expression(null, { + timeUnit: TimeUnit.MONTH, + field: 'date', + gte: 'January' + }); + assert.equal(expr, 'time(datetime(0, month(datum["date"]), 1, 0, 0, 0, 0))>=time(datetime(0, 0, 1, 0, 0, 0, 0))'); + }); + it('should return a correct expression for an InFilter', function () { + var expr = expression(null, { field: 'color', oneOf: ['red', 'yellow'] }); + assert.equal(expr, 'indexof(["red","yellow"], datum["color"]) !== -1'); + }); + it('should return a correct expression for a RangeFilter', function () { + var expr = expression(null, { field: 'x', range: [0, 5] }); + assert.equal(expr, 'inrange(datum["x"], [0, 5])'); + }); + it('should return a correct expression for a RangeFilter with no lower bound', function () { + var expr = expression(null, { field: 'x', range: [null, 5] }); + assert.equal(expr, 'datum["x"] <= 5'); + }); + it('should return a correct expression for a RangeFilter with no upper bound', function () { + var expr = expression(null, { field: 'x', range: [0, null] }); + assert.equal(expr, 'datum["x"] >= 0'); + }); + it('should return true for a RangeFilter with no bound', function () { + var expr = expression(null, { field: 'x', range: [null, null] }); + assert.equal(expr, 'true'); + }); + it('should return a correct expression for an expression filter', function () { + var expr = expression(null, 'datum["x"]===5'); + assert.equal(expr, 'datum["x"]===5'); + }); + }); + it('generates expressions for composed filters', function () { + var expr = expression(null, { not: { field: 'color', equal: 'red' } }); + assert.equal(expr, '!(datum["color"]==="red")'); + expr = expression(null, { and: [ + { field: 'color', equal: 'red' }, + { field: 'x', range: [0, 5] } + ] }); + assert.equal(expr, '(datum["color"]==="red") && (inrange(datum["x"], [0, 5]))'); + expr = expression(null, { and: [ + { field: 'color', oneOf: ['red', 'yellow'] }, + { or: [ + { field: 'x', range: [0, null] }, + 'datum.price > 10', + { not: 'datum["x"]===5' } + ] } + ] }); + assert.equal(expr, '(indexof(["red","yellow"], datum["color"]) !== -1) && ' + + '((datum["x"] >= 0) || (datum.price > 10) || (!(datum["x"]===5)))'); + }); + describe('fieldFilterExpression', function () { + it('generates a range predicate using inequalities when useInRange=false', function () { + var expr = fieldFilterExpression({ field: 'x', range: [0, 5] }, false); + assert.equal(expr, 'datum["x"] >= 0 && datum["x"] <= 5'); + }); + }); +}); +//# sourceMappingURL=predicate.test.js.map \ No newline at end of file diff --git a/build/test/predicate.test.js.map b/build/test/predicate.test.js.map new file mode 100644 index 0000000000..81b512a02d --- /dev/null +++ b/build/test/predicate.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"predicate.test.js","sourceRoot":"","sources":["../../test/predicate.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\n\nimport {expression, fieldFilterExpression, isFieldEqualPredicate, isFieldLTEPredicate, isFieldOneOfPredicate, isFieldRangePredicate} from '../src/predicate';\nimport {TimeUnit} from '../src/timeunit';\n\ndescribe('filter', () => {\n const equalFilter = {field: 'color', equal: 'red'};\n const oneOfFilter = {field: 'color', oneOf: ['red', 'yellow']};\n const rangeFilter = {field: 'x', range: [0, 5]};\n const exprFilter = 'datum[\"x\"]===5';\n const lessThanEqualsFilter = {field: 'x', lte: 'z'};\n\n describe('isEqualFilter', () => {\n it('should return true for an equal filter', () => {\n assert.isTrue(isFieldEqualPredicate(equalFilter));\n });\n\n it('should return false for other filters', () => {\n [oneOfFilter, rangeFilter, exprFilter].forEach((filter) => {\n assert.isFalse(isFieldEqualPredicate(filter));\n });\n });\n });\n\n describe('islessThanEqualsFilter', () => {\n it('should return true for less than equals to filter', () => {\n assert.isTrue(isFieldLTEPredicate(lessThanEqualsFilter));\n });\n\n it('should return false for other filters', () => {\n [equalFilter, oneOfFilter, rangeFilter, exprFilter].forEach((filter) => {\n assert.isFalse(isFieldLTEPredicate(filter));\n });\n });\n });\n\n describe('isOneOfFilter', () => {\n it('should return true for an in filter', () => {\n assert.isTrue(isFieldOneOfPredicate(oneOfFilter));\n });\n\n it('should return false for other filters', () => {\n [equalFilter, rangeFilter, exprFilter].forEach((filter) => {\n assert.isFalse(isFieldOneOfPredicate(filter));\n });\n });\n });\n\n describe('isRangeFilter', () => {\n it('should return true for a range filter', () => {\n assert.isTrue(isFieldRangePredicate(rangeFilter));\n });\n\n it('should return false for other filters', () => {\n [oneOfFilter, equalFilter, exprFilter].forEach((filter) => {\n assert.isFalse(isFieldRangePredicate(filter));\n });\n });\n });\n\n describe('expression', () => {\n it('should return a correct expression for an EqualFilter', () => {\n const expr = expression(null, {field: 'color', equal: 'red'});\n assert.equal(expr, 'datum[\"color\"]===\"red\"');\n });\n\n it('should return correct expression for lessThan', () => {\n const expr = expression(null, {field: 'x', lt: 1});\n assert.equal(expr, 'datum[\"x\"]<1');\n });\n\n it('should return correct expression for greaterThan', () => {\n const expr = expression(null, {field: 'x', gt: 'aardvark'});\n assert.equal(expr, 'datum[\"x\"]>\"aardvark\"');\n });\n\n it('should return correct expression for lessThanEquals', () => {\n const expr = expression(null, {field: 'x', lte: 'zyzzyva'});\n assert.equal(expr, 'datum[\"x\"]<=\"zyzzyva\"');\n });\n\n it('should return correct expression for greaterThanEquals', () => {\n const expr = expression(null, {field: 'x', gte: 1});\n assert.equal(expr, 'datum[\"x\"]>=1');\n });\n\n it('should return a correct expression for an EqualFilter with datetime object', () => {\n const expr = expression(null, {\n field: 'date',\n equal: {\n month: 'January'\n }\n });\n assert.equal(expr, 'datum[\"date\"]===time(datetime(0, 0, 1, 0, 0, 0, 0))');\n });\n\n it('should return a correct expression for an EqualFilter with time unit and datetime object', () => {\n const expr = expression(null, {\n timeUnit: TimeUnit.MONTH,\n field: 'date',\n equal: {\n month: 'January'\n }\n });\n assert.equal(expr, 'time(datetime(0, month(datum[\"date\"]), 1, 0, 0, 0, 0))===time(datetime(0, 0, 1, 0, 0, 0, 0))');\n });\n\n it('should return a correct expression for an EqualFilter with datetime object', () => {\n const expr = expression(null, {\n timeUnit: TimeUnit.MONTH,\n field: 'date',\n equal: 'January'\n });\n assert.equal(expr, 'time(datetime(0, month(datum[\"date\"]), 1, 0, 0, 0, 0))===time(datetime(0, 0, 1, 0, 0, 0, 0))');\n });\n\n\n it('should return a correct expression for an lessThanFilter with datetime object', () => {\n const expr = expression(null, {\n field: 'date',\n lt: {\n month: 'February'\n }\n });\n assert.equal(expr, 'datum[\"date\"] {\n const expr = expression(null, {\n timeUnit: TimeUnit.MONTH,\n field: 'date',\n gt: {\n month: 'January'\n }\n });\n assert.equal(expr, 'time(datetime(0, month(datum[\"date\"]), 1, 0, 0, 0, 0))>time(datetime(0, 0, 1, 0, 0, 0, 0))');\n });\n\n it('should return a correct expression for an greaterThanEqualsFilter with datetime object', () => {\n const expr = expression(null, {\n timeUnit: TimeUnit.MONTH,\n field: 'date',\n gte: 'January'\n });\n assert.equal(expr, 'time(datetime(0, month(datum[\"date\"]), 1, 0, 0, 0, 0))>=time(datetime(0, 0, 1, 0, 0, 0, 0))');\n });\n\n it('should return a correct expression for an InFilter', () => {\n const expr = expression(null, {field: 'color', oneOf: ['red', 'yellow']});\n assert.equal(expr, 'indexof([\"red\",\"yellow\"], datum[\"color\"]) !== -1');\n });\n\n it('should return a correct expression for a RangeFilter', () => {\n const expr = expression(null, {field: 'x', range: [0, 5]});\n assert.equal(expr, 'inrange(datum[\"x\"], [0, 5])');\n });\n\n it('should return a correct expression for a RangeFilter with no lower bound', () => {\n const expr = expression(null, {field: 'x', range: [null, 5]});\n assert.equal(expr, 'datum[\"x\"] <= 5');\n });\n\n it('should return a correct expression for a RangeFilter with no upper bound', () => {\n const expr = expression(null, {field: 'x', range: [0, null]});\n assert.equal(expr, 'datum[\"x\"] >= 0');\n });\n\n\n it('should return true for a RangeFilter with no bound', () => {\n const expr = expression(null, {field: 'x', range: [null, null]});\n assert.equal(expr, 'true');\n });\n\n it('should return a correct expression for an expression filter', () => {\n const expr = expression(null, 'datum[\"x\"]===5');\n assert.equal(expr, 'datum[\"x\"]===5');\n });\n });\n\n it('generates expressions for composed filters', () => {\n let expr = expression(null, {not: {field: 'color', equal: 'red'}});\n assert.equal(expr, '!(datum[\"color\"]===\"red\")');\n\n expr = expression(null, {and: [\n {field: 'color', equal: 'red'},\n {field: 'x', range: [0, 5]}\n ]});\n\n assert.equal(expr, '(datum[\"color\"]===\"red\") && (inrange(datum[\"x\"], [0, 5]))');\n\n expr = expression(null, {and: [\n {field: 'color', oneOf: ['red', 'yellow']},\n {or: [\n {field: 'x', range: [0, null]},\n 'datum.price > 10',\n {not: 'datum[\"x\"]===5'}\n ]}\n ]});\n\n assert.equal(expr, '(indexof([\"red\",\"yellow\"], datum[\"color\"]) !== -1) && ' +\n '((datum[\"x\"] >= 0) || (datum.price > 10) || (!(datum[\"x\"]===5)))');\n });\n\n\n describe('fieldFilterExpression', () => {\n it('generates a range predicate using inequalities when useInRange=false', () => {\n const expr = fieldFilterExpression({field: 'x', range: [0, 5]}, false);\n assert.equal(expr, 'datum[\"x\"] >= 0 && datum[\"x\"] <= 5');\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/scale.test.d.ts b/build/test/scale.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/scale.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/scale.test.js b/build/test/scale.test.js new file mode 100644 index 0000000000..3c3603b58d --- /dev/null +++ b/build/test/scale.test.js @@ -0,0 +1,124 @@ +import { assert } from 'chai'; +import { Channel, SCALE_CHANNELS } from '../src/channel'; +import * as scale from '../src/scale'; +import { channelSupportScaleType, CONTINUOUS_TO_CONTINUOUS_SCALES, getSupportedScaleType, SCALE_TYPES, ScaleType } from '../src/scale'; +import { Type } from '../src/type'; +import { some, without } from '../src/util'; +describe('scale', function () { + describe('scaleTypeSupportProperty', function () { + // Make sure we always edit this when we add new channel + it('should have at least one supported scale types for all scale properties', function () { + var _loop_1 = function (prop) { + assert(some(scale.SCALE_TYPES, function (scaleType) { + return scale.scaleTypeSupportProperty(scaleType, prop); + })); + }; + for (var _i = 0, _a = scale.SCALE_PROPERTIES; _i < _a.length; _i++) { + var prop = _a[_i]; + _loop_1(prop); + } + }); + // TODO: write more test blindly (Don't look at our code, just look at D3 code.) + assert.isFalse(scale.scaleTypeSupportProperty('bin-linear', 'zero')); + }); + describe('scaleTypes', function () { + it('should either hasContinuousDomain or hasDiscreteDomain', function () { + for (var _i = 0, _a = scale.SCALE_TYPES; _i < _a.length; _i++) { + var scaleType = _a[_i]; + assert(scale.hasContinuousDomain(scaleType) !== scale.hasDiscreteDomain(scaleType)); + } + }); + }); + describe('channelSupportScaleType', function () { + // Make sure we always edit this when we add new channel + it('should have at least one supported scale types for all channels with scale', function () { + var _loop_2 = function (channel) { + assert(some(SCALE_TYPES, function (scaleType) { + return channelSupportScaleType(channel, scaleType); + })); + }; + for (var _i = 0, SCALE_CHANNELS_1 = SCALE_CHANNELS; _i < SCALE_CHANNELS_1.length; _i++) { + var channel = SCALE_CHANNELS_1[_i]; + _loop_2(channel); + } + }); + // Make sure we always edit this when we add new scale type + it('should have at least one supported channel for all scale types', function () { + var _loop_3 = function (scaleType) { + assert(some(SCALE_CHANNELS, function (channel) { + return channelSupportScaleType(channel, scaleType); + })); + }; + for (var _i = 0, SCALE_TYPES_1 = SCALE_TYPES; _i < SCALE_TYPES_1.length; _i++) { + var scaleType = SCALE_TYPES_1[_i]; + _loop_3(scaleType); + } + }); + it('shape should support only ordinal', function () { + assert(channelSupportScaleType('shape', 'ordinal')); + var nonOrdinal = without(SCALE_TYPES, ['ordinal']); + for (var _i = 0, nonOrdinal_1 = nonOrdinal; _i < nonOrdinal_1.length; _i++) { + var scaleType = nonOrdinal_1[_i]; + assert(!channelSupportScaleType('shape', scaleType)); + } + }); + it('color should support all scale types except band', function () { + for (var _i = 0, SCALE_TYPES_2 = SCALE_TYPES; _i < SCALE_TYPES_2.length; _i++) { + var scaleType = SCALE_TYPES_2[_i]; + assert.equal(channelSupportScaleType('color', scaleType), scaleType !== 'band'); + } + }); + it('x, y, size, opacity should support all continuous scale type as well as band and point', function () { + // x,y should use either band or point for ordinal input + var scaleTypes = CONTINUOUS_TO_CONTINUOUS_SCALES.concat([ScaleType.BAND, ScaleType.POINT]); + for (var _i = 0, _a = ['x', 'y', 'size', 'opacity']; _i < _a.length; _i++) { + var channel = _a[_i]; + assert(!channelSupportScaleType(channel, 'ordinal')); + assert(!channelSupportScaleType(channel, 'sequential')); + for (var _b = 0, scaleTypes_1 = scaleTypes; _b < scaleTypes_1.length; _b++) { + var scaleType = scaleTypes_1[_b]; + assert(channelSupportScaleType(channel, scaleType), "Error: " + channel + ", " + scaleType); + } + } + }); + }); + describe('getSupportedScaleType', function () { + it('should return correct scale types for quantitative positional channels', function () { + var type = Type.QUANTITATIVE; + var positionalScaleTypes = [ScaleType.LINEAR, ScaleType.LOG, ScaleType.POW, ScaleType.SQRT]; + // x channel + var scaleTypes = getSupportedScaleType(Channel.X, type); + assert.deepEqual(positionalScaleTypes, scaleTypes); + // y channel + scaleTypes = getSupportedScaleType(Channel.Y, Type.QUANTITATIVE); + assert.deepEqual(scaleTypes, positionalScaleTypes); + }); + it('should return correct scale types for quantitative positional channels with bin', function () { + var type = Type.QUANTITATIVE; + var positionalScaleTypesBinned = [ScaleType.LINEAR, ScaleType.BIN_LINEAR]; + // x channel + var scaleTypes = getSupportedScaleType(Channel.X, type, true); + assert.deepEqual(scaleTypes, positionalScaleTypesBinned); + // y channel + scaleTypes = getSupportedScaleType(Channel.Y, type, true); + assert.deepEqual(scaleTypes, positionalScaleTypesBinned); + }); + it('should return correct scale types for nominal positional channels', function () { + var type = Type.NOMINAL; + var nominalPositionalScaleTypes = [ScaleType.POINT, ScaleType.BAND]; + var scaleTypes = getSupportedScaleType(Channel.X, type); + assert.deepEqual(scaleTypes, nominalPositionalScaleTypes); + scaleTypes = getSupportedScaleType(Channel.Y, type); + assert.deepEqual(scaleTypes, nominalPositionalScaleTypes); + }); + it('should return correct scale types for temporal positional channels', function () { + var type = Type.TEMPORAL; + var temporalPositionalScaleTypes = [ScaleType.TIME, ScaleType.UTC]; + var scaleTypes = getSupportedScaleType(Channel.X, type); + assert.deepEqual(scaleTypes, temporalPositionalScaleTypes); + scaleTypes = getSupportedScaleType(Channel.Y, type); + assert.deepEqual(scaleTypes, temporalPositionalScaleTypes); + }); + }); +}); +//# sourceMappingURL=scale.test.js.map \ No newline at end of file diff --git a/build/test/scale.test.js.map b/build/test/scale.test.js.map new file mode 100644 index 0000000000..ad957f9ed9 --- /dev/null +++ b/build/test/scale.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scale.test.js","sourceRoot":"","sources":["../../test/scale.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAC,OAAO,EAAE,cAAc,EAAe,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAAE,qBAAqB,EACtD,WAAW,EACX,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAC,IAAI,EAAC,MAAM,aAAa,CAAC;AACjC,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,MAAM,aAAa,CAAC;AAE1C,QAAQ,CAAC,OAAO,EAAE;IAChB,QAAQ,CAAC,0BAA0B,EAAE;QACnC,wDAAwD;QACxD,EAAE,CAAC,yEAAyE,EAAE;oCACjE,IAAI;gBACb,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,UAAC,SAAS;oBACvC,OAAO,KAAK,CAAC,wBAAwB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;gBACzD,CAAC,CAAC,CAAC,CAAC;YACN,CAAC;YAJD,KAAmB,UAAsB,EAAtB,KAAA,KAAK,CAAC,gBAAgB,EAAtB,cAAsB,EAAtB,IAAsB;gBAApC,IAAM,IAAI,SAAA;wBAAJ,IAAI;aAId;QACH,CAAC,CAAC,CAAC;QAEH,gFAAgF;QAEhF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE;QACrB,EAAE,CAAC,wDAAwD,EAAE;YAC3D,KAAwB,UAAiB,EAAjB,KAAA,KAAK,CAAC,WAAW,EAAjB,cAAiB,EAAjB,IAAiB,EAAE;gBAAtC,IAAM,SAAS,SAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,SAAS,CAAC,KAAK,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;aACrF;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAGH,QAAQ,CAAC,yBAAyB,EAAE;QAClC,wDAAwD;QACxD,EAAE,CAAC,4EAA4E,EAAE;oCACpE,OAAO;gBAChB,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,UAAC,SAAS;oBACjC,OAAO,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;gBACrD,CAAC,CAAC,CAAC,CAAC;YACN,CAAC;YAJD,KAAsB,UAAc,EAAd,iCAAc,EAAd,4BAAc,EAAd,IAAc;gBAA/B,IAAM,OAAO,uBAAA;wBAAP,OAAO;aAIjB;QACH,CAAC,CAAC,CAAC;QAEH,2DAA2D;QAC3D,EAAE,CAAC,gEAAgE,EAAE;oCACxD,SAAS;gBAClB,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,UAAC,OAAO;oBAClC,OAAO,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;gBACrD,CAAC,CAAC,CAAC,CAAC;YACN,CAAC;YAJD,KAAwB,UAAW,EAAX,2BAAW,EAAX,yBAAW,EAAX,IAAW;gBAA9B,IAAM,SAAS,oBAAA;wBAAT,SAAS;aAInB;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE;YACtC,MAAM,CAAC,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;YACpD,IAAM,UAAU,GAAG,OAAO,CAAY,WAAW,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;YAChE,KAAwB,UAAU,EAAV,yBAAU,EAAV,wBAAU,EAAV,IAAU,EAAE;gBAA/B,IAAM,SAAS,mBAAA;gBAClB,MAAM,CAAC,CAAC,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;aACtD;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE;YACrD,KAAwB,UAAW,EAAX,2BAAW,EAAX,yBAAW,EAAX,IAAW,EAAE;gBAAhC,IAAM,SAAS,oBAAA;gBAClB,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,SAAS,KAAK,MAAM,CAAC,CAAC;aACjF;QACH,CAAC,CAAC,CAAC;QAGH,EAAE,CAAC,wFAAwF,EAAE;YAC3F,wDAAwD;YACxD,IAAM,UAAU,GAAO,+BAA+B,SAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,EAAC,CAAC;YAEzF,KAAsB,UAA+C,EAA/C,KAAA,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,CAAmB,EAA/C,cAA+C,EAA/C,IAA+C,EAAE;gBAAlE,IAAM,OAAO,SAAA;gBAChB,MAAM,CAAC,CAAC,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;gBACrD,MAAM,CAAC,CAAC,uBAAuB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;gBACxD,KAAwB,UAAU,EAAV,yBAAU,EAAV,wBAAU,EAAV,IAAU,EAAE;oBAA/B,IAAM,SAAS,mBAAA;oBAClB,MAAM,CAAC,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,YAAU,OAAO,UAAK,SAAW,CAAC,CAAC;iBACxF;aACF;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE;QAChC,EAAE,CAAC,wEAAwE,EAAE;YAC3E,IAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC;YAC/B,IAAM,oBAAoB,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;YAE9F,YAAY;YACZ,IAAI,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YACxD,MAAM,CAAC,SAAS,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;YAEnD,YAAY;YACZ,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YACjE,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iFAAiF,EAAE;YACpF,IAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC;YAC/B,IAAM,0BAA0B,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;YAE5E,YAAY;YACZ,IAAI,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAC9D,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC;YAEzD,YAAY;YACZ,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAC1D,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mEAAmE,EAAE;YACtE,IAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;YAC1B,IAAM,2BAA2B,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;YAEtE,IAAI,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YACxD,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAC;YAE1D,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YACpD,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oEAAoE,EAAE;YACvE,IAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC3B,IAAM,4BAA4B,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;YAErE,IAAI,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YACxD,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,4BAA4B,CAAC,CAAC;YAE3D,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YACpD,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,4BAA4B,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\nimport {Channel, SCALE_CHANNELS, ScaleChannel} from '../src/channel';\nimport * as scale from '../src/scale';\nimport {\n channelSupportScaleType,\n CONTINUOUS_TO_CONTINUOUS_SCALES, getSupportedScaleType,\n SCALE_TYPES,\n ScaleType\n} from '../src/scale';\nimport {Type} from '../src/type';\nimport {some, without} from '../src/util';\n\ndescribe('scale', () => {\n describe('scaleTypeSupportProperty', () => {\n // Make sure we always edit this when we add new channel\n it('should have at least one supported scale types for all scale properties', () => {\n for (const prop of scale.SCALE_PROPERTIES) {\n assert(some(scale.SCALE_TYPES, (scaleType) => {\n return scale.scaleTypeSupportProperty(scaleType, prop);\n }));\n }\n });\n\n // TODO: write more test blindly (Don't look at our code, just look at D3 code.)\n\n assert.isFalse(scale.scaleTypeSupportProperty('bin-linear', 'zero'));\n });\n\n describe('scaleTypes', () => {\n it('should either hasContinuousDomain or hasDiscreteDomain', () => {\n for (const scaleType of scale.SCALE_TYPES) {\n assert(scale.hasContinuousDomain(scaleType) !== scale.hasDiscreteDomain(scaleType));\n }\n });\n });\n\n\n describe('channelSupportScaleType', () => {\n // Make sure we always edit this when we add new channel\n it('should have at least one supported scale types for all channels with scale', () => {\n for (const channel of SCALE_CHANNELS) {\n assert(some(SCALE_TYPES, (scaleType) => {\n return channelSupportScaleType(channel, scaleType);\n }));\n }\n });\n\n // Make sure we always edit this when we add new scale type\n it('should have at least one supported channel for all scale types', () => {\n for (const scaleType of SCALE_TYPES) {\n assert(some(SCALE_CHANNELS, (channel) => {\n return channelSupportScaleType(channel, scaleType);\n }));\n }\n });\n\n it('shape should support only ordinal', () => {\n assert(channelSupportScaleType('shape', 'ordinal'));\n const nonOrdinal = without(SCALE_TYPES, ['ordinal']);\n for (const scaleType of nonOrdinal) {\n assert(!channelSupportScaleType('shape', scaleType));\n }\n });\n\n it('color should support all scale types except band', () => {\n for (const scaleType of SCALE_TYPES) {\n assert.equal(channelSupportScaleType('color', scaleType), scaleType !== 'band');\n }\n });\n\n\n it('x, y, size, opacity should support all continuous scale type as well as band and point', () => {\n // x,y should use either band or point for ordinal input\n const scaleTypes = [...CONTINUOUS_TO_CONTINUOUS_SCALES, ScaleType.BAND, ScaleType.POINT];\n\n for (const channel of ['x', 'y', 'size', 'opacity'] as ScaleChannel[]) {\n assert(!channelSupportScaleType(channel, 'ordinal'));\n assert(!channelSupportScaleType(channel, 'sequential'));\n for (const scaleType of scaleTypes) {\n assert(channelSupportScaleType(channel, scaleType), `Error: ${channel}, ${scaleType}`);\n }\n }\n });\n });\n\n describe('getSupportedScaleType', () => {\n it('should return correct scale types for quantitative positional channels', () => {\n const type = Type.QUANTITATIVE;\n const positionalScaleTypes = [ScaleType.LINEAR, ScaleType.LOG, ScaleType.POW, ScaleType.SQRT];\n\n // x channel\n let scaleTypes = getSupportedScaleType(Channel.X, type);\n assert.deepEqual(positionalScaleTypes, scaleTypes);\n\n // y channel\n scaleTypes = getSupportedScaleType(Channel.Y, Type.QUANTITATIVE);\n assert.deepEqual(scaleTypes, positionalScaleTypes);\n });\n\n it('should return correct scale types for quantitative positional channels with bin', () => {\n const type = Type.QUANTITATIVE;\n const positionalScaleTypesBinned = [ScaleType.LINEAR, ScaleType.BIN_LINEAR];\n\n // x channel\n let scaleTypes = getSupportedScaleType(Channel.X, type, true);\n assert.deepEqual(scaleTypes, positionalScaleTypesBinned);\n\n // y channel\n scaleTypes = getSupportedScaleType(Channel.Y, type, true);\n assert.deepEqual(scaleTypes, positionalScaleTypesBinned);\n });\n\n it('should return correct scale types for nominal positional channels', () => {\n const type = Type.NOMINAL;\n const nominalPositionalScaleTypes = [ScaleType.POINT, ScaleType.BAND];\n\n let scaleTypes = getSupportedScaleType(Channel.X, type);\n assert.deepEqual(scaleTypes, nominalPositionalScaleTypes);\n\n scaleTypes = getSupportedScaleType(Channel.Y, type);\n assert.deepEqual(scaleTypes, nominalPositionalScaleTypes);\n });\n\n it('should return correct scale types for temporal positional channels', () => {\n const type = Type.TEMPORAL;\n const temporalPositionalScaleTypes = [ScaleType.TIME, ScaleType.UTC];\n\n let scaleTypes = getSupportedScaleType(Channel.X, type);\n assert.deepEqual(scaleTypes, temporalPositionalScaleTypes);\n\n scaleTypes = getSupportedScaleType(Channel.Y, type);\n assert.deepEqual(scaleTypes, temporalPositionalScaleTypes);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/spec.test.d.ts b/build/test/spec.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/spec.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/spec.test.js b/build/test/spec.test.js new file mode 100644 index 0000000000..a20ddf6076 --- /dev/null +++ b/build/test/spec.test.js @@ -0,0 +1,859 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import * as log from '../src/log'; +import { fieldDefs, normalize } from '../src/spec'; +import { defaultConfig, initConfig } from './../src/config'; +// describe('isStacked()') -- tested as part of stackOffset in stack.test.ts +describe('normalize()', function () { + describe('normalizeFacetedUnit', function () { + it('should convert single extended spec with column into a composite spec', function () { + var spec = { + "name": "faceted", + "width": 123, + "height": 234, + "description": "faceted spec", + "data": { "url": "data/movies.json" }, + "mark": "point", + "encoding": { + "column": { "field": "MPAA_Rating", "type": "ordinal" }, + "x": { "field": "Worldwide_Gross", "type": "quantitative" }, + "y": { "field": "US_DVD_Sales", "type": "quantitative" } + } + }; + var config = initConfig(spec.config); + assert.deepEqual(normalize(spec, config), { + "name": "faceted", + "description": "faceted spec", + "data": { "url": "data/movies.json" }, + "facet": { + "column": { "field": "MPAA_Rating", "type": "ordinal" } + }, + "spec": { + "mark": "point", + "width": 123, + "height": 234, + "encoding": { + "x": { "field": "Worldwide_Gross", "type": "quantitative" }, + "y": { "field": "US_DVD_Sales", "type": "quantitative" } + } + } + }); + }); + it('should convert single extended spec with row into a composite spec', function () { + var spec = { + "data": { "url": "data/movies.json" }, + "mark": "point", + "encoding": { + "row": { "field": "MPAA_Rating", "type": "ordinal" }, + "x": { "field": "Worldwide_Gross", "type": "quantitative" }, + "y": { "field": "US_DVD_Sales", "type": "quantitative" } + } + }; + var config = initConfig(spec.config); + assert.deepEqual(normalize(spec, config), { + "data": { "url": "data/movies.json" }, + "facet": { + "row": { "field": "MPAA_Rating", "type": "ordinal" } + }, + "spec": { + "mark": "point", + "encoding": { + "x": { "field": "Worldwide_Gross", "type": "quantitative" }, + "y": { "field": "US_DVD_Sales", "type": "quantitative" } + } + } + }); + }); + }); + describe('normalizeFacet', function () { + it('should produce correct layered specs for mean point and vertical error bar', function () { + assert.deepEqual(normalize({ + "description": "A error bar plot showing mean, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [{ "filter": "datum.year == 2000" }], + facet: { + "row": { "field": "MPAA_Rating", "type": "ordinal" } + }, + spec: { + layer: [ + { + "mark": "point", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "mean", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 2 } + } + }, + { + mark: 'error-bar', + encoding: { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + }, + "size": { "value": 5 } + } + } + ] + } + }, defaultConfig), { + "description": "A error bar plot showing mean, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": [{ "filter": "datum.year == 2000" }], + facet: { + "row": { "field": "MPAA_Rating", "type": "ordinal" } + }, + spec: { + layer: [ + { + "mark": "point", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "mean", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 2 } + } + }, + { + "layer": [ + { + "mark": "rule", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + } + } + }, + { + "mark": "tick", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 } + } + }, + { + "mark": "tick", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "max", + "field": "people", + "type": "quantitative", + }, + "size": { "value": 5 } + } + } + ] + } + ] + } + }); + }); + }); + describe('normalizeLayer', function () { + it('correctly passes shared projection and encoding to children of layer', function () { + var output = normalize({ + "data": { "url": "data/population.json" }, + "projection": { "type": "mercator" }, + "encoding": { + "x": { "field": "age", "type": "ordinal" } + }, + "layer": [ + { "mark": "point" }, + { + "layer": [ + { "mark": "rule" }, + { + "mark": "text", + "encoding": { + "text": { "field": "a", "type": "nominal" } + } + } + ] + } + ] + }, defaultConfig); + assert.deepEqual(output, { + "data": { "url": "data/population.json" }, + layer: [ + { + "projection": { "type": "mercator" }, + "mark": "point", + "encoding": { + "x": { "field": "age", "type": "ordinal" } + } + }, + { + "layer": [ + { + "projection": { "type": "mercator" }, + "mark": "rule", + "encoding": { + "x": { "field": "age", "type": "ordinal" } + } + }, + { + "projection": { "type": "mercator" }, + "mark": "text", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "text": { "field": "a", "type": "nominal" } + } + } + ] + } + ] + }); + }); + it('correctly overrides shared projection and encoding and throws warnings', log.wrap(function (localLogger) { + var output = normalize({ + "data": { "url": "data/population.json" }, + "projection": { "type": "mercator" }, + "encoding": { + "x": { "field": "age", "type": "ordinal" } + }, + "layer": [ + { + "projection": { "type": "albersUsa" }, + "mark": "rule" + }, + { + "mark": "text", + "encoding": { + "x": { "field": "a", "type": "nominal" } + } + } + ] + }, defaultConfig); + assert.equal(localLogger.warns.length, 2); + assert.equal(localLogger.warns[0], log.message.projectionOverridden({ + parentProjection: { "type": "mercator" }, + projection: { "type": "albersUsa" } + })); + assert.equal(localLogger.warns[1], log.message.encodingOverridden(['x'])); + assert.deepEqual(output, { + "data": { "url": "data/population.json" }, + layer: [ + { + "projection": { "type": "albersUsa" }, + "mark": "rule", + "encoding": { + "x": { "field": "age", "type": "ordinal" } + } + }, + { + "projection": { "type": "mercator" }, + "mark": "text", + "encoding": { + "x": { "field": "a", "type": "nominal" }, + } + } + ] + }); + })); + it('should produce correct layered specs for mean point and vertical error bar', function () { + assert.deepEqual(normalize({ + "data": { "url": "data/population.json" }, + layer: [ + { + "mark": "point", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "mean", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 2 } + } + }, + { + mark: 'error-bar', + encoding: { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + }, + "size": { "value": 5 } + } + } + ] + }, defaultConfig), { + "data": { "url": "data/population.json" }, + layer: [ + { + "mark": "point", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "mean", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 2 } + } + }, + { + "layer": [ + { + "mark": "rule", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + } + } + }, + { + "mark": "tick", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 } + } + }, + { + "mark": "tick", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "max", + "field": "people", + "type": "quantitative", + }, + "size": { "value": 5 } + } + } + ] + } + ] + }); + }); + }); + describe('normalizePathOverlay', function () { + it('correctly normalizes line with overlayed point.', function () { + var spec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + }, + "config": { "line": { "point": {} } } + }; + var normalizedSpec = normalize(spec, spec.config); + assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": { "type": "point", "opacity": 1, "filled": true }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + } + ], + "config": { "line": { "point": {} } } + }); + }); + it('correctly normalizes line with transparent point overlayed.', function () { + var spec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": { "type": "line", "point": "transparent" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }; + var normalizedSpec = normalize(spec, spec.config); + assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": { "type": "point", "opacity": 0, "filled": true }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + } + ] + }); + }); + it('correctly normalizes line with point overlayed via mark definition.', function () { + var spec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": { "type": "line", "point": { "color": "red" } }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }; + var normalizedSpec = normalize(spec, spec.config); + assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": { "type": "point", "opacity": 1, "filled": true, "color": "red" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + } + ] + }); + }); + it('correctly normalizes faceted line plots with overlayed point.', function () { + var spec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": "line", + "encoding": { + "row": { "field": "symbol", "type": "nominal" }, + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + }, + "config": { "line": { "point": {} } } + }; + var normalizedSpec = normalize(spec, spec.config); + assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "facet": { + "row": { "field": "symbol", "type": "nominal" }, + }, + "spec": { + "layer": [ + { + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": { "type": "point", "opacity": 1, "filled": true }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + } + ], + }, + "config": { "line": { "point": {} } } + }); + }); + it('correctly normalizes area with overlay line and point', function () { + var spec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + }, + "config": { "area": { "line": {}, "point": {} } } + }; + var normalizedSpec = normalize(spec, spec.config); + assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "mark": { "type": "area", "opacity": 0.7 }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": { "type": "line" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": { "type": "point", "opacity": 1, "filled": true }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + } + ], + "config": { "area": { "line": {}, "point": {} } } + }); + }); + it('correctly normalizes interpolated area with overlay line', function () { + var spec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": { "type": "area", "interpolate": "monotone" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + }, + "config": { "area": { "line": {} } } + }; + var normalizedSpec = normalize(spec, spec.config); + assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "mark": { "type": "area", "opacity": 0.7, "interpolate": "monotone" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": { "type": "line", "interpolate": "monotone" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + } + ], + "config": { "area": { "line": {} } } + }); + }); + it('correctly normalizes area with disabled overlay point and line.', function () { + for (var _i = 0, _a = [null, false]; _i < _a.length; _i++) { + var overlay = _a[_i]; + var spec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": { "type": "area", "point": overlay, "line": overlay }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }; + var normalizedSpec = normalize(spec, spec.config); + assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }); + } + }); + it('correctly normalizes area with overlay point and line disabled in config.', function () { + for (var _i = 0, _a = [null, false]; _i < _a.length; _i++) { + var overlay = _a[_i]; + var spec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": { "type": "area" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + }, + "config": { + "area": { "point": overlay, "line": overlay } + } + }; + var normalizedSpec = normalize(spec, spec.config); + assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + }, + "config": { + "area": { "point": overlay, "line": overlay } + } + }); + } + }); + it('correctly normalizes stacked area with overlay line', function () { + var spec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "aggregate": "sum", "field": "price", "type": "quantitative" }, + "color": { "field": "symbol", "type": "nominal" } + }, + "config": { "area": { "line": {} } } + }; + var normalizedSpec = normalize(spec, spec.config); + assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "mark": { "type": "area", "opacity": 0.7 }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "aggregate": "sum", "field": "price", "type": "quantitative" }, + "color": { "field": "symbol", "type": "nominal" } + } + }, + { + "mark": { "type": "line" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "aggregate": "sum", "field": "price", "type": "quantitative", "stack": "zero" }, + "color": { "field": "symbol", "type": "nominal" } + } + } + ], + "config": { "area": { "line": {} } } + }); + }); + it('correctly normalizes streamgraph with overlay line', function () { + var spec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "aggregate": "sum", "field": "price", "type": "quantitative", "stack": "center" }, + "color": { "field": "symbol", "type": "nominal" } + }, + "config": { "area": { "line": {} } } + }; + var normalizedSpec = normalize(spec, spec.config); + assert.deepEqual(normalizedSpec, { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "mark": { "type": "area", "opacity": 0.7 }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "aggregate": "sum", "field": "price", "type": "quantitative", "stack": "center" }, + "color": { "field": "symbol", "type": "nominal" } + } + }, + { + "mark": { "type": "line" }, + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "aggregate": "sum", "field": "price", "type": "quantitative", "stack": "center" }, + "color": { "field": "symbol", "type": "nominal" } + } + } + ], + "config": { "area": { "line": {} } } + }); + }); + }); +}); +describe('normalizeRangedUnitSpec', function () { + it('should convert y2 -> y if there is no y in the encoding', function () { + var spec = { + "data": { "url": "data/population.json" }, + "mark": "rule", + "encoding": { + "y2": { "field": "age", "type": "ordinal" }, + "x": { "aggregate": "min", "field": "people", "type": "quantitative" }, + "x2": { "aggregate": "max", "field": "people", "type": "quantitative" } + } + }; + assert.deepEqual(normalize(spec, defaultConfig), { + "data": { "url": "data/population.json" }, + "mark": "rule", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { "aggregate": "min", "field": "people", "type": "quantitative" }, + "x2": { "aggregate": "max", "field": "people", "type": "quantitative" } + } + }); + }); + it('should do nothing if there is no missing x or y', function () { + var spec = { + "data": { "url": "data/population.json" }, + "mark": "rule", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { "aggregate": "min", "field": "people", "type": "quantitative" }, + "x2": { "aggregate": "max", "field": "people", "type": "quantitative" } + } + }; + assert.deepEqual(normalize(spec, defaultConfig), spec); + }); + it('should convert x2 -> x if there is no x in the encoding', function () { + var spec = { + "data": { "url": "data/population.json" }, + "mark": "rule", + "encoding": { + "x2": { "field": "age", "type": "ordinal" }, + "y": { "aggregate": "min", "field": "people", "type": "quantitative" }, + "y2": { "aggregate": "max", "field": "people", "type": "quantitative" } + } + }; + assert.deepEqual(normalize(spec, defaultConfig), { + "data": { "url": "data/population.json" }, + "mark": "rule", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { "aggregate": "min", "field": "people", "type": "quantitative" }, + "y2": { "aggregate": "max", "field": "people", "type": "quantitative" } + } + }); + }); +}); +describe('fieldDefs()', function () { + it('should get all non-duplicate fieldDefs from an encoding', function () { + var spec = { + "data": { "url": "data/cars.json" }, + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + } + }; + assert.sameDeepMembers(fieldDefs(spec), [ + { "field": "Horsepower", "type": "quantitative" }, + { "field": "Miles_per_Gallon", "type": "quantitative" } + ]); + }); + it('should get all non-duplicate fieldDefs from all layer in a LayerSpec', function () { + var layerSpec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "description": "Google's stock price over time.", + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "description": "Google's stock price over time.", + "mark": "point", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" }, + "color": { "field": "symbol", "type": "nominal" } + }, + "config": { "mark": { "filled": true } } + } + ] + }; + assert.sameDeepMembers(fieldDefs(layerSpec), [ + { "field": "date", "type": "temporal" }, + { "field": "price", "type": "quantitative" }, + { "field": "symbol", "type": "nominal" } + ]); + }); + it('should get all non-duplicate fieldDefs from all layer in a LayerSpec (merging duplicate fields with different scale types)', function () { + var layerSpec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "layer": [ + { + "description": "Google's stock price over time.", + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "description": "Google's stock price over time.", + "mark": "point", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" }, + "color": { "field": "date", "type": "temporal", "scale": { "type": "pow" } } + }, + "config": { "mark": { "filled": true } } + } + ] + }; + assert.sameDeepMembers(fieldDefs(layerSpec), [ + { "field": "date", "type": "temporal" }, + { "field": "price", "type": "quantitative" } + ]); + }); + it('should get all non-duplicate fieldDefs from facet and layer in a FacetSpec', function () { + var facetSpec = { + "data": { "url": "data/movies.json" }, + "facet": { "row": { "field": "MPAA_Rating", "type": "ordinal" } }, + "spec": { + "mark": "point", + "encoding": { + "x": { "field": "Worldwide_Gross", "type": "quantitative" }, + "y": { "field": "US_DVD_Sales", "type": "quantitative" } + } + } + }; + assert.sameDeepMembers(fieldDefs(facetSpec), [ + { "field": "MPAA_Rating", "type": "ordinal" }, + { "field": "Worldwide_Gross", "type": "quantitative" }, + { "field": "US_DVD_Sales", "type": "quantitative" } + ]); + }); +}); +//# sourceMappingURL=spec.test.js.map \ No newline at end of file diff --git a/build/test/spec.test.js.map b/build/test/spec.test.js.map new file mode 100644 index 0000000000..add96a8811 --- /dev/null +++ b/build/test/spec.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"spec.test.js","sourceRoot":"","sources":["../../test/spec.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\nimport {assert} from 'chai';\n\nimport {Field, FieldDef} from '../src/fielddef';\nimport {LocalLogger} from '../src/log';\nimport * as log from '../src/log';\nimport {fieldDefs, normalize, NormalizedSpec, TopLevel, TopLevelSpec} from '../src/spec';\nimport {defaultConfig, initConfig} from './../src/config';\n\n// describe('isStacked()') -- tested as part of stackOffset in stack.test.ts\n\ndescribe('normalize()', function () {\n describe('normalizeFacetedUnit', () => {\n it('should convert single extended spec with column into a composite spec', function() {\n const spec: any = {\n \"name\": \"faceted\",\n \"width\": 123,\n \"height\": 234,\n \"description\": \"faceted spec\",\n \"data\": {\"url\": \"data/movies.json\"},\n \"mark\": \"point\",\n \"encoding\": {\n \"column\": {\"field\": \"MPAA_Rating\",\"type\": \"ordinal\"},\n \"x\": {\"field\": \"Worldwide_Gross\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"US_DVD_Sales\",\"type\": \"quantitative\"}\n }\n };\n const config = initConfig(spec.config);\n assert.deepEqual(normalize(spec, config), {\n \"name\": \"faceted\",\n \"description\": \"faceted spec\",\n \"data\": {\"url\": \"data/movies.json\"},\n \"facet\": {\n \"column\": {\"field\": \"MPAA_Rating\",\"type\": \"ordinal\"}\n },\n \"spec\": {\n \"mark\": \"point\",\n \"width\": 123,\n \"height\": 234,\n \"encoding\": {\n \"x\": {\"field\": \"Worldwide_Gross\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"US_DVD_Sales\",\"type\": \"quantitative\"}\n }\n }\n });\n });\n\n it('should convert single extended spec with row into a composite spec', function() {\n const spec: any = {\n \"data\": {\"url\": \"data/movies.json\"},\n \"mark\": \"point\",\n \"encoding\": {\n \"row\": {\"field\": \"MPAA_Rating\",\"type\": \"ordinal\"},\n \"x\": {\"field\": \"Worldwide_Gross\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"US_DVD_Sales\",\"type\": \"quantitative\"}\n }\n };\n\n const config = initConfig(spec.config);\n assert.deepEqual(normalize(spec, config), {\n \"data\": {\"url\": \"data/movies.json\"},\n \"facet\": {\n \"row\": {\"field\": \"MPAA_Rating\",\"type\": \"ordinal\"}\n },\n \"spec\": {\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"Worldwide_Gross\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"US_DVD_Sales\",\"type\": \"quantitative\"}\n }\n }\n });\n });\n });\n\n describe('normalizeFacet', () => {\n it('should produce correct layered specs for mean point and vertical error bar', () => {\n assert.deepEqual(normalize({\n \"description\": \"A error bar plot showing mean, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [{\"filter\": \"datum.year == 2000\"}],\n facet: {\n \"row\": {\"field\": \"MPAA_Rating\",\"type\": \"ordinal\"}\n },\n spec: {\n layer: [\n {\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 2}\n }\n },\n {\n mark: 'error-bar',\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"min\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"aggregate\": \"max\",\n \"field\": \"people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5}\n }\n }\n ]\n }\n }, defaultConfig), {\n \"description\": \"A error bar plot showing mean, min, and max in the US population distribution of age groups in 2000.\",\n \"data\": {\"url\": \"data/population.json\"},\n \"transform\": [{\"filter\": \"datum.year == 2000\"}],\n facet: {\n \"row\": {\"field\": \"MPAA_Rating\",\"type\": \"ordinal\"}\n },\n spec: {\n layer: [\n {\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 2}\n }\n },\n {\n \"layer\": [\n {\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"min\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"aggregate\": \"max\",\n \"field\": \"people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n \"mark\": \"tick\",\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"min\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5}\n }\n },\n {\n \"mark\": \"tick\",\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"max\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n // \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5}\n }\n }\n ]\n }\n ]\n }\n });\n });\n });\n\n describe('normalizeLayer', () => {\n it('correctly passes shared projection and encoding to children of layer', () => {\n const output = normalize({\n \"data\": {\"url\": \"data/population.json\"},\n \"projection\": {\"type\": \"mercator\"},\n \"encoding\": {\n \"x\": {\"field\": \"age\", \"type\": \"ordinal\"}\n },\n \"layer\": [\n {\"mark\": \"point\"},\n {\n \"layer\": [\n {\"mark\": \"rule\"},\n {\n \"mark\": \"text\",\n \"encoding\": {\n \"text\": {\"field\": \"a\", \"type\": \"nominal\"}\n }\n }\n ]\n }\n ]\n }, defaultConfig);\n\n assert.deepEqual(output, {\n \"data\": {\"url\": \"data/population.json\"},\n layer: [\n {\n \"projection\": {\"type\": \"mercator\"},\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"age\", \"type\": \"ordinal\"}\n }\n },\n {\n \"layer\": [\n {\n \"projection\": {\"type\": \"mercator\"},\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"age\", \"type\": \"ordinal\"}\n }\n },\n {\n \"projection\": {\"type\": \"mercator\"},\n \"mark\": \"text\",\n \"encoding\": {\n \"x\": {\"field\": \"age\", \"type\": \"ordinal\"},\n \"text\": {\"field\": \"a\", \"type\": \"nominal\"}\n }\n }\n ]\n }\n ]\n });\n });\n\n\n it('correctly overrides shared projection and encoding and throws warnings', log.wrap((localLogger: LocalLogger) => {\n const output = normalize({\n \"data\": {\"url\": \"data/population.json\"},\n \"projection\": {\"type\": \"mercator\"},\n \"encoding\": {\n \"x\": {\"field\": \"age\", \"type\": \"ordinal\"}\n },\n \"layer\": [\n {\n \"projection\": {\"type\": \"albersUsa\"},\n \"mark\": \"rule\"\n },\n {\n \"mark\": \"text\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"nominal\"}\n }\n }\n ]\n }, defaultConfig);\n\n assert.equal(localLogger.warns.length, 2);\n\n assert.equal(localLogger.warns[0], log.message.projectionOverridden({\n parentProjection: {\"type\": \"mercator\"},\n projection: {\"type\": \"albersUsa\"}\n }));\n\n assert.equal(localLogger.warns[1], log.message.encodingOverridden(['x']));\n\n assert.deepEqual(output, {\n \"data\": {\"url\": \"data/population.json\"},\n layer: [\n {\n \"projection\": {\"type\": \"albersUsa\"},\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"age\", \"type\": \"ordinal\"}\n }\n },\n {\n \"projection\": {\"type\": \"mercator\"},\n \"mark\": \"text\",\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"nominal\"},\n }\n }\n ]\n });\n }));\n\n it('should produce correct layered specs for mean point and vertical error bar', () => {\n assert.deepEqual(normalize({\n \"data\": {\"url\": \"data/population.json\"},\n layer: [\n {\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 2}\n }\n },\n {\n mark: 'error-bar',\n encoding: {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"min\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"aggregate\": \"max\",\n \"field\": \"people\",\n \"type\": \"quantitative\"\n },\n \"size\": {\"value\": 5}\n }\n }\n ]\n }, defaultConfig), {\n \"data\": {\"url\": \"data/population.json\"},\n layer: [\n {\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"mean\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 2}\n }\n },\n {\n \"layer\": [\n {\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"min\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"y2\": {\n \"aggregate\": \"max\",\n \"field\": \"people\",\n \"type\": \"quantitative\"\n }\n }\n },\n {\n \"mark\": \"tick\",\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"min\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5}\n }\n },\n {\n \"mark\": \"tick\",\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\n \"aggregate\": \"max\",\n \"field\": \"people\",\n \"type\": \"quantitative\",\n // \"axis\": {\"title\": \"population\"}\n },\n \"size\": {\"value\": 5}\n }\n }\n ]\n }\n ]\n });\n });\n });\n\n describe('normalizePathOverlay', () => {\n it('correctly normalizes line with overlayed point.', () => {\n const spec: TopLevelSpec = {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n },\n \"config\": {\"line\": {\"point\": {}}}\n };\n const normalizedSpec = normalize(spec, spec.config);\n assert.deepEqual>(normalizedSpec, {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"layer\": [\n {\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n },\n {\n \"mark\": {\"type\": \"point\", \"opacity\": 1, \"filled\": true},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n }\n ],\n \"config\": {\"line\": {\"point\": {}}}\n });\n });\n\n it('correctly normalizes line with transparent point overlayed.', () => {\n const spec: TopLevelSpec = {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": {\"type\": \"line\", \"point\": \"transparent\"},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n };\n const normalizedSpec = normalize(spec, spec.config);\n assert.deepEqual>(normalizedSpec, {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"layer\": [\n {\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n },\n {\n \"mark\": {\"type\": \"point\", \"opacity\": 0, \"filled\": true},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n }\n ]\n });\n });\n\n it('correctly normalizes line with point overlayed via mark definition.', () => {\n const spec: TopLevelSpec = {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": {\"type\": \"line\", \"point\": {\"color\": \"red\"}},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n };\n const normalizedSpec = normalize(spec, spec.config);\n assert.deepEqual>(normalizedSpec, {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"layer\": [\n {\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n },\n {\n \"mark\": {\"type\": \"point\", \"opacity\": 1, \"filled\": true, \"color\": \"red\"},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n }\n ]\n });\n });\n\n it('correctly normalizes faceted line plots with overlayed point.', () => {\n const spec: TopLevelSpec = {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": \"line\",\n \"encoding\": {\n \"row\": {\"field\": \"symbol\", \"type\": \"nominal\"},\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n },\n \"config\": {\"line\": {\"point\": {}}}\n };\n const normalizedSpec = normalize(spec, spec.config);\n assert.deepEqual>(normalizedSpec, {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"facet\": {\n \"row\": {\"field\": \"symbol\", \"type\": \"nominal\"},\n },\n \"spec\": {\n \"layer\": [\n {\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n },\n {\n \"mark\": {\"type\": \"point\", \"opacity\": 1, \"filled\": true},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n }\n ],\n },\n \"config\": {\"line\": {\"point\": {}}}\n });\n });\n\n it('correctly normalizes area with overlay line and point', () => {\n const spec: TopLevelSpec = {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": \"area\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n },\n \"config\": {\"area\": {\"line\": {}, \"point\": {}}}\n };\n const normalizedSpec = normalize(spec, spec.config);\n assert.deepEqual>(normalizedSpec, {\n \"data\": {\"url\": \"data/stocks.csv\",\"format\": {\"type\": \"csv\"}},\n \"layer\": [\n {\n \"mark\": {\"type\": \"area\", \"opacity\": 0.7},\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"}\n }\n },\n {\n \"mark\": {\"type\": \"line\"},\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"}\n }\n },\n {\n \"mark\": {\"type\": \"point\", \"opacity\": 1, \"filled\": true},\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"}\n }\n }\n ],\n \"config\": {\"area\": {\"line\": {}, \"point\": {}}}\n });\n });\n\n it('correctly normalizes interpolated area with overlay line', () => {\n const spec: TopLevelSpec = {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": {\"type\": \"area\", \"interpolate\": \"monotone\"},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n },\n \"config\": {\"area\": {\"line\": {}}}\n };\n const normalizedSpec = normalize(spec, spec.config);\n assert.deepEqual>(normalizedSpec, {\n \"data\": {\"url\": \"data/stocks.csv\",\"format\": {\"type\": \"csv\"}},\n \"layer\": [\n {\n \"mark\": {\"type\": \"area\", \"opacity\": 0.7, \"interpolate\": \"monotone\"},\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"}\n }\n },\n {\n \"mark\": {\"type\": \"line\", \"interpolate\": \"monotone\"},\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"}\n }\n }\n ],\n \"config\": {\"area\": {\"line\": {}}}\n });\n });\n\n it('correctly normalizes area with disabled overlay point and line.', () => {\n for (const overlay of [null, false]) {\n const spec: TopLevelSpec = {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": {\"type\": \"area\", \"point\": overlay, \"line\": overlay},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n };\n const normalizedSpec = normalize(spec, spec.config);\n assert.deepEqual>(normalizedSpec, {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": \"area\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n }\n });\n }\n });\n\n it('correctly normalizes area with overlay point and line disabled in config.', () => {\n for (const overlay of [null, false]) {\n const spec: TopLevelSpec = {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": {\"type\": \"area\"},\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n },\n \"config\": {\n \"area\": {\"point\": overlay, \"line\": overlay}\n }\n };\n const normalizedSpec = normalize(spec, spec.config);\n assert.deepEqual>(normalizedSpec, {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": \"area\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"field\": \"price\", \"type\": \"quantitative\"}\n },\n \"config\": {\n \"area\": {\"point\": overlay, \"line\": overlay}\n }\n });\n }\n });\n\n it('correctly normalizes stacked area with overlay line', () => {\n const spec: TopLevelSpec = {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": \"area\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"aggregate\": \"sum\", \"field\": \"price\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"symbol\", \"type\": \"nominal\"}\n },\n \"config\": {\"area\": {\"line\": {}}}\n };\n const normalizedSpec = normalize(spec, spec.config);\n assert.deepEqual>(normalizedSpec, {\n \"data\": {\"url\": \"data/stocks.csv\",\"format\": {\"type\": \"csv\"}},\n \"layer\": [\n {\n \"mark\": {\"type\": \"area\", \"opacity\": 0.7},\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"aggregate\": \"sum\", \"field\": \"price\",\"type\": \"quantitative\"},\n \"color\": {\"field\": \"symbol\", \"type\": \"nominal\"}\n }\n },\n {\n \"mark\": {\"type\": \"line\"},\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"aggregate\": \"sum\", \"field\": \"price\",\"type\": \"quantitative\", \"stack\": \"zero\"},\n \"color\": {\"field\": \"symbol\", \"type\": \"nominal\"}\n }\n }\n ],\n \"config\": {\"area\": {\"line\": {}}}\n });\n });\n\n it('correctly normalizes streamgraph with overlay line', () => {\n const spec: TopLevelSpec = {\n \"data\": {\"url\": \"data/stocks.csv\", \"format\": {\"type\": \"csv\"}},\n \"mark\": \"area\",\n \"encoding\": {\n \"x\": {\"field\": \"date\", \"type\": \"temporal\"},\n \"y\": {\"aggregate\": \"sum\", \"field\": \"price\", \"type\": \"quantitative\", \"stack\": \"center\"},\n \"color\": {\"field\": \"symbol\", \"type\": \"nominal\"}\n },\n \"config\": {\"area\": {\"line\": {}}}\n };\n const normalizedSpec = normalize(spec, spec.config);\n assert.deepEqual>(normalizedSpec, {\n \"data\": {\"url\": \"data/stocks.csv\",\"format\": {\"type\": \"csv\"}},\n \"layer\": [\n {\n \"mark\": {\"type\": \"area\", \"opacity\": 0.7},\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"aggregate\": \"sum\", \"field\": \"price\",\"type\": \"quantitative\", \"stack\": \"center\"},\n \"color\": {\"field\": \"symbol\", \"type\": \"nominal\"}\n }\n },\n {\n \"mark\": {\"type\": \"line\"},\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"aggregate\": \"sum\", \"field\": \"price\",\"type\": \"quantitative\", \"stack\": \"center\"},\n \"color\": {\"field\": \"symbol\", \"type\": \"nominal\"}\n }\n }\n ],\n \"config\": {\"area\": {\"line\": {}}}\n });\n });\n });\n});\n\ndescribe('normalizeRangedUnitSpec', () => {\n it('should convert y2 -> y if there is no y in the encoding', function() {\n const spec: NormalizedSpec = {\n \"data\": {\"url\": \"data/population.json\"},\n \"mark\": \"rule\",\n \"encoding\": {\n \"y2\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\"aggregate\": \"min\", \"field\": \"people\", \"type\": \"quantitative\"},\n \"x2\": {\"aggregate\": \"max\", \"field\": \"people\", \"type\": \"quantitative\"}\n }\n };\n\n assert.deepEqual(normalize(spec, defaultConfig), {\n \"data\": {\"url\": \"data/population.json\"},\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\"aggregate\": \"min\", \"field\": \"people\", \"type\": \"quantitative\"},\n \"x2\": {\"aggregate\": \"max\", \"field\": \"people\", \"type\": \"quantitative\"}\n }\n });\n });\n\n it('should do nothing if there is no missing x or y', function() {\n const spec: NormalizedSpec = {\n \"data\": {\"url\": \"data/population.json\"},\n \"mark\": \"rule\",\n \"encoding\": {\n \"y\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"x\": {\"aggregate\": \"min\", \"field\": \"people\", \"type\": \"quantitative\"},\n \"x2\": {\"aggregate\": \"max\", \"field\": \"people\", \"type\": \"quantitative\"}\n }\n };\n\n assert.deepEqual(normalize(spec, defaultConfig), spec);\n });\n\n it('should convert x2 -> x if there is no x in the encoding', function() {\n const spec: NormalizedSpec = {\n \"data\": {\"url\": \"data/population.json\"},\n \"mark\": \"rule\",\n \"encoding\": {\n \"x2\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\"aggregate\": \"min\", \"field\": \"people\", \"type\": \"quantitative\"},\n \"y2\": {\"aggregate\": \"max\", \"field\": \"people\", \"type\": \"quantitative\"}\n }\n };\n\n assert.deepEqual(normalize(spec, defaultConfig), {\n \"data\": {\"url\": \"data/population.json\"},\n \"mark\": \"rule\",\n \"encoding\": {\n \"x\": {\"field\": \"age\",\"type\": \"ordinal\"},\n \"y\": {\"aggregate\": \"min\", \"field\": \"people\", \"type\": \"quantitative\"},\n \"y2\": {\"aggregate\": \"max\", \"field\": \"people\", \"type\": \"quantitative\"}\n }\n });\n });\n});\n\ndescribe('fieldDefs()', function() {\n it('should get all non-duplicate fieldDefs from an encoding', function() {\n const spec: any = {\n \"data\": {\"url\": \"data/cars.json\"},\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\"}\n }\n };\n\n assert.sameDeepMembers>(fieldDefs(spec), [\n {\"field\": \"Horsepower\",\"type\": \"quantitative\"},\n {\"field\": \"Miles_per_Gallon\",\"type\": \"quantitative\"}\n ]);\n });\n\n it('should get all non-duplicate fieldDefs from all layer in a LayerSpec', function() {\n const layerSpec: any = {\n \"data\": {\"url\": \"data/stocks.csv\",\"format\": {\"type\": \"csv\"}},\n \"layer\": [\n {\n \"description\": \"Google's stock price over time.\",\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"}\n }\n },\n {\n \"description\": \"Google's stock price over time.\",\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"},\n \"color\": {\"field\": \"symbol\", \"type\": \"nominal\"}\n },\n \"config\": {\"mark\": {\"filled\": true}}\n }\n ]\n };\n\n assert.sameDeepMembers>(fieldDefs(layerSpec), [\n {\"field\": \"date\",\"type\": \"temporal\"},\n {\"field\": \"price\",\"type\": \"quantitative\"},\n {\"field\": \"symbol\", \"type\": \"nominal\"}\n ]);\n });\n\n it('should get all non-duplicate fieldDefs from all layer in a LayerSpec (merging duplicate fields with different scale types)', function() {\n const layerSpec: any = {\n \"data\": {\"url\": \"data/stocks.csv\",\"format\": {\"type\": \"csv\"}},\n \"layer\": [\n {\n \"description\": \"Google's stock price over time.\",\n \"mark\": \"line\",\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"}\n }\n },\n {\n \"description\": \"Google's stock price over time.\",\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"date\",\"type\": \"temporal\"},\n \"y\": {\"field\": \"price\",\"type\": \"quantitative\"},\n \"color\": {\"field\": \"date\",\"type\": \"temporal\", \"scale\": {\"type\": \"pow\"}}\n },\n \"config\": {\"mark\": {\"filled\": true}}\n }\n ]\n };\n\n assert.sameDeepMembers>(fieldDefs(layerSpec), [\n {\"field\": \"date\",\"type\": \"temporal\"},\n {\"field\": \"price\",\"type\": \"quantitative\"}\n ]);\n });\n\n it('should get all non-duplicate fieldDefs from facet and layer in a FacetSpec', function() {\n const facetSpec: any = {\n \"data\": {\"url\": \"data/movies.json\"},\n \"facet\": {\"row\": {\"field\": \"MPAA_Rating\",\"type\": \"ordinal\"}},\n \"spec\": {\n \"mark\": \"point\",\n \"encoding\": {\n \"x\": {\"field\": \"Worldwide_Gross\",\"type\": \"quantitative\"},\n \"y\": {\"field\": \"US_DVD_Sales\",\"type\": \"quantitative\"}\n }\n }\n };\n\n assert.sameDeepMembers>(fieldDefs(facetSpec), [\n {\"field\": \"MPAA_Rating\",\"type\": \"ordinal\"},\n {\"field\": \"Worldwide_Gross\",\"type\": \"quantitative\"},\n {\"field\": \"US_DVD_Sales\",\"type\": \"quantitative\"}\n ]);\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/stack.test.d.ts b/build/test/stack.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/stack.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/stack.test.js b/build/test/stack.test.js new file mode 100644 index 0000000000..784378aa4c --- /dev/null +++ b/build/test/stack.test.js @@ -0,0 +1,462 @@ +/* tslint:disable:quotemark */ +import { assert } from 'chai'; +import { DETAIL, X, Y } from '../src/channel'; +import * as log from '../src/log'; +import { AREA, BAR, PRIMITIVE_MARKS, RECT } from '../src/mark'; +import { ScaleType } from '../src/scale'; +import { isStacked } from '../src/spec'; +import { stack, STACK_BY_DEFAULT_MARKS, STACKABLE_MARKS } from '../src/stack'; +describe('stack', function () { + var NON_STACKABLE_MARKS = [RECT]; + it('should be disabled for non-stackable marks with at least of of the stack channel', function () { + var _loop_1 = function (stacked) { + NON_STACKABLE_MARKS.forEach(function (nonStackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": nonStackableMark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack)); + assert.isFalse(isStacked(spec)); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize', null, 'none']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_1(stacked); + } + }); + it('should be allowed for raw plot', function () { + STACKABLE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "field": "yield", "type": "quantitative", "stack": "zero" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + } + }; + var stackProps = stack(spec.mark, spec.encoding, undefined); + assert.equal(stackProps.fieldChannel, 'x'); + assert.isTrue(isStacked(spec)); + }); + }); + it('should prioritize axis with stack', function () { + STACKABLE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "field": "yield", "type": "quantitative", "stack": "zero" }, + "y": { "field": "variety", "type": "quantitative" }, + "color": { "field": "site", "type": "nominal" } + } + }; + var stackProps = stack(spec.mark, spec.encoding, undefined); + assert.equal(stackProps.fieldChannel, 'x'); + assert.isTrue(isStacked(spec)); + }); + }); + it('should always be disabled if there is no stackby channel', function () { + var _loop_2 = function (stacked) { + PRIMITIVE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack)); + assert.isFalse(isStacked(spec)); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize', null, 'none']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_2(stacked); + } + }); + it('should always be disabled if the stackby channel is aggregated', function () { + var _loop_3 = function (stacked) { + PRIMITIVE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "aggregate": "count", "type": "quantitative" } + }, + "config": { + "stack": stacked + } + }; + assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack)); + assert.isFalse(isStacked(spec)); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize', null, 'none']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_3(stacked); + } + }); + it('should always be disabled if the stackby channel is identical to y', function () { + var _loop_4 = function (stacked) { + PRIMITIVE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "variety", "type": "nominal" }, + }, + "config": { + "stack": stacked + } + }; + assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack)); + assert.isFalse(isStacked(spec)); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize', null, 'none']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_4(stacked); + } + }); + it('can enabled if one of the stackby channels is not aggregated', function () { + var _loop_5 = function (stacked) { + var marks = stacked === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS; + marks.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "aggregate": "count", "type": "quantitative" }, + "detail": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + var _stack = stack(spec.mark, spec.encoding, spec.config.stack); + assert.isOk(_stack); + assert.isTrue(isStacked(spec)); + assert.equal(_stack.stackBy[0].channel, DETAIL); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_5(stacked); + } + }); + it('can enabled if one of the stackby channels is not aggregated', function () { + var _loop_6 = function (stacked) { + var marks = stacked === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS; + marks.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative", "stack": stacked }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "aggregate": "count", "type": "quantitative" }, + "detail": { "field": "site", "type": "nominal" } + } + }; + var _stack = stack(spec.mark, spec.encoding, undefined); + assert.isOk(_stack); + assert.isTrue(isStacked(spec)); + assert.equal(_stack.stackBy[0].channel, DETAIL); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_6(stacked); + } + }); + it('should always be disabled if both x and y are aggregate', function () { + var _loop_7 = function (stacked) { + PRIMITIVE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "aggregate": "count", "type": "quantitative" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack)); + assert.isFalse(isStacked(spec)); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize', null, 'none']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_7(stacked); + } + }); + it('should always be disabled if neither x nor y is aggregate or stack', function () { + var _loop_8 = function (stacked) { + PRIMITIVE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "field": "variety", "type": "nominal" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack)); + assert.isFalse(isStacked(spec)); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize', null, 'none']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_8(stacked); + } + }); + it('should always be disabled if there is both x and x2', function () { + var _loop_9 = function (stacked) { + var marks = stacked === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS; + marks.forEach(function (mark) { + var spec = { + "mark": mark, + "encoding": { + "x": { "field": "a", "type": "quantitative", "aggregate": "sum" }, + "x2": { "field": "a", "type": "quantitative", "aggregate": "sum" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack)); + assert.isFalse(isStacked(spec)); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_9(stacked); + } + }); + it('should always be disabled if there is both y and y2', function () { + var _loop_10 = function (stacked) { + var marks = stacked === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS; + marks.forEach(function (mark) { + var spec = { + "mark": mark, + "encoding": { + "y": { "field": "a", "type": "quantitative", "aggregate": "sum" }, + "y2": { "field": "a", "type": "quantitative", "aggregate": "sum" }, + "x": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack)); + assert.isFalse(isStacked(spec)); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_10(stacked); + } + }); + it('should always be warned if the aggregated axis has non-linear scale', log.wrap(function (localLogger) { + var _loop_11 = function (stacked) { + [ScaleType.LOG, ScaleType.POW, ScaleType.SQRT].forEach(function (scaleType) { + var marks = stacked === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS; + marks.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "field": "a", "type": "quantitative", "aggregate": "sum", "scale": { "type": scaleType } }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + assert.isNotNull(stack(spec.mark, spec.encoding, spec.config.stack)); + assert.isTrue(isStacked(spec)); + var warns = localLogger.warns; + assert.equal(warns[warns.length - 1], log.message.cannotStackNonLinearScale(scaleType)); + }); + }); + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_11(stacked); + } + })); + it('should throws warning if the aggregated axis has a non-summative aggregate', log.wrap(function (localLogger) { + var _loop_12 = function (stackOffset) { + var _loop_13 = function (aggregate) { + var marks = stackOffset === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS; + marks.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { + aggregate: aggregate, + stack: stackOffset, + "field": "a", + "type": "quantitative" + }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + } + }; + assert.isTrue(isStacked(spec)); + var warns = localLogger.warns; + assert.equal(warns[warns.length - 1], log.message.stackNonSummativeAggregate(aggregate)); + }); + }; + for (var _i = 0, _a = ['average', 'variance', 'q3']; _i < _a.length; _i++) { + var aggregate = _a[_i]; + _loop_13(aggregate); + } + }; + for (var _i = 0, _a = [undefined, 'center', 'zero', 'normalize']; _i < _a.length; _i++) { + var stackOffset = _a[_i]; + _loop_12(stackOffset); + } + })); + describe('stack().groupbyChannel, .fieldChannel', function () { + it('should be correct for horizontal', function () { + [BAR, AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + } + }; + var _stack = stack(spec.mark, spec.encoding, undefined); + assert.equal(_stack.fieldChannel, X); + assert.equal(_stack.groupbyChannel, Y); + assert.isTrue(isStacked(spec)); + }); + }); + it('should be correct for horizontal (single)', function () { + [BAR, AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "color": { "field": "site", "type": "nominal" } + } + }; + var _stack = stack(spec.mark, spec.encoding, undefined); + assert.equal(_stack.fieldChannel, X); + assert.equal(_stack.groupbyChannel, null); + assert.isTrue(isStacked(spec)); + }); + }); + it('should be correct for vertical', function () { + [BAR, AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "y": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "x": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + } + }; + var _stack = stack(spec.mark, spec.encoding, undefined); + assert.equal(_stack.fieldChannel, Y); + assert.equal(_stack.groupbyChannel, X); + assert.isTrue(isStacked(spec)); + }); + }); + it('should be correct for vertical (single)', function () { + [BAR, AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "y": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "color": { "field": "site", "type": "nominal" } + } + }; + var _stack = stack(spec.mark, spec.encoding, undefined); + assert.equal(_stack.fieldChannel, Y); + assert.equal(_stack.groupbyChannel, null); + assert.isTrue(isStacked(spec)); + }); + }); + }); + describe('stack().offset', function () { + it('should be zero for stackable marks with at least of of the stack channel if stacked is unspecified', function () { + [BAR, AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + } + }; + assert.equal(stack(spec.mark, spec.encoding, undefined).offset, 'zero'); + assert.isTrue(isStacked(spec)); + }); + }); + it('should be the specified stacked for stackable marks with at least one of the stack channel', function () { + var _loop_14 = function (stacked) { + [BAR, AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + assert.equal(stack(spec.mark, spec.encoding, spec.config.stack).offset, stacked); + assert.equal(isStacked(spec), true); + }); + }; + for (var _i = 0, _a = ['center', 'zero', 'normalize']; _i < _a.length; _i++) { + var stacked = _a[_i]; + _loop_14(stacked); + } + }); + }); +}); +//# sourceMappingURL=stack.test.js.map \ No newline at end of file diff --git a/build/test/stack.test.js.map b/build/test/stack.test.js.map new file mode 100644 index 0000000000..32697b90ec --- /dev/null +++ b/build/test/stack.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"stack.test.js","sourceRoot":"","sources":["../../test/stack.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* tslint:disable:quotemark */\nimport {assert} from 'chai';\nimport {AggregateOp} from 'vega';\n\nimport {DETAIL, X, Y} from '../src/channel';\nimport * as log from '../src/log';\nimport {AREA, BAR, PRIMITIVE_MARKS, RECT} from '../src/mark';\nimport {ScaleType} from '../src/scale';\nimport {isStacked, NormalizedUnitSpec, TopLevel} from '../src/spec';\nimport {stack, STACK_BY_DEFAULT_MARKS, STACKABLE_MARKS, StackOffset} from '../src/stack';\n\ndescribe('stack', () => {\n const NON_STACKABLE_MARKS = [RECT];\n\n it('should be disabled for non-stackable marks with at least of of the stack channel', () => {\n for (const stacked of [undefined, 'center', 'zero', 'normalize', null, 'none'] as StackOffset[]) {\n NON_STACKABLE_MARKS.forEach((nonStackableMark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": nonStackableMark,\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n },\n \"config\": {\n \"stack\": stacked\n }\n };\n assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack));\n assert.isFalse(isStacked(spec));\n });\n }\n });\n\n it('should be allowed for raw plot', () => {\n STACKABLE_MARKS.forEach((mark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\"field\": \"yield\", \"type\": \"quantitative\", \"stack\": \"zero\"},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n }\n };\n const stackProps = stack(spec.mark, spec.encoding, undefined);\n assert.equal(stackProps.fieldChannel, 'x');\n assert.isTrue(isStacked(spec));\n });\n });\n\n\n it('should prioritize axis with stack', () => {\n STACKABLE_MARKS.forEach((mark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\"field\": \"yield\", \"type\": \"quantitative\", \"stack\": \"zero\"},\n \"y\": {\"field\": \"variety\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n }\n };\n const stackProps = stack(spec.mark, spec.encoding, undefined);\n assert.equal(stackProps.fieldChannel, 'x');\n assert.isTrue(isStacked(spec));\n });\n });\n\n it('should always be disabled if there is no stackby channel', () => {\n for (const stacked of [undefined, 'center', 'zero', 'normalize', null, 'none'] as StackOffset[]) {\n PRIMITIVE_MARKS.forEach((mark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"}\n },\n \"config\": {\n \"stack\": stacked\n }\n };\n assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack));\n assert.isFalse(isStacked(spec));\n });\n }\n });\n\n it('should always be disabled if the stackby channel is aggregated', () => {\n for (const stacked of [undefined, 'center', 'zero', 'normalize', null, 'none'] as StackOffset[]) {\n PRIMITIVE_MARKS.forEach((mark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"aggregate\": \"count\", \"type\": \"quantitative\"}\n },\n \"config\": {\n \"stack\": stacked\n }\n };\n assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack));\n assert.isFalse(isStacked(spec));\n });\n }\n });\n\n it('should always be disabled if the stackby channel is identical to y', () => {\n for (const stacked of [undefined, 'center', 'zero', 'normalize', null, 'none'] as StackOffset[]) {\n PRIMITIVE_MARKS.forEach((mark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"variety\", \"type\": \"nominal\"},\n },\n \"config\": {\n \"stack\": stacked\n }\n };\n assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack));\n assert.isFalse(isStacked(spec));\n });\n }\n });\n\n it('can enabled if one of the stackby channels is not aggregated', () => {\n for (const stacked of [undefined, 'center', 'zero', 'normalize'] as StackOffset[]) {\n const marks = stacked === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS;\n marks.forEach((mark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"aggregate\": \"count\", \"type\": \"quantitative\"},\n \"detail\": {\"field\": \"site\", \"type\": \"nominal\"}\n },\n \"config\": {\n \"stack\": stacked\n }\n };\n const _stack = stack(spec.mark, spec.encoding, spec.config.stack);\n assert.isOk(_stack);\n assert.isTrue(isStacked(spec));\n assert.equal(_stack.stackBy[0].channel, DETAIL);\n });\n }\n });\n\n it('can enabled if one of the stackby channels is not aggregated', () => {\n for (const stacked of [undefined, 'center', 'zero', 'normalize'] as StackOffset[]) {\n const marks = stacked === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS;\n marks.forEach((mark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\", \"stack\": stacked},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"aggregate\": \"count\", \"type\": \"quantitative\"},\n \"detail\": {\"field\": \"site\", \"type\": \"nominal\"}\n }\n };\n\n const _stack = stack(spec.mark, spec.encoding, undefined);\n assert.isOk(_stack);\n assert.isTrue(isStacked(spec));\n assert.equal(_stack.stackBy[0].channel, DETAIL);\n });\n }\n });\n\n it('should always be disabled if both x and y are aggregate', () => {\n for (const stacked of [undefined, 'center', 'zero', 'normalize', null, 'none'] as StackOffset[]) {\n PRIMITIVE_MARKS.forEach((mark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"y\": {\"aggregate\": \"count\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n },\n \"config\": {\n \"stack\": stacked\n }\n };\n assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack));\n assert.isFalse(isStacked(spec));\n });\n }\n });\n\n it('should always be disabled if neither x nor y is aggregate or stack', () => {\n for (const stacked of [undefined, 'center', 'zero', 'normalize', null, 'none'] as StackOffset[]) {\n PRIMITIVE_MARKS.forEach((mark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n },\n \"config\": {\n \"stack\": stacked\n }\n };\n assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack));\n assert.isFalse(isStacked(spec));\n });\n }\n });\n\n it('should always be disabled if there is both x and x2', () => {\n for (const stacked of [undefined, 'center', 'zero', 'normalize'] as StackOffset[]) {\n const marks = stacked === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS;\n marks.forEach((mark) => {\n const spec: TopLevel = {\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"quantitative\", \"aggregate\": \"sum\"},\n \"x2\": {\"field\": \"a\", \"type\": \"quantitative\", \"aggregate\": \"sum\"},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n },\n \"config\": {\n \"stack\": stacked\n }\n };\n assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack));\n assert.isFalse(isStacked(spec));\n });\n }\n });\n\n it('should always be disabled if there is both y and y2', () => {\n for (const stacked of [undefined, 'center', 'zero', 'normalize'] as StackOffset[]) {\n const marks = stacked === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS;\n marks.forEach((mark) => {\n const spec: TopLevel = {\n \"mark\": mark,\n \"encoding\": {\n \"y\": {\"field\": \"a\", \"type\": \"quantitative\", \"aggregate\": \"sum\"},\n \"y2\": {\"field\": \"a\", \"type\": \"quantitative\", \"aggregate\": \"sum\"},\n \"x\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n },\n \"config\": {\n \"stack\": stacked\n }\n };\n assert.isNull(stack(spec.mark, spec.encoding, spec.config.stack));\n assert.isFalse(isStacked(spec));\n });\n }\n });\n\n it('should always be warned if the aggregated axis has non-linear scale', log.wrap((localLogger) => {\n for (const stacked of [undefined, 'center', 'zero', 'normalize'] as StackOffset[]) {\n [ScaleType.LOG, ScaleType.POW, ScaleType.SQRT].forEach((scaleType) => {\n const marks = stacked === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS;\n marks.forEach((mark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\"field\": \"a\", \"type\": \"quantitative\", \"aggregate\": \"sum\", \"scale\": {\"type\": scaleType}},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n },\n \"config\": {\n \"stack\": stacked\n }\n };\n assert.isNotNull(stack(spec.mark, spec.encoding, spec.config.stack));\n assert.isTrue(isStacked(spec));\n const warns = localLogger.warns;\n assert.equal(warns[warns.length-1], log.message.cannotStackNonLinearScale(scaleType));\n });\n });\n }\n }));\n\n it('should throws warning if the aggregated axis has a non-summative aggregate', log.wrap((localLogger) => {\n for (const stackOffset of [undefined, 'center', 'zero', 'normalize'] as StackOffset[]) {\n for (const aggregate of ['average', 'variance', 'q3'] as AggregateOp[]) {\n const marks = stackOffset === undefined ? STACK_BY_DEFAULT_MARKS : STACKABLE_MARKS;\n marks.forEach((mark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": mark,\n \"encoding\": {\n \"x\": {\n aggregate,\n stack: stackOffset,\n \"field\": \"a\",\n \"type\": \"quantitative\"\n },\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n }\n };\n assert.isTrue(isStacked(spec));\n const warns = localLogger.warns;\n assert.equal(warns[warns.length-1], log.message.stackNonSummativeAggregate(aggregate));\n });\n }\n }\n }));\n\n describe('stack().groupbyChannel, .fieldChannel', () => {\n it('should be correct for horizontal', () => {\n [BAR, AREA].forEach((stackableMark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": stackableMark,\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n }\n };\n const _stack = stack(spec.mark, spec.encoding, undefined);\n assert.equal(_stack.fieldChannel, X);\n assert.equal(_stack.groupbyChannel, Y);\n assert.isTrue(isStacked(spec));\n });\n });\n\n it('should be correct for horizontal (single)', () => {\n [BAR, AREA].forEach((stackableMark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": stackableMark,\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n }\n };\n const _stack = stack(spec.mark, spec.encoding, undefined);\n assert.equal(_stack.fieldChannel, X);\n assert.equal(_stack.groupbyChannel, null);\n assert.isTrue(isStacked(spec));\n });\n });\n\n it('should be correct for vertical', () => {\n [BAR, AREA].forEach((stackableMark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": stackableMark,\n \"encoding\": {\n \"y\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"x\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n }\n };\n const _stack = stack(spec.mark, spec.encoding, undefined);\n assert.equal(_stack.fieldChannel, Y);\n assert.equal(_stack.groupbyChannel, X);\n assert.isTrue(isStacked(spec));\n });\n });\n\n it('should be correct for vertical (single)', () => {\n [BAR, AREA].forEach((stackableMark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": stackableMark,\n \"encoding\": {\n \"y\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n }\n };\n const _stack = stack(spec.mark, spec.encoding, undefined);\n assert.equal(_stack.fieldChannel, Y);\n assert.equal(_stack.groupbyChannel, null);\n assert.isTrue(isStacked(spec));\n });\n });\n });\n\n describe('stack().offset', () => {\n it('should be zero for stackable marks with at least of of the stack channel if stacked is unspecified', () => {\n [BAR, AREA].forEach((stackableMark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": stackableMark,\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n }\n };\n assert.equal(stack(spec.mark, spec.encoding, undefined).offset, 'zero');\n assert.isTrue(isStacked(spec));\n });\n });\n\n it('should be the specified stacked for stackable marks with at least one of the stack channel', () => {\n for (const stacked of ['center', 'zero', 'normalize'] as StackOffset[]) {\n [BAR, AREA].forEach((stackableMark) => {\n const spec: TopLevel = {\n \"data\": {\"url\": \"data/barley.json\"},\n \"mark\": stackableMark,\n \"encoding\": {\n \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n },\n \"config\": {\n \"stack\": stacked\n }\n };\n assert.equal(stack(spec.mark, spec.encoding, spec.config.stack).offset, stacked);\n assert.equal(isStacked(spec), true);\n });\n }\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/timeunit.test.d.ts b/build/test/timeunit.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/timeunit.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/timeunit.test.js b/build/test/timeunit.test.js new file mode 100644 index 0000000000..26e88dbe8e --- /dev/null +++ b/build/test/timeunit.test.js @@ -0,0 +1,151 @@ +import { assert } from 'chai'; +import { containsTimeUnit, convert, fieldExpr, formatExpression, TimeUnit } from '../src/timeunit'; +describe('timeUnit', function () { + describe('containsTimeUnit', function () { + it('should return true for quarter given quarter', function () { + var fullTimeUnit = TimeUnit.QUARTER; + var timeUnit = TimeUnit.QUARTER; + assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return true for yearquarter given quarter', function () { + var fullTimeUnit = TimeUnit.YEARQUARTER; + var timeUnit = TimeUnit.QUARTER; + assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return true for SECONDS and MILLISECONDS given SECONDSMILLISECONDS', function () { + var fullTimeUnit = TimeUnit.SECONDSMILLISECONDS; + var timeUnit = TimeUnit.SECONDS; + assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return true for MILLISECONDS given SECONDSMILLISECONDS', function () { + var fullTimeUnit = TimeUnit.SECONDSMILLISECONDS; + var timeUnit = TimeUnit.MILLISECONDS; + assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return false for quarter given year', function () { + var fullTimeUnit = TimeUnit.YEAR; + var timeUnit = TimeUnit.QUARTER; + assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), false); + }); + it('should return false for SECONDS given MILLISECONDS', function () { + var fullTimeUnit = TimeUnit.MILLISECONDS; + var timeUnit = TimeUnit.SECONDS; + assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), false); + }); + }); + describe('fieldExpr', function () { + it('should return correct field expression for YEARMONTHDATEHOURSMINUTESSECONDS', function () { + assert.equal(fieldExpr(TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, 'x'), 'datetime(year(datum["x"]), month(datum["x"]), date(datum["x"]), hours(datum["x"]), minutes(datum["x"]), seconds(datum["x"]), 0)'); + }); + it('should return correct field expression for QUARTER', function () { + assert.equal(fieldExpr(TimeUnit.QUARTER, 'x'), 'datetime(0, (quarter(datum["x"])-1)*3, 1, 0, 0, 0, 0)'); + }); + it('should return correct field expression for DAY', function () { + assert.equal(fieldExpr(TimeUnit.DAY, 'x'), 'datetime(2006, 0, day(datum["x"])+1, 0, 0, 0, 0)'); + }); + it('should return correct field expression for MILLISECONDS', function () { + assert.equal(fieldExpr(TimeUnit.MILLISECONDS, 'x'), 'datetime(0, 0, 1, 0, 0, 0, milliseconds(datum["x"]))'); + }); + it('should return correct field expression with utc for MILLISECONDS', function () { + assert.equal(fieldExpr(TimeUnit.UTCQUARTER, 'x'), 'datetime(0, (utcquarter(datum["x"])-1)*3, 1, 0, 0, 0, 0)'); + assert.equal(fieldExpr(TimeUnit.UTCMILLISECONDS, 'x'), 'datetime(0, 0, 1, 0, 0, 0, utcmilliseconds(datum["x"]))'); + }); + }); + describe('convert', function () { + it('should throw an error for the DAY timeunit', function () { + assert.throws(function () { + convert(TimeUnit.DAY, new Date(2000, 11, 2, 23, 59, 59, 999)); + }, Error, 'Cannot convert to TimeUnits containing \'day\''); + }); + it('should return expected result for YEARQUARTER', function () { + var date = convert(TimeUnit.YEARQUARTER, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(2000, 9, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for UTCYEARQUARTER', function () { + var date = convert(TimeUnit.UTCYEARQUARTER, new Date(Date.UTC(2000, 11, 2, 23, 59, 59, 999))); + assert.equal(date.getTime(), new Date(Date.UTC(2000, 9, 1, 0, 0, 0, 0)).getTime()); + }); + it('should return expected result for YEARQUARTERMONTH', function () { + var date = convert(TimeUnit.YEARQUARTERMONTH, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(2000, 11, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTH', function () { + var date = convert(TimeUnit.YEARMONTH, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(2000, 11, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for UTCYEARMONTH', function () { + var date = convert(TimeUnit.UTCYEARMONTH, new Date(Date.UTC(2000, 11, 2, 23, 59, 59, 999))); + assert.equal(date.getTime(), new Date(Date.UTC(2000, 11, 1, 0, 0, 0, 0)).getTime()); + }); + it('should return expected result for UTCYEARMONTH', function () { + var date = convert(TimeUnit.UTCYEAR, new Date(Date.UTC(2000, 11, 2, 23, 59, 59, 999))); + assert.equal(date.getTime(), new Date(Date.UTC(2000, 0, 1, 0, 0, 0, 0)).getTime()); + }); + it('should return expected result for YEARMONTHDATE', function () { + var date = convert(TimeUnit.YEARMONTHDATE, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(2000, 11, 2, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTHDATEHOURS', function () { + var date = convert(TimeUnit.YEARMONTHDATEHOURS, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 0, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTHDATEHOURSMINUTES', function () { + var date = convert(TimeUnit.YEARMONTHDATEHOURSMINUTES, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 59, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTHDATEHOURSMINUTESSECONDS', function () { + var date = convert(TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 59, 59, 0).getTime()); + }); + it('should return expected result for QUARTERMONTH', function () { + var date = convert(TimeUnit.QUARTERMONTH, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(1900, 11, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for HOURSMINUTES', function () { + var date = convert(TimeUnit.HOURSMINUTES, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(1900, 0, 1, 23, 59, 0, 0).getTime()); + }); + it('should return expected result for HOURSMINUTESSECONDS', function () { + var date = convert(TimeUnit.HOURSMINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(1900, 0, 1, 23, 59, 59, 0).getTime()); + }); + it('should return expected result for MINUTESSECONDS', function () { + var date = convert(TimeUnit.MINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(1900, 0, 1, 0, 59, 59, 0).getTime()); + }); + it('should return expected result for SECONDSMILLISECONDS', function () { + var date = convert(TimeUnit.SECONDSMILLISECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + assert.equal(date.getTime(), new Date(1900, 0, 1, 0, 0, 59, 999).getTime()); + }); + }); + describe('template', function () { + it('should return correct template for YEARMONTHDATEHOURSMINUTESSECONDS', function () { + assert.equal(formatExpression(TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, 'datum.x', undefined, false), "timeFormat(datum.x, '%b %d, %Y %H:%M:%S')"); + }); + it('should return correct template for YEARMONTH (No comma)', function () { + assert.equal(formatExpression(TimeUnit.YEARMONTH, 'datum.x', undefined, false), "timeFormat(datum.x, '%b %Y')"); + }); + it('should return correct template for DAY', function () { + assert.equal(formatExpression(TimeUnit.DAY, 'datum.x', undefined, false), "timeFormat(datum.x, '%A')"); + }); + it('should return correct template for DAY (shortened)', function () { + assert.equal(formatExpression(TimeUnit.DAY, 'datum.x', true, false), "timeFormat(datum.x, '%a')"); + }); + it('should return correct template for QUARTER', function () { + assert.equal(formatExpression(TimeUnit.QUARTER, 'datum.x', undefined, false), "'Q' + quarter(datum.x)"); + }); + it('should return correct template for YEARQUARTER', function () { + assert.equal(formatExpression(TimeUnit.YEARQUARTER, 'datum.x', undefined, false), "'Q' + quarter(datum.x) + ' ' + timeFormat(datum.x, '%Y')"); + }); + it('should return correct template for milliseconds', function () { + assert.equal(formatExpression(TimeUnit.MILLISECONDS, 'datum.x', undefined, false), "timeFormat(datum.x, '%L')"); + }); + it('should return correct template for no timeUnit', function () { + assert.equal(formatExpression(undefined, 'datum.x', undefined, false), undefined); + }); + it('should return correct template for YEARMONTH (No comma) with utc scale', function () { + assert.equal(formatExpression(TimeUnit.YEARMONTH, 'datum.x', undefined, true), "utcFormat(datum.x, '%b %Y')"); + }); + }); +}); +//# sourceMappingURL=timeunit.test.js.map \ No newline at end of file diff --git a/build/test/timeunit.test.js.map b/build/test/timeunit.test.js.map new file mode 100644 index 0000000000..3159ebbadc --- /dev/null +++ b/build/test/timeunit.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"timeunit.test.js","sourceRoot":"","sources":["../../test/timeunit.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {containsTimeUnit, convert, fieldExpr, formatExpression, TimeUnit} from '../src/timeunit';\n\n\ndescribe('timeUnit', () => {\n describe('containsTimeUnit', function () {\n it('should return true for quarter given quarter', function() {\n const fullTimeUnit = TimeUnit.QUARTER;\n const timeUnit = TimeUnit.QUARTER;\n assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), true);\n });\n\n it('should return true for yearquarter given quarter', function() {\n const fullTimeUnit = TimeUnit.YEARQUARTER;\n const timeUnit = TimeUnit.QUARTER;\n assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), true);\n });\n\n it('should return true for SECONDS and MILLISECONDS given SECONDSMILLISECONDS', function() {\n const fullTimeUnit = TimeUnit.SECONDSMILLISECONDS;\n const timeUnit = TimeUnit.SECONDS;\n assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), true);\n });\n\n it('should return true for MILLISECONDS given SECONDSMILLISECONDS', function() {\n const fullTimeUnit = TimeUnit.SECONDSMILLISECONDS;\n const timeUnit = TimeUnit.MILLISECONDS;\n assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), true);\n });\n\n it('should return false for quarter given year', function() {\n const fullTimeUnit = TimeUnit.YEAR;\n const timeUnit = TimeUnit.QUARTER;\n assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), false);\n });\n\n it('should return false for SECONDS given MILLISECONDS', function() {\n const fullTimeUnit = TimeUnit.MILLISECONDS;\n const timeUnit = TimeUnit.SECONDS;\n assert.equal(containsTimeUnit(fullTimeUnit, timeUnit), false);\n });\n });\n\n describe('fieldExpr', () => {\n it('should return correct field expression for YEARMONTHDATEHOURSMINUTESSECONDS', () => {\n assert.equal(\n fieldExpr(TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, 'x'),\n 'datetime(year(datum[\"x\"]), month(datum[\"x\"]), date(datum[\"x\"]), hours(datum[\"x\"]), minutes(datum[\"x\"]), seconds(datum[\"x\"]), 0)'\n );\n });\n\n it('should return correct field expression for QUARTER', () => {\n assert.equal(\n fieldExpr(TimeUnit.QUARTER, 'x'),\n 'datetime(0, (quarter(datum[\"x\"])-1)*3, 1, 0, 0, 0, 0)'\n );\n });\n\n it('should return correct field expression for DAY', () => {\n assert.equal(\n fieldExpr(TimeUnit.DAY, 'x'),\n 'datetime(2006, 0, day(datum[\"x\"])+1, 0, 0, 0, 0)'\n );\n });\n\n it('should return correct field expression for MILLISECONDS', () => {\n assert.equal(\n fieldExpr(TimeUnit.MILLISECONDS, 'x'),\n 'datetime(0, 0, 1, 0, 0, 0, milliseconds(datum[\"x\"]))'\n );\n });\n\n it('should return correct field expression with utc for MILLISECONDS', () => {\n assert.equal(\n fieldExpr(TimeUnit.UTCQUARTER, 'x'),\n 'datetime(0, (utcquarter(datum[\"x\"])-1)*3, 1, 0, 0, 0, 0)'\n );\n\n assert.equal(\n fieldExpr(TimeUnit.UTCMILLISECONDS, 'x'),\n 'datetime(0, 0, 1, 0, 0, 0, utcmilliseconds(datum[\"x\"]))'\n );\n });\n });\n\n describe('convert', function () {\n it('should throw an error for the DAY timeunit', function() {\n assert.throws(function() {\n convert(TimeUnit.DAY, new Date(2000, 11, 2, 23, 59, 59, 999));\n }, Error, 'Cannot convert to TimeUnits containing \\'day\\'');\n });\n\n it('should return expected result for YEARQUARTER', function() {\n const date: Date = convert(TimeUnit.YEARQUARTER, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(2000, 9, 1, 0, 0, 0, 0).getTime());\n });\n\n it('should return expected result for UTCYEARQUARTER', function() {\n const date: Date = convert(TimeUnit.UTCYEARQUARTER, new Date(Date.UTC(2000, 11, 2, 23, 59, 59, 999)));\n assert.equal(date.getTime(), new Date(Date.UTC(2000, 9, 1, 0, 0, 0, 0)).getTime());\n });\n\n it('should return expected result for YEARQUARTERMONTH', function() {\n const date: Date = convert(TimeUnit.YEARQUARTERMONTH, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(2000, 11, 1, 0, 0, 0, 0).getTime());\n });\n\n it('should return expected result for YEARMONTH', function() {\n const date: Date = convert(TimeUnit.YEARMONTH, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(2000, 11, 1, 0, 0, 0, 0).getTime());\n });\n\n it('should return expected result for UTCYEARMONTH', function() {\n const date: Date = convert(TimeUnit.UTCYEARMONTH, new Date(Date.UTC(2000, 11, 2, 23, 59, 59, 999)));\n assert.equal(date.getTime(), new Date(Date.UTC(2000, 11, 1, 0, 0, 0, 0)).getTime());\n });\n\n\n it('should return expected result for UTCYEARMONTH', function() {\n const date: Date = convert(TimeUnit.UTCYEAR, new Date(Date.UTC(2000, 11, 2, 23, 59, 59, 999)));\n assert.equal(date.getTime(), new Date(Date.UTC(2000, 0, 1, 0, 0, 0, 0)).getTime());\n });\n\n it('should return expected result for YEARMONTHDATE', function() {\n const date: Date = convert(TimeUnit.YEARMONTHDATE, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(2000, 11, 2, 0, 0, 0, 0).getTime());\n });\n\n it('should return expected result for YEARMONTHDATEHOURS', function() {\n const date: Date = convert(TimeUnit.YEARMONTHDATEHOURS, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 0, 0, 0).getTime());\n });\n\n it('should return expected result for YEARMONTHDATEHOURSMINUTES', function() {\n const date: Date = convert(TimeUnit.YEARMONTHDATEHOURSMINUTES, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 59, 0, 0).getTime());\n });\n\n it('should return expected result for YEARMONTHDATEHOURSMINUTESSECONDS', function() {\n const date: Date = convert(TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 59, 59, 0).getTime());\n });\n\n it('should return expected result for QUARTERMONTH', function() {\n const date: Date = convert(TimeUnit.QUARTERMONTH, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(1900, 11, 1, 0, 0, 0, 0).getTime());\n });\n\n it('should return expected result for HOURSMINUTES', function() {\n const date: Date = convert(TimeUnit.HOURSMINUTES, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(1900, 0, 1, 23, 59, 0, 0).getTime());\n });\n\n it('should return expected result for HOURSMINUTESSECONDS', function() {\n const date: Date = convert(TimeUnit.HOURSMINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(1900, 0, 1, 23, 59, 59, 0).getTime());\n });\n\n it('should return expected result for MINUTESSECONDS', function() {\n const date: Date = convert(TimeUnit.MINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(1900, 0, 1, 0, 59, 59, 0).getTime());\n });\n\n it('should return expected result for SECONDSMILLISECONDS', function() {\n const date: Date = convert(TimeUnit.SECONDSMILLISECONDS, new Date(2000, 11, 2, 23, 59, 59, 999));\n assert.equal(date.getTime(), new Date(1900, 0, 1, 0, 0, 59, 999).getTime());\n });\n });\n\n describe('template', () => {\n it('should return correct template for YEARMONTHDATEHOURSMINUTESSECONDS', () => {\n assert.equal(\n formatExpression(TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS,'datum.x', undefined, false),\n \"timeFormat(datum.x, '%b %d, %Y %H:%M:%S')\"\n );\n });\n\n it('should return correct template for YEARMONTH (No comma)', () => {\n assert.equal(\n formatExpression(TimeUnit.YEARMONTH,'datum.x', undefined, false),\n \"timeFormat(datum.x, '%b %Y')\"\n );\n });\n\n it('should return correct template for DAY', () => {\n assert.equal(\n formatExpression(TimeUnit.DAY,'datum.x', undefined, false),\n \"timeFormat(datum.x, '%A')\"\n );\n });\n\n it('should return correct template for DAY (shortened)', () => {\n assert.equal(\n formatExpression(TimeUnit.DAY,'datum.x', true, false),\n \"timeFormat(datum.x, '%a')\"\n );\n });\n\n it('should return correct template for QUARTER', () => {\n assert.equal(\n formatExpression(TimeUnit.QUARTER,'datum.x', undefined, false),\n \"'Q' + quarter(datum.x)\"\n );\n });\n\n it('should return correct template for YEARQUARTER', () => {\n assert.equal(\n formatExpression(TimeUnit.YEARQUARTER,'datum.x', undefined, false),\n \"'Q' + quarter(datum.x) + ' ' + timeFormat(datum.x, '%Y')\"\n );\n });\n\n it('should return correct template for milliseconds', () => {\n assert.equal(\n formatExpression(TimeUnit.MILLISECONDS,'datum.x', undefined, false),\n \"timeFormat(datum.x, '%L')\"\n );\n });\n\n it('should return correct template for no timeUnit', () => {\n assert.equal(\n formatExpression(undefined,'datum.x', undefined, false),\n undefined\n );\n });\n\n it('should return correct template for YEARMONTH (No comma) with utc scale', () => {\n assert.equal(\n formatExpression(TimeUnit.YEARMONTH,'datum.x', undefined, true),\n \"utcFormat(datum.x, '%b %Y')\"\n );\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/transform.test.d.ts b/build/test/transform.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/transform.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/transform.test.js b/build/test/transform.test.js new file mode 100644 index 0000000000..bffefb664a --- /dev/null +++ b/build/test/transform.test.js @@ -0,0 +1,26 @@ +import { assert } from 'chai'; +import * as log from '../src/log'; +import { normalizeTransform } from '../src/transform'; +describe('normalizeTransform()', function () { + it('replaces filter with timeUnit=yearmonthday with yearmonthdate and throws the right warning', log.wrap(function (localLogger) { + var filter = { + and: [ + { not: { timeUnit: 'yearmonthday', field: 'd', equal: { year: 2008 } } }, + { or: [{ field: 'a', equal: 5 }] } + ] + }; + var transform = [ + { filter: filter } + ]; + assert.deepEqual(normalizeTransform(transform), [{ + filter: { + and: [ + { not: { timeUnit: 'yearmonthdate', field: 'd', equal: { year: 2008 } } }, + { or: [{ field: 'a', equal: 5 }] } + ] + } + }]); + assert.equal(localLogger.warns[0], log.message.dayReplacedWithDate('yearmonthday')); + })); +}); +//# sourceMappingURL=transform.test.js.map \ No newline at end of file diff --git a/build/test/transform.test.js.map b/build/test/transform.test.js.map new file mode 100644 index 0000000000..090f725e3a --- /dev/null +++ b/build/test/transform.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"transform.test.js","sourceRoot":"","sources":["../../test/transform.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAIlC,OAAO,EAAC,kBAAkB,EAAY,MAAM,kBAAkB,CAAC;AAE/D,QAAQ,CAAC,sBAAsB,EAAE;IAC/B,EAAE,CAAC,4FAA4F,EAAE,GAAG,CAAC,IAAI,CAAC,UAAC,WAAW;QACpH,IAAM,MAAM,GAA8B;YACxC,GAAG,EAAE;gBACH,EAAC,GAAG,EAAE,EAAC,QAAQ,EAAE,cAA0B,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,EAAC,EAAC;gBAC9E,EAAC,EAAE,EAAE,CAAC,EAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAC,CAAC,EAAC;aAC/B;SACF,CAAC;QACF,IAAM,SAAS,GAAgB;YAC7B,EAAC,MAAM,QAAA,EAAC;SACT,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC/C,MAAM,EAAE;oBACN,GAAG,EAAE;wBACH,EAAC,GAAG,EAAE,EAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,EAAC,EAAC;wBACnE,EAAC,EAAE,EAAE,CAAC,EAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAC,CAAC,EAAC;qBAC/B;iBACF;aACF,CAAC,CAAC,CAAC;QACJ,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC,CAAC;AACN,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\nimport * as log from '../src/log';\nimport {LogicalOperand} from '../src/logical';\nimport {Predicate} from '../src/predicate';\nimport {TimeUnit} from '../src/timeunit';\nimport {normalizeTransform, Transform} from '../src/transform';\n\ndescribe('normalizeTransform()', () => {\n it('replaces filter with timeUnit=yearmonthday with yearmonthdate and throws the right warning', log.wrap((localLogger) => {\n const filter: LogicalOperand = {\n and: [\n {not: {timeUnit: 'yearmonthday' as TimeUnit, field: 'd', equal: {year: 2008}}},\n {or: [{field: 'a', equal: 5}]}\n ]\n };\n const transform: Transform[] = [\n {filter}\n ];\n assert.deepEqual(normalizeTransform(transform), [{\n filter: {\n and: [\n {not: {timeUnit: 'yearmonthdate', field: 'd', equal: {year: 2008}}},\n {or: [{field: 'a', equal: 5}]}\n ]\n }\n }]);\n assert.equal(localLogger.warns[0], log.message.dayReplacedWithDate('yearmonthday'));\n }));\n});\n"]} \ No newline at end of file diff --git a/build/test/type.test.d.ts b/build/test/type.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/type.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/type.test.js b/build/test/type.test.js new file mode 100644 index 0000000000..72b7d1a3bb --- /dev/null +++ b/build/test/type.test.js @@ -0,0 +1,40 @@ +import { assert } from 'chai'; +import * as type from '../src/type'; +describe('type', function () { + describe('getFullName()', function () { + it('should return correct lowercase, full type names.', function () { + for (var _i = 0, _a = ['q', 'Q', 'quantitative', 'QUANTITATIVE']; _i < _a.length; _i++) { + var t = _a[_i]; + assert.equal(type.getFullName(t), 'quantitative'); + } + for (var _b = 0, _c = ['t', 'T', 'temporal', 'TEMPORAL']; _b < _c.length; _b++) { + var t = _c[_b]; + assert.equal(type.getFullName(t), 'temporal'); + } + for (var _d = 0, _e = ['o', 'O', 'ordinal', 'ORDINAL']; _d < _e.length; _d++) { + var t = _e[_d]; + assert.equal(type.getFullName(t), 'ordinal'); + } + for (var _f = 0, _g = ['n', 'N', 'nominal', 'NOMINAL']; _f < _g.length; _f++) { + var t = _g[_f]; + assert.equal(type.getFullName(t), 'nominal'); + } + for (var _h = 0, _j = ['latitude', 'LATITUDE']; _h < _j.length; _h++) { + var t = _j[_h]; + assert.equal(type.getFullName(t), 'latitude'); + } + for (var _k = 0, _l = ['longitude', 'LONGITUDE']; _k < _l.length; _k++) { + var t = _l[_k]; + assert.equal(type.getFullName(t), 'longitude'); + } + for (var _m = 0, _o = ['geojson', 'GEOJSON']; _m < _o.length; _m++) { + var t = _o[_m]; + assert.equal(type.getFullName(t), 'geojson'); + } + }); + it('should return undefined for invalid type', function () { + assert.equal(type.getFullName('haha'), undefined); + }); + }); +}); +//# sourceMappingURL=type.test.js.map \ No newline at end of file diff --git a/build/test/type.test.js.map b/build/test/type.test.js.map new file mode 100644 index 0000000000..5e4c673686 --- /dev/null +++ b/build/test/type.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"type.test.js","sourceRoot":"","sources":["../../test/type.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AAEpC,QAAQ,CAAC,MAAM,EAAE;IACf,QAAQ,CAAC,eAAe,EAAE;QACxB,EAAE,CAAC,mDAAmD,EAAE;YACtD,KAAgB,UAA0C,EAA1C,MAAC,GAAG,EAAE,GAAG,EAAE,cAAc,EAAE,cAAc,CAAC,EAA1C,cAA0C,EAA1C,IAA0C,EAAE;gBAAvD,IAAM,CAAC,SAAA;gBACV,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;aACnD;YACD,KAAgB,UAAkC,EAAlC,MAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,CAAC,EAAlC,cAAkC,EAAlC,IAAkC,EAAE;gBAA/C,IAAM,CAAC,SAAA;gBACV,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;aAC/C;YACD,KAAgB,UAAgC,EAAhC,MAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;gBAA7C,IAAM,CAAC,SAAA;gBACV,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;aAC9C;YACD,KAAgB,UAAgC,EAAhC,MAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;gBAA7C,IAAM,CAAC,SAAA;gBACV,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;aAC9C;YACD,KAAgB,UAAwB,EAAxB,MAAC,UAAU,EAAE,UAAU,CAAC,EAAxB,cAAwB,EAAxB,IAAwB,EAAE;gBAArC,IAAM,CAAC,SAAA;gBACV,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;aAC/C;YACD,KAAgB,UAA0B,EAA1B,MAAC,WAAW,EAAE,WAAW,CAAC,EAA1B,cAA0B,EAA1B,IAA0B,EAAE;gBAAvC,IAAM,CAAC,SAAA;gBACV,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;aAChD;YACD,KAAgB,UAAsB,EAAtB,MAAC,SAAS,EAAE,SAAS,CAAC,EAAtB,cAAsB,EAAtB,IAAsB,EAAE;gBAAnC,IAAM,CAAC,SAAA;gBACV,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;aAC9C;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE;YAC7C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {assert} from 'chai';\n\nimport * as type from '../src/type';\n\ndescribe('type', function () {\n describe('getFullName()', () => {\n it('should return correct lowercase, full type names.', () => {\n for (const t of ['q', 'Q', 'quantitative', 'QUANTITATIVE']) {\n assert.equal(type.getFullName(t), 'quantitative');\n }\n for (const t of ['t', 'T', 'temporal', 'TEMPORAL']) {\n assert.equal(type.getFullName(t), 'temporal');\n }\n for (const t of ['o', 'O', 'ordinal', 'ORDINAL']) {\n assert.equal(type.getFullName(t), 'ordinal');\n }\n for (const t of ['n', 'N', 'nominal', 'NOMINAL']) {\n assert.equal(type.getFullName(t), 'nominal');\n }\n for (const t of ['latitude', 'LATITUDE']) {\n assert.equal(type.getFullName(t), 'latitude');\n }\n for (const t of ['longitude', 'LONGITUDE']) {\n assert.equal(type.getFullName(t), 'longitude');\n }\n for (const t of ['geojson', 'GEOJSON']) {\n assert.equal(type.getFullName(t), 'geojson');\n }\n });\n\n it('should return undefined for invalid type', () => {\n assert.equal(type.getFullName('haha'), undefined);\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/util.d.ts b/build/test/util.d.ts new file mode 100644 index 0000000000..986279f4fd --- /dev/null +++ b/build/test/util.d.ts @@ -0,0 +1,17 @@ +import { ConcatModel } from '../src/compile/concat'; +import { FacetModel } from '../src/compile/facet'; +import { LayerModel } from '../src/compile/layer'; +import { Model } from '../src/compile/model'; +import { RepeatModel } from '../src/compile/repeat'; +import { UnitModel } from '../src/compile/unit'; +import { NormalizedConcatSpec, NormalizedFacetSpec, NormalizedLayerSpec, NormalizedRepeatSpec, NormalizedUnitSpec, TopLevel, TopLevelSpec } from '../src/spec'; +export declare function parseModel(inputSpec: TopLevelSpec): Model; +export declare function parseModelWithScale(inputSpec: TopLevelSpec): Model; +export declare function parseUnitModel(spec: TopLevel): UnitModel; +export declare function parseUnitModelWithScale(spec: TopLevel): UnitModel; +export declare function parseUnitModelWithScaleAndLayoutSize(spec: TopLevel): UnitModel; +export declare function parseLayerModel(spec: TopLevel): LayerModel; +export declare function parseFacetModel(spec: TopLevel): FacetModel; +export declare function parseFacetModelWithScale(spec: TopLevel): FacetModel; +export declare function parseRepeatModel(spec: TopLevel): RepeatModel; +export declare function parseConcatModel(spec: TopLevel): ConcatModel; diff --git a/build/test/util.js b/build/test/util.js new file mode 100644 index 0000000000..8981647edc --- /dev/null +++ b/build/test/util.js @@ -0,0 +1,52 @@ +import { buildModel } from '../src/compile/buildmodel'; +import { ConcatModel } from '../src/compile/concat'; +import { FacetModel } from '../src/compile/facet'; +import { LayerModel } from '../src/compile/layer'; +import { RepeatModel } from '../src/compile/repeat'; +import { UnitModel } from '../src/compile/unit'; +import { initConfig } from '../src/config'; +import { normalize, } from '../src/spec'; +import { isLayerSpec, isUnitSpec } from '../src/spec'; +import { normalizeAutoSize } from '../src/toplevelprops'; +export function parseModel(inputSpec) { + var config = initConfig(inputSpec.config); + var spec = normalize(inputSpec, config); + var autosize = normalizeAutoSize(inputSpec.autosize, config.autosize, isLayerSpec(spec) || isUnitSpec(spec)); + return buildModel(spec, null, '', undefined, undefined, config, autosize.type === 'fit'); +} +export function parseModelWithScale(inputSpec) { + var model = parseModel(inputSpec); + model.parseScale(); + return model; +} +export function parseUnitModel(spec) { + return new UnitModel(spec, null, '', undefined, undefined, initConfig(spec.config), normalizeAutoSize(spec.autosize, spec.config ? spec.config.autosize : undefined, true).type === 'fit'); +} +export function parseUnitModelWithScale(spec) { + var model = parseUnitModel(spec); + model.parseScale(); + return model; +} +export function parseUnitModelWithScaleAndLayoutSize(spec) { + var model = parseUnitModelWithScale(spec); + model.parseLayoutSize(); + return model; +} +export function parseLayerModel(spec) { + return new LayerModel(spec, null, '', undefined, undefined, initConfig(spec.config), normalizeAutoSize(spec.autosize, spec.config ? spec.config.autosize : undefined, true).type === 'fit'); +} +export function parseFacetModel(spec) { + return new FacetModel(spec, null, '', undefined, initConfig(spec.config)); +} +export function parseFacetModelWithScale(spec) { + var model = parseFacetModel(spec); + model.parseScale(); + return model; +} +export function parseRepeatModel(spec) { + return new RepeatModel(spec, null, '', undefined, initConfig(spec.config)); +} +export function parseConcatModel(spec) { + return new ConcatModel(spec, null, '', undefined, initConfig(spec.config)); +} +//# sourceMappingURL=util.js.map \ No newline at end of file diff --git a/build/test/util.js.map b/build/test/util.js.map new file mode 100644 index 0000000000..11f713cd7e --- /dev/null +++ b/build/test/util.js.map @@ -0,0 +1 @@ +{"version":3,"file":"util.js","sourceRoot":"","sources":["../../test/util.ts"],"names":[],"mappings":"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","sourcesContent":["import {buildModel} from '../src/compile/buildmodel';\nimport {ConcatModel} from '../src/compile/concat';\nimport {FacetModel} from '../src/compile/facet';\nimport {LayerModel} from '../src/compile/layer';\nimport {Model} from '../src/compile/model';\nimport {RepeatModel} from '../src/compile/repeat';\nimport {UnitModel} from '../src/compile/unit';\nimport {initConfig} from '../src/config';\nimport {\n normalize,\n NormalizedConcatSpec,\n NormalizedFacetSpec,\n NormalizedLayerSpec,\n NormalizedRepeatSpec,\n NormalizedUnitSpec,\n TopLevel,\n TopLevelSpec,\n} from '../src/spec';\nimport {isLayerSpec, isUnitSpec} from '../src/spec';\nimport {normalizeAutoSize} from '../src/toplevelprops';\n\nexport function parseModel(inputSpec: TopLevelSpec): Model {\n const config = initConfig(inputSpec.config);\n const spec = normalize(inputSpec, config);\n const autosize = normalizeAutoSize(inputSpec.autosize, config.autosize, isLayerSpec(spec) || isUnitSpec(spec));\n return buildModel(spec, null, '', undefined, undefined, config, autosize.type === 'fit');\n}\n\nexport function parseModelWithScale(inputSpec: TopLevelSpec): Model {\n const model = parseModel(inputSpec);\n model.parseScale();\n return model;\n}\n\nexport function parseUnitModel(spec: TopLevel) {\n return new UnitModel(spec, null, '', undefined, undefined, initConfig(spec.config), normalizeAutoSize(spec.autosize, spec.config ? spec.config.autosize : undefined, true).type === 'fit');\n}\n\nexport function parseUnitModelWithScale(spec: TopLevel) {\n const model = parseUnitModel(spec);\n model.parseScale();\n return model;\n}\n\nexport function parseUnitModelWithScaleAndLayoutSize(spec: TopLevel) {\n const model = parseUnitModelWithScale(spec);\n model.parseLayoutSize();\n return model;\n}\n\n\nexport function parseLayerModel(spec: TopLevel) {\n return new LayerModel(spec, null, '', undefined, undefined, initConfig(spec.config), normalizeAutoSize(spec.autosize, spec.config ? spec.config.autosize : undefined, true).type === 'fit');\n}\n\nexport function parseFacetModel(spec: TopLevel) {\n return new FacetModel(spec, null, '', undefined, initConfig(spec.config));\n}\n\nexport function parseFacetModelWithScale(spec: TopLevel) {\n const model = parseFacetModel(spec);\n model.parseScale();\n return model;\n}\n\nexport function parseRepeatModel(spec: TopLevel) {\n return new RepeatModel(spec, null, '', undefined, initConfig(spec.config));\n}\n\nexport function parseConcatModel(spec: TopLevel) {\n return new ConcatModel(spec, null, '', undefined, initConfig(spec.config));\n}\n"]} \ No newline at end of file diff --git a/build/test/util.test.d.ts b/build/test/util.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/util.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/util.test.js b/build/test/util.test.js new file mode 100644 index 0000000000..0ec32a2590 --- /dev/null +++ b/build/test/util.test.js @@ -0,0 +1,125 @@ +import { assert } from 'chai'; +import { flatAccessWithDatum } from '../src/util'; +import { accessPathDepth, accessPathWithDatum, deleteNestedProperty, hash, replacePathInField, stringify, varName, } from '../src/util'; +describe('util', function () { + describe('varName', function () { + it('replaces all non-alphanumeric characters with _', function () { + assert.equal(varName('bin-mpg$!@#%_+1'), 'bin_mpg_______1'); + }); + it('prepends _ if the string starts with number', function () { + assert.equal(varName('1a'), '_1a'); + }); + }); + describe('stringify', function () { + it('stringifies numbers', function () { + assert.equal(stringify(12), '12'); + }); + it('stringifies booleans', function () { + assert.equal(stringify(true), 'true'); + }); + it('stringifies strings', function () { + assert.equal(stringify('foo'), '"foo"'); + }); + it('stringifies objects', function () { + assert.equal(stringify({ foo: 42 }), '{"foo":42}'); + }); + }); + describe('hash', function () { + it('hashes numbers as numbers', function () { + assert.equal(hash(12), 12); + }); + it('hashes booleans as strings so that they can be used as keys', function () { + assert.equal(hash(true), 'true'); + }); + it('hashes strings as strings', function () { + assert.equal(hash('foo'), 'foo'); + }); + it('hashes objects', function () { + assert.equal(hash({ foo: 42 }), '{"foo":42}'); + }); + }); + describe('deleteNestedProperty', function () { + it('removes a property from an object', function () { + var originalObject = { + property1: { property1: 'value1' }, + property2: { property5: 'value2' }, + property3: { property6: 'value3', property7: 'value4' } + }; + var newObject = { + property2: { property5: 'value2' }, + property3: { property6: 'value3', property7: 'value4' } + }; + deleteNestedProperty(originalObject, ['property1']); + assert.equal(stringify(originalObject), stringify(newObject)); + }); + it('removes nested properties', function () { + var originalObject = { + property1: { property4: 'value1' }, + property2: { property5: 'value2' }, + property3: { property6: 'value3', property7: 'value4' } + }; + var newObject = { + property2: { property5: 'value2' }, + property3: { property6: 'value3', property7: 'value4' } + }; + deleteNestedProperty(originalObject, ['property1', 'property4']); + assert.equal(stringify(originalObject), stringify(newObject)); + }); + it('stops when it does not empty the last element', function () { + var originalObject = { + property1: { property4: 'value1' }, + property2: { property5: 'value2' }, + property3: { property6: 'value3', property7: 'value4' } + }; + var newObject = { + property1: { property4: 'value1' }, + property2: { property5: 'value2' }, + property3: { property6: 'value3' } + }; + deleteNestedProperty(originalObject, ['property3', 'property7']); + assert.equal(stringify(originalObject), stringify(newObject)); + }); + }); + describe('accessPathWithDatum', function () { + it('should parse foo', function () { + assert.equal(accessPathWithDatum('foo'), 'datum["foo"]'); + }); + it('should parse foo.bar', function () { + assert.equal(accessPathWithDatum('foo.bar'), 'datum["foo"] && datum["foo"]["bar"]'); + }); + it('should support cusotom datum', function () { + assert.equal(accessPathWithDatum('foo', 'parent'), 'parent["foo"]'); + }); + }); + describe('flatAccessWithDatum', function () { + it('should parse foo.bar', function () { + assert.equal(flatAccessWithDatum('foo.bar'), 'datum["foo.bar"]'); + }); + it('should return string value of field name', function () { + assert.equal(flatAccessWithDatum('foo["bar"].baz'), 'datum["foo.bar.baz"]'); + }); + it('should support cusotom datum', function () { + assert.equal(flatAccessWithDatum('foo', 'parent'), 'parent["foo"]'); + }); + }); + describe('accessPathDepth', function () { + it('should return 1 if the field is not nested', function () { + assert.equal(accessPathDepth('foo'), 1); + }); + it('should return 1 if . is escaped', function () { + assert.equal(accessPathDepth('foo\\.bar'), 1); + }); + it('should return 2 for foo.bar', function () { + assert.equal(accessPathDepth('foo.bar'), 2); + }); + }); + describe('removePathFromField', function () { + it('should convert nested accesses to \\.', function () { + assert.equal(replacePathInField('foo["bar"].baz'), 'foo\\.bar\\.baz'); + }); + it('should keep \\.', function () { + assert.equal(replacePathInField('foo\\.bar'), 'foo\\.bar'); + }); + }); +}); +//# sourceMappingURL=util.test.js.map \ No newline at end of file diff --git a/build/test/util.test.js.map b/build/test/util.test.js.map new file mode 100644 index 0000000000..d0e7b0e5b9 --- /dev/null +++ b/build/test/util.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"util.test.js","sourceRoot":"","sources":["../../test/util.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {flatAccessWithDatum} from '../src/util';\n\nimport {\n accessPathDepth,\n accessPathWithDatum,\n deleteNestedProperty,\n hash,\n replacePathInField,\n stringify,\n varName,\n} from '../src/util';\n\ndescribe('util', () => {\n describe('varName', () => {\n it('replaces all non-alphanumeric characters with _', () => {\n assert.equal(varName('bin-mpg$!@#%_+1'), 'bin_mpg_______1');\n });\n\n it('prepends _ if the string starts with number', () => {\n assert.equal(varName('1a'), '_1a');\n });\n });\n\n describe('stringify', () => {\n it('stringifies numbers', () => {\n assert.equal(stringify(12), '12');\n });\n\n it('stringifies booleans', () => {\n assert.equal(stringify(true), 'true');\n });\n\n it('stringifies strings', () => {\n assert.equal(stringify('foo'), '\"foo\"');\n });\n\n it('stringifies objects', () => {\n assert.equal(stringify({foo: 42}), '{\"foo\":42}');\n });\n });\n\n describe('hash', () => {\n it('hashes numbers as numbers', () => {\n assert.equal(hash(12), 12);\n });\n\n it('hashes booleans as strings so that they can be used as keys', () => {\n assert.equal(hash(true), 'true');\n });\n\n it('hashes strings as strings', () => {\n assert.equal(hash('foo'), 'foo');\n });\n\n it('hashes objects', () => {\n assert.equal(hash({foo: 42}), '{\"foo\":42}');\n });\n });\n describe('deleteNestedProperty', () => {\n it('removes a property from an object', () => {\n const originalObject = {\n property1: {property1: 'value1'},\n property2: {property5: 'value2'},\n property3: {property6: 'value3', property7: 'value4'}\n };\n const newObject = {\n property2: {property5: 'value2'},\n property3: {property6: 'value3', property7: 'value4'}\n };\n deleteNestedProperty(originalObject, ['property1']);\n assert.equal(stringify(originalObject), stringify(newObject));\n });\n\n it('removes nested properties', () => {\n const originalObject = {\n property1: {property4: 'value1'},\n property2: {property5: 'value2'},\n property3: {property6: 'value3', property7: 'value4'}\n };\n const newObject = {\n property2: {property5: 'value2'},\n property3: {property6: 'value3', property7: 'value4'}\n };\n deleteNestedProperty(originalObject, ['property1', 'property4']);\n assert.equal(stringify(originalObject), stringify(newObject));\n });\n\n it('stops when it does not empty the last element', () => {\n const originalObject = {\n property1: {property4: 'value1'},\n property2: {property5: 'value2'},\n property3: {property6: 'value3', property7: 'value4'}\n };\n const newObject = {\n property1: {property4: 'value1'},\n property2: {property5: 'value2'},\n property3: {property6: 'value3'}\n };\n deleteNestedProperty(originalObject, ['property3', 'property7']);\n assert.equal(stringify(originalObject), stringify(newObject));\n });\n });\n\n describe('accessPathWithDatum', () => {\n it('should parse foo', () => {\n assert.equal(accessPathWithDatum('foo'), 'datum[\"foo\"]');\n });\n\n it('should parse foo.bar', () => {\n assert.equal(accessPathWithDatum('foo.bar'), 'datum[\"foo\"] && datum[\"foo\"][\"bar\"]');\n });\n\n it('should support cusotom datum', () => {\n assert.equal(accessPathWithDatum('foo', 'parent'), 'parent[\"foo\"]');\n });\n });\n\n describe('flatAccessWithDatum', () => {\n it('should parse foo.bar', () => {\n assert.equal(flatAccessWithDatum('foo.bar'), 'datum[\"foo.bar\"]');\n });\n\n it('should return string value of field name', () => {\n assert.equal(flatAccessWithDatum('foo[\"bar\"].baz'), 'datum[\"foo.bar.baz\"]');\n });\n\n it('should support cusotom datum', () => {\n assert.equal(flatAccessWithDatum('foo', 'parent'), 'parent[\"foo\"]');\n });\n });\n\n describe('accessPathDepth', () => {\n it('should return 1 if the field is not nested', () => {\n assert.equal(accessPathDepth('foo'), 1);\n });\n\n it('should return 1 if . is escaped', () => {\n assert.equal(accessPathDepth('foo\\\\.bar'), 1);\n });\n\n it('should return 2 for foo.bar', () => {\n assert.equal(accessPathDepth('foo.bar'), 2);\n });\n });\n\n describe('removePathFromField', () => {\n it('should convert nested accesses to \\\\.', () => {\n assert.equal(replacePathInField('foo[\"bar\"].baz'), 'foo\\\\.bar\\\\.baz');\n });\n\n it('should keep \\\\.', () => {\n assert.equal(replacePathInField('foo\\\\.bar'), 'foo\\\\.bar');\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/test/validate.test.d.ts b/build/test/validate.test.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/build/test/validate.test.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/build/test/validate.test.js b/build/test/validate.test.js new file mode 100644 index 0000000000..f9b20c4ad2 --- /dev/null +++ b/build/test/validate.test.js @@ -0,0 +1,68 @@ +import { assert } from 'chai'; +import { AREA, BAR, LINE, TEXT } from '../src/mark'; +import { getEncodingMappingError } from '../src/validate'; +describe('vl.validate', function () { + describe('getEncodingMappingError()', function () { + it('should return no error for valid specs', function () { + assert.isNull(getEncodingMappingError({ + mark: BAR, + encoding: { + x: { field: 'a', type: 'quantitative' } + } + })); + assert.isNull(getEncodingMappingError({ + mark: LINE, + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'a', type: 'quantitative' } + } + })); + assert.isNull(getEncodingMappingError({ + mark: AREA, + encoding: { + x: { field: 'a', type: 'quantitative' }, + y: { field: 'b', type: 'quantitative' } + } + })); + }); + it('should return error for invalid specs', function () { + assert.isNotNull(getEncodingMappingError({ + mark: LINE, + encoding: { + x: { field: 'b', type: 'quantitative' } // missing y + } + })); + assert.isNotNull(getEncodingMappingError({ + mark: AREA, + encoding: { + y: { field: 'b', type: 'quantitative' } // missing x + } + })); + assert.isNotNull(getEncodingMappingError({ + mark: TEXT, + encoding: { + y: { field: 'b', type: 'quantitative' } // missing text + } + })); + assert.isNotNull(getEncodingMappingError({ + mark: LINE, + encoding: { + shape: { field: 'b', type: 'quantitative' } // using shape with line + } + })); + assert.isNotNull(getEncodingMappingError({ + mark: AREA, + encoding: { + shape: { field: 'b', type: 'quantitative' } // using shape with area + } + })); + assert.isNotNull(getEncodingMappingError({ + mark: BAR, + encoding: { + shape: { field: 'b', type: 'quantitative' } // using shape with bar + } + })); + }); + }); +}); +//# sourceMappingURL=validate.test.js.map \ No newline at end of file diff --git a/build/test/validate.test.js.map b/build/test/validate.test.js.map new file mode 100644 index 0000000000..1728e682ab --- /dev/null +++ b/build/test/validate.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"validate.test.js","sourceRoot":"","sources":["../../test/validate.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {assert} from 'chai';\nimport {AREA, BAR, LINE, TEXT} from '../src/mark';\nimport {getEncodingMappingError} from '../src/validate';\n\ndescribe('vl.validate', function() {\n describe('getEncodingMappingError()', function () {\n it('should return no error for valid specs', function() {\n assert.isNull(getEncodingMappingError({\n mark: BAR,\n encoding: {\n x: {field: 'a', type: 'quantitative'}\n }\n }));\n\n assert.isNull(getEncodingMappingError({\n mark: LINE,\n encoding: {\n x: {field: 'b', type: 'quantitative'},\n y: {field: 'a', type: 'quantitative'}\n }\n }));\n\n assert.isNull(getEncodingMappingError({\n mark: AREA,\n encoding: {\n x: {field: 'a', type: 'quantitative'},\n y: {field: 'b', type: 'quantitative'}\n }\n }));\n });\n\n it('should return error for invalid specs', function() {\n assert.isNotNull(getEncodingMappingError({\n mark: LINE,\n encoding: {\n x: {field: 'b', type: 'quantitative'} // missing y\n }\n }));\n\n assert.isNotNull(getEncodingMappingError({\n mark: AREA,\n encoding: {\n y: {field: 'b', type: 'quantitative'} // missing x\n }\n }));\n\n assert.isNotNull(getEncodingMappingError({\n mark: TEXT,\n encoding: {\n y: {field: 'b', type: 'quantitative'} // missing text\n }\n }));\n\n assert.isNotNull(getEncodingMappingError({\n mark: LINE,\n encoding: {\n shape: {field: 'b', type: 'quantitative'} // using shape with line\n }\n }));\n\n assert.isNotNull(getEncodingMappingError({\n mark: AREA,\n encoding: {\n shape: {field: 'b', type: 'quantitative'} // using shape with area\n }\n }));\n\n assert.isNotNull(getEncodingMappingError({\n mark: BAR,\n encoding: {\n shape: {field: 'b', type: 'quantitative'} // using shape with bar\n }\n }));\n });\n });\n});\n"]} \ No newline at end of file diff --git a/build/vega-lite.js b/build/vega-lite.js new file mode 100644 index 0000000000..dd19f7466a --- /dev/null +++ b/build/vega-lite.js @@ -0,0 +1,13216 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.vl = {}))); +}(this, (function (exports) { 'use strict'; + + function accessor(fn, fields, name) { + fn.fields = fields || []; + fn.fname = name; + return fn; + } + + function error(message) { + throw Error(message); + } + + function splitAccessPath(p) { + var path = [], + q = null, + b = 0, + n = p.length, + s = '', + i, j, c; + + p = p + ''; + + function push() { + path.push(s + p.substring(i, j)); + s = ''; + i = j + 1; + } + + for (i=j=0; j i) { + push(); + } else { + i = j + 1; + } + } else if (c === '[') { + if (j > i) push(); + b = i = j + 1; + } else if (c === ']') { + if (!b) error('Access path missing open bracket: ' + p); + if (b > 0) push(); + b = 0; + i = j + 1; + } + } + + if (b) error('Access path missing closing bracket: ' + p); + if (q) error('Access path missing closing quote: ' + p); + + if (j > i) { + j++; + push(); + } + + return path; + } + + var isArray = Array.isArray; + + function isObject(_) { + return _ === Object(_); + } + + function isString(_) { + return typeof _ === 'string'; + } + + function $(x) { + return isArray(x) ? '[' + x.map($) + ']' + : isObject(x) || isString(x) ? + // Output valid JSON and JS source strings. + // See http://timelessrepo.com/json-isnt-a-javascript-subset + JSON.stringify(x).replace('\u2028','\\u2028').replace('\u2029', '\\u2029') + : x; + } + + function field(field, name) { + var path = splitAccessPath(field), + code = 'return _[' + path.map($).join('][') + '];'; + + return accessor( + Function('_', code), + [(field = path.length===1 ? path[0] : field)], + name || field + ); + } + + var empty = []; + + var id = field('id'); + + var identity = accessor(function(_) { return _; }, empty, 'identity'); + + var zero = accessor(function() { return 0; }, empty, 'zero'); + + var one = accessor(function() { return 1; }, empty, 'one'); + + var truthy = accessor(function() { return true; }, empty, 'true'); + + var falsy = accessor(function() { return false; }, empty, 'false'); + + function log(method, level, input) { + var args = [level].concat([].slice.call(input)); + console[method].apply(console, args); // eslint-disable-line no-console + } + + var None = 0; + var Error$1 = 1; + var Warn = 2; + var Info = 3; + var Debug = 4; + + function logger(_) { + var level = _ || None; + return { + level: function(_) { + if (arguments.length) { + level = +_; + return this; + } else { + return level; + } + }, + error: function() { + if (level >= Error$1) log('error', 'ERROR', arguments); + return this; + }, + warn: function() { + if (level >= Warn) log('warn', 'WARN', arguments); + return this; + }, + info: function() { + if (level >= Info) log('log', 'INFO', arguments); + return this; + }, + debug: function() { + if (level >= Debug) log('log', 'DEBUG', arguments); + return this; + } + } + } + + function isFunction(_) { + return typeof _ === 'function'; + } + + function isBoolean(_) { + return typeof _ === 'boolean'; + } + + function isNumber(_) { + return typeof _ === 'number'; + } + + function toSet(_) { + for (var s={}, i=0, n=_.length; i= '0' && ch <= '9') { + string += ch; + next(); + } + if (ch === '.') { + string += '.'; + while (next() && ch >= '0' && ch <= '9') { + string += ch; + } + } + if (ch === 'e' || ch === 'E') { + string += ch; + next(); + if (ch === '-' || ch === '+') { + string += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + } + number = +string; + if (!isFinite(number)) { + error$1("Bad number"); + } else { + return number; + } + }, + + string = function () { + // Parse a string value. + var hex, + i, + string = '', + uffff; + + // When parsing for string values, we must look for " and \ characters. + if (ch === '"') { + while (next()) { + if (ch === '"') { + next(); + return string; + } else if (ch === '\\') { + next(); + if (ch === 'u') { + uffff = 0; + for (i = 0; i < 4; i += 1) { + hex = parseInt(next(), 16); + if (!isFinite(hex)) { + break; + } + uffff = uffff * 16 + hex; + } + string += String.fromCharCode(uffff); + } else if (typeof escapee[ch] === 'string') { + string += escapee[ch]; + } else { + break; + } + } else { + string += ch; + } + } + } + error$1("Bad string"); + }, + + white = function () { + + // Skip whitespace. + + while (ch && ch <= ' ') { + next(); + } + }, + + word = function () { + + // true, false, or null. + + switch (ch) { + case 't': + next('t'); + next('r'); + next('u'); + next('e'); + return true; + case 'f': + next('f'); + next('a'); + next('l'); + next('s'); + next('e'); + return false; + case 'n': + next('n'); + next('u'); + next('l'); + next('l'); + return null; + } + error$1("Unexpected '" + ch + "'"); + }, + + value, // Place holder for the value function. + + array$1 = function () { + + // Parse an array value. + + var array = []; + + if (ch === '[') { + next('['); + white(); + if (ch === ']') { + next(']'); + return array; // empty array + } + while (ch) { + array.push(value()); + white(); + if (ch === ']') { + next(']'); + return array; + } + next(','); + white(); + } + } + error$1("Bad array"); + }, + + object = function () { + + // Parse an object value. + + var key, + object = {}; + + if (ch === '{') { + next('{'); + white(); + if (ch === '}') { + next('}'); + return object; // empty object + } + while (ch) { + key = string(); + white(); + next(':'); + if (Object.hasOwnProperty.call(object, key)) { + error$1('Duplicate key "' + key + '"'); + } + object[key] = value(); + white(); + if (ch === '}') { + next('}'); + return object; + } + next(','); + white(); + } + } + error$1("Bad object"); + }; + + value = function () { + + // Parse a JSON value. It could be an object, an array, a string, a number, + // or a word. + + white(); + switch (ch) { + case '{': + return object(); + case '[': + return array$1(); + case '"': + return string(); + case '-': + return number(); + default: + return ch >= '0' && ch <= '9' ? number() : word(); + } + }; + + // Return the json_parse function. It will have access to all of the above + // functions and variables. + + var parse = function (source, reviver) { + var result; + + text = source; + at = 0; + ch = ' '; + result = value(); + white(); + if (ch) { + error$1("Syntax error"); + } + + // If there is a reviver function, we recursively walk the new structure, + // passing each name/value pair to the reviver function for possible + // transformation, starting with a temporary root object that holds the result + // in an empty key. If there is not a reviver function, we simply return the + // result. + + return typeof reviver === 'function' ? (function walk(holder, key) { + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + }({'': result}, '')) : result; + }; + + var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + function quote(string) { + // If the string contains no control characters, no quote characters, and no + // backslash characters, then we can safely slap some quotes around it. + // Otherwise we must also replace the offending characters with safe escape + // sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + function str(key, holder) { + // Produce a string from holder[key]. + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + + // If the value has a toJSON method, call it to obtain a replacement value. + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + + // If we were called with a replacer function, then call the replacer to + // obtain a replacement value. + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + + // What happens next depends on the value's type. + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + // JSON numbers must be finite. Encode non-finite numbers as null. + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + // If the value is a boolean or null, convert it to a string. Note: + // typeof null does not produce 'null'. The case is included here in + // the remote chance that this gets fixed someday. + return String(value); + + case 'object': + if (!value) return 'null'; + gap += indent; + partial = []; + + // Array.isArray + if (Object.prototype.toString.apply(value) === '[object Array]') { + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + + // Join all of the elements together, separated with commas, and + // wrap them in brackets. + v = partial.length === 0 ? '[]' : gap ? + '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + + // If the replacer is an array, use it to select the members to be + // stringified. + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + else { + // Otherwise, iterate through all of the keys in the object. + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + + // Join all of the member texts together, separated with commas, + // and wrap them in braces. + + v = partial.length === 0 ? '{}' : gap ? + '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : + '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + + var stringify = function (value, replacer, space) { + var i; + gap = ''; + indent = ''; + + // If the space parameter is a number, make an indent string containing that + // many spaces. + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + } + // If the space parameter is a string, it will be used as the indent string. + else if (typeof space === 'string') { + indent = space; + } + + // If there is a replacer, it must be a function or an array. + // Otherwise, throw an error. + rep = replacer; + if (replacer && typeof replacer !== 'function' + && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + + // Make a fake root object containing our value under the key of ''. + // Return the result of stringifying the value. + return str('', {'': value}); + }; + + var parse$1 = parse; + var stringify$1 = stringify; + + var jsonify = { + parse: parse$1, + stringify: stringify$1 + }; + + var json = typeof JSON !== 'undefined' ? JSON : jsonify; + + var jsonStableStringify = function (obj, opts) { + if (!opts) opts = {}; + if (typeof opts === 'function') opts = { cmp: opts }; + var space = opts.space || ''; + if (typeof space === 'number') space = Array(space+1).join(' '); + var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false; + var replacer = opts.replacer || function(key, value) { return value; }; + + var cmp = opts.cmp && (function (f) { + return function (node) { + return function (a, b) { + var aobj = { key: a, value: node[a] }; + var bobj = { key: b, value: node[b] }; + return f(aobj, bobj); + }; + }; + })(opts.cmp); + + var seen = []; + return (function stringify (parent, key, node, level) { + var indent = space ? ('\n' + new Array(level + 1).join(space)) : ''; + var colonSeparator = space ? ': ' : ':'; + + if (node && node.toJSON && typeof node.toJSON === 'function') { + node = node.toJSON(); + } + + node = replacer.call(parent, key, node); + + if (node === undefined) { + return; + } + if (typeof node !== 'object' || node === null) { + return json.stringify(node); + } + if (isArray$1(node)) { + var out = []; + for (var i = 0; i < node.length; i++) { + var item = stringify(node, i, node[i], level+1) || json.stringify(null); + out.push(indent + space + item); + } + return '[' + out.join(',') + indent + ']'; + } + else { + if (seen.indexOf(node) !== -1) { + if (cycles) return json.stringify('__cycle__'); + throw new TypeError('Converting circular structure to JSON'); + } + else seen.push(node); + + var keys = objectKeys(node).sort(cmp && cmp(node)); + var out = []; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = stringify(node, key, node[key], level+1); + + if(!value) continue; + + var keyValue = json.stringify(key) + + colonSeparator + + value; + out.push(indent + space + keyValue); + } + seen.splice(seen.indexOf(node), 1); + return '{' + out.join(',') + indent + '}'; + } + })({ '': obj }, '', obj, 0); + }; + + var isArray$1 = Array.isArray || function (x) { + return {}.toString.call(x) === '[object Array]'; + }; + + var objectKeys = Object.keys || function (obj) { + var has = Object.prototype.hasOwnProperty || function () { return true }; + var keys = []; + for (var key in obj) { + if (has.call(obj, key)) keys.push(key); + } + return keys; + }; + + function isLogicalOr(op) { + return !!op.or; + } + function isLogicalAnd(op) { + return !!op.and; + } + function isLogicalNot(op) { + return !!op.not; + } + function forEachLeaf(op, fn) { + if (isLogicalNot(op)) { + forEachLeaf(op.not, fn); + } + else if (isLogicalAnd(op)) { + for (var _i = 0, _a = op.and; _i < _a.length; _i++) { + var subop = _a[_i]; + forEachLeaf(subop, fn); + } + } + else if (isLogicalOr(op)) { + for (var _b = 0, _c = op.or; _b < _c.length; _b++) { + var subop = _c[_b]; + forEachLeaf(subop, fn); + } + } + else { + fn(op); + } + } + function normalizeLogicalOperand(op, normalizer) { + if (isLogicalNot(op)) { + return { not: normalizeLogicalOperand(op.not, normalizer) }; + } + else if (isLogicalAnd(op)) { + return { and: op.and.map(function (o) { return normalizeLogicalOperand(o, normalizer); }) }; + } + else if (isLogicalOr(op)) { + return { or: op.or.map(function (o) { return normalizeLogicalOperand(o, normalizer); }) }; + } + else { + return normalizer(op); + } + } + + /** + * Creates an object composed of the picked object properties. + * + * Example: (from lodash) + * + * var object = {'a': 1, 'b': '2', 'c': 3}; + * pick(object, ['a', 'c']); + * // → {'a': 1, 'c': 3} + * + */ + function pick(obj, props) { + var copy = {}; + for (var _i = 0, props_1 = props; _i < props_1.length; _i++) { + var prop = props_1[_i]; + if (obj.hasOwnProperty(prop)) { + copy[prop] = obj[prop]; + } + } + return copy; + } + /** + * The opposite of _.pick; this method creates an object composed of the own + * and inherited enumerable string keyed properties of object that are not omitted. + */ + function omit(obj, props) { + var copy = __assign({}, obj); + for (var _i = 0, props_2 = props; _i < props_2.length; _i++) { + var prop = props_2[_i]; + delete copy[prop]; + } + return copy; + } + /** + * Converts any object into a string representation that can be consumed by humans. + */ + var stringify$2 = jsonStableStringify; + /** + * Converts any object into a string of limited size, or a number. + */ + function hash(a) { + if (isNumber(a)) { + return a; + } + var str = isString(a) ? a : jsonStableStringify(a); + // short strings can be used as hash directly, longer strings are hashed to reduce memory usage + if (str.length < 100) { + return str; + } + // from http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/ + var h = 0; + for (var i = 0; i < str.length; i++) { + var char = str.charCodeAt(i); + h = ((h << 5) - h) + char; + h = h & h; // Convert to 32bit integer + } + return h; + } + function contains(array$$1, item) { + return array$$1.indexOf(item) > -1; + } + /** Returns the array without the elements in item */ + function without(array$$1, excludedItems) { + return array$$1.filter(function (item) { return !contains(excludedItems, item); }); + } + function union(array$$1, other) { + return array$$1.concat(without(other, array$$1)); + } + /** + * Returns true if any item returns true. + */ + function some(arr, f) { + var i = 0; + for (var k = 0; k < arr.length; k++) { + if (f(arr[k], k, i++)) { + return true; + } + } + return false; + } + /** + * Returns true if all items return true. + */ + function every(arr, f) { + var i = 0; + for (var k = 0; k < arr.length; k++) { + if (!f(arr[k], k, i++)) { + return false; + } + } + return true; + } + function flatten(arrays) { + return [].concat.apply([], arrays); + } + /** + * recursively merges src into dest + */ + function mergeDeep(dest) { + var src = []; + for (var _i = 1; _i < arguments.length; _i++) { + src[_i - 1] = arguments[_i]; + } + for (var _a = 0, src_1 = src; _a < src_1.length; _a++) { + var s = src_1[_a]; + dest = deepMerge_(dest, s); + } + return dest; + } + // recursively merges src into dest + function deepMerge_(dest, src) { + if (typeof src !== 'object' || src === null) { + return dest; + } + for (var p in src) { + if (!src.hasOwnProperty(p)) { + continue; + } + if (src[p] === undefined) { + continue; + } + if (typeof src[p] !== 'object' || isArray(src[p]) || src[p] === null) { + dest[p] = src[p]; + } + else if (typeof dest[p] !== 'object' || dest[p] === null) { + dest[p] = mergeDeep(isArray(src[p].constructor) ? [] : {}, src[p]); + } + else { + mergeDeep(dest[p], src[p]); + } + } + return dest; + } + function unique(values, f) { + var results = []; + var u = {}; + var v; + for (var _i = 0, values_1 = values; _i < values_1.length; _i++) { + var val = values_1[_i]; + v = f(val); + if (v in u) { + continue; + } + u[v] = 1; + results.push(val); + } + return results; + } + /** + * Returns true if the two dictionaries disagree. Applies only to defined values. + */ + function differ(dict, other) { + for (var key$$1 in dict) { + if (dict.hasOwnProperty(key$$1)) { + if (other[key$$1] && dict[key$$1] && other[key$$1] !== dict[key$$1]) { + return true; + } + } + } + return false; + } + function hasIntersection(a, b) { + for (var key$$1 in a) { + if (key$$1 in b) { + return true; + } + } + return false; + } + function isNumeric(num) { + return !isNaN(num); + } + function differArray(array$$1, other) { + if (array$$1.length !== other.length) { + return true; + } + array$$1.sort(); + other.sort(); + for (var i = 0; i < array$$1.length; i++) { + if (other[i] !== array$$1[i]) { + return true; + } + } + return false; + } + // This is a stricter version of Object.keys but with better types. See https://github.com/Microsoft/TypeScript/pull/12253#issuecomment-263132208 + var keys = Object.keys; + function vals(x) { + var _vals = []; + for (var k in x) { + if (x.hasOwnProperty(k)) { + _vals.push(x[k]); + } + } + return _vals; + } + function flagKeys(f) { + return keys(f); + } + function duplicate(obj) { + return JSON.parse(JSON.stringify(obj)); + } + function isBoolean$1(b) { + return b === true || b === false; + } + /** + * Convert a string into a valid variable name + */ + function varName(s) { + // Replace non-alphanumeric characters (anything besides a-zA-Z0-9_) with _ + var alphanumericS = s.replace(/\W/g, '_'); + // Add _ if the string has leading numbers. + return (s.match(/^\d+/) ? '_' : '') + alphanumericS; + } + function logicalExpr(op, cb) { + if (isLogicalNot(op)) { + return '!(' + logicalExpr(op.not, cb) + ')'; + } + else if (isLogicalAnd(op)) { + return '(' + op.and.map(function (and) { return logicalExpr(and, cb); }).join(') && (') + ')'; + } + else if (isLogicalOr(op)) { + return '(' + op.or.map(function (or) { return logicalExpr(or, cb); }).join(') || (') + ')'; + } + else { + return cb(op); + } + } + /** + * Delete nested property of an object, and delete the ancestors of the property if they become empty. + */ + function deleteNestedProperty(obj, orderedProps) { + if (orderedProps.length === 0) { + return true; + } + var prop = orderedProps.shift(); + if (deleteNestedProperty(obj[prop], orderedProps)) { + delete obj[prop]; + } + return Object.keys(obj).length === 0; + } + function titlecase(s) { + return s.charAt(0).toUpperCase() + s.substr(1); + } + /** + * Converts a path to an access path with datum. + * @param path The field name. + * @param datum The string to use for `datum`. + */ + function accessPathWithDatum(path, datum) { + if (datum === void 0) { datum = 'datum'; } + var pieces = splitAccessPath(path); + var prefixes = []; + for (var i = 1; i <= pieces.length; i++) { + var prefix = "[" + pieces.slice(0, i).map($).join('][') + "]"; + prefixes.push("" + datum + prefix); + } + return prefixes.join(' && '); + } + /** + * Return access with datum to the falttened field. + * @param path The field name. + * @param datum The string to use for `datum`. + */ + function flatAccessWithDatum(path, datum) { + if (datum === void 0) { datum = 'datum'; } + return datum + "[" + $(splitAccessPath(path).join('.')) + "]"; + } + /** + * Replaces path accesses with access to non-nested field. + * For example, `foo["bar"].baz` becomes `foo\\.bar\\.baz`. + */ + function replacePathInField(path) { + return "" + splitAccessPath(path).map(function (p) { return p.replace('.', '\\.'); }).join('\\.'); + } + /** + * Remove path accesses with access from field. + * For example, `foo["bar"].baz` becomes `foo.bar.baz`. + */ + function removePathFromField(path) { + return "" + splitAccessPath(path).join('.'); + } + /** + * Count the depth of the path. Returns 1 for fields that are not nested. + */ + function accessPathDepth(path) { + if (!path) { + return 0; + } + return splitAccessPath(path).length; + } + + var util = /*#__PURE__*/Object.freeze({ + pick: pick, + omit: omit, + stringify: stringify$2, + hash: hash, + contains: contains, + without: without, + union: union, + some: some, + every: every, + flatten: flatten, + mergeDeep: mergeDeep, + unique: unique, + differ: differ, + hasIntersection: hasIntersection, + isNumeric: isNumeric, + differArray: differArray, + keys: keys, + vals: vals, + flagKeys: flagKeys, + duplicate: duplicate, + isBoolean: isBoolean$1, + varName: varName, + logicalExpr: logicalExpr, + deleteNestedProperty: deleteNestedProperty, + titlecase: titlecase, + accessPathWithDatum: accessPathWithDatum, + flatAccessWithDatum: flatAccessWithDatum, + replacePathInField: replacePathInField, + removePathFromField: removePathFromField, + accessPathDepth: accessPathDepth + }); + + var AGGREGATE_OP_INDEX = { + argmax: 1, + argmin: 1, + average: 1, + count: 1, + distinct: 1, + max: 1, + mean: 1, + median: 1, + min: 1, + missing: 1, + q1: 1, + q3: 1, + ci0: 1, + ci1: 1, + stderr: 1, + stdev: 1, + stdevp: 1, + sum: 1, + valid: 1, + values: 1, + variance: 1, + variancep: 1, + }; + var AGGREGATE_OPS = flagKeys(AGGREGATE_OP_INDEX); + function isAggregateOp(a) { + return !!AGGREGATE_OP_INDEX[a]; + } + var COUNTING_OPS = ['count', 'valid', 'missing', 'distinct']; + function isCountingAggregateOp(aggregate) { + return aggregate && contains(COUNTING_OPS, aggregate); + } + /** Additive-based aggregation operations. These can be applied to stack. */ + var SUM_OPS = [ + 'count', + 'sum', + 'distinct', + 'valid', + 'missing' + ]; + /** + * Aggregation operators that always produce values within the range [domainMin, domainMax]. + */ + var SHARED_DOMAIN_OPS = [ + 'mean', + 'average', + 'median', + 'q1', + 'q3', + 'min', + 'max', + ]; + var SHARED_DOMAIN_OP_INDEX = toSet(SHARED_DOMAIN_OPS); + + var aggregate = /*#__PURE__*/Object.freeze({ + AGGREGATE_OPS: AGGREGATE_OPS, + isAggregateOp: isAggregateOp, + COUNTING_OPS: COUNTING_OPS, + isCountingAggregateOp: isCountingAggregateOp, + SUM_OPS: SUM_OPS, + SHARED_DOMAIN_OPS: SHARED_DOMAIN_OPS, + SHARED_DOMAIN_OP_INDEX: SHARED_DOMAIN_OP_INDEX + }); + + var AXIS_PARTS = ['domain', 'grid', 'labels', 'ticks', 'title']; + /** + * A dictionary listing whether a certain axis property is applicable for only main axes or only grid axes. + * (Properties not listed are applicable for both) + */ + var AXIS_PROPERTY_TYPE = { + grid: 'grid', + gridScale: 'grid', + domain: 'main', + labels: 'main', + labelFlush: 'main', + labelOverlap: 'main', + minExtent: 'main', + maxExtent: 'main', + offset: 'main', + ticks: 'main', + title: 'main', + values: 'both', + scale: 'both', + zindex: 'both' // this is actually set afterward, so it doesn't matter + }; + var COMMON_AXIS_PROPERTIES_INDEX = { + orient: 1, + domain: 1, + format: 1, + grid: 1, + labelBound: 1, + labelFlush: 1, + labelPadding: 1, + labels: 1, + labelOverlap: 1, + maxExtent: 1, + minExtent: 1, + offset: 1, + position: 1, + tickCount: 1, + ticks: 1, + tickSize: 1, + title: 1, + titlePadding: 1, + values: 1, + zindex: 1, + }; + var AXIS_PROPERTIES_INDEX = __assign({}, COMMON_AXIS_PROPERTIES_INDEX, { encoding: 1, labelAngle: 1, titleMaxLength: 1 }); + var VG_AXIS_PROPERTIES_INDEX = __assign({ scale: 1 }, COMMON_AXIS_PROPERTIES_INDEX, { gridScale: 1, encode: 1 }); + function isAxisProperty(prop) { + return !!AXIS_PROPERTIES_INDEX[prop]; + } + var VG_AXIS_PROPERTIES = flagKeys(VG_AXIS_PROPERTIES_INDEX); + // Export for dependent projects + var AXIS_PROPERTIES = flagKeys(AXIS_PROPERTIES_INDEX); + + var axis = /*#__PURE__*/Object.freeze({ + AXIS_PARTS: AXIS_PARTS, + AXIS_PROPERTY_TYPE: AXIS_PROPERTY_TYPE, + isAxisProperty: isAxisProperty, + VG_AXIS_PROPERTIES: VG_AXIS_PROPERTIES, + AXIS_PROPERTIES: AXIS_PROPERTIES + }); + + /* + * Constants and utilities for encoding channels (Visual variables) + * such as 'x', 'y', 'color'. + */ + var Channel; + (function (Channel) { + // Facet + Channel.ROW = 'row'; + Channel.COLUMN = 'column'; + // Position + Channel.X = 'x'; + Channel.Y = 'y'; + Channel.X2 = 'x2'; + Channel.Y2 = 'y2'; + // Geo Position + Channel.LATITUDE = 'latitude'; + Channel.LONGITUDE = 'longitude'; + Channel.LATITUDE2 = 'latitude2'; + Channel.LONGITUDE2 = 'longitude2'; + // Mark property with scale + Channel.COLOR = 'color'; + Channel.FILL = 'fill'; + Channel.STROKE = 'stroke'; + Channel.SHAPE = 'shape'; + Channel.SIZE = 'size'; + Channel.OPACITY = 'opacity'; + // Non-scale channel + Channel.TEXT = 'text'; + Channel.ORDER = 'order'; + Channel.DETAIL = 'detail'; + Channel.KEY = 'key'; + Channel.TOOLTIP = 'tooltip'; + Channel.HREF = 'href'; + })(Channel || (Channel = {})); + var X = Channel.X; + var Y = Channel.Y; + var X2 = Channel.X2; + var Y2 = Channel.Y2; + var LATITUDE = Channel.LATITUDE; + var LATITUDE2 = Channel.LATITUDE2; + var LONGITUDE = Channel.LONGITUDE; + var LONGITUDE2 = Channel.LONGITUDE2; + var ROW = Channel.ROW; + var COLUMN = Channel.COLUMN; + var SHAPE = Channel.SHAPE; + var SIZE = Channel.SIZE; + var COLOR = Channel.COLOR; + var FILL = Channel.FILL; + var STROKE = Channel.STROKE; + var TEXT = Channel.TEXT; + var DETAIL = Channel.DETAIL; + var KEY = Channel.KEY; + var ORDER = Channel.ORDER; + var OPACITY = Channel.OPACITY; + var TOOLTIP = Channel.TOOLTIP; + var HREF = Channel.HREF; + var GEOPOSITION_CHANNEL_INDEX = { + longitude: 1, + longitude2: 1, + latitude: 1, + latitude2: 1, + }; + var GEOPOSITION_CHANNELS = flagKeys(GEOPOSITION_CHANNEL_INDEX); + var UNIT_CHANNEL_INDEX = __assign({ + // position + x: 1, y: 1, x2: 1, y2: 1 }, GEOPOSITION_CHANNEL_INDEX, { + // color + color: 1, fill: 1, stroke: 1, + // other non-position with scale + opacity: 1, size: 1, shape: 1, + // channels without scales + order: 1, text: 1, detail: 1, key: 1, tooltip: 1, href: 1 }); + function isColorChannel(channel) { + return channel === 'color' || channel === 'fill' || channel === 'stroke'; + } + var FACET_CHANNEL_INDEX = { + row: 1, + column: 1 + }; + var CHANNEL_INDEX = __assign({}, UNIT_CHANNEL_INDEX, FACET_CHANNEL_INDEX); + var CHANNELS = flagKeys(CHANNEL_INDEX); + var _o = CHANNEL_INDEX.order, _d = CHANNEL_INDEX.detail, SINGLE_DEF_CHANNEL_INDEX = __rest(CHANNEL_INDEX, ["order", "detail"]); + /** + * Channels that cannot have an array of channelDef. + * model.fieldDef, getFieldDef only work for these channels. + * + * (The only two channels that can have an array of channelDefs are "detail" and "order". + * Since there can be multiple fieldDefs for detail and order, getFieldDef/model.fieldDef + * are not applicable for them. Similarly, selection projection won't work with "detail" and "order".) + */ + var SINGLE_DEF_CHANNELS = flagKeys(SINGLE_DEF_CHANNEL_INDEX); + function isChannel(str) { + return !!CHANNEL_INDEX[str]; + } + // CHANNELS without COLUMN, ROW + var UNIT_CHANNELS = flagKeys(UNIT_CHANNEL_INDEX); + // NONPOSITION_CHANNELS = UNIT_CHANNELS without X, Y, X2, Y2; + var _x = UNIT_CHANNEL_INDEX.x, _y = UNIT_CHANNEL_INDEX.y, + // x2 and y2 share the same scale as x and y + _x2 = UNIT_CHANNEL_INDEX.x2, _y2 = UNIT_CHANNEL_INDEX.y2, _latitude = UNIT_CHANNEL_INDEX.latitude, _longitude = UNIT_CHANNEL_INDEX.longitude, _latitude2 = UNIT_CHANNEL_INDEX.latitude2, _longitude2 = UNIT_CHANNEL_INDEX.longitude2, + // The rest of unit channels then have scale + NONPOSITION_CHANNEL_INDEX = __rest(UNIT_CHANNEL_INDEX, ["x", "y", "x2", "y2", "latitude", "longitude", "latitude2", "longitude2"]); + var NONPOSITION_CHANNELS = flagKeys(NONPOSITION_CHANNEL_INDEX); + // POSITION_SCALE_CHANNELS = X and Y; + var POSITION_SCALE_CHANNEL_INDEX = { x: 1, y: 1 }; + var POSITION_SCALE_CHANNELS = flagKeys(POSITION_SCALE_CHANNEL_INDEX); + // NON_POSITION_SCALE_CHANNEL = SCALE_CHANNELS without X, Y + var + NONPOSITION_SCALE_CHANNEL_INDEX = __rest(NONPOSITION_CHANNEL_INDEX, ["text", "tooltip", "href", "detail", "key", "order"]); + var NONPOSITION_SCALE_CHANNELS = flagKeys(NONPOSITION_SCALE_CHANNEL_INDEX); + // Declare SCALE_CHANNEL_INDEX + var SCALE_CHANNEL_INDEX = __assign({}, POSITION_SCALE_CHANNEL_INDEX, NONPOSITION_SCALE_CHANNEL_INDEX); + /** List of channels with scales */ + var SCALE_CHANNELS = flagKeys(SCALE_CHANNEL_INDEX); + function isScaleChannel(channel) { + return !!SCALE_CHANNEL_INDEX[channel]; + } + /** + * Return whether a channel supports a particular mark type. + * @param channel channel name + * @param mark the mark type + * @return whether the mark supports the channel + */ + function supportMark(channel, mark) { + return mark in getSupportedMark(channel); + } + /** + * Return a dictionary showing whether a channel supports mark type. + * @param channel + * @return A dictionary mapping mark types to boolean values. + */ + function getSupportedMark(channel) { + switch (channel) { + case COLOR: + case FILL: + case STROKE: + case DETAIL: + case KEY: + case TOOLTIP: + case HREF: + case ORDER: // TODO: revise (order might not support rect, which is not stackable?) + case OPACITY: + case ROW: + case COLUMN: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, rect: true, line: true, trail: true, area: true, text: true, geoshape: true + }; + case X: + case Y: + case LATITUDE: + case LONGITUDE: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, rect: true, line: true, trail: true, area: true, text: true + }; + case X2: + case Y2: + case LATITUDE2: + case LONGITUDE2: + return { + rule: true, bar: true, rect: true, area: true + }; + case SIZE: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, text: true, line: true, trail: true + }; + case SHAPE: + return { point: true, geoshape: true }; + case TEXT: + return { text: true }; + } + } + function rangeType(channel) { + switch (channel) { + case X: + case Y: + case SIZE: + case OPACITY: + // X2 and Y2 use X and Y scales, so they similarly have continuous range. + case X2: + case Y2: + return 'continuous'; + case ROW: + case COLUMN: + case SHAPE: + // TEXT, TOOLTIP, and HREF have no scale but have discrete output + case TEXT: + case TOOLTIP: + case HREF: + return 'discrete'; + // Color can be either continuous or discrete, depending on scale type. + case COLOR: + case FILL: + case STROKE: + return 'flexible'; + // No scale, no range type. + case LATITUDE: + case LONGITUDE: + case LATITUDE2: + case LONGITUDE2: + case DETAIL: + case KEY: + case ORDER: + return undefined; + } + /* istanbul ignore next: should never reach here. */ + throw new Error('rangeType not implemented for ' + channel); + } + + var channel = /*#__PURE__*/Object.freeze({ + get Channel () { return Channel; }, + X: X, + Y: Y, + X2: X2, + Y2: Y2, + LATITUDE: LATITUDE, + LATITUDE2: LATITUDE2, + LONGITUDE: LONGITUDE, + LONGITUDE2: LONGITUDE2, + ROW: ROW, + COLUMN: COLUMN, + SHAPE: SHAPE, + SIZE: SIZE, + COLOR: COLOR, + FILL: FILL, + STROKE: STROKE, + TEXT: TEXT, + DETAIL: DETAIL, + KEY: KEY, + ORDER: ORDER, + OPACITY: OPACITY, + TOOLTIP: TOOLTIP, + HREF: HREF, + GEOPOSITION_CHANNEL_INDEX: GEOPOSITION_CHANNEL_INDEX, + GEOPOSITION_CHANNELS: GEOPOSITION_CHANNELS, + isColorChannel: isColorChannel, + CHANNELS: CHANNELS, + SINGLE_DEF_CHANNELS: SINGLE_DEF_CHANNELS, + isChannel: isChannel, + UNIT_CHANNELS: UNIT_CHANNELS, + NONPOSITION_CHANNELS: NONPOSITION_CHANNELS, + POSITION_SCALE_CHANNELS: POSITION_SCALE_CHANNELS, + NONPOSITION_SCALE_CHANNELS: NONPOSITION_SCALE_CHANNELS, + SCALE_CHANNELS: SCALE_CHANNELS, + isScaleChannel: isScaleChannel, + supportMark: supportMark, + getSupportedMark: getSupportedMark, + rangeType: rangeType + }); + + function binToString(bin) { + if (isBoolean(bin)) { + return 'bin'; + } + return 'bin' + keys(bin).map(function (p) { return varName("_" + p + "_" + bin[p]); }).join(''); + } + function isBinParams(bin) { + return bin && !isBoolean(bin); + } + function autoMaxBins(channel) { + switch (channel) { + case ROW: + case COLUMN: + case SIZE: + case COLOR: + case FILL: + case STROKE: + case OPACITY: + // Facets and Size shouldn't have too many bins + // We choose 6 like shape to simplify the rule + case SHAPE: + return 6; // Vega's "shape" has 6 distinct values + default: + return 10; + } + } + + var bin = /*#__PURE__*/Object.freeze({ + binToString: binToString, + isBinParams: isBinParams, + autoMaxBins: autoMaxBins + }); + + var Mark; + (function (Mark) { + Mark.AREA = 'area'; + Mark.BAR = 'bar'; + Mark.LINE = 'line'; + Mark.POINT = 'point'; + Mark.RECT = 'rect'; + Mark.RULE = 'rule'; + Mark.TEXT = 'text'; + Mark.TICK = 'tick'; + Mark.TRAIL = 'trail'; + Mark.CIRCLE = 'circle'; + Mark.SQUARE = 'square'; + Mark.GEOSHAPE = 'geoshape'; + })(Mark || (Mark = {})); + var AREA = Mark.AREA; + var BAR = Mark.BAR; + var LINE = Mark.LINE; + var POINT = Mark.POINT; + var TEXT$1 = Mark.TEXT; + var TICK = Mark.TICK; + var TRAIL = Mark.TRAIL; + var RECT = Mark.RECT; + var RULE = Mark.RULE; + var GEOSHAPE = Mark.GEOSHAPE; + var CIRCLE = Mark.CIRCLE; + var SQUARE = Mark.SQUARE; + // Using mapped type to declare index, ensuring we always have all marks when we add more. + var MARK_INDEX = { + area: 1, + bar: 1, + line: 1, + point: 1, + text: 1, + tick: 1, + trail: 1, + rect: 1, + geoshape: 1, + rule: 1, + circle: 1, + square: 1 + }; + function isMark(m) { + return !!MARK_INDEX[m]; + } + function isPathMark(m) { + return contains(['line', 'area', 'trail'], m); + } + var PRIMITIVE_MARKS = flagKeys(MARK_INDEX); + function isMarkDef(mark) { + return mark['type']; + } + var PRIMITIVE_MARK_INDEX = toSet(PRIMITIVE_MARKS); + function isPrimitiveMark(mark) { + var markType = isMarkDef(mark) ? mark.type : mark; + return markType in PRIMITIVE_MARK_INDEX; + } + var STROKE_CONFIG = ['stroke', 'strokeWidth', + 'strokeDash', 'strokeDashOffset', 'strokeOpacity', 'strokeJoin', 'strokeMiterLimit']; + var FILL_CONFIG = ['fill', 'fillOpacity']; + var FILL_STROKE_CONFIG = [].concat(STROKE_CONFIG, FILL_CONFIG); + var VL_ONLY_MARK_CONFIG_PROPERTIES = ['filled', 'color']; + var VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = { + area: ['line', 'point'], + bar: ['binSpacing', 'continuousBandSize', 'discreteBandSize'], + line: ['point'], + text: ['shortTimeLabels'], + tick: ['bandSize', 'thickness'] + }; + var defaultMarkConfig = { + color: '#4c78a8', + }; + var defaultBarConfig = { + binSpacing: 1, + continuousBandSize: 5 + }; + var defaultTickConfig = { + thickness: 1 + }; + + var mark = /*#__PURE__*/Object.freeze({ + get Mark () { return Mark; }, + AREA: AREA, + BAR: BAR, + LINE: LINE, + POINT: POINT, + TEXT: TEXT$1, + TICK: TICK, + TRAIL: TRAIL, + RECT: RECT, + RULE: RULE, + GEOSHAPE: GEOSHAPE, + CIRCLE: CIRCLE, + SQUARE: SQUARE, + isMark: isMark, + isPathMark: isPathMark, + PRIMITIVE_MARKS: PRIMITIVE_MARKS, + isMarkDef: isMarkDef, + isPrimitiveMark: isPrimitiveMark, + STROKE_CONFIG: STROKE_CONFIG, + FILL_CONFIG: FILL_CONFIG, + FILL_STROKE_CONFIG: FILL_STROKE_CONFIG, + VL_ONLY_MARK_CONFIG_PROPERTIES: VL_ONLY_MARK_CONFIG_PROPERTIES, + VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX: VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX, + defaultMarkConfig: defaultMarkConfig, + defaultBarConfig: defaultBarConfig, + defaultTickConfig: defaultTickConfig + }); + + /** + * Vega-Lite's singleton logger utility. + */ + /** + * Main (default) Vega Logger instance for Vega-Lite + */ + var main = logger(Warn); + var current = main; + /** + * Set the singleton logger to be a custom logger + */ + function set(newLogger) { + current = newLogger; + return current; + } + /** + * Reset the main logger to use the default Vega Logger + */ + function reset() { + current = main; + return current; + } + function warn() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.warn.apply(current, arguments); + } + function debug() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.debug.apply(current, arguments); + } + /** + * Collection of all Vega-Lite Error Messages + */ + var message; + (function (message) { + message.INVALID_SPEC = 'Invalid spec'; + // FIT + message.FIT_NON_SINGLE = 'Autosize "fit" only works for single views and layered views.'; + message.CANNOT_FIX_RANGE_STEP_WITH_FIT = 'Cannot use a fixed value of "rangeStep" when "autosize" is "fit".'; + // SELECTION + function cannotProjectOnChannelWithoutField(channel) { + return "Cannot project a selection on encoding channel \"" + channel + "\", which has no field."; + } + message.cannotProjectOnChannelWithoutField = cannotProjectOnChannelWithoutField; + function nearestNotSupportForContinuous(mark) { + return "The \"nearest\" transform is not supported for " + mark + " marks."; + } + message.nearestNotSupportForContinuous = nearestNotSupportForContinuous; + function selectionNotFound(name) { + return "Cannot find a selection named \"" + name + "\""; + } + message.selectionNotFound = selectionNotFound; + message.SCALE_BINDINGS_CONTINUOUS = 'Scale bindings are currently only supported for scales with unbinned, continuous domains.'; + // REPEAT + function noSuchRepeatedValue(field$$1) { + return "Unknown repeated value \"" + field$$1 + "\"."; + } + message.noSuchRepeatedValue = noSuchRepeatedValue; + // CONCAT + message.CONCAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in concatenated views.'; + // REPEAT + message.REPEAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in repeated views.'; + // TITLE + function cannotSetTitleAnchor(type) { + return "Cannot set title \"anchor\" for a " + type + " spec"; + } + message.cannotSetTitleAnchor = cannotSetTitleAnchor; + // DATA + function unrecognizedParse(p) { + return "Unrecognized parse \"" + p + "\"."; + } + message.unrecognizedParse = unrecognizedParse; + function differentParse(field$$1, local, ancestor) { + return "An ancestor parsed field \"" + field$$1 + "\" as " + ancestor + " but a child wants to parse the field as " + local + "."; + } + message.differentParse = differentParse; + // TRANSFORMS + function invalidTransformIgnored(transform) { + return "Ignoring an invalid transform: " + stringify$2(transform) + "."; + } + message.invalidTransformIgnored = invalidTransformIgnored; + message.NO_FIELDS_NEEDS_AS = 'If "from.fields" is not specified, "as" has to be a string that specifies the key to be used for the data from the secondary source.'; + // ENCODING & FACET + function encodingOverridden(channels) { + return "Layer's shared " + channels.join(',') + " channel " + (channels.length === 1 ? 'is' : 'are') + " overriden"; + } + message.encodingOverridden = encodingOverridden; + function projectionOverridden(opt) { + var parentProjection = opt.parentProjection, projection = opt.projection; + return "Layer's shared projection " + stringify$2(parentProjection) + " is overridden by a child projection " + stringify$2(projection) + "."; + } + message.projectionOverridden = projectionOverridden; + function primitiveChannelDef(channel, type, value) { + return "Channel " + channel + " is a " + type + ". Converted to {value: " + stringify$2(value) + "}."; + } + message.primitiveChannelDef = primitiveChannelDef; + function invalidFieldType(type) { + return "Invalid field type \"" + type + "\""; + } + message.invalidFieldType = invalidFieldType; + function nonZeroScaleUsedWithLengthMark(mark, channel, opt) { + var scaleText = opt.scaleType ? opt.scaleType + " scale" : + opt.zeroFalse ? 'scale with zero=false' : + 'scale with custom domain that excludes zero'; + return "A " + scaleText + " is used to encode " + mark + "'s " + channel + ". This can be misleading as the " + (channel === 'x' ? 'width' : 'height') + " of the " + mark + " can be arbitrary based on the scale domain. You may want to use point mark instead."; + } + message.nonZeroScaleUsedWithLengthMark = nonZeroScaleUsedWithLengthMark; + function invalidFieldTypeForCountAggregate(type, aggregate) { + return "Invalid field type \"" + type + "\" for aggregate: \"" + aggregate + "\", using \"quantitative\" instead."; + } + message.invalidFieldTypeForCountAggregate = invalidFieldTypeForCountAggregate; + function invalidAggregate(aggregate) { + return "Invalid aggregation operator \"" + aggregate + "\""; + } + message.invalidAggregate = invalidAggregate; + function emptyOrInvalidFieldType(type, channel, newType) { + return "Invalid field type \"" + type + "\" for channel \"" + channel + "\", using \"" + newType + "\" instead."; + } + message.emptyOrInvalidFieldType = emptyOrInvalidFieldType; + function droppingColor(type, opt) { + var fill = opt.fill, stroke = opt.stroke; + return "Dropping color " + type + " as the plot also has " + (fill && stroke ? 'fill and stroke' : fill ? 'fill' : 'stroke'); + } + message.droppingColor = droppingColor; + function emptyFieldDef(fieldDef, channel) { + return "Dropping " + stringify$2(fieldDef) + " from channel \"" + channel + "\" since it does not contain data field or value."; + } + message.emptyFieldDef = emptyFieldDef; + function latLongDeprecated(channel, type, newChannel) { + return channel + "-encoding with type " + type + " is deprecated. Replacing with " + newChannel + "-encoding."; + } + message.latLongDeprecated = latLongDeprecated; + message.LINE_WITH_VARYING_SIZE = 'Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.'; + function incompatibleChannel(channel, markOrFacet, when) { + return channel + " dropped as it is incompatible with \"" + markOrFacet + "\"" + (when ? " when " + when : '') + "."; + } + message.incompatibleChannel = incompatibleChannel; + function invalidEncodingChannel(channel) { + return channel + "-encoding is dropped as " + channel + " is not a valid encoding channel."; + } + message.invalidEncodingChannel = invalidEncodingChannel; + function facetChannelShouldBeDiscrete(channel) { + return channel + " encoding should be discrete (ordinal / nominal / binned)."; + } + message.facetChannelShouldBeDiscrete = facetChannelShouldBeDiscrete; + function discreteChannelCannotEncode(channel, type) { + return "Using discrete channel \"" + channel + "\" to encode \"" + type + "\" field can be misleading as it does not encode " + (type === 'ordinal' ? 'order' : 'magnitude') + "."; + } + message.discreteChannelCannotEncode = discreteChannelCannotEncode; + // Mark + message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.'; + function lineWithRange(hasX2, hasY2) { + var channels = hasX2 && hasY2 ? 'x2 and y2' : hasX2 ? 'x2' : 'y2'; + return "Line mark is for continuous lines and thus cannot be used with " + channels + ". We will use the rule mark (line segments) instead."; + } + message.lineWithRange = lineWithRange; + function orientOverridden(original, actual) { + return "Specified orient \"" + original + "\" overridden with \"" + actual + "\""; + } + message.orientOverridden = orientOverridden; + // SCALE + message.CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = 'custom domain scale cannot be unioned with default field-based domain'; + function cannotUseScalePropertyWithNonColor(prop) { + return "Cannot use the scale property \"" + prop + "\" with non-color channel."; + } + message.cannotUseScalePropertyWithNonColor = cannotUseScalePropertyWithNonColor; + function unaggregateDomainHasNoEffectForRawField(fieldDef) { + return "Using unaggregated domain with raw field has no effect (" + stringify$2(fieldDef) + ")."; + } + message.unaggregateDomainHasNoEffectForRawField = unaggregateDomainHasNoEffectForRawField; + function unaggregateDomainWithNonSharedDomainOp(aggregate) { + return "Unaggregated domain not applicable for \"" + aggregate + "\" since it produces values outside the origin domain of the source data."; + } + message.unaggregateDomainWithNonSharedDomainOp = unaggregateDomainWithNonSharedDomainOp; + function unaggregatedDomainWithLogScale(fieldDef) { + return "Unaggregated domain is currently unsupported for log scale (" + stringify$2(fieldDef) + ")."; + } + message.unaggregatedDomainWithLogScale = unaggregatedDomainWithLogScale; + function cannotApplySizeToNonOrientedMark(mark) { + return "Cannot apply size to non-oriented mark \"" + mark + "\"."; + } + message.cannotApplySizeToNonOrientedMark = cannotApplySizeToNonOrientedMark; + function rangeStepDropped(channel) { + return "rangeStep for \"" + channel + "\" is dropped as top-level " + (channel === 'x' ? 'width' : 'height') + " is provided."; + } + message.rangeStepDropped = rangeStepDropped; + function scaleTypeNotWorkWithChannel(channel, scaleType, defaultScaleType) { + return "Channel \"" + channel + "\" does not work with \"" + scaleType + "\" scale. We are using \"" + defaultScaleType + "\" scale instead."; + } + message.scaleTypeNotWorkWithChannel = scaleTypeNotWorkWithChannel; + function scaleTypeNotWorkWithFieldDef(scaleType, defaultScaleType) { + return "FieldDef does not work with \"" + scaleType + "\" scale. We are using \"" + defaultScaleType + "\" scale instead."; + } + message.scaleTypeNotWorkWithFieldDef = scaleTypeNotWorkWithFieldDef; + function scalePropertyNotWorkWithScaleType(scaleType, propName, channel) { + return channel + "-scale's \"" + propName + "\" is dropped as it does not work with " + scaleType + " scale."; + } + message.scalePropertyNotWorkWithScaleType = scalePropertyNotWorkWithScaleType; + function scaleTypeNotWorkWithMark(mark, scaleType) { + return "Scale type \"" + scaleType + "\" does not work with mark \"" + mark + "\"."; + } + message.scaleTypeNotWorkWithMark = scaleTypeNotWorkWithMark; + function mergeConflictingProperty(property, propertyOf, v1, v2) { + return "Conflicting " + propertyOf.toString() + " property \"" + property.toString() + "\" (" + stringify$2(v1) + " and " + stringify$2(v2) + "). Using " + stringify$2(v1) + "."; + } + message.mergeConflictingProperty = mergeConflictingProperty; + function independentScaleMeansIndependentGuide(channel) { + return "Setting the scale to be independent for \"" + channel + "\" means we also have to set the guide (axis or legend) to be independent."; + } + message.independentScaleMeansIndependentGuide = independentScaleMeansIndependentGuide; + function domainSortDropped(sort) { + return "Dropping sort property " + stringify$2(sort) + " as unioned domains only support boolean or op 'count'."; + } + message.domainSortDropped = domainSortDropped; + message.UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains'; + message.MORE_THAN_ONE_SORT = 'Domains that should be unioned has conflicting sort properties. Sort will be set to true.'; + // AXIS + message.INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.'; + // STACK + function cannotStackRangedMark(channel) { + return "Cannot stack \"" + channel + "\" if there is already \"" + channel + "2\""; + } + message.cannotStackRangedMark = cannotStackRangedMark; + function cannotStackNonLinearScale(scaleType) { + return "Cannot stack non-linear scale (" + scaleType + ")"; + } + message.cannotStackNonLinearScale = cannotStackNonLinearScale; + function stackNonSummativeAggregate(aggregate) { + return "Stacking is applied even though the aggregate function is non-summative (\"" + aggregate + "\")"; + } + message.stackNonSummativeAggregate = stackNonSummativeAggregate; + // TIMEUNIT + function invalidTimeUnit(unitName, value) { + return "Invalid " + unitName + ": " + stringify$2(value); + } + message.invalidTimeUnit = invalidTimeUnit; + function dayReplacedWithDate(fullTimeUnit) { + return "Time unit \"" + fullTimeUnit + "\" is not supported. We are replacing it with " + fullTimeUnit.replace('day', 'date') + "."; + } + message.dayReplacedWithDate = dayReplacedWithDate; + function droppedDay(d) { + return "Dropping day from datetime " + stringify$2(d) + " as day cannot be combined with other units."; + } + message.droppedDay = droppedDay; + })(message || (message = {})); + + // DateTime definition object + /* + * A designated year that starts on Sunday. + */ + var SUNDAY_YEAR = 2006; + function isDateTime(o) { + return !!o && (!!o.year || !!o.quarter || !!o.month || !!o.date || !!o.day || + !!o.hours || !!o.minutes || !!o.seconds || !!o.milliseconds); + } + var MONTHS = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december']; + var SHORT_MONTHS = MONTHS.map(function (m) { return m.substr(0, 3); }); + var DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']; + var SHORT_DAYS = DAYS.map(function (d) { return d.substr(0, 3); }); + function normalizeQuarter(q) { + if (isNumber(q)) { + if (q > 4) { + warn(message.invalidTimeUnit('quarter', q)); + } + // We accept 1-based quarter, so need to readjust to 0-based quarter + return (q - 1) + ''; + } + else { + // Invalid quarter + throw new Error(message.invalidTimeUnit('quarter', q)); + } + } + function normalizeMonth(m) { + if (isNumber(m)) { + // We accept 1-based month, so need to readjust to 0-based month + return (m - 1) + ''; + } + else { + var lowerM = m.toLowerCase(); + var monthIndex = MONTHS.indexOf(lowerM); + if (monthIndex !== -1) { + return monthIndex + ''; // 0 for january, ... + } + var shortM = lowerM.substr(0, 3); + var shortMonthIndex = SHORT_MONTHS.indexOf(shortM); + if (shortMonthIndex !== -1) { + return shortMonthIndex + ''; + } + // Invalid month + throw new Error(message.invalidTimeUnit('month', m)); + } + } + function normalizeDay(d) { + if (isNumber(d)) { + // mod so that this can be both 0-based where 0 = sunday + // and 1-based where 7=sunday + return (d % 7) + ''; + } + else { + var lowerD = d.toLowerCase(); + var dayIndex = DAYS.indexOf(lowerD); + if (dayIndex !== -1) { + return dayIndex + ''; // 0 for january, ... + } + var shortD = lowerD.substr(0, 3); + var shortDayIndex = SHORT_DAYS.indexOf(shortD); + if (shortDayIndex !== -1) { + return shortDayIndex + ''; + } + // Invalid day + throw new Error(message.invalidTimeUnit('day', d)); + } + } + /** + * Return Vega Expression for a particular date time. + * @param d + * @param normalize whether to normalize quarter, month, day. + */ + function dateTimeExpr(d, normalize) { + if (normalize === void 0) { normalize = false; } + var units = []; + if (normalize && d.day !== undefined) { + if (keys(d).length > 1) { + warn(message.droppedDay(d)); + d = duplicate(d); + delete d.day; + } + } + if (d.year !== undefined) { + units.push(d.year); + } + else if (d.day !== undefined) { + // Set year to 2006 for working with day since January 1 2006 is a Sunday + units.push(SUNDAY_YEAR); + } + else { + units.push(0); + } + if (d.month !== undefined) { + var month = normalize ? normalizeMonth(d.month) : d.month; + units.push(month); + } + else if (d.quarter !== undefined) { + var quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter; + units.push(quarter + '*3'); + } + else { + units.push(0); // months start at zero in JS + } + if (d.date !== undefined) { + units.push(d.date); + } + else if (d.day !== undefined) { + // HACK: Day only works as a standalone unit + // This is only correct because we always set year to 2006 for day + var day = normalize ? normalizeDay(d.day) : d.day; + units.push(day + '+1'); + } + else { + units.push(1); // Date starts at 1 in JS + } + // Note: can't use TimeUnit enum here as importing it will create + // circular dependency problem! + for (var _i = 0, _a = ['hours', 'minutes', 'seconds', 'milliseconds']; _i < _a.length; _i++) { + var timeUnit = _a[_i]; + if (d[timeUnit] !== undefined) { + units.push(d[timeUnit]); + } + else { + units.push(0); + } + } + if (d.utc) { + return "utc(" + units.join(', ') + ")"; + } + else { + return "datetime(" + units.join(', ') + ")"; + } + } + + var datetime = /*#__PURE__*/Object.freeze({ + isDateTime: isDateTime, + MONTHS: MONTHS, + SHORT_MONTHS: SHORT_MONTHS, + DAYS: DAYS, + SHORT_DAYS: SHORT_DAYS, + dateTimeExpr: dateTimeExpr + }); + + var TimeUnit; + (function (TimeUnit) { + TimeUnit.YEAR = 'year'; + TimeUnit.MONTH = 'month'; + TimeUnit.DAY = 'day'; + TimeUnit.DATE = 'date'; + TimeUnit.HOURS = 'hours'; + TimeUnit.MINUTES = 'minutes'; + TimeUnit.SECONDS = 'seconds'; + TimeUnit.MILLISECONDS = 'milliseconds'; + TimeUnit.YEARMONTH = 'yearmonth'; + TimeUnit.YEARMONTHDATE = 'yearmonthdate'; + TimeUnit.YEARMONTHDATEHOURS = 'yearmonthdatehours'; + TimeUnit.YEARMONTHDATEHOURSMINUTES = 'yearmonthdatehoursminutes'; + TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS = 'yearmonthdatehoursminutesseconds'; + // MONTHDATE always include 29 February since we use year 0th (which is a leap year); + TimeUnit.MONTHDATE = 'monthdate'; + TimeUnit.HOURSMINUTES = 'hoursminutes'; + TimeUnit.HOURSMINUTESSECONDS = 'hoursminutesseconds'; + TimeUnit.MINUTESSECONDS = 'minutesseconds'; + TimeUnit.SECONDSMILLISECONDS = 'secondsmilliseconds'; + TimeUnit.QUARTER = 'quarter'; + TimeUnit.YEARQUARTER = 'yearquarter'; + TimeUnit.QUARTERMONTH = 'quartermonth'; + TimeUnit.YEARQUARTERMONTH = 'yearquartermonth'; + TimeUnit.UTCYEAR = 'utcyear'; + TimeUnit.UTCMONTH = 'utcmonth'; + TimeUnit.UTCDAY = 'utcday'; + TimeUnit.UTCDATE = 'utcdate'; + TimeUnit.UTCHOURS = 'utchours'; + TimeUnit.UTCMINUTES = 'utcminutes'; + TimeUnit.UTCSECONDS = 'utcseconds'; + TimeUnit.UTCMILLISECONDS = 'utcmilliseconds'; + TimeUnit.UTCYEARMONTH = 'utcyearmonth'; + TimeUnit.UTCYEARMONTHDATE = 'utcyearmonthdate'; + TimeUnit.UTCYEARMONTHDATEHOURS = 'utcyearmonthdatehours'; + TimeUnit.UTCYEARMONTHDATEHOURSMINUTES = 'utcyearmonthdatehoursminutes'; + TimeUnit.UTCYEARMONTHDATEHOURSMINUTESSECONDS = 'utcyearmonthdatehoursminutesseconds'; + // MONTHDATE always include 29 February since we use year 0th (which is a leap year); + TimeUnit.UTCMONTHDATE = 'utcmonthdate'; + TimeUnit.UTCHOURSMINUTES = 'utchoursminutes'; + TimeUnit.UTCHOURSMINUTESSECONDS = 'utchoursminutesseconds'; + TimeUnit.UTCMINUTESSECONDS = 'utcminutesseconds'; + TimeUnit.UTCSECONDSMILLISECONDS = 'utcsecondsmilliseconds'; + TimeUnit.UTCQUARTER = 'utcquarter'; + TimeUnit.UTCYEARQUARTER = 'utcyearquarter'; + TimeUnit.UTCQUARTERMONTH = 'utcquartermonth'; + TimeUnit.UTCYEARQUARTERMONTH = 'utcyearquartermonth'; + })(TimeUnit || (TimeUnit = {})); + /** Time Unit that only corresponds to only one part of Date objects. */ + var LOCAL_SINGLE_TIMEUNIT_INDEX = { + year: 1, + quarter: 1, + month: 1, + day: 1, + date: 1, + hours: 1, + minutes: 1, + seconds: 1, + milliseconds: 1 + }; + var TIMEUNIT_PARTS = flagKeys(LOCAL_SINGLE_TIMEUNIT_INDEX); + function isLocalSingleTimeUnit(timeUnit) { + return !!LOCAL_SINGLE_TIMEUNIT_INDEX[timeUnit]; + } + var UTC_SINGLE_TIMEUNIT_INDEX = { + utcyear: 1, + utcquarter: 1, + utcmonth: 1, + utcday: 1, + utcdate: 1, + utchours: 1, + utcminutes: 1, + utcseconds: 1, + utcmilliseconds: 1 + }; + function isUtcSingleTimeUnit(timeUnit) { + return !!UTC_SINGLE_TIMEUNIT_INDEX[timeUnit]; + } + var LOCAL_MULTI_TIMEUNIT_INDEX = { + yearquarter: 1, + yearquartermonth: 1, + yearmonth: 1, + yearmonthdate: 1, + yearmonthdatehours: 1, + yearmonthdatehoursminutes: 1, + yearmonthdatehoursminutesseconds: 1, + quartermonth: 1, + monthdate: 1, + hoursminutes: 1, + hoursminutesseconds: 1, + minutesseconds: 1, + secondsmilliseconds: 1 + }; + var UTC_MULTI_TIMEUNIT_INDEX = { + utcyearquarter: 1, + utcyearquartermonth: 1, + utcyearmonth: 1, + utcyearmonthdate: 1, + utcyearmonthdatehours: 1, + utcyearmonthdatehoursminutes: 1, + utcyearmonthdatehoursminutesseconds: 1, + utcquartermonth: 1, + utcmonthdate: 1, + utchoursminutes: 1, + utchoursminutesseconds: 1, + utcminutesseconds: 1, + utcsecondsmilliseconds: 1 + }; + var UTC_TIMEUNIT_INDEX = __assign({}, UTC_SINGLE_TIMEUNIT_INDEX, UTC_MULTI_TIMEUNIT_INDEX); + function isUTCTimeUnit(t) { + return !!UTC_TIMEUNIT_INDEX[t]; + } + function getLocalTimeUnit(t) { + return t.substr(3); + } + var TIMEUNIT_INDEX = __assign({}, LOCAL_SINGLE_TIMEUNIT_INDEX, UTC_SINGLE_TIMEUNIT_INDEX, LOCAL_MULTI_TIMEUNIT_INDEX, UTC_MULTI_TIMEUNIT_INDEX); + var TIMEUNITS = flagKeys(TIMEUNIT_INDEX); + function isTimeUnit(t) { + return !!TIMEUNIT_INDEX[t]; + } + var SET_DATE_METHOD = { + year: 'setFullYear', + month: 'setMonth', + date: 'setDate', + hours: 'setHours', + minutes: 'setMinutes', + seconds: 'setSeconds', + milliseconds: 'setMilliseconds', + // Day and quarter have their own special cases + quarter: null, + day: null, + }; + /** + * Converts a date to only have the measurements relevant to the specified unit + * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00' + * Note: the base date is Jan 01 1900 00:00:00 + */ + function convert(unit, date) { + var isUTC = isUTCTimeUnit(unit); + var result = isUTC ? + // start with uniform date + new Date(Date.UTC(0, 0, 1, 0, 0, 0, 0)) : + new Date(0, 0, 1, 0, 0, 0, 0); + for (var _i = 0, TIMEUNIT_PARTS_1 = TIMEUNIT_PARTS; _i < TIMEUNIT_PARTS_1.length; _i++) { + var timeUnitPart = TIMEUNIT_PARTS_1[_i]; + if (containsTimeUnit(unit, timeUnitPart)) { + switch (timeUnitPart) { + case TimeUnit.DAY: + throw new Error('Cannot convert to TimeUnits containing \'day\''); + case TimeUnit.QUARTER: { + var _a = dateMethods('month', isUTC), getDateMethod_1 = _a.getDateMethod, setDateMethod_1 = _a.setDateMethod; + // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3) + result[setDateMethod_1]((Math.floor(date[getDateMethod_1]() / 3)) * 3); + break; + } + default: + var _b = dateMethods(timeUnitPart, isUTC), getDateMethod = _b.getDateMethod, setDateMethod = _b.setDateMethod; + result[setDateMethod](date[getDateMethod]()); + } + } + } + return result; + } + function dateMethods(singleUnit, isUtc) { + var rawSetDateMethod = SET_DATE_METHOD[singleUnit]; + var setDateMethod = isUtc ? 'setUTC' + rawSetDateMethod.substr(3) : rawSetDateMethod; + var getDateMethod = 'get' + (isUtc ? 'UTC' : '') + rawSetDateMethod.substr(3); + return { setDateMethod: setDateMethod, getDateMethod: getDateMethod }; + } + function getTimeUnitParts(timeUnit) { + return TIMEUNIT_PARTS.reduce(function (parts, part) { + if (containsTimeUnit(timeUnit, part)) { + return parts.concat(part); + } + return parts; + }, []); + } + /** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */ + function containsTimeUnit(fullTimeUnit, timeUnit) { + var index = fullTimeUnit.indexOf(timeUnit); + return index > -1 && + (timeUnit !== TimeUnit.SECONDS || + index === 0 || + fullTimeUnit.charAt(index - 1) !== 'i' // exclude milliseconds + ); + } + /** + * Returns Vega expresssion for a given timeUnit and fieldRef + */ + function fieldExpr(fullTimeUnit, field) { + var fieldRef = accessPathWithDatum(field); + var utc = isUTCTimeUnit(fullTimeUnit) ? 'utc' : ''; + function func(timeUnit) { + if (timeUnit === TimeUnit.QUARTER) { + // quarter starting at 0 (0,3,6,9). + return "(" + utc + "quarter(" + fieldRef + ")-1)"; + } + else { + return "" + utc + timeUnit + "(" + fieldRef + ")"; + } + } + var d = TIMEUNIT_PARTS.reduce(function (dateExpr, tu) { + if (containsTimeUnit(fullTimeUnit, tu)) { + dateExpr[tu] = func(tu); + } + return dateExpr; + }, {}); + return dateTimeExpr(d); + } + /** + * returns the signal expression used for axis labels for a time unit + */ + function formatExpression(timeUnit, field, shortTimeLabels, isUTCScale) { + if (!timeUnit) { + return undefined; + } + var dateComponents = []; + var expression = ''; + var hasYear = containsTimeUnit(timeUnit, TimeUnit.YEAR); + if (containsTimeUnit(timeUnit, TimeUnit.QUARTER)) { + // special expression for quarter as prefix + expression = "'Q' + quarter(" + field + ")"; + } + if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) { + // By default use short month name + dateComponents.push(shortTimeLabels !== false ? '%b' : '%B'); + } + if (containsTimeUnit(timeUnit, TimeUnit.DAY)) { + dateComponents.push(shortTimeLabels ? '%a' : '%A'); + } + else if (containsTimeUnit(timeUnit, TimeUnit.DATE)) { + dateComponents.push('%d' + (hasYear ? ',' : '')); // add comma if there is year + } + if (hasYear) { + dateComponents.push(shortTimeLabels ? '%y' : '%Y'); + } + var timeComponents = []; + if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) { + timeComponents.push('%H'); + } + if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) { + timeComponents.push('%M'); + } + if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) { + timeComponents.push('%S'); + } + if (containsTimeUnit(timeUnit, TimeUnit.MILLISECONDS)) { + timeComponents.push('%L'); + } + var dateTimeComponents = []; + if (dateComponents.length > 0) { + dateTimeComponents.push(dateComponents.join(' ')); + } + if (timeComponents.length > 0) { + dateTimeComponents.push(timeComponents.join(':')); + } + if (dateTimeComponents.length > 0) { + if (expression) { + // Add space between quarter and main time format + expression += " + ' ' + "; + } + // We only use utcFormat for utc scale + // For utc time units, the data is already converted as a part of timeUnit transform. + // Thus, utc time units should use timeFormat to avoid shifting the time twice. + if (isUTCScale) { + expression += "utcFormat(" + field + ", '" + dateTimeComponents.join(' ') + "')"; + } + else { + expression += "timeFormat(" + field + ", '" + dateTimeComponents.join(' ') + "')"; + } + } + // If expression is still an empty string, return undefined instead. + return expression || undefined; + } + function normalizeTimeUnit(timeUnit) { + if (timeUnit !== 'day' && timeUnit.indexOf('day') >= 0) { + warn(message.dayReplacedWithDate(timeUnit)); + return timeUnit.replace('day', 'date'); + } + return timeUnit; + } + + var timeunit = /*#__PURE__*/Object.freeze({ + get TimeUnit () { return TimeUnit; }, + TIMEUNIT_PARTS: TIMEUNIT_PARTS, + isLocalSingleTimeUnit: isLocalSingleTimeUnit, + isUtcSingleTimeUnit: isUtcSingleTimeUnit, + isUTCTimeUnit: isUTCTimeUnit, + getLocalTimeUnit: getLocalTimeUnit, + TIMEUNITS: TIMEUNITS, + isTimeUnit: isTimeUnit, + convert: convert, + getTimeUnitParts: getTimeUnitParts, + containsTimeUnit: containsTimeUnit, + fieldExpr: fieldExpr, + formatExpression: formatExpression, + normalizeTimeUnit: normalizeTimeUnit + }); + + /** Constants and utilities for data type */ + /** Data type based on level of measurement */ + var Type; + (function (Type) { + Type.QUANTITATIVE = 'quantitative'; + Type.ORDINAL = 'ordinal'; + Type.TEMPORAL = 'temporal'; + Type.NOMINAL = 'nominal'; + Type.LATITUDE = 'latitude'; + Type.LONGITUDE = 'longitude'; + Type.GEOJSON = 'geojson'; + })(Type || (Type = {})); + var TYPE_INDEX = { + quantitative: 1, + ordinal: 1, + temporal: 1, + nominal: 1, + latitude: 1, + longitude: 1, + geojson: 1 + }; + function isType(t) { + return !!TYPE_INDEX[t]; + } + var QUANTITATIVE = Type.QUANTITATIVE; + var ORDINAL = Type.ORDINAL; + var TEMPORAL = Type.TEMPORAL; + var NOMINAL = Type.NOMINAL; + var GEOJSON = Type.GEOJSON; + /** + * Get full, lowercase type name for a given type. + * @param type + * @return Full type name. + */ + function getFullName(type) { + if (type) { + type = type.toLowerCase(); + switch (type) { + case 'q': + case QUANTITATIVE: + return 'quantitative'; + case 't': + case TEMPORAL: + return 'temporal'; + case 'o': + case ORDINAL: + return 'ordinal'; + case 'n': + case NOMINAL: + return 'nominal'; + case Type.LATITUDE: + return 'latitude'; + case Type.LONGITUDE: + return 'longitude'; + case GEOJSON: + return 'geojson'; + } + } + // If we get invalid input, return undefined type. + return undefined; + } + + var type = /*#__PURE__*/Object.freeze({ + get Type () { return Type; }, + TYPE_INDEX: TYPE_INDEX, + isType: isType, + QUANTITATIVE: QUANTITATIVE, + ORDINAL: ORDINAL, + TEMPORAL: TEMPORAL, + NOMINAL: NOMINAL, + GEOJSON: GEOJSON, + getFullName: getFullName + }); + + function isConditionalSelection(c) { + return c['selection']; + } + function isRepeatRef(field$$1) { + return field$$1 && !isString(field$$1) && 'repeat' in field$$1; + } + function toFieldDefBase(fieldDef) { + var field$$1 = fieldDef.field, timeUnit = fieldDef.timeUnit, bin = fieldDef.bin, aggregate = fieldDef.aggregate; + return __assign({}, (timeUnit ? { timeUnit: timeUnit } : {}), (bin ? { bin: bin } : {}), (aggregate ? { aggregate: aggregate } : {}), { field: field$$1 }); + } + function isConditionalDef(channelDef) { + return !!channelDef && !!channelDef.condition; + } + /** + * Return if a channelDef is a ConditionalValueDef with ConditionFieldDef + */ + function hasConditionalFieldDef(channelDef) { + return !!channelDef && !!channelDef.condition && !isArray(channelDef.condition) && isFieldDef(channelDef.condition); + } + function hasConditionalValueDef(channelDef) { + return !!channelDef && !!channelDef.condition && (isArray(channelDef.condition) || isValueDef(channelDef.condition)); + } + function isFieldDef(channelDef) { + return !!channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count'); + } + function isStringFieldDef(fieldDef) { + return isFieldDef(fieldDef) && isString(fieldDef.field); + } + function isValueDef(channelDef) { + return channelDef && 'value' in channelDef && channelDef['value'] !== undefined; + } + function isScaleFieldDef(channelDef) { + return !!channelDef && (!!channelDef['scale'] || !!channelDef['sort']); + } + function isOpFieldDef(fieldDef) { + return !!fieldDef['op']; + } + function vgField(fieldDef, opt) { + if (opt === void 0) { opt = {}; } + var field$$1 = fieldDef.field; + var prefix = opt.prefix; + var suffix = opt.suffix; + if (isCount(fieldDef)) { + field$$1 = 'count_*'; + } + else { + var fn = undefined; + if (!opt.nofn) { + if (isOpFieldDef(fieldDef)) { + fn = fieldDef.op; + } + else if (fieldDef.bin) { + fn = binToString(fieldDef.bin); + suffix = opt.binSuffix || ''; + } + else if (fieldDef.aggregate) { + fn = String(fieldDef.aggregate); + } + else if (fieldDef.timeUnit) { + fn = String(fieldDef.timeUnit); + } + } + if (fn) { + field$$1 = field$$1 ? fn + "_" + field$$1 : fn; + } + } + if (suffix) { + field$$1 = field$$1 + "_" + suffix; + } + if (prefix) { + field$$1 = prefix + "_" + field$$1; + } + if (opt.expr) { + // Expression to access flattened field. No need to escape dots. + return flatAccessWithDatum(field$$1, opt.expr); + } + else { + // We flattened all fields so paths should have become dot. + return replacePathInField(field$$1); + } + } + function isDiscrete(fieldDef) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + case 'geojson': + return true; + case 'quantitative': + return !!fieldDef.bin; + case 'latitude': + case 'longitude': + case 'temporal': + return false; + } + throw new Error(message.invalidFieldType(fieldDef.type)); + } + function isContinuous(fieldDef) { + return !isDiscrete(fieldDef); + } + function isCount(fieldDef) { + return fieldDef.aggregate === 'count'; + } + function verbalTitleFormatter(fieldDef, config) { + var field$$1 = fieldDef.field, bin = fieldDef.bin, timeUnit = fieldDef.timeUnit, aggregate = fieldDef.aggregate; + if (aggregate === 'count') { + return config.countTitle; + } + else if (bin) { + return field$$1 + " (binned)"; + } + else if (timeUnit) { + var units = getTimeUnitParts(timeUnit).join('-'); + return field$$1 + " (" + units + ")"; + } + else if (aggregate) { + return titlecase(aggregate) + " of " + field$$1; + } + return field$$1; + } + function functionalTitleFormatter(fieldDef, config) { + var fn = fieldDef.aggregate || fieldDef.timeUnit || (fieldDef.bin && 'bin'); + if (fn) { + return fn.toUpperCase() + '(' + fieldDef.field + ')'; + } + else { + return fieldDef.field; + } + } + var defaultTitleFormatter = function (fieldDef, config) { + switch (config.fieldTitle) { + case 'plain': + return fieldDef.field; + case 'functional': + return functionalTitleFormatter(fieldDef, config); + default: + return verbalTitleFormatter(fieldDef, config); + } + }; + var titleFormatter = defaultTitleFormatter; + function setTitleFormatter(formatter) { + titleFormatter = formatter; + } + function resetTitleFormatter() { + setTitleFormatter(defaultTitleFormatter); + } + function title(fieldDef, config) { + return titleFormatter(fieldDef, config); + } + function defaultType(fieldDef, channel) { + if (fieldDef.timeUnit) { + return 'temporal'; + } + if (fieldDef.bin) { + return 'quantitative'; + } + switch (rangeType(channel)) { + case 'continuous': + return 'quantitative'; + case 'discrete': + return 'nominal'; + case 'flexible': // color + return 'nominal'; + default: + return 'quantitative'; + } + } + /** + * Returns the fieldDef -- either from the outer channelDef or from the condition of channelDef. + * @param channelDef + */ + function getFieldDef(channelDef) { + if (isFieldDef(channelDef)) { + return channelDef; + } + else if (hasConditionalFieldDef(channelDef)) { + return channelDef.condition; + } + return undefined; + } + /** + * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + */ + function normalize(channelDef, channel) { + if (isString(channelDef) || isNumber(channelDef) || isBoolean(channelDef)) { + var primitiveType = isString(channelDef) ? 'string' : + isNumber(channelDef) ? 'number' : 'boolean'; + warn(message.primitiveChannelDef(channel, primitiveType, channelDef)); + return { value: channelDef }; + } + // If a fieldDef contains a field, we need type. + if (isFieldDef(channelDef)) { + return normalizeFieldDef(channelDef, channel); + } + else if (hasConditionalFieldDef(channelDef)) { + return __assign({}, channelDef, { + // Need to cast as normalizeFieldDef normally return FieldDef, but here we know that it is definitely Condition + condition: normalizeFieldDef(channelDef.condition, channel) }); + } + return channelDef; + } + function normalizeFieldDef(fieldDef, channel) { + // Drop invalid aggregate + if (fieldDef.aggregate && !isAggregateOp(fieldDef.aggregate)) { + var aggregate = fieldDef.aggregate, fieldDefWithoutAggregate = __rest(fieldDef, ["aggregate"]); + warn(message.invalidAggregate(fieldDef.aggregate)); + fieldDef = fieldDefWithoutAggregate; + } + // Normalize Time Unit + if (fieldDef.timeUnit) { + fieldDef = __assign({}, fieldDef, { timeUnit: normalizeTimeUnit(fieldDef.timeUnit) }); + } + // Normalize bin + if (fieldDef.bin) { + fieldDef = __assign({}, fieldDef, { bin: normalizeBin(fieldDef.bin, channel) }); + } + // Normalize Type + if (fieldDef.type) { + var fullType = getFullName(fieldDef.type); + if (fieldDef.type !== fullType) { + // convert short type to full type + fieldDef = __assign({}, fieldDef, { type: fullType }); + } + if (fieldDef.type !== 'quantitative') { + if (isCountingAggregateOp(fieldDef.aggregate)) { + warn(message.invalidFieldTypeForCountAggregate(fieldDef.type, fieldDef.aggregate)); + fieldDef = __assign({}, fieldDef, { type: 'quantitative' }); + } + } + } + else { + // If type is empty / invalid, then augment with default type + var newType = defaultType(fieldDef, channel); + warn(message.emptyOrInvalidFieldType(fieldDef.type, channel, newType)); + fieldDef = __assign({}, fieldDef, { type: newType }); + } + var _a = channelCompatibility(fieldDef, channel), compatible = _a.compatible, warning = _a.warning; + if (!compatible) { + warn(warning); + } + return fieldDef; + } + function normalizeBin(bin, channel) { + if (isBoolean(bin)) { + return { maxbins: autoMaxBins(channel) }; + } + else if (!bin.maxbins && !bin.step) { + return __assign({}, bin, { maxbins: autoMaxBins(channel) }); + } + else { + return bin; + } + } + var COMPATIBLE = { compatible: true }; + function channelCompatibility(fieldDef, channel) { + var type = fieldDef.type; + switch (channel) { + case 'row': + case 'column': + if (isContinuous(fieldDef)) { + return { + compatible: false, + warning: message.facetChannelShouldBeDiscrete(channel) + }; + } + return COMPATIBLE; + case 'x': + case 'y': + case 'color': + case 'fill': + case 'stroke': + case 'text': + case 'detail': + case 'key': + case 'tooltip': + case 'href': + return COMPATIBLE; + case 'longitude': + case 'longitude2': + case 'latitude': + case 'latitude2': + if (type !== QUANTITATIVE) { + return { + compatible: false, + warning: "Channel " + channel + " should be used with a quantitative field only, not " + fieldDef.type + " field." + }; + } + return COMPATIBLE; + case 'opacity': + case 'size': + case 'x2': + case 'y2': + if ((type === 'nominal' && !fieldDef['sort']) || type === 'geojson') { + return { + compatible: false, + warning: "Channel " + channel + " should not be used with an unsorted discrete field." + }; + } + return COMPATIBLE; + case 'shape': + if (fieldDef.type !== 'nominal' && fieldDef.type !== 'geojson') { + return { + compatible: false, + warning: 'Shape channel should be used with only either nominal or geojson data' + }; + } + return COMPATIBLE; + case 'order': + if (fieldDef.type === 'nominal' && !('sort' in fieldDef)) { + return { + compatible: false, + warning: "Channel order is inappropriate for nominal field, which has no inherent order." + }; + } + return COMPATIBLE; + } + throw new Error('channelCompatability not implemented for channel ' + channel); + } + function isNumberFieldDef(fieldDef) { + return fieldDef.type === 'quantitative' || !!fieldDef.bin; + } + function isTimeFieldDef(fieldDef) { + return fieldDef.type === 'temporal' || !!fieldDef.timeUnit; + } + /** + * Getting a value associated with a fielddef. + * Convert the value to Vega expression if applicable (for datetime object, or string if the field def is temporal or has timeUnit) + */ + function valueExpr(v, _a) { + var timeUnit = _a.timeUnit, type = _a.type, time = _a.time, undefinedIfExprNotRequired = _a.undefinedIfExprNotRequired; + var _b; + var expr = undefined; + if (isDateTime(v)) { + expr = dateTimeExpr(v, true); + } + else if (isString(v) || isNumber(v)) { + if (timeUnit || type === 'temporal') { + if (isLocalSingleTimeUnit(timeUnit)) { + expr = dateTimeExpr((_b = {}, _b[timeUnit] = v, _b), true); + } + else if (isUtcSingleTimeUnit(timeUnit)) { + // FIXME is this really correct? + expr = valueExpr(v, { timeUnit: getLocalTimeUnit(timeUnit) }); + } + else { + // just pass the string to date function (which will call JS Date.parse()) + expr = "datetime(" + JSON.stringify(v) + ")"; + } + } + } + if (expr) { + return time ? "time(" + expr + ")" : expr; + } + // number or boolean or normal string + return undefinedIfExprNotRequired ? undefined : JSON.stringify(v); + } + /** + * Standardize value array -- convert each value to Vega expression if applicable + */ + function valueArray(fieldDef, values) { + var timeUnit = fieldDef.timeUnit, type = fieldDef.type; + return values.map(function (v) { + var expr = valueExpr(v, { timeUnit: timeUnit, type: type, undefinedIfExprNotRequired: true }); + // return signal for the expression if we need an expression + if (expr !== undefined) { + return { signal: expr }; + } + // otherwise just return the original value + return v; + }); + } + + var fielddef = /*#__PURE__*/Object.freeze({ + isConditionalSelection: isConditionalSelection, + isRepeatRef: isRepeatRef, + toFieldDefBase: toFieldDefBase, + isConditionalDef: isConditionalDef, + hasConditionalFieldDef: hasConditionalFieldDef, + hasConditionalValueDef: hasConditionalValueDef, + isFieldDef: isFieldDef, + isStringFieldDef: isStringFieldDef, + isValueDef: isValueDef, + isScaleFieldDef: isScaleFieldDef, + vgField: vgField, + isDiscrete: isDiscrete, + isContinuous: isContinuous, + isCount: isCount, + verbalTitleFormatter: verbalTitleFormatter, + functionalTitleFormatter: functionalTitleFormatter, + defaultTitleFormatter: defaultTitleFormatter, + setTitleFormatter: setTitleFormatter, + resetTitleFormatter: resetTitleFormatter, + title: title, + defaultType: defaultType, + getFieldDef: getFieldDef, + normalize: normalize, + normalizeFieldDef: normalizeFieldDef, + normalizeBin: normalizeBin, + channelCompatibility: channelCompatibility, + isNumberFieldDef: isNumberFieldDef, + isTimeFieldDef: isTimeFieldDef, + valueExpr: valueExpr, + valueArray: valueArray + }); + + function channelHasField(encoding, channel) { + var channelDef = encoding && encoding[channel]; + if (channelDef) { + if (isArray(channelDef)) { + return some(channelDef, function (fieldDef) { return !!fieldDef.field; }); + } + else { + return isFieldDef(channelDef) || hasConditionalFieldDef(channelDef); + } + } + return false; + } + function isAggregate(encoding) { + return some(CHANNELS, function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + if (isArray(channelDef)) { + return some(channelDef, function (fieldDef) { return !!fieldDef.aggregate; }); + } + else { + var fieldDef = getFieldDef(channelDef); + return fieldDef && !!fieldDef.aggregate; + } + } + return false; + }); + } + function normalizeEncoding(encoding, mark) { + return keys(encoding).reduce(function (normalizedEncoding, channel) { + var _a; + if (!isChannel(channel)) { + // Drop invalid channel + warn(message.invalidEncodingChannel(channel)); + return normalizedEncoding; + } + if (!supportMark(channel, mark)) { + // Drop unsupported channel + warn(message.incompatibleChannel(channel, mark)); + return normalizedEncoding; + } + // Drop line's size if the field is aggregated. + if (channel === 'size' && mark === 'line') { + var fieldDef = getFieldDef(encoding[channel]); + if (fieldDef && fieldDef.aggregate) { + warn(message.LINE_WITH_VARYING_SIZE); + return normalizedEncoding; + } + } + // Drop color if either fill or stroke is specified + if (channel === 'color' && ('fill' in encoding || 'stroke' in encoding)) { + warn(message.droppingColor('encoding', { fill: 'fill' in encoding, stroke: 'stroke' in encoding })); + return normalizedEncoding; + } + var channelDef = encoding[channel]; + if (channel === 'detail' || + (channel === 'order' && !isArray(channelDef) && !isValueDef(channelDef)) || + (channel === 'tooltip' && isArray(channelDef))) { + if (channelDef) { + // Array of fieldDefs for detail channel (or production rule) + normalizedEncoding[channel] = (isArray(channelDef) ? channelDef : [channelDef]) + .reduce(function (defs, fieldDef) { + if (!isFieldDef(fieldDef)) { + warn(message.emptyFieldDef(fieldDef, channel)); + } + else { + defs.push(normalizeFieldDef(fieldDef, channel)); + } + return defs; + }, []); + } + } + else { + var fieldDef = getFieldDef(encoding[channel]); + if (fieldDef && contains([Type.LATITUDE, Type.LONGITUDE], fieldDef.type)) { + var _b = channel, _ = normalizedEncoding[_b], newEncoding = __rest(normalizedEncoding, [typeof _b === "symbol" ? _b : _b + ""]); + var newChannel = channel === 'x' ? 'longitude' : + channel === 'y' ? 'latitude' : + channel === 'x2' ? 'longitude2' : + channel === 'y2' ? 'latitude2' : undefined; + warn(message.latLongDeprecated(channel, fieldDef.type, newChannel)); + return __assign({}, newEncoding, (_a = {}, _a[newChannel] = __assign({}, normalize(fieldDef, channel), { type: 'quantitative' }), _a)); + } + if (!isFieldDef(channelDef) && !isValueDef(channelDef) && !isConditionalDef(channelDef)) { + warn(message.emptyFieldDef(channelDef, channel)); + return normalizedEncoding; + } + normalizedEncoding[channel] = normalize(channelDef, channel); + } + return normalizedEncoding; + }, {}); + } + function isRanged(encoding) { + return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2)); + } + function fieldDefs(encoding) { + var arr = []; + CHANNELS.forEach(function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (isArray(channelDef) ? channelDef : [channelDef]).forEach(function (def) { + if (isFieldDef(def)) { + arr.push(def); + } + else if (hasConditionalFieldDef(def)) { + arr.push(def.condition); + } + }); + } + }); + return arr; + } + function forEach(mapping, f, thisArg) { + if (!mapping) { + return; + } + var _loop_1 = function (channel) { + if (isArray(mapping[channel])) { + mapping[channel].forEach(function (channelDef) { + f.call(thisArg, channelDef, channel); + }); + } + else { + f.call(thisArg, mapping[channel], channel); + } + }; + for (var _i = 0, _a = keys(mapping); _i < _a.length; _i++) { + var channel = _a[_i]; + _loop_1(channel); + } + } + function reduce(mapping, f, init, thisArg) { + if (!mapping) { + return init; + } + return keys(mapping).reduce(function (r, channel) { + var map = mapping[channel]; + if (isArray(map)) { + return map.reduce(function (r1, channelDef) { + return f.call(thisArg, r1, channelDef, channel); + }, r); + } + else { + return f.call(thisArg, r, map, channel); + } + }, init); + } + + var encoding = /*#__PURE__*/Object.freeze({ + channelHasField: channelHasField, + isAggregate: isAggregate, + normalizeEncoding: normalizeEncoding, + isRanged: isRanged, + fieldDefs: fieldDefs, + forEach: forEach, + reduce: reduce + }); + + function getMarkSpecificConfigMixins(markSpecificConfig, channel) { + var _a; + var value = markSpecificConfig[channel]; + return value !== undefined ? (_a = {}, _a[channel] = { value: value }, _a) : {}; + } + + var BOXPLOT = 'box-plot'; + function isBoxPlotDef(mark) { + return !!mark['type']; + } + var BOXPLOT_STYLES = ['boxWhisker', 'box', 'boxMid']; + var VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX = { + box: ['size', 'color', 'extent'], + boxWhisker: ['color'], + boxMid: ['color'] + }; + var supportedChannels = ['x', 'y', 'color', 'detail', 'opacity', 'size']; + function filterUnsupportedChannels(spec) { + return __assign({}, spec, { encoding: reduce(spec.encoding, function (newEncoding, fieldDef, channel) { + if (supportedChannels.indexOf(channel) > -1) { + newEncoding[channel] = fieldDef; + } + else { + warn(message.incompatibleChannel(channel, BOXPLOT)); + } + return newEncoding; + }, {}) }); + } + function normalizeBoxPlot(spec, config) { + var _a, _b, _c, _d; + spec = filterUnsupportedChannels(spec); + // TODO: use selection + var mark = spec.mark, encoding = spec.encoding, selection = spec.selection, _p = spec.projection, outerSpec = __rest(spec, ["mark", "encoding", "selection", "projection"]); + var kIQRScalar = undefined; + if (isNumber(config.box.extent)) { + kIQRScalar = config.box.extent; + } + if (isBoxPlotDef(mark)) { + if (mark.extent) { + if (mark.extent === 'min-max') { + kIQRScalar = undefined; + } + } + } + var orient = boxOrient(spec); + var _e = boxParams(spec, orient, kIQRScalar), transform = _e.transform, continuousAxisChannelDef = _e.continuousAxisChannelDef, continuousAxis = _e.continuousAxis, encodingWithoutContinuousAxis = _e.encodingWithoutContinuousAxis; + var size = encodingWithoutContinuousAxis.size, encodingWithoutSizeColorAndContinuousAxis = __rest(encodingWithoutContinuousAxis, ["color", "size"]); + // Size encoding or the default config.box.size is applied to box and boxMid + var sizeMixins = size ? { size: size } : getMarkSpecificConfigMixins(config.box, 'size'); + var continuousAxisScaleAndAxis = {}; + if (continuousAxisChannelDef.scale) { + continuousAxisScaleAndAxis['scale'] = continuousAxisChannelDef.scale; + } + if (continuousAxisChannelDef.axis) { + continuousAxisScaleAndAxis['axis'] = continuousAxisChannelDef.axis; + } + return __assign({}, outerSpec, { transform: transform, layer: [ + { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + encoding: __assign((_a = {}, _a[continuousAxis] = __assign({ field: 'lower_whisker_' + continuousAxisChannelDef.field, type: continuousAxisChannelDef.type }, continuousAxisScaleAndAxis), _a[continuousAxis + '2'] = { + field: 'lower_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _a), encodingWithoutSizeColorAndContinuousAxis, getMarkSpecificConfigMixins(config.boxWhisker, 'color')) + }, { + mark: { + type: 'rule', + style: 'boxWhisker' + }, + encoding: __assign((_b = {}, _b[continuousAxis] = { + field: 'upper_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _b[continuousAxis + '2'] = { + field: 'upper_whisker_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _b), encodingWithoutSizeColorAndContinuousAxis, getMarkSpecificConfigMixins(config.boxWhisker, 'color')) + }, + __assign({}, (selection ? { selection: selection } : {}), { mark: { + type: 'bar', + style: 'box' + }, encoding: __assign((_c = {}, _c[continuousAxis] = { + field: 'lower_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _c[continuousAxis + '2'] = { + field: 'upper_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _c), encodingWithoutContinuousAxis, (encodingWithoutContinuousAxis.color ? {} : getMarkSpecificConfigMixins(config.box, 'color')), sizeMixins) }), + { + mark: { + type: 'tick', + style: 'boxMid' + }, + encoding: __assign((_d = {}, _d[continuousAxis] = { + field: 'mid_box_' + continuousAxisChannelDef.field, + type: continuousAxisChannelDef.type + }, _d), encodingWithoutSizeColorAndContinuousAxis, getMarkSpecificConfigMixins(config.boxMid, 'color'), sizeMixins) + } + ] }); + } + function boxOrient(spec) { + var mark = spec.mark, encoding = spec.encoding, _p = spec.projection, _outerSpec = __rest(spec, ["mark", "encoding", "projection"]); + if (isFieldDef(encoding.x) && isContinuous(encoding.x)) { + // x is continuous + if (isFieldDef(encoding.y) && isContinuous(encoding.y)) { + // both x and y are continuous + if (encoding.x.aggregate === undefined && encoding.y.aggregate === BOXPLOT) { + return 'vertical'; + } + else if (encoding.y.aggregate === undefined && encoding.x.aggregate === BOXPLOT) { + return 'horizontal'; + } + else if (encoding.x.aggregate === BOXPLOT && encoding.y.aggregate === BOXPLOT) { + throw new Error('Both x and y cannot have aggregate'); + } + else { + if (isBoxPlotDef(mark) && mark.orient) { + return mark.orient; + } + // default orientation = vertical + return 'vertical'; + } + } + // x is continuous but y is not + return 'horizontal'; + } + else if (isFieldDef(encoding.y) && isContinuous(encoding.y)) { + // y is continuous but x is not + return 'vertical'; + } + else { + // Neither x nor y is continuous. + throw new Error('Need a valid continuous axis for boxplots'); + } + } + function boxContinousAxis(spec, orient) { + var mark = spec.mark, encoding = spec.encoding, _p = spec.projection, _outerSpec = __rest(spec, ["mark", "encoding", "projection"]); + var continuousAxisChannelDef; + var continuousAxis; + if (orient === 'vertical') { + continuousAxis = 'y'; + continuousAxisChannelDef = encoding.y; // Safe to cast because if y is not continuous fielddef, the orient would not be vertical. + } + else { + continuousAxis = 'x'; + continuousAxisChannelDef = encoding.x; // Safe to cast because if x is not continuous fielddef, the orient would not be horizontal. + } + if (continuousAxisChannelDef && continuousAxisChannelDef.aggregate) { + var aggregate = continuousAxisChannelDef.aggregate, continuousAxisWithoutAggregate = __rest(continuousAxisChannelDef, ["aggregate"]); + if (aggregate !== BOXPLOT) { + warn("Continuous axis should not have customized aggregation function " + aggregate); + } + continuousAxisChannelDef = continuousAxisWithoutAggregate; + } + return { + continuousAxisChannelDef: continuousAxisChannelDef, + continuousAxis: continuousAxis + }; + } + function boxParams(spec, orient, kIQRScalar) { + var _a = boxContinousAxis(spec, orient), continuousAxisChannelDef = _a.continuousAxisChannelDef, continuousAxis = _a.continuousAxis; + var encoding = spec.encoding; + var isMinMax = kIQRScalar === undefined; + var aggregate = [ + { + op: 'q1', + field: continuousAxisChannelDef.field, + as: 'lower_box_' + continuousAxisChannelDef.field + }, + { + op: 'q3', + field: continuousAxisChannelDef.field, + as: 'upper_box_' + continuousAxisChannelDef.field + }, + { + op: 'median', + field: continuousAxisChannelDef.field, + as: 'mid_box_' + continuousAxisChannelDef.field + } + ]; + var postAggregateCalculates = []; + aggregate.push({ + op: 'min', + field: continuousAxisChannelDef.field, + as: (isMinMax ? 'lower_whisker_' : 'min_') + continuousAxisChannelDef.field + }); + aggregate.push({ + op: 'max', + field: continuousAxisChannelDef.field, + as: (isMinMax ? 'upper_whisker_' : 'max_') + continuousAxisChannelDef.field + }); + if (!isMinMax) { + postAggregateCalculates = [ + { + calculate: "datum.upper_box_" + continuousAxisChannelDef.field + " - datum.lower_box_" + continuousAxisChannelDef.field, + as: 'iqr_' + continuousAxisChannelDef.field + }, + { + calculate: "min(datum.upper_box_" + continuousAxisChannelDef.field + " + datum.iqr_" + continuousAxisChannelDef.field + " * " + kIQRScalar + ", datum.max_" + continuousAxisChannelDef.field + ")", + as: 'upper_whisker_' + continuousAxisChannelDef.field + }, + { + calculate: "max(datum.lower_box_" + continuousAxisChannelDef.field + " - datum.iqr_" + continuousAxisChannelDef.field + " * " + kIQRScalar + ", datum.min_" + continuousAxisChannelDef.field + ")", + as: 'lower_whisker_' + continuousAxisChannelDef.field + } + ]; + } + var groupby = []; + var bins = []; + var timeUnits = []; + var encodingWithoutContinuousAxis = {}; + forEach(encoding, function (channelDef, channel) { + if (channel === continuousAxis) { + // Skip continuous axis as we already handle it separately + return; + } + if (isFieldDef(channelDef)) { + if (channelDef.aggregate && channelDef.aggregate !== BOXPLOT) { + aggregate.push({ + op: channelDef.aggregate, + field: channelDef.field, + as: vgField(channelDef) + }); + } + else if (channelDef.aggregate === undefined) { + var transformedField = vgField(channelDef); + // Add bin or timeUnit transform if applicable + var bin = channelDef.bin; + if (bin) { + var field$$1 = channelDef.field; + bins.push({ bin: bin, field: field$$1, as: transformedField }); + } + else if (channelDef.timeUnit) { + var timeUnit = channelDef.timeUnit, field$$1 = channelDef.field; + timeUnits.push({ timeUnit: timeUnit, field: field$$1, as: transformedField }); + } + groupby.push(transformedField); + } + // now the field should refer to post-transformed field instead + encodingWithoutContinuousAxis[channel] = { + field: vgField(channelDef), + type: channelDef.type + }; + } + else { + // For value def, just copy + encodingWithoutContinuousAxis[channel] = encoding[channel]; + } + }); + return { + transform: [].concat(bins, timeUnits, [{ aggregate: aggregate, groupby: groupby }], postAggregateCalculates), + continuousAxisChannelDef: continuousAxisChannelDef, + continuousAxis: continuousAxis, + encodingWithoutContinuousAxis: encodingWithoutContinuousAxis + }; + } + + var ERRORBAR = 'error-bar'; + function normalizeErrorBar(spec) { + // TODO: use selection + var _m = spec.mark, _sel = spec.selection, _p = spec.projection, encoding = spec.encoding, outerSpec = __rest(spec, ["mark", "selection", "projection", "encoding"]); + var _s = encoding.size, encodingWithoutSize = __rest(encoding, ["size"]); + var _x2 = encoding.x2, _y2 = encoding.y2, encodingWithoutX2Y2 = __rest(encoding, ["x2", "y2"]); + var encodingWithoutX_X2_Y_Y2 = __rest(encodingWithoutX2Y2, ["x", "y"]); + if (!encoding.x2 && !encoding.y2) { + throw new Error('Neither x2 or y2 provided'); + } + return __assign({}, outerSpec, { layer: [ + { + mark: 'rule', + encoding: encodingWithoutSize + }, { + mark: 'tick', + encoding: encodingWithoutX2Y2 + }, { + mark: 'tick', + encoding: encoding.x2 ? __assign({ x: encoding.x2, y: encoding.y }, encodingWithoutX_X2_Y_Y2) : __assign({ x: encoding.x, y: encoding.y2 }, encodingWithoutX_X2_Y_Y2) + } + ] }); + } + + /** + * Registry index for all composite mark's normalizer + */ + var normalizerRegistry = {}; + function add(mark, normalizer) { + normalizerRegistry[mark] = normalizer; + } + function remove(mark) { + delete normalizerRegistry[mark]; + } + var COMPOSITE_MARK_STYLES = BOXPLOT_STYLES; + var VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = __assign({}, VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX); + add(BOXPLOT, normalizeBoxPlot); + add(ERRORBAR, normalizeErrorBar); + /** + * Transform a unit spec with composite mark into a normal layer spec. + */ + function normalize$1( + // This GenericUnitSpec has any as Encoding because unit specs with composite mark can have additional encoding channels. + spec, config) { + var mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var normalizer = normalizerRegistry[mark]; + if (normalizer) { + return normalizer(spec, config); + } + throw new Error("Invalid mark type \"" + mark + "\""); + } + + var index = /*#__PURE__*/Object.freeze({ + add: add, + remove: remove, + COMPOSITE_MARK_STYLES: COMPOSITE_MARK_STYLES, + VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX: VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX, + normalize: normalize$1 + }); + + var VL_ONLY_GUIDE_CONFIG = ['shortTimeLabels']; + + var defaultLegendConfig = {}; + var COMMON_LEGEND_PROPERTY_INDEX = { + entryPadding: 1, + format: 1, + offset: 1, + orient: 1, + padding: 1, + tickCount: 1, + title: 1, + type: 1, + values: 1, + zindex: 1 + }; + var VG_LEGEND_PROPERTY_INDEX = __assign({}, COMMON_LEGEND_PROPERTY_INDEX, { + // channel scales + opacity: 1, shape: 1, stroke: 1, fill: 1, size: 1, + // encode + encode: 1 }); + var LEGEND_PROPERTIES = flagKeys(COMMON_LEGEND_PROPERTY_INDEX); + var VG_LEGEND_PROPERTIES = flagKeys(VG_LEGEND_PROPERTY_INDEX); + + var legend = /*#__PURE__*/Object.freeze({ + defaultLegendConfig: defaultLegendConfig, + LEGEND_PROPERTIES: LEGEND_PROPERTIES, + VG_LEGEND_PROPERTIES: VG_LEGEND_PROPERTIES + }); + + var ScaleType; + (function (ScaleType) { + // Continuous - Quantitative + ScaleType.LINEAR = 'linear'; + ScaleType.BIN_LINEAR = 'bin-linear'; + ScaleType.LOG = 'log'; + ScaleType.POW = 'pow'; + ScaleType.SQRT = 'sqrt'; + // Continuous - Time + ScaleType.TIME = 'time'; + ScaleType.UTC = 'utc'; + // sequential + ScaleType.SEQUENTIAL = 'sequential'; + // Quantile, Quantize, threshold + ScaleType.QUANTILE = 'quantile'; + ScaleType.QUANTIZE = 'quantize'; + ScaleType.THRESHOLD = 'threshold'; + ScaleType.ORDINAL = 'ordinal'; + ScaleType.BIN_ORDINAL = 'bin-ordinal'; + ScaleType.POINT = 'point'; + ScaleType.BAND = 'band'; + })(ScaleType || (ScaleType = {})); + /** + * Index for scale categories -- only scale of the same categories can be merged together. + * Current implementation is trying to be conservative and avoid merging scale type that might not work together + */ + var SCALE_CATEGORY_INDEX = { + linear: 'numeric', + log: 'numeric', + pow: 'numeric', + sqrt: 'numeric', + 'bin-linear': 'bin-linear', + time: 'time', + utc: 'time', + sequential: 'sequential', + ordinal: 'ordinal', + 'bin-ordinal': 'bin-ordinal', + point: 'ordinal-position', + band: 'ordinal-position' + }; + var SCALE_TYPES = keys(SCALE_CATEGORY_INDEX); + /** + * Whether the two given scale types can be merged together. + */ + function scaleCompatible(scaleType1, scaleType2) { + var scaleCategory1 = SCALE_CATEGORY_INDEX[scaleType1]; + var scaleCategory2 = SCALE_CATEGORY_INDEX[scaleType2]; + return scaleCategory1 === scaleCategory2 || + (scaleCategory1 === 'ordinal-position' && scaleCategory2 === 'time') || + (scaleCategory2 === 'ordinal-position' && scaleCategory1 === 'time'); + } + /** + * Index for scale precedence -- high score = higher priority for merging. + */ + var SCALE_PRECEDENCE_INDEX = { + // numeric + linear: 0, + log: 1, + pow: 1, + sqrt: 1, + // time + time: 0, + utc: 0, + // ordinal-position -- these have higher precedence than continuous scales as they support more types of data + point: 10, + band: 11, + // non grouped types + 'bin-linear': 0, + sequential: 0, + ordinal: 0, + 'bin-ordinal': 0, + }; + /** + * Return scale categories -- only scale of the same categories can be merged together. + */ + function scaleTypePrecedence(scaleType) { + return SCALE_PRECEDENCE_INDEX[scaleType]; + } + var CONTINUOUS_TO_CONTINUOUS_SCALES = ['linear', 'bin-linear', 'log', 'pow', 'sqrt', 'time', 'utc']; + var CONTINUOUS_TO_CONTINUOUS_INDEX = toSet(CONTINUOUS_TO_CONTINUOUS_SCALES); + var CONTINUOUS_DOMAIN_SCALES = CONTINUOUS_TO_CONTINUOUS_SCALES.concat(['sequential' /* TODO add 'quantile', 'quantize', 'threshold'*/]); + var CONTINUOUS_DOMAIN_INDEX = toSet(CONTINUOUS_DOMAIN_SCALES); + var DISCRETE_DOMAIN_SCALES = ['ordinal', 'bin-ordinal', 'point', 'band']; + var DISCRETE_DOMAIN_INDEX = toSet(DISCRETE_DOMAIN_SCALES); + var BIN_SCALES_INDEX = toSet(['bin-linear', 'bin-ordinal']); + var TIME_SCALE_TYPES = ['time', 'utc']; + function hasDiscreteDomain(type) { + return type in DISCRETE_DOMAIN_INDEX; + } + function isBinScale(type) { + return type in BIN_SCALES_INDEX; + } + function hasContinuousDomain(type) { + return type in CONTINUOUS_DOMAIN_INDEX; + } + function isContinuousToContinuous(type) { + return type in CONTINUOUS_TO_CONTINUOUS_INDEX; + } + var defaultScaleConfig = { + textXRangeStep: 90, + rangeStep: 21, + pointPadding: 0.5, + bandPaddingInner: 0.1, + facetSpacing: 16, + minBandSize: 2, + minFontSize: 8, + maxFontSize: 40, + minOpacity: 0.3, + maxOpacity: 0.8, + // FIXME: revise if these *can* become ratios of rangeStep + minSize: 9, + minStrokeWidth: 1, + maxStrokeWidth: 4 + }; + function isExtendedScheme(scheme) { + return scheme && !!scheme['name']; + } + function isSelectionDomain(domain) { + return domain && domain['selection']; + } + var SCALE_PROPERTY_INDEX = { + type: 1, + domain: 1, + range: 1, + rangeStep: 1, + scheme: 1, + // Other properties + reverse: 1, + round: 1, + // quantitative / time + clamp: 1, + nice: 1, + // quantitative + base: 1, + exponent: 1, + interpolate: 1, + zero: 1, + // band/point + padding: 1, + paddingInner: 1, + paddingOuter: 1 + }; + var SCALE_PROPERTIES = flagKeys(SCALE_PROPERTY_INDEX); + var NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX = __rest(SCALE_PROPERTY_INDEX, ["type", "domain", "range", "rangeStep", "scheme"]); + var NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES = flagKeys(NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX); + var SCALE_TYPE_INDEX = generateScaleTypeIndex(); + function scaleTypeSupportProperty(scaleType, propName) { + switch (propName) { + case 'type': + case 'domain': + case 'reverse': + case 'range': + return true; + case 'scheme': + return contains(['sequential', 'ordinal', 'bin-ordinal', 'quantile', 'quantize'], scaleType); + case 'interpolate': + // FIXME(https://github.com/vega/vega-lite/issues/2902) how about ordinal? + return contains(['linear', 'bin-linear', 'pow', 'log', 'sqrt', 'utc', 'time'], scaleType); + case 'round': + return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point'; + case 'padding': + return isContinuousToContinuous(scaleType) || contains(['point', 'band'], scaleType); + case 'paddingOuter': + case 'rangeStep': + return contains(['point', 'band'], scaleType); + case 'paddingInner': + return scaleType === 'band'; + case 'clamp': + return isContinuousToContinuous(scaleType) || scaleType === 'sequential'; + case 'nice': + return isContinuousToContinuous(scaleType) || scaleType === 'sequential' || scaleType === 'quantize'; + case 'exponent': + return scaleType === 'pow'; + case 'base': + return scaleType === 'log'; + case 'zero': + return hasContinuousDomain(scaleType) && !contains([ + 'log', + 'time', 'utc', + 'bin-linear', + 'threshold', + 'quantile' // quantile depends on distribution so zero does not matter + ], scaleType); + } + /* istanbul ignore next: should never reach here*/ + throw new Error("Invalid scale property " + propName + "."); + } + /** + * Returns undefined if the input channel supports the input scale property name + */ + function channelScalePropertyIncompatability(channel, propName) { + switch (propName) { + case 'interpolate': + case 'scheme': + if (!isColorChannel(channel)) { + return message.cannotUseScalePropertyWithNonColor(channel); + } + return undefined; + case 'type': + case 'domain': + case 'range': + case 'base': + case 'exponent': + case 'nice': + case 'padding': + case 'paddingInner': + case 'paddingOuter': + case 'rangeStep': + case 'reverse': + case 'round': + case 'clamp': + case 'zero': + return undefined; // GOOD! + } + /* istanbul ignore next: it should never reach here */ + throw new Error("Invalid scale property \"" + propName + "\"."); + } + function scaleTypeSupportDataType(specifiedType, fieldDefType, bin) { + if (contains([Type.ORDINAL, Type.NOMINAL], fieldDefType)) { + return specifiedType === undefined || hasDiscreteDomain(specifiedType); + } + else if (fieldDefType === Type.TEMPORAL) { + return contains([ScaleType.TIME, ScaleType.UTC, ScaleType.SEQUENTIAL, undefined], specifiedType); + } + else if (fieldDefType === Type.QUANTITATIVE) { + if (bin) { + return contains([ScaleType.BIN_LINEAR, ScaleType.BIN_ORDINAL, ScaleType.LINEAR], specifiedType); + } + return contains([ScaleType.LOG, ScaleType.POW, ScaleType.SQRT, ScaleType.QUANTILE, ScaleType.QUANTIZE, ScaleType.LINEAR, ScaleType.SEQUENTIAL, undefined], specifiedType); + } + return true; + } + function channelSupportScaleType(channel, scaleType) { + switch (channel) { + case Channel.X: + case Channel.Y: + case Channel.SIZE: // TODO: size and opacity can support ordinal with more modification + case Channel.OPACITY: + // Although it generally doesn't make sense to use band with size and opacity, + // it can also work since we use band: 0.5 to get midpoint. + return isContinuousToContinuous(scaleType) || contains(['band', 'point'], scaleType); + case Channel.COLOR: + case Channel.FILL: + case Channel.STROKE: + return scaleType !== 'band'; // band does not make sense with color + case Channel.SHAPE: + return scaleType === 'ordinal'; // shape = lookup only + } + /* istanbul ignore next: it should never reach here */ + return false; + } + function getSupportedScaleType(channel, fieldDefType, bin) { + return SCALE_TYPE_INDEX[generateScaleTypeIndexKey(channel, fieldDefType, bin)]; + } + // generates ScaleTypeIndex where keys are encoding channels and values are list of valid ScaleTypes + function generateScaleTypeIndex() { + var index = {}; + for (var _i = 0, CHANNELS_1 = CHANNELS; _i < CHANNELS_1.length; _i++) { + var channel = CHANNELS_1[_i]; + for (var _a = 0, _b = keys(TYPE_INDEX); _a < _b.length; _a++) { + var fieldDefType = _b[_a]; + for (var _c = 0, SCALE_TYPES_1 = SCALE_TYPES; _c < SCALE_TYPES_1.length; _c++) { + var scaleType = SCALE_TYPES_1[_c]; + for (var _d = 0, _e = [false, true]; _d < _e.length; _d++) { + var bin = _e[_d]; + var key$$1 = generateScaleTypeIndexKey(channel, fieldDefType, bin); + if (channelSupportScaleType(channel, scaleType) && scaleTypeSupportDataType(scaleType, fieldDefType, bin)) { + index[key$$1] = index[key$$1] || []; + index[key$$1].push(scaleType); + } + } + } + } + } + return index; + } + function generateScaleTypeIndexKey(channel, fieldDefType, bin) { + var key$$1 = channel + '_' + fieldDefType; + return bin ? key$$1 + '_bin' : key$$1; + } + + var scale = /*#__PURE__*/Object.freeze({ + get ScaleType () { return ScaleType; }, + SCALE_TYPES: SCALE_TYPES, + scaleCompatible: scaleCompatible, + scaleTypePrecedence: scaleTypePrecedence, + CONTINUOUS_TO_CONTINUOUS_SCALES: CONTINUOUS_TO_CONTINUOUS_SCALES, + CONTINUOUS_DOMAIN_SCALES: CONTINUOUS_DOMAIN_SCALES, + DISCRETE_DOMAIN_SCALES: DISCRETE_DOMAIN_SCALES, + TIME_SCALE_TYPES: TIME_SCALE_TYPES, + hasDiscreteDomain: hasDiscreteDomain, + isBinScale: isBinScale, + hasContinuousDomain: hasContinuousDomain, + isContinuousToContinuous: isContinuousToContinuous, + defaultScaleConfig: defaultScaleConfig, + isExtendedScheme: isExtendedScheme, + isSelectionDomain: isSelectionDomain, + SCALE_PROPERTIES: SCALE_PROPERTIES, + NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES: NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES, + SCALE_TYPE_INDEX: SCALE_TYPE_INDEX, + scaleTypeSupportProperty: scaleTypeSupportProperty, + channelScalePropertyIncompatability: channelScalePropertyIncompatability, + scaleTypeSupportDataType: scaleTypeSupportDataType, + channelSupportScaleType: channelSupportScaleType, + getSupportedScaleType: getSupportedScaleType + }); + + var SELECTION_ID = '_vgsid_'; + var defaultConfig = { + single: { + on: 'click', + fields: [SELECTION_ID], + resolve: 'global', + empty: 'all' + }, + multi: { + on: 'click', + fields: [SELECTION_ID], + toggle: 'event.shiftKey', + resolve: 'global', + empty: 'all' + }, + interval: { + on: '[mousedown, window:mouseup] > window:mousemove!', + encodings: ['x', 'y'], + translate: '[mousedown, window:mouseup] > window:mousemove!', + zoom: 'wheel!', + mark: { fill: '#333', fillOpacity: 0.125, stroke: 'white' }, + resolve: 'global' + } + }; + + function extractTitleConfig(titleConfig) { + var + // These are non-mark title config that need to be hardcoded + anchor = titleConfig.anchor, offset = titleConfig.offset, orient = titleConfig.orient, + // color needs to be redirect to fill + color = titleConfig.color, + // The rest are mark config. + titleMarkConfig = __rest(titleConfig, ["anchor", "offset", "orient", "color"]); + var mark = __assign({}, titleMarkConfig, color ? { fill: color } : {}); + var nonMark = __assign({}, anchor ? { anchor: anchor } : {}, offset ? { offset: offset } : {}, orient ? { orient: orient } : {}); + return { mark: mark, nonMark: nonMark }; + } + + var defaultViewConfig = { + width: 200, + height: 200 + }; + var defaultConfig$1 = { + padding: 5, + timeFormat: '', + countTitle: 'Number of Records', + invalidValues: 'filter', + view: defaultViewConfig, + mark: defaultMarkConfig, + area: {}, + bar: defaultBarConfig, + circle: {}, + geoshape: {}, + line: {}, + point: {}, + rect: {}, + rule: { color: 'black' }, + square: {}, + text: { color: 'black' }, + tick: defaultTickConfig, + trail: {}, + box: { size: 14, extent: 1.5 }, + boxWhisker: {}, + boxMid: { color: 'white' }, + scale: defaultScaleConfig, + projection: {}, + axis: {}, + axisX: {}, + axisY: { minExtent: 30 }, + axisLeft: {}, + axisRight: {}, + axisTop: {}, + axisBottom: {}, + axisBand: {}, + legend: defaultLegendConfig, + selection: defaultConfig, + style: {}, + title: {}, + }; + function initConfig(config) { + return mergeDeep(duplicate(defaultConfig$1), config); + } + var MARK_STYLES = ['view'].concat(PRIMITIVE_MARKS, COMPOSITE_MARK_STYLES); + var VL_ONLY_CONFIG_PROPERTIES = [ + 'padding', 'numberFormat', 'timeFormat', 'countTitle', + 'stack', 'scale', 'selection', 'invalidValues', + 'overlay' // FIXME: Redesign and unhide this + ]; + var VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = __assign({ view: ['width', 'height'] }, VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX, VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX); + function stripAndRedirectConfig(config) { + config = duplicate(config); + for (var _i = 0, VL_ONLY_CONFIG_PROPERTIES_1 = VL_ONLY_CONFIG_PROPERTIES; _i < VL_ONLY_CONFIG_PROPERTIES_1.length; _i++) { + var prop = VL_ONLY_CONFIG_PROPERTIES_1[_i]; + delete config[prop]; + } + // Remove Vega-Lite only axis/legend config + if (config.axis) { + for (var _a = 0, VL_ONLY_GUIDE_CONFIG_1 = VL_ONLY_GUIDE_CONFIG; _a < VL_ONLY_GUIDE_CONFIG_1.length; _a++) { + var prop = VL_ONLY_GUIDE_CONFIG_1[_a]; + delete config.axis[prop]; + } + } + if (config.legend) { + for (var _b = 0, VL_ONLY_GUIDE_CONFIG_2 = VL_ONLY_GUIDE_CONFIG; _b < VL_ONLY_GUIDE_CONFIG_2.length; _b++) { + var prop = VL_ONLY_GUIDE_CONFIG_2[_b]; + delete config.legend[prop]; + } + } + // Remove Vega-Lite only generic mark config + if (config.mark) { + for (var _c = 0, VL_ONLY_MARK_CONFIG_PROPERTIES_1 = VL_ONLY_MARK_CONFIG_PROPERTIES; _c < VL_ONLY_MARK_CONFIG_PROPERTIES_1.length; _c++) { + var prop = VL_ONLY_MARK_CONFIG_PROPERTIES_1[_c]; + delete config.mark[prop]; + } + } + for (var _d = 0, MARK_STYLES_1 = MARK_STYLES; _d < MARK_STYLES_1.length; _d++) { + var markType = MARK_STYLES_1[_d]; + // Remove Vega-Lite-only mark config + for (var _e = 0, VL_ONLY_MARK_CONFIG_PROPERTIES_2 = VL_ONLY_MARK_CONFIG_PROPERTIES; _e < VL_ONLY_MARK_CONFIG_PROPERTIES_2.length; _e++) { + var prop = VL_ONLY_MARK_CONFIG_PROPERTIES_2[_e]; + delete config[markType][prop]; + } + // Remove Vega-Lite only mark-specific config + var vlOnlyMarkSpecificConfigs = VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX[markType]; + if (vlOnlyMarkSpecificConfigs) { + for (var _f = 0, vlOnlyMarkSpecificConfigs_1 = vlOnlyMarkSpecificConfigs; _f < vlOnlyMarkSpecificConfigs_1.length; _f++) { + var prop = vlOnlyMarkSpecificConfigs_1[_f]; + delete config[markType][prop]; + } + } + // Redirect mark config to config.style so that mark config only affect its own mark type + // without affecting other marks that share the same underlying Vega marks. + // For example, config.rect should not affect bar marks. + redirectConfig(config, markType); + } + // Redirect config.title -- so that title config do not + // affect header labels, which also uses `title` directive to implement. + redirectConfig(config, 'title', 'group-title'); + // Remove empty config objects + for (var prop in config) { + if (isObject(config[prop]) && keys(config[prop]).length === 0) { + delete config[prop]; + } + } + return keys(config).length > 0 ? config : undefined; + } + function redirectConfig(config, prop, toProp) { + var propConfig = prop === 'title' ? extractTitleConfig(config.title).mark : config[prop]; + if (prop === 'view') { + toProp = 'cell'; // View's default style is "cell" + } + var style = __assign({}, propConfig, config.style[prop]); + // set config.style if it is not an empty object + if (keys(style).length > 0) { + config.style[toProp || prop] = style; + } + delete config[prop]; + } + + var config = /*#__PURE__*/Object.freeze({ + defaultViewConfig: defaultViewConfig, + defaultConfig: defaultConfig$1, + initConfig: initConfig, + stripAndRedirectConfig: stripAndRedirectConfig + }); + + var STACK_OFFSET_INDEX = { + zero: 1, + center: 1, + normalize: 1 + }; + function isStackOffset(s) { + return !!STACK_OFFSET_INDEX[s]; + } + var STACKABLE_MARKS = [BAR, AREA, RULE, POINT, CIRCLE, SQUARE, LINE, TEXT$1, TICK]; + var STACK_BY_DEFAULT_MARKS = [BAR, AREA]; + function potentialStackedChannel(encoding) { + var xDef = encoding.x; + var yDef = encoding.y; + if (isFieldDef(xDef) && isFieldDef(yDef)) { + if (xDef.type === 'quantitative' && yDef.type === 'quantitative') { + if (xDef.stack) { + return 'x'; + } + else if (yDef.stack) { + return 'y'; + } + // if there is no explicit stacking, only apply stack if there is only one aggregate for x or y + if ((!!xDef.aggregate) !== (!!yDef.aggregate)) { + return xDef.aggregate ? 'x' : 'y'; + } + } + else if (xDef.type === 'quantitative') { + return 'x'; + } + else if (yDef.type === 'quantitative') { + return 'y'; + } + } + else if (isFieldDef(xDef) && xDef.type === 'quantitative') { + return 'x'; + } + else if (isFieldDef(yDef) && yDef.type === 'quantitative') { + return 'y'; + } + return undefined; + } + // Note: CompassQL uses this method and only pass in required properties of each argument object. + // If required properties change, make sure to update CompassQL. + function stack(m, encoding, stackConfig) { + var mark = isMarkDef(m) ? m.type : m; + // Should have stackable mark + if (!contains(STACKABLE_MARKS, mark)) { + return null; + } + var fieldChannel = potentialStackedChannel(encoding); + if (!fieldChannel) { + return null; + } + var stackedFieldDef = encoding[fieldChannel]; + var stackedField = isStringFieldDef(stackedFieldDef) ? vgField(stackedFieldDef, {}) : undefined; + var dimensionChannel = fieldChannel === 'x' ? 'y' : 'x'; + var dimensionDef = encoding[dimensionChannel]; + var dimensionField = isStringFieldDef(dimensionDef) ? vgField(dimensionDef, {}) : undefined; + // Should have grouping level of detail that is different from the dimension field + var stackBy = NONPOSITION_CHANNELS.reduce(function (sc, channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (isArray(channelDef) ? channelDef : [channelDef]).forEach(function (cDef) { + var fieldDef = getFieldDef(cDef); + if (fieldDef.aggregate) { + return; + } + // Check whether the channel's field is identical to x/y's field or if the channel is a repeat + var f = isStringFieldDef(fieldDef) ? vgField(fieldDef, {}) : undefined; + if ( + // if fielddef is a repeat, just include it in the stack by + !f || + // otherwise, the field must be different from x and y fields. + (f !== dimensionField && f !== stackedField)) { + sc.push({ channel: channel, fieldDef: fieldDef }); + } + }); + } + return sc; + }, []); + if (stackBy.length === 0) { + return null; + } + // Automatically determine offset + var offset = undefined; + if (stackedFieldDef.stack !== undefined) { + offset = stackedFieldDef.stack; + } + else if (contains(STACK_BY_DEFAULT_MARKS, mark)) { + // Bar and Area with sum ops are automatically stacked by default + offset = stackConfig === undefined ? 'zero' : stackConfig; + } + else { + offset = stackConfig; + } + if (!offset || !isStackOffset(offset)) { + return null; + } + // warn when stacking non-linear + if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== ScaleType.LINEAR) { + warn(message.cannotStackNonLinearScale(stackedFieldDef.scale.type)); + } + // Check if it is a ranged mark + if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) { + if (stackedFieldDef.stack !== undefined) { + warn(message.cannotStackRangedMark(fieldChannel)); + } + return null; + } + // Warn if stacking summative aggregate + if (stackedFieldDef.aggregate && !contains(SUM_OPS, stackedFieldDef.aggregate)) { + warn(message.stackNonSummativeAggregate(stackedFieldDef.aggregate)); + } + return { + groupbyChannel: dimensionDef ? dimensionChannel : undefined, + fieldChannel: fieldChannel, + impute: isPathMark(mark), + stackBy: stackBy, + offset: offset + }; + } + + var stack$1 = /*#__PURE__*/Object.freeze({ + isStackOffset: isStackOffset, + STACKABLE_MARKS: STACKABLE_MARKS, + STACK_BY_DEFAULT_MARKS: STACK_BY_DEFAULT_MARKS, + stack: stack + }); + + /* Custom type guards */ + function isFacetSpec(spec) { + return spec['facet'] !== undefined; + } + function isUnitSpec(spec) { + return !!spec['mark']; + } + function isLayerSpec(spec) { + return spec['layer'] !== undefined; + } + function isRepeatSpec(spec) { + return spec['repeat'] !== undefined; + } + function isConcatSpec(spec) { + return isVConcatSpec(spec) || isHConcatSpec(spec); + } + function isVConcatSpec(spec) { + return spec['vconcat'] !== undefined; + } + function isHConcatSpec(spec) { + return spec['hconcat'] !== undefined; + } + /** + * Decompose extended unit specs into composition of pure unit specs. + */ + // TODO: consider moving this to another file. Maybe vl.spec.normalize or vl.normalize + function normalize$2(spec, config) { + if (isFacetSpec(spec)) { + return normalizeFacet(spec, config); + } + if (isLayerSpec(spec)) { + return normalizeLayer(spec, config); + } + if (isRepeatSpec(spec)) { + return normalizeRepeat(spec, config); + } + if (isVConcatSpec(spec)) { + return normalizeVConcat(spec, config); + } + if (isHConcatSpec(spec)) { + return normalizeHConcat(spec, config); + } + if (isUnitSpec(spec)) { + var hasRow = channelHasField(spec.encoding, ROW); + var hasColumn = channelHasField(spec.encoding, COLUMN); + if (hasRow || hasColumn) { + return normalizeFacetedUnit(spec, config); + } + return normalizeNonFacetUnit(spec, config); + } + throw new Error(message.INVALID_SPEC); + } + function normalizeFacet(spec, config) { + var subspec = spec.spec, rest = __rest(spec, ["spec"]); + return __assign({}, rest, { + // TODO: remove "any" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760 + spec: normalize$2(subspec, config) }); + } + function mergeEncoding(opt) { + var parentEncoding = opt.parentEncoding, encoding = opt.encoding; + if (parentEncoding && encoding) { + var overriden = keys(parentEncoding).reduce(function (o, key$$1) { + if (encoding[key$$1]) { + o.push(key$$1); + } + return o; + }, []); + if (overriden.length > 0) { + warn(message.encodingOverridden(overriden)); + } + } + var merged = __assign({}, (parentEncoding || {}), (encoding || {})); + return keys(merged).length > 0 ? merged : undefined; + } + function mergeProjection(opt) { + var parentProjection = opt.parentProjection, projection = opt.projection; + if (parentProjection && projection) { + warn(message.projectionOverridden({ parentProjection: parentProjection, projection: projection })); + } + return projection || parentProjection; + } + function normalizeLayer(spec, config, parentEncoding, parentProjection) { + var layer = spec.layer, encoding = spec.encoding, projection = spec.projection, rest = __rest(spec, ["layer", "encoding", "projection"]); + var mergedEncoding = mergeEncoding({ parentEncoding: parentEncoding, encoding: encoding }); + var mergedProjection = mergeProjection({ parentProjection: parentProjection, projection: projection }); + return __assign({}, rest, { layer: layer.map(function (subspec) { + if (isLayerSpec(subspec)) { + return normalizeLayer(subspec, config, mergedEncoding, mergedProjection); + } + return normalizeNonFacetUnit(subspec, config, mergedEncoding, mergedProjection); + }) }); + } + function normalizeRepeat(spec, config) { + var subspec = spec.spec, rest = __rest(spec, ["spec"]); + return __assign({}, rest, { spec: normalize$2(subspec, config) }); + } + function normalizeVConcat(spec, config) { + var vconcat = spec.vconcat, rest = __rest(spec, ["vconcat"]); + return __assign({}, rest, { vconcat: vconcat.map(function (subspec) { return normalize$2(subspec, config); }) }); + } + function normalizeHConcat(spec, config) { + var hconcat = spec.hconcat, rest = __rest(spec, ["hconcat"]); + return __assign({}, rest, { hconcat: hconcat.map(function (subspec) { return normalize$2(subspec, config); }) }); + } + function normalizeFacetedUnit(spec, config) { + // New encoding in the inside spec should not contain row / column + // as row/column should be moved to facet + var _a = spec.encoding, row = _a.row, column = _a.column, encoding = __rest(_a, ["row", "column"]); + // Mark and encoding should be moved into the inner spec + var mark = spec.mark, width = spec.width, projection = spec.projection, height = spec.height, selection = spec.selection, _ = spec.encoding, outerSpec = __rest(spec, ["mark", "width", "projection", "height", "selection", "encoding"]); + return __assign({}, outerSpec, { facet: __assign({}, (row ? { row: row } : {}), (column ? { column: column } : {})), spec: normalizeNonFacetUnit(__assign({}, (projection ? { projection: projection } : {}), { mark: mark }, (width ? { width: width } : {}), (height ? { height: height } : {}), { encoding: encoding }, (selection ? { selection: selection } : {})), config) }); + } + function isNonFacetUnitSpecWithPrimitiveMark(spec) { + return isPrimitiveMark(spec.mark); + } + function getPointOverlay(markDef, markConfig, encoding) { + if (markDef.point === 'transparent') { + return { opacity: 0 }; + } + else if (markDef.point) { // truthy : true or object + return isObject(markDef.point) ? markDef.point : {}; + } + else if (markDef.point !== undefined) { // false or null + return null; + } + else { // undefined (not disabled) + if (markConfig.point || encoding.shape) { + // enable point overlay if config[mark].point is truthy or if encoding.shape is provided + return isObject(markConfig.point) ? markConfig.point : {}; + } + // markDef.point is defined as falsy + return null; + } + } + function getLineOverlay(markDef, markConfig) { + if (markDef.line) { // true or object + return markDef.line === true ? {} : markDef.line; + } + else if (markDef.line !== undefined) { // false or null + return null; + } + else { // undefined (not disabled) + if (markConfig.line) { + // enable line overlay if config[mark].line is truthy + return markConfig.line === true ? {} : markConfig.line; + } + // markDef.point is defined as falsy + return null; + } + } + function normalizeNonFacetUnit(spec, config, parentEncoding, parentProjection) { + var encoding = spec.encoding, projection = spec.projection; + var mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + // merge parent encoding / projection first + if (parentEncoding || parentProjection) { + var mergedProjection = mergeProjection({ parentProjection: parentProjection, projection: projection }); + var mergedEncoding = mergeEncoding({ parentEncoding: parentEncoding, encoding: encoding }); + return normalizeNonFacetUnit(__assign({}, spec, (mergedProjection ? { projection: mergedProjection } : {}), (mergedEncoding ? { encoding: mergedEncoding } : {})), config); + } + if (isNonFacetUnitSpecWithPrimitiveMark(spec)) { + // TODO: thoroughly test + if (isRanged(encoding)) { + return normalizeRangedUnit(spec); + } + if (mark === 'line' && (encoding.x2 || encoding.y2)) { + warn(message.lineWithRange(!!encoding.x2, !!encoding.y2)); + return normalizeNonFacetUnit(__assign({ mark: 'rule' }, spec), config, parentEncoding, parentProjection); + } + if (isPathMark(mark)) { + return normalizePathOverlay(spec, config); + } + return spec; // Nothing to normalize + } + else { + return normalize$1(spec, config); + } + } + function normalizeRangedUnit(spec) { + var hasX = channelHasField(spec.encoding, X); + var hasY = channelHasField(spec.encoding, Y); + var hasX2 = channelHasField(spec.encoding, X2); + var hasY2 = channelHasField(spec.encoding, Y2); + if ((hasX2 && !hasX) || (hasY2 && !hasY)) { + var normalizedSpec = duplicate(spec); + if (hasX2 && !hasX) { + normalizedSpec.encoding.x = normalizedSpec.encoding.x2; + delete normalizedSpec.encoding.x2; + } + if (hasY2 && !hasY) { + normalizedSpec.encoding.y = normalizedSpec.encoding.y2; + delete normalizedSpec.encoding.y2; + } + return normalizedSpec; + } + return spec; + } + function dropLineAndPoint(markDef) { + var _point = markDef.point, _line = markDef.line, mark = __rest(markDef, ["point", "line"]); + return keys(mark).length > 1 ? mark : mark.type; + } + function normalizePathOverlay(spec, config) { + if (config === void 0) { config = {}; } + var _a; + // _ is used to denote a dropped property of the unit spec + // which should not be carried over to the layer spec + var selection = spec.selection, projection = spec.projection, encoding = spec.encoding, mark = spec.mark, outerSpec = __rest(spec, ["selection", "projection", "encoding", "mark"]); + var markDef = isMarkDef(mark) ? mark : { type: mark }; + var pointOverlay = getPointOverlay(markDef, config[markDef.type], encoding); + var lineOverlay = markDef.type === 'area' && getLineOverlay(markDef, config[markDef.type]); + if (!pointOverlay && !lineOverlay) { + return __assign({}, spec, { + // Do not include point / line overlay in the normalize spec + mark: dropLineAndPoint(markDef) }); + } + var layer = [__assign({}, (selection ? { selection: selection } : {}), { + // Do not include point / line overlay in the normalize spec + mark: dropLineAndPoint(__assign({}, markDef, (markDef.type === 'area' ? { opacity: 0.7 } : {}))), + // drop shape from encoding as this might be used to trigger point overlay + encoding: omit(encoding, ['shape']) })]; + // FIXME: determine rules for applying selections. + // Need to copy stack config to overlayed layer + var stackProps = stack(markDef, encoding, config ? config.stack : undefined); + var overlayEncoding = encoding; + if (stackProps) { + var stackFieldChannel = stackProps.fieldChannel, offset = stackProps.offset; + overlayEncoding = __assign({}, encoding, (_a = {}, _a[stackFieldChannel] = __assign({}, encoding[stackFieldChannel], (offset ? { stack: offset } : {})), _a)); + } + if (lineOverlay) { + layer.push(__assign({}, (projection ? { projection: projection } : {}), { mark: __assign({ type: 'line' }, pick(markDef, ['clip', 'interpolate']), lineOverlay), encoding: overlayEncoding })); + } + if (pointOverlay) { + layer.push(__assign({}, (projection ? { projection: projection } : {}), { mark: __assign({ type: 'point', opacity: 1, filled: true }, pick(markDef, ['clip']), pointOverlay), encoding: overlayEncoding })); + } + return __assign({}, outerSpec, { layer: layer }); + } + // TODO: add vl.spec.validate & move stuff from vl.validate to here + /* Accumulate non-duplicate fieldDefs in a dictionary */ + function accumulate(dict, defs) { + defs.forEach(function (fieldDef) { + // Consider only pure fieldDef properties (ignoring scale, axis, legend) + var pureFieldDef = ['field', 'type', 'value', 'timeUnit', 'bin', 'aggregate'].reduce(function (f, key$$1) { + if (fieldDef[key$$1] !== undefined) { + f[key$$1] = fieldDef[key$$1]; + } + return f; + }, {}); + var key$$1 = hash(pureFieldDef); + dict[key$$1] = dict[key$$1] || fieldDef; + }); + return dict; + } + /* Recursively get fieldDefs from a spec, returns a dictionary of fieldDefs */ + function fieldDefIndex(spec, dict) { + if (dict === void 0) { dict = {}; } + // FIXME(https://github.com/vega/vega-lite/issues/2207): Support fieldDefIndex for repeat + if (isLayerSpec(spec)) { + spec.layer.forEach(function (layer) { + if (isUnitSpec(layer)) { + accumulate(dict, fieldDefs(layer.encoding)); + } + else { + fieldDefIndex(layer, dict); + } + }); + } + else if (isFacetSpec(spec)) { + accumulate(dict, fieldDefs(spec.facet)); + fieldDefIndex(spec.spec, dict); + } + else if (isRepeatSpec(spec)) { + fieldDefIndex(spec.spec, dict); + } + else if (isConcatSpec(spec)) { + var childSpec = isVConcatSpec(spec) ? spec.vconcat : spec.hconcat; + childSpec.forEach(function (child) { return fieldDefIndex(child, dict); }); + } + else { // Unit Spec + accumulate(dict, fieldDefs(spec.encoding)); + } + return dict; + } + /* Returns all non-duplicate fieldDefs in a spec in a flat array */ + function fieldDefs$1(spec) { + return vals(fieldDefIndex(spec)); + } + function isStacked(spec, config) { + config = config || spec.config; + if (isPrimitiveMark(spec.mark)) { + return stack(spec.mark, spec.encoding, config ? config.stack : undefined) !== null; + } + return false; + } + + var spec = /*#__PURE__*/Object.freeze({ + isFacetSpec: isFacetSpec, + isUnitSpec: isUnitSpec, + isLayerSpec: isLayerSpec, + isRepeatSpec: isRepeatSpec, + isConcatSpec: isConcatSpec, + isVConcatSpec: isVConcatSpec, + isHConcatSpec: isHConcatSpec, + normalize: normalize$2, + fieldDefs: fieldDefs$1, + isStacked: isStacked + }); + + function extractCompositionLayout(layout) { + var _a = layout || {}, _b = _a.align, align = _b === void 0 ? undefined : _b, _c = _a.center, center = _c === void 0 ? undefined : _c, _d = _a.bounds, bounds = _d === void 0 ? undefined : _d, _e = _a.spacing, spacing = _e === void 0 ? undefined : _e; + return { align: align, bounds: bounds, center: center, spacing: spacing }; + } + function _normalizeAutoSize(autosize) { + return isString(autosize) ? { type: autosize } : autosize || {}; + } + function normalizeAutoSize(topLevelAutosize, configAutosize, isUnitOrLayer) { + if (isUnitOrLayer === void 0) { isUnitOrLayer = true; } + var autosize = __assign({ type: 'pad' }, _normalizeAutoSize(configAutosize), _normalizeAutoSize(topLevelAutosize)); + if (autosize.type === 'fit') { + if (!isUnitOrLayer) { + warn(message.FIT_NON_SINGLE); + autosize.type = 'pad'; + } + } + return autosize; + } + var TOP_LEVEL_PROPERTIES = [ + 'background', 'padding', 'datasets' + // We do not include "autosize" here as it is supported by only unit and layer specs and thus need to be normalized + ]; + function extractTopLevelProperties(t) { + return TOP_LEVEL_PROPERTIES.reduce(function (o, p) { + if (t && t[p] !== undefined) { + o[p] = t[p]; + } + return o; + }, {}); + } + + function isUrlData(data) { + return !!data['url']; + } + function isInlineData(data) { + return !!data['values']; + } + function isNamedData(data) { + return !!data['name'] && !isUrlData(data) && !isInlineData(data); + } + var MAIN = 'main'; + var RAW = 'raw'; + + var data = /*#__PURE__*/Object.freeze({ + isUrlData: isUrlData, + isInlineData: isInlineData, + isNamedData: isNamedData, + MAIN: MAIN, + RAW: RAW + }); + + /** + * Parse an event selector string. + * Returns an array of event stream definitions. + */ + function parseSelector(selector, source, marks) { + DEFAULT_SOURCE = source || VIEW; + MARKS = marks || DEFAULT_MARKS; + return parseMerge(selector.trim()).map(parseSelector$1); + } + + var VIEW = 'view', + LBRACK = '[', + RBRACK = ']', + LBRACE = '{', + RBRACE = '}', + COLON = ':', + COMMA = ',', + NAME = '@', + GT = '>', + ILLEGAL = /[[\]{}]/, + DEFAULT_SOURCE, + MARKS, + DEFAULT_MARKS = { + '*': 1, + arc: 1, + area: 1, + group: 1, + image: 1, + line: 1, + path: 1, + rect: 1, + rule: 1, + shape: 1, + symbol: 1, + text: 1, + trail: 1 + }; + + function isMarkType(type) { + return MARKS.hasOwnProperty(type); + } + + function find(s, i, endChar, pushChar, popChar) { + var count = 0, + n = s.length, + c; + for (; i= 0) --count; + else if (pushChar && pushChar.indexOf(c) >= 0) ++count; + } + return i; + } + + function parseMerge(s) { + var output = [], + start = 0, + n = s.length, + i = 0; + + while (i < n) { + i = find(s, i, COMMA, LBRACK + LBRACE, RBRACK + RBRACE); + output.push(s.substring(start, i).trim()); + start = ++i; + } + + if (output.length === 0) { + throw 'Empty event selector: ' + s; + } + return output; + } + + function parseSelector$1(s) { + return s[0] === '[' + ? parseBetween(s) + : parseStream(s); + } + + function parseBetween(s) { + var n = s.length, + i = 1, + b, stream; + + i = find(s, i, RBRACK, LBRACK, RBRACK); + if (i === n) { + throw 'Empty between selector: ' + s; + } + + b = parseMerge(s.substring(1, i)); + if (b.length !== 2) { + throw 'Between selector must have two elements: ' + s; + } + + s = s.slice(i + 1).trim(); + if (s[0] !== GT) { + throw 'Expected \'>\' after between selector: ' + s; + } + + b = b.map(parseSelector$1); + + stream = parseSelector$1(s.slice(1).trim()); + if (stream.between) { + return { + between: b, + stream: stream + }; + } else { + stream.between = b; + } + + return stream; + } + + function parseStream(s) { + var stream = {source: DEFAULT_SOURCE}, + source = [], + throttle = [0, 0], + markname = 0, + start = 0, + n = s.length, + i = 0, j, + filter; + + // extract throttle from end + if (s[n-1] === RBRACE) { + i = s.lastIndexOf(LBRACE); + if (i >= 0) { + try { + throttle = parseThrottle(s.substring(i+1, n-1)); + } catch (e) { + throw 'Invalid throttle specification: ' + s; + } + s = s.slice(0, i).trim(); + n = s.length; + } else throw 'Unmatched right brace: ' + s; + i = 0; + } + + if (!n) throw s; + + // set name flag based on first char + if (s[0] === NAME) markname = ++i; + + // extract first part of multi-part stream selector + j = find(s, i, COLON); + if (j < n) { + source.push(s.substring(start, j).trim()); + start = i = ++j; + } + + // extract remaining part of stream selector + i = find(s, i, LBRACK); + if (i === n) { + source.push(s.substring(start, n).trim()); + } else { + source.push(s.substring(start, i).trim()); + filter = []; + start = ++i; + if (start === n) throw 'Unmatched left bracket: ' + s; + } + + // extract filters + while (i < n) { + i = find(s, i, RBRACK); + if (i === n) throw 'Unmatched left bracket: ' + s; + filter.push(s.substring(start, i).trim()); + if (i < n-1 && s[++i] !== LBRACK) throw 'Expected left bracket: ' + s; + start = ++i; + } + + // marshall event stream specification + if (!(n = source.length) || ILLEGAL.test(source[n-1])) { + throw 'Invalid event selector: ' + s; + } + + if (n > 1) { + stream.type = source[1]; + if (markname) { + stream.markname = source[0].slice(1); + } else if (isMarkType(source[0])) { + stream.marktype = source[0]; + } else { + stream.source = source[0]; + } + } else { + stream.type = source[0]; + } + if (stream.type.slice(-1) === '!') { + stream.consume = true; + stream.type = stream.type.slice(0, -1); + } + if (filter != null) stream.filter = filter; + if (throttle[0]) stream.throttle = throttle[0]; + if (throttle[1]) stream.debounce = throttle[1]; + + return stream; + } + + function parseThrottle(s) { + var a = s.split(COMMA); + if (!s.length || a.length > 2) throw s; + return a.map(function(_) { + var x = +_; + if (x !== x) throw s; + return x; + }); + } + + function isVgSignalRef(o) { + return !!o['signal']; + } + function isVgRangeStep(range) { + return !!range['step']; + } + function isDataRefUnionedDomain(domain) { + if (!isArray(domain)) { + return 'fields' in domain && !('data' in domain); + } + return false; + } + function isFieldRefUnionDomain(domain) { + if (!isArray(domain)) { + return 'fields' in domain && 'data' in domain; + } + return false; + } + function isDataRefDomain(domain) { + if (!isArray(domain)) { + return 'field' in domain && 'data' in domain; + } + return false; + } + var VG_MARK_CONFIG_INDEX = { + opacity: 1, + fill: 1, + fillOpacity: 1, + stroke: 1, + strokeCap: 1, + strokeWidth: 1, + strokeOpacity: 1, + strokeDash: 1, + strokeDashOffset: 1, + strokeJoin: 1, + strokeMiterLimit: 1, + size: 1, + shape: 1, + interpolate: 1, + tension: 1, + orient: 1, + align: 1, + baseline: 1, + text: 1, + dir: 1, + dx: 1, + dy: 1, + ellipsis: 1, + limit: 1, + radius: 1, + theta: 1, + angle: 1, + font: 1, + fontSize: 1, + fontWeight: 1, + fontStyle: 1, + cursor: 1, + href: 1, + tooltip: 1, + cornerRadius: 1, + }; + var VG_MARK_CONFIGS = flagKeys(VG_MARK_CONFIG_INDEX); + + function assembleTitle(title$$1, config) { + if (isArray(title$$1)) { + return title$$1.map(function (fieldDef) { return title(fieldDef, config); }).join(', '); + } + return title$$1; + } + function assembleAxis(axisCmpt, kind, config, opt) { + if (opt === void 0) { opt = { header: false }; } + var _a = axisCmpt.combine(), orient = _a.orient, scale = _a.scale, title$$1 = _a.title, zindex = _a.zindex, axis = __rest(_a, ["orient", "scale", "title", "zindex"]); + // Remove properties that are not valid for this kind of axis + keys(axis).forEach(function (key$$1) { + var propType = AXIS_PROPERTY_TYPE[key$$1]; + if (propType && propType !== kind && propType !== 'both') { + delete axis[key$$1]; + } + }); + if (kind === 'grid') { + if (!axis.grid) { + return undefined; + } + // Remove unnecessary encode block + if (axis.encode) { + // Only need to keep encode block for grid + var grid = axis.encode.grid; + axis.encode = __assign({}, (grid ? { grid: grid } : {})); + if (keys(axis.encode).length === 0) { + delete axis.encode; + } + } + return __assign({ scale: scale, + orient: orient }, axis, { domain: false, labels: false, + // Always set min/maxExtent to 0 to ensure that `config.axis*.minExtent` and `config.axis*.maxExtent` + // would not affect gridAxis + maxExtent: 0, minExtent: 0, ticks: false, zindex: zindex !== undefined ? zindex : 0 // put grid behind marks by default + }); + } + else { // kind === 'main' + if (!opt.header && axisCmpt.mainExtracted) { + // if mainExtracted has been extracted to a separate facet + return undefined; + } + // Remove unnecessary encode block + if (axis.encode) { + for (var _i = 0, AXIS_PARTS_1 = AXIS_PARTS; _i < AXIS_PARTS_1.length; _i++) { + var part = AXIS_PARTS_1[_i]; + if (!axisCmpt.hasAxisPart(part)) { + delete axis.encode[part]; + } + } + if (keys(axis.encode).length === 0) { + delete axis.encode; + } + } + var titleString = assembleTitle(title$$1, config); + return __assign({ scale: scale, + orient: orient, grid: false }, (titleString ? { title: titleString } : {}), axis, { zindex: zindex !== undefined ? zindex : 1 // put axis line above marks by default + }); + } + } + function assembleAxes(axisComponents, config) { + var _a = axisComponents.x, x = _a === void 0 ? [] : _a, _b = axisComponents.y, y = _b === void 0 ? [] : _b; + return x.map(function (a) { return assembleAxis(a, 'main', config); }).concat(x.map(function (a) { return assembleAxis(a, 'grid', config); }), y.map(function (a) { return assembleAxis(a, 'main', config); }), y.map(function (a) { return assembleAxis(a, 'grid', config); })).filter(function (a) { return a; }); // filter undefined + } + + var HEADER_TITLE_PROPERTIES_MAP = { + titleAnchor: 'anchor', + titleAngle: 'angle', + titleBaseline: 'baseline', + titleColor: 'color', + titleFont: 'font', + titleFontSize: 'fontSize', + titleFontWeight: 'fontWeight', + titleLimit: 'limit' + }; + var HEADER_LABEL_PROPERTIES_MAP = { + labelAngle: 'angle', + labelColor: 'color', + labelFont: 'font', + labelFontSize: 'fontSize', + labelLimit: 'limit', + }; + var HEADER_TITLE_PROPERTIES = Object.keys(HEADER_TITLE_PROPERTIES_MAP); + var HEADER_LABEL_PROPERTIES = Object.keys(HEADER_LABEL_PROPERTIES_MAP); + + var header = /*#__PURE__*/Object.freeze({ + HEADER_TITLE_PROPERTIES_MAP: HEADER_TITLE_PROPERTIES_MAP, + HEADER_LABEL_PROPERTIES_MAP: HEADER_LABEL_PROPERTIES_MAP, + HEADER_TITLE_PROPERTIES: HEADER_TITLE_PROPERTIES, + HEADER_LABEL_PROPERTIES: HEADER_LABEL_PROPERTIES + }); + + function isSortField(sort) { + return !!sort && (sort['op'] === 'count' || !!sort['field']) && !!sort['op']; + } + function isSortArray(sort) { + return !!sort && isArray(sort); + } + + var sort = /*#__PURE__*/Object.freeze({ + isSortField: isSortField, + isSortArray: isSortArray + }); + + // TODO: we need to find a way to refactor these so that scaleName is a part of scale + // but that's complicated. For now, this is a huge step moving forward. + /** + * @return Vega ValueRef for normal x- or y-position without projection + */ + function position(channel, channelDef, scaleName, scale, stack, defaultRef) { + if (isFieldDef(channelDef) && stack && channel === stack.fieldChannel) { + // x or y use stack_end so that stacked line's point mark use stack_end too. + return fieldRef(channelDef, scaleName, { suffix: 'end' }); + } + return midPoint(channel, channelDef, scaleName, scale, stack, defaultRef); + } + /** + * @return Vega ValueRef for normal x2- or y2-position without projection + */ + function position2(channel, aFieldDef, a2fieldDef, scaleName, scale, stack, defaultRef) { + if (isFieldDef(aFieldDef) && stack && + // If fieldChannel is X and channel is X2 (or Y and Y2) + channel.charAt(0) === stack.fieldChannel.charAt(0)) { + return fieldRef(aFieldDef, scaleName, { suffix: 'start' }); + } + return midPoint(channel, a2fieldDef, scaleName, scale, stack, defaultRef); + } + function getOffset(channel, markDef) { + var offsetChannel = channel + 'Offset'; + // TODO: in the future read from encoding channel too + var markDefOffsetValue = markDef[offsetChannel]; + if (markDefOffsetValue) { + return markDefOffsetValue; + } + return undefined; + } + /** + * Value Ref for binned fields + */ + function bin$1(fieldDef, scaleName, side, offset) { + var binSuffix = side === 'start' ? undefined : 'end'; + return fieldRef(fieldDef, scaleName, { binSuffix: binSuffix }, offset ? { offset: offset } : {}); + } + function fieldRef(fieldDef, scaleName, opt, mixins) { + var ref = __assign({}, (scaleName ? { scale: scaleName } : {}), { field: vgField(fieldDef, opt) }); + if (mixins) { + return __assign({}, ref, mixins); + } + return ref; + } + function bandRef(scaleName, band) { + if (band === void 0) { band = true; } + return { + scale: scaleName, + band: band + }; + } + /** + * Signal that returns the middle of a bin. Should only be used with x and y. + */ + function binMidSignal(fieldDef, scaleName) { + return { + signal: "(" + + ("scale(\"" + scaleName + "\", " + vgField(fieldDef, { expr: 'datum' }) + ")") + + " + " + + ("scale(\"" + scaleName + "\", " + vgField(fieldDef, { binSuffix: 'end', expr: 'datum' }) + ")") + + ")/2" + }; + } + /** + * @returns {VgValueRef} Value Ref for xc / yc or mid point for other channels. + */ + function midPoint(channel, channelDef, scaleName, scale, stack, defaultRef) { + // TODO: datum support + if (channelDef) { + /* istanbul ignore else */ + if (isFieldDef(channelDef)) { + if (channelDef.bin) { + // Use middle only for x an y to place marks in the center between start and end of the bin range. + // We do not use the mid point for other channels (e.g. size) so that properties of legends and marks match. + if (contains([X, Y], channel) && channelDef.type === QUANTITATIVE) { + if (stack && stack.impute) { + // For stack, we computed bin_mid so we can impute. + return fieldRef(channelDef, scaleName, { binSuffix: 'mid' }); + } + // For non-stack, we can just calculate bin mid on the fly using signal. + return binMidSignal(channelDef, scaleName); + } + return fieldRef(channelDef, scaleName, binRequiresRange(channelDef, channel) ? { binSuffix: 'range' } : {}); + } + if (scale) { + var scaleType = scale.get('type'); + if (hasDiscreteDomain(scaleType)) { + if (scaleType === 'band') { + // For band, to get mid point, need to offset by half of the band + return fieldRef(channelDef, scaleName, { binSuffix: 'range' }, { band: 0.5 }); + } + return fieldRef(channelDef, scaleName, { binSuffix: 'range' }); + } + } + return fieldRef(channelDef, scaleName, {}); // no need for bin suffix + } + else if (isValueDef(channelDef)) { + var value = channelDef.value; + if (contains(['x', 'x2'], channel) && value === 'width') { + return { field: { group: 'width' } }; + } + else if (contains(['y', 'y2'], channel) && value === 'height') { + return { field: { group: 'height' } }; + } + return { value: value }; + } + // If channelDef is neither field def or value def, it's a condition-only def. + // In such case, we will use default ref. + } + return isFunction(defaultRef) ? defaultRef() : defaultRef; + } + function text$1(textDef, config) { + // text + if (textDef) { + if (isFieldDef(textDef)) { + return formatSignalRef(textDef, textDef.format, 'datum', config); + } + else if (isValueDef(textDef)) { + return { value: textDef.value }; + } + } + return undefined; + } + function mid(sizeRef) { + return __assign({}, sizeRef, { mult: 0.5 }); + } + /** + * Whether the scale definitely includes zero in the domain + */ + function domainDefinitelyIncludeZero(scale) { + if (scale.get('zero') !== false) { + return true; + } + var domains = scale.domains; + if (isArray(domains)) { + return some(domains, function (d) { return isArray(d) && d.length === 2 && d[0] <= 0 && d[1] >= 0; }); + } + return false; + } + function getDefaultRef(defaultRef, channel, scaleName, scale, mark) { + return function () { + if (isString(defaultRef)) { + if (scaleName) { + var scaleType = scale.get('type'); + if (contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scaleType)) { + // Log scales cannot have zero. + // Zero in time scale is arbitrary, and does not affect ratio. + // (Time is an interval level of measurement, not ratio). + // See https://en.wikipedia.org/wiki/Level_of_measurement for more info. + if (mark === 'bar' || mark === 'area') { + warn(message.nonZeroScaleUsedWithLengthMark(mark, channel, { scaleType: scaleType })); + } + } + else { + if (domainDefinitelyIncludeZero(scale)) { + return { + scale: scaleName, + value: 0 + }; + } + if (mark === 'bar' || mark === 'area') { + warn(message.nonZeroScaleUsedWithLengthMark(mark, channel, { zeroFalse: scale.explicit.zero === false })); + } + } + } + if (defaultRef === 'zeroOrMin') { + return channel === 'x' ? { value: 0 } : { field: { group: 'height' } }; + } + else { // zeroOrMax + return channel === 'x' ? { field: { group: 'width' } } : { value: 0 }; + } + } + return defaultRef; + }; + } + + function color(model, opt) { + if (opt === void 0) { opt = { valueOnly: false }; } + var _a, _b; + var markDef = model.markDef, encoding = model.encoding, config = model.config; + var filled = markDef.filled, markType = markDef.type; + var configValue = { + fill: getMarkConfig('fill', markDef, config), + stroke: getMarkConfig('stroke', markDef, config), + color: getMarkConfig('color', markDef, config) + }; + var transparentIfNeeded = contains(['bar', 'point', 'circle', 'square', 'geoshape'], markType) ? 'transparent' : undefined; + var defaultValue = { + fill: markDef.fill || configValue.fill || + // If there is no fill, always fill symbols, bar, geoshape + // with transparent fills https://github.com/vega/vega-lite/issues/1316 + transparentIfNeeded, + stroke: markDef.stroke || configValue.stroke + }; + var colorVgChannel = filled ? 'fill' : 'stroke'; + var fillStrokeMarkDefAndConfig = __assign({}, (defaultValue.fill ? { + fill: { value: defaultValue.fill } + } : {}), (defaultValue.stroke ? { + stroke: { value: defaultValue.stroke } + } : {})); + if (encoding.fill || encoding.stroke) { + // ignore encoding.color, markDef.color, config.color + if (markDef.color) { + // warn for markDef.color (no need to warn encoding.color as it will be dropped in normalized already) + warn(message.droppingColor('property', { fill: 'fill' in encoding, stroke: 'stroke' in encoding })); + } + return __assign({}, nonPosition('fill', model, { defaultValue: defaultValue.fill || transparentIfNeeded }), nonPosition('stroke', model, { defaultValue: defaultValue.stroke })); + } + else if (encoding.color) { + return __assign({}, fillStrokeMarkDefAndConfig, nonPosition('color', model, { + vgChannel: colorVgChannel, + // apply default fill/stroke first, then color config, then transparent if needed. + defaultValue: markDef[colorVgChannel] || markDef.color || configValue[colorVgChannel] || configValue.color || (filled ? transparentIfNeeded : undefined) + })); + } + else if (markDef.fill || markDef.stroke) { + // Ignore markDef.color, config.color + if (markDef.color) { + warn(message.droppingColor('property', { fill: 'fill' in markDef, stroke: 'stroke' in markDef })); + } + return fillStrokeMarkDefAndConfig; + } + else if (markDef.color) { + return __assign({}, fillStrokeMarkDefAndConfig, (_a = {}, _a[colorVgChannel] = { value: markDef.color }, _a)); + } + else if (configValue.fill || configValue.stroke) { + // ignore config.color + return fillStrokeMarkDefAndConfig; + } + else if (configValue.color) { + return __assign({}, (transparentIfNeeded ? { fill: { value: 'transparent' } } : {}), (_b = {}, _b[colorVgChannel] = { value: configValue.color }, _b)); + } + return {}; + } + function baseEncodeEntry(model, ignore) { + return __assign({}, markDefProperties(model.markDef, ignore), color(model), nonPosition('opacity', model), tooltip(model), text$2(model, 'href')); + } + function markDefProperties(mark, ignore) { + return VG_MARK_CONFIGS.reduce(function (m, prop) { + if (mark[prop] !== undefined && ignore[prop] !== 'ignore') { + m[prop] = { value: mark[prop] }; + } + return m; + }, {}); + } + function valueIfDefined(prop, value) { + var _a; + if (value !== undefined) { + return _a = {}, _a[prop] = { value: value }, _a; + } + return undefined; + } + function validPredicate(vgRef) { + return vgRef + " !== null && !isNaN(" + vgRef + ")"; + } + function defined(model) { + if (model.config.invalidValues === 'filter') { + var fields = ['x', 'y'].map(function (channel) { + var scaleComponent = model.getScaleComponent(channel); + if (scaleComponent) { + var scaleType = scaleComponent.get('type'); + // Discrete domain scales can handle invalid values, but continuous scales can't. + if (hasContinuousDomain(scaleType)) { + return model.vgField(channel, { expr: 'datum' }); + } + } + return undefined; + }) + .filter(function (field$$1) { return !!field$$1; }) + .map(validPredicate); + if (fields.length > 0) { + return { + defined: { signal: fields.join(' && ') } + }; + } + } + return {}; + } + /** + * Return mixins for non-positional channels with scales. (Text doesn't have scale.) + */ + function nonPosition(channel, model, opt) { + if (opt === void 0) { opt = {}; } + var defaultValue = opt.defaultValue, vgChannel = opt.vgChannel; + var defaultRef = opt.defaultRef || (defaultValue !== undefined ? { value: defaultValue } : undefined); + var channelDef = model.encoding[channel]; + return wrapCondition(model, channelDef, vgChannel || channel, function (cDef) { + return midPoint(channel, cDef, model.scaleName(channel), model.getScaleComponent(channel), null, // No need to provide stack for non-position as it does not affect mid point + defaultRef); + }); + } + /** + * Return a mixin that include a Vega production rule for a Vega-Lite conditional channel definition. + * or a simple mixin if channel def has no condition. + */ + function wrapCondition(model, channelDef, vgChannel, refFn) { + var _a, _b; + var condition = channelDef && channelDef.condition; + var valueRef = refFn(channelDef); + if (condition) { + var conditions = isArray(condition) ? condition : [condition]; + var vgConditions = conditions.map(function (c) { + var conditionValueRef = refFn(c); + var test = isConditionalSelection(c) ? selectionPredicate(model, c.selection) : expression(model, c.test); + return __assign({ test: test }, conditionValueRef); + }); + return _a = {}, + _a[vgChannel] = vgConditions.concat((valueRef !== undefined ? [valueRef] : [])), + _a; + } + else { + return valueRef !== undefined ? (_b = {}, _b[vgChannel] = valueRef, _b) : {}; + } + } + function tooltip(model) { + var channel = 'tooltip'; + var channelDef = model.encoding[channel]; + if (isArray(channelDef)) { + var keyValues = channelDef.map(function (fieldDef) { + var key$$1 = fieldDef.title !== undefined ? fieldDef.title : vgField(fieldDef, { binSuffix: 'range' }); + var value = text$1(fieldDef, model.config).signal; + return "\"" + key$$1 + "\": " + value; + }); + return { tooltip: { signal: "{" + keyValues.join(', ') + "}" } }; + } + else { + // if not an array, behave just like text + return textCommon(model, channel, channelDef); + } + } + function text$2(model, channel) { + if (channel === void 0) { channel = 'text'; } + var channelDef = model.encoding[channel]; + return textCommon(model, channel, channelDef); + } + function textCommon(model, channel, channelDef) { + return wrapCondition(model, channelDef, channel, function (cDef) { return text$1(cDef, model.config); }); + } + function bandPosition(fieldDef, channel, model) { + var _a, _b, _c; + var scaleName = model.scaleName(channel); + var sizeChannel = channel === 'x' ? 'width' : 'height'; + if (model.encoding.size || model.markDef.size !== undefined) { + var orient = model.markDef.orient; + if (orient) { + var centeredBandPositionMixins = (_a = {}, + // Use xc/yc and place the mark at the middle of the band + // This way we never have to deal with size's condition for x/y position. + _a[channel + 'c'] = fieldRef(fieldDef, scaleName, {}, { band: 0.5 }), + _a); + if (getFieldDef(model.encoding.size)) { + return __assign({}, centeredBandPositionMixins, nonPosition('size', model, { vgChannel: sizeChannel })); + } + else if (isValueDef(model.encoding.size)) { + return __assign({}, centeredBandPositionMixins, nonPosition('size', model, { vgChannel: sizeChannel })); + } + else if (model.markDef.size !== undefined) { + return __assign({}, centeredBandPositionMixins, (_b = {}, _b[sizeChannel] = { value: model.markDef.size }, _b)); + } + } + else { + warn(message.cannotApplySizeToNonOrientedMark(model.markDef.type)); + } + } + return _c = {}, + _c[channel] = fieldRef(fieldDef, scaleName, { binSuffix: 'range' }), + _c[sizeChannel] = bandRef(scaleName), + _c; + } + function centeredBandPosition(channel, model, defaultPosRef, defaultSizeRef) { + var centerChannel = channel === 'x' ? 'xc' : 'yc'; + var sizeChannel = channel === 'x' ? 'width' : 'height'; + return __assign({}, pointPosition(channel, model, defaultPosRef, centerChannel), nonPosition('size', model, { defaultRef: defaultSizeRef, vgChannel: sizeChannel })); + } + function binnedPosition(fieldDef, channel, scaleName, spacing, reverse) { + if (channel === 'x') { + return { + x2: bin$1(fieldDef, scaleName, 'start', reverse ? 0 : spacing), + x: bin$1(fieldDef, scaleName, 'end', reverse ? spacing : 0) + }; + } + else { + return { + y2: bin$1(fieldDef, scaleName, 'start', reverse ? spacing : 0), + y: bin$1(fieldDef, scaleName, 'end', reverse ? 0 : spacing) + }; + } + } + /** + * Return mixins for point (non-band) position channels. + */ + function pointPosition(channel, model, defaultRef, vgChannel) { + // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613 + var _a; + var encoding = model.encoding, mark = model.mark, stack = model.stack; + var channelDef = encoding[channel]; + var scaleName = model.scaleName(channel); + var scale = model.getScaleComponent(channel); + var offset = getOffset(channel, model.markDef); + var valueRef = !channelDef && (encoding.latitude || encoding.longitude) ? + // use geopoint output if there are lat/long and there is no point position overriding lat/long. + { field: model.getName(channel) } : __assign({}, position(channel, encoding[channel], scaleName, scale, stack, getDefaultRef(defaultRef, channel, scaleName, scale, mark)), (offset ? { offset: offset } : {})); + return _a = {}, + _a[vgChannel || channel] = valueRef, + _a; + } + /** + * Return mixins for x2, y2. + * If channel is not specified, return one channel based on orientation. + */ + function pointPosition2(model, defaultRef, channel) { + var _a; + var encoding = model.encoding, mark = model.mark, stack = model.stack; + var baseChannel = channel === 'x2' ? 'x' : 'y'; + var channelDef = encoding[baseChannel]; + var scaleName = model.scaleName(baseChannel); + var scale = model.getScaleComponent(baseChannel); + var offset = getOffset(channel, model.markDef); + var valueRef = !channelDef && (encoding.latitude || encoding.longitude) ? + // use geopoint output if there are lat2/long2 and there is no point position2 overriding lat2/long2. + { field: model.getName(channel) } : __assign({}, position2(channel, channelDef, encoding[channel], scaleName, scale, stack, getDefaultRef(defaultRef, baseChannel, scaleName, scale, mark)), (offset ? { offset: offset } : {})); + return _a = {}, _a[channel] = valueRef, _a; + } + + function applyMarkConfig(e, model, propsList) { + for (var _i = 0, propsList_2 = propsList; _i < propsList_2.length; _i++) { + var property = propsList_2[_i]; + var value = getMarkConfig(property, model.markDef, model.config); + if (value !== undefined) { + e[property] = { value: value }; + } + } + return e; + } + function getStyles(mark) { + return [].concat(mark.type, mark.style || []); + } + /** + * Return property value from style or mark specific config property if exists. + * Otherwise, return general mark specific config. + */ + function getMarkConfig(prop, mark, config) { + // By default, read from mark config first! + var value = config.mark[prop]; + // Then read mark specific config, which has higher precedence + var markSpecificConfig = config[mark.type]; + if (markSpecificConfig[prop] !== undefined) { + value = markSpecificConfig[prop]; + } + // Then read style config, which has even higher precedence. + var styles = getStyles(mark); + for (var _i = 0, styles_1 = styles; _i < styles_1.length; _i++) { + var style = styles_1[_i]; + var styleConfig = config.style[style]; + // MarkConfig extends VgMarkConfig so a prop may not be a valid property for style + // However here we also check if it is defined, so it is okay to cast here + var p = prop; + if (styleConfig && styleConfig[p] !== undefined) { + value = styleConfig[p]; + } + } + return value; + } + function formatSignalRef(fieldDef, specifiedFormat, expr, config) { + var format = numberFormat(fieldDef, specifiedFormat, config); + if (fieldDef.bin) { + var startField = vgField(fieldDef, { expr: expr }); + var endField = vgField(fieldDef, { expr: expr, binSuffix: 'end' }); + return { + signal: binFormatExpression(startField, endField, format, config) + }; + } + else if (fieldDef.type === 'quantitative') { + return { + signal: "" + formatExpr(vgField(fieldDef, { expr: expr, binSuffix: 'range' }), format) + }; + } + else if (isTimeFieldDef(fieldDef)) { + var isUTCScale = isScaleFieldDef(fieldDef) && fieldDef['scale'] && fieldDef['scale'].type === ScaleType.UTC; + return { + signal: timeFormatExpression(vgField(fieldDef, { expr: expr }), fieldDef.timeUnit, specifiedFormat, config.text.shortTimeLabels, config.timeFormat, isUTCScale, true) + }; + } + else { + return { + signal: "''+" + vgField(fieldDef, { expr: expr }) + }; + } + } + function getSpecifiedOrDefaultValue(specifiedValue, defaultValue) { + if (specifiedValue !== undefined) { + return specifiedValue; + } + return defaultValue; + } + /** + * Returns number format for a fieldDef + * + * @param format explicitly specified format + */ + function numberFormat(fieldDef, specifiedFormat, config) { + if (fieldDef.type === QUANTITATIVE) { + // add number format for quantitative type only + // Specified format in axis/legend has higher precedence than fieldDef.format + if (specifiedFormat) { + return specifiedFormat; + } + // TODO: need to make this work correctly for numeric ordinal / nominal type + return config.numberFormat; + } + return undefined; + } + function formatExpr(field$$1, format) { + return "format(" + field$$1 + ", \"" + (format || '') + "\")"; + } + function numberFormatExpr(field$$1, specifiedFormat, config) { + return formatExpr(field$$1, specifiedFormat || config.numberFormat); + } + function binFormatExpression(startField, endField, format, config) { + return startField + " === null || isNaN(" + startField + ") ? \"null\" : " + numberFormatExpr(startField, format, config) + " + \" - \" + " + numberFormatExpr(endField, format, config); + } + /** + * Returns the time expression used for axis/legend labels or text mark for a temporal field + */ + function timeFormatExpression(field$$1, timeUnit, format, shortTimeLabels, timeFormatConfig, isUTCScale, alwaysReturn) { + if (alwaysReturn === void 0) { alwaysReturn = false; } + if (!timeUnit || format) { + // If there is not time unit, or if user explicitly specify format for axis/legend/text. + format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit. + if (format || alwaysReturn) { + return (isUTCScale ? 'utc' : 'time') + "Format(" + field$$1 + ", '" + format + "')"; + } + else { + return undefined; + } + } + else { + return formatExpression(timeUnit, field$$1, shortTimeLabels, isUTCScale); + } + } + /** + * Return Vega sort parameters (tuple of field and order). + */ + function sortParams(orderDef, fieldRefOption) { + return (isArray(orderDef) ? orderDef : [orderDef]).reduce(function (s, orderChannelDef) { + s.field.push(vgField(orderChannelDef, fieldRefOption)); + s.order.push(orderChannelDef.sort || 'ascending'); + return s; + }, { field: [], order: [] }); + } + function mergeTitleFieldDefs(f1, f2) { + var merged = f1.slice(); + f2.forEach(function (fdToMerge) { + for (var _i = 0, merged_1 = merged; _i < merged_1.length; _i++) { + var fieldDef1 = merged_1[_i]; + // If already exists, no need to append to merged array + if (stringify$2(fieldDef1) === stringify$2(fdToMerge)) { + return; + } + } + merged.push(fdToMerge); + }); + return merged; + } + function mergeTitle(title1, title2) { + return title1 === title2 ? + title1 : // if title is the same just use one of them + title1 + ', ' + title2; // join title with comma if different + } + function mergeTitleComponent(v1, v2) { + if (isArray(v1.value) && isArray(v2.value)) { + return { + explicit: v1.explicit, + value: mergeTitleFieldDefs(v1.value, v2.value) + }; + } + else if (!isArray(v1.value) && !isArray(v2.value)) { + return { + explicit: v1.explicit, + value: mergeTitle(v1.value, v2.value) + }; + } + /* istanbul ignore next: Condition should not happen -- only for warning in development. */ + throw new Error('It should never reach here'); + } + /** + * Checks whether a fieldDef for a particular channel requires a computed bin range. + */ + function binRequiresRange(fieldDef, channel) { + if (!fieldDef.bin) { + console.warn('Only use this method with binned field defs'); + return false; + } + // We need the range only when the user explicitly forces a binned field to be use discrete scale. In this case, bin range is used in axis and legend labels. + // We could check whether the axis or legend exists (not disabled) but that seems overkill. + return isScaleChannel(channel) && contains(['ordinal', 'nominal'], fieldDef.type); + } + function guideEncodeEntry(encoding, model) { + return keys(encoding).reduce(function (encode, channel) { + var valueDef = encoding[channel]; + return __assign({}, encode, wrapCondition(model, valueDef, channel, function (x) { return ({ value: x.value }); })); + }, {}); + } + + /** + * A node in the dataflow tree. + */ + var DataFlowNode = /** @class */ (function () { + function DataFlowNode(parent, debugName) { + this.debugName = debugName; + this._children = []; + this._parent = null; + if (parent) { + this.parent = parent; + } + } + /** + * Clone this node with a deep copy but don't clone links to children or parents. + */ + DataFlowNode.prototype.clone = function () { + throw new Error('Cannot clone node'); + }; + /** + * Set of fields that are being created by this node. + */ + DataFlowNode.prototype.producedFields = function () { + return {}; + }; + DataFlowNode.prototype.dependentFields = function () { + return {}; + }; + Object.defineProperty(DataFlowNode.prototype, "parent", { + get: function () { + return this._parent; + }, + /** + * Set the parent of the node and also add this not to the parent's children. + */ + set: function (parent) { + this._parent = parent; + parent.addChild(this); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(DataFlowNode.prototype, "children", { + get: function () { + return this._children; + }, + enumerable: true, + configurable: true + }); + DataFlowNode.prototype.numChildren = function () { + return this._children.length; + }; + DataFlowNode.prototype.addChild = function (child) { + this._children.push(child); + }; + DataFlowNode.prototype.removeChild = function (oldChild) { + this._children.splice(this._children.indexOf(oldChild), 1); + }; + /** + * Remove node from the dataflow. + */ + DataFlowNode.prototype.remove = function () { + for (var _i = 0, _a = this._children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parent = this._parent; + } + this._parent.removeChild(this); + }; + /** + * Insert another node as a parent of this node. + */ + DataFlowNode.prototype.insertAsParentOf = function (other) { + var parent = other.parent; + parent.removeChild(this); + this.parent = parent; + other.parent = this; + }; + DataFlowNode.prototype.swapWithParent = function () { + var parent = this._parent; + var newParent = parent.parent; + // reconnect the children + for (var _i = 0, _a = this._children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parent = parent; + } + // remove old links + this._children = []; // equivalent to removing every child link one by one + parent.removeChild(this); + parent.parent.removeChild(parent); + // swap two nodes + this.parent = newParent; + parent.parent = this; + }; + return DataFlowNode; + }()); + var OutputNode = /** @class */ (function (_super) { + __extends(OutputNode, _super); + /** + * @param source The name of the source. Will change in assemble. + * @param type The type of the output node. + * @param refCounts A global ref counter map. + */ + function OutputNode(parent, source, type, refCounts) { + var _this = _super.call(this, parent, source) || this; + _this.type = type; + _this.refCounts = refCounts; + _this._source = _this._name = source; + if (_this.refCounts && !(_this._name in _this.refCounts)) { + _this.refCounts[_this._name] = 0; + } + return _this; + } + OutputNode.prototype.clone = function () { + var cloneObj = new this.constructor; + cloneObj.debugName = 'clone_' + this.debugName; + cloneObj._source = this._source; + cloneObj._name = 'clone_' + this._name; + cloneObj.type = this.type; + cloneObj.refCounts = this.refCounts; + cloneObj.refCounts[cloneObj._name] = 0; + return cloneObj; + }; + /** + * Request the datasource name and increase the ref counter. + * + * During the parsing phase, this will return the simple name such as 'main' or 'raw'. + * It is crucial to request the name from an output node to mark it as a required node. + * If nobody ever requests the name, this datasource will not be instantiated in the assemble phase. + * + * In the assemble phase, this will return the correct name. + */ + OutputNode.prototype.getSource = function () { + this.refCounts[this._name]++; + return this._source; + }; + OutputNode.prototype.isRequired = function () { + return !!this.refCounts[this._name]; + }; + OutputNode.prototype.setSource = function (source) { + this._source = source; + }; + return OutputNode; + }(DataFlowNode)); + + /** + * We don't know what a calculate node depends on so we should never move it beyond anything that produces fields. + */ + var CalculateNode = /** @class */ (function (_super) { + __extends(CalculateNode, _super); + function CalculateNode(parent, transform) { + var _this = _super.call(this, parent) || this; + _this.transform = transform; + return _this; + } + CalculateNode.prototype.clone = function () { + return new CalculateNode(null, duplicate(this.transform)); + }; + CalculateNode.parseAllForSortIndex = function (parent, model) { + // get all the encoding with sort fields from model + model.forEachFieldDef(function (fieldDef, channel) { + if (!isScaleFieldDef(fieldDef)) { + return; + } + if (isSortArray(fieldDef.sort)) { + var field_1 = fieldDef.field, timeUnit_1 = fieldDef.timeUnit; + var sort = fieldDef.sort; + // generate `datum["a"] === val0 ? 0 : datum["a"] === val1 ? 1 : ... : n` via FieldEqualPredicate + var calculate = sort.map(function (sortValue, i) { + return fieldFilterExpression({ field: field_1, timeUnit: timeUnit_1, equal: sortValue }) + " ? " + i + " : "; + }).join('') + sort.length; + parent = new CalculateNode(parent, { + calculate: calculate, + as: sortArrayIndexField(fieldDef, channel) + }); + } + }); + return parent; + }; + CalculateNode.prototype.producedFields = function () { + var out = {}; + out[this.transform.as] = true; + return out; + }; + CalculateNode.prototype.assemble = function () { + return { + type: 'formula', + expr: this.transform.calculate, + as: this.transform.as + }; + }; + return CalculateNode; + }(DataFlowNode)); + function sortArrayIndexField(fieldDef, channel, expr) { + return vgField(fieldDef, { prefix: channel, suffix: 'sort_index', expr: expr }); + } + + var HEADER_CHANNELS = ['row', 'column']; + var HEADER_TYPES = ['header', 'footer']; + function getHeaderType(orient) { + if (orient === 'top' || orient === 'left') { + return 'header'; + } + return 'footer'; + } + function getTitleGroup(model, channel) { + var title$$1 = model.component.layoutHeaders[channel].title; + var textOrient = channel === 'row' ? 'left' : undefined; + var config = model.config ? model.config : undefined; + var facetFieldDef = model.component.layoutHeaders[channel].facetFieldDef ? model.component.layoutHeaders[channel].facetFieldDef : undefined; + return { + name: channel + "-title", + type: 'group', + role: channel + "-title", + title: __assign({ text: title$$1, offset: 10, orient: textOrient, style: 'guide-title' }, getHeaderProperties(config, facetFieldDef, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP)) + }; + } + function getHeaderGroups(model, channel) { + var layoutHeader = model.component.layoutHeaders[channel]; + var groups = []; + for (var _i = 0, HEADER_TYPES_1 = HEADER_TYPES; _i < HEADER_TYPES_1.length; _i++) { + var headerType = HEADER_TYPES_1[_i]; + if (layoutHeader[headerType]) { + for (var _a = 0, _b = layoutHeader[headerType]; _a < _b.length; _a++) { + var headerCmpt = _b[_a]; + groups.push(getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt)); + } + } + } + return groups; + } + // 0, (0,90), 90, (90, 180), 180, (180, 270), 270, (270, 0) + function labelAlign(angle) { + // to keep angle in [0, 360) + angle = ((angle % 360) + 360) % 360; + if ((angle + 90) % 180 === 0) { // for 90 and 270 + return {}; // default center + } + else if (angle < 90 || 270 < angle) { + return { align: { value: 'right' } }; + } + else if (135 <= angle && angle < 225) { + return { align: { value: 'left' } }; + } + return {}; + } + function getSort(facetFieldDef, channel) { + var sort = facetFieldDef.sort; + if (isSortField(sort)) { + return { + field: vgField(sort, { expr: 'datum' }), + order: sort.order || 'ascending' + }; + } + else if (isArray(sort)) { + return { + field: sortArrayIndexField(facetFieldDef, channel, 'datum'), + order: 'ascending' + }; + } + else { + return { + field: vgField(facetFieldDef, { expr: 'datum' }), + order: sort || 'ascending' + }; + } + } + function getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt) { + var _a; + if (headerCmpt) { + var title$$1 = null; + var facetFieldDef = layoutHeader.facetFieldDef; + if (facetFieldDef && headerCmpt.labels) { + var _b = facetFieldDef.header, header = _b === void 0 ? {} : _b; + var format = header.format, labelAngle = header.labelAngle; + var config = model.config ? model.config : undefined; + var update = __assign({}, labelAlign(labelAngle)); + title$$1 = __assign({ text: formatSignalRef(facetFieldDef, format, 'parent', model.config), offset: 10, orient: channel === 'row' ? 'left' : 'top', style: 'guide-label' }, getHeaderProperties(config, facetFieldDef, HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP), (keys(update).length > 0 ? { encode: { update: update } } : {})); + } + var axes = headerCmpt.axes; + var hasAxes = axes && axes.length > 0; + if (title$$1 || hasAxes) { + var sizeChannel = channel === 'row' ? 'height' : 'width'; + return __assign({ name: model.getName(channel + "_" + headerType), type: 'group', role: channel + "-" + headerType }, (layoutHeader.facetFieldDef ? { + from: { data: model.getName(channel + '_domain') }, + sort: getSort(facetFieldDef, channel) + } : {}), (title$$1 ? { title: title$$1 } : {}), (headerCmpt.sizeSignal ? { + encode: { + update: (_a = {}, + _a[sizeChannel] = headerCmpt.sizeSignal, + _a) + } + } : {}), (hasAxes ? { axes: axes } : {})); + } + } + return null; + } + function getHeaderProperties(config, facetFieldDef, properties, propertiesMap) { + var props = {}; + for (var _i = 0, properties_1 = properties; _i < properties_1.length; _i++) { + var prop = properties_1[_i]; + if (config && config.header) { + if (config.header[prop]) { + props[propertiesMap[prop]] = config.header[prop]; + } + } + if (facetFieldDef && facetFieldDef.header) { + if (facetFieldDef.header[prop]) { + props[propertiesMap[prop]] = facetFieldDef.header[prop]; + } + } + } + return props; + } + + function assembleLayoutSignals(model) { + return [].concat(sizeSignals(model, 'width'), sizeSignals(model, 'height')); + } + function sizeSignals(model, sizeType) { + var channel = sizeType === 'width' ? 'x' : 'y'; + var size = model.component.layoutSize.get(sizeType); + if (!size || size === 'merged') { + return []; + } + // Read size signal name from name map, just in case it is the top-level size signal that got renamed. + var name = model.getSizeSignalRef(sizeType).signal; + if (size === 'range-step') { + var scaleComponent = model.getScaleComponent(channel); + if (scaleComponent) { + var type = scaleComponent.get('type'); + var range = scaleComponent.get('range'); + if (hasDiscreteDomain(type) && isVgRangeStep(range)) { + var scaleName = model.scaleName(channel); + if (isFacetModel(model.parent)) { + // If parent is facet and this is an independent scale, return only signal signal + // as the width/height will be calculated using the cardinality from + // facet's aggregate rather than reading from scale domain + var parentResolve = model.parent.component.resolve; + if (parentResolve.scale[channel] === 'independent') { + return [stepSignal(scaleName, range)]; + } + } + return [ + stepSignal(scaleName, range), + { + name: name, + update: sizeExpr(scaleName, scaleComponent, "domain('" + scaleName + "').length") + } + ]; + } + } + /* istanbul ignore next: Condition should not happen -- only for warning in development. */ + throw new Error('layout size is range step although there is no rangeStep.'); + } + else { + return [{ + name: name, + value: size + }]; + } + } + function stepSignal(scaleName, range) { + return { + name: scaleName + '_step', + value: range.step, + }; + } + function sizeExpr(scaleName, scaleComponent, cardinality) { + var type = scaleComponent.get('type'); + var padding = scaleComponent.get('padding'); + var paddingOuter = scaleComponent.get('paddingOuter'); + paddingOuter = paddingOuter !== undefined ? paddingOuter : padding; + var paddingInner = scaleComponent.get('paddingInner'); + paddingInner = type === 'band' ? + // only band has real paddingInner + (paddingInner !== undefined ? paddingInner : padding) : + // For point, as calculated in https://github.com/vega/vega-scale/blob/master/src/band.js#L128, + // it's equivalent to have paddingInner = 1 since there is only n-1 steps between n points. + 1; + return "bandspace(" + cardinality + ", " + paddingInner + ", " + paddingOuter + ") * " + scaleName + "_step"; + } + + function defaultScaleResolve(channel, model) { + if (isLayerModel(model) || isFacetModel(model)) { + return 'shared'; + } + else if (isConcatModel(model) || isRepeatModel(model)) { + return contains(POSITION_SCALE_CHANNELS, channel) ? 'independent' : 'shared'; + } + /* istanbul ignore next: should never reach here. */ + throw new Error('invalid model type for resolve'); + } + function parseGuideResolve(resolve, channel) { + var channelScaleResolve = resolve.scale[channel]; + var guide = contains(POSITION_SCALE_CHANNELS, channel) ? 'axis' : 'legend'; + if (channelScaleResolve === 'independent') { + if (resolve[guide][channel] === 'shared') { + warn(message.independentScaleMeansIndependentGuide(channel)); + } + return 'independent'; + } + return resolve[guide][channel] || 'shared'; + } + + /** + * Generic class for storing properties that are explicitly specified + * and implicitly determined by the compiler. + * This is important for scale/axis/legend merging as + * we want to prioritize properties that users explicitly specified. + */ + var Split = /** @class */ (function () { + function Split(explicit, implicit) { + if (explicit === void 0) { explicit = {}; } + if (implicit === void 0) { implicit = {}; } + this.explicit = explicit; + this.implicit = implicit; + } + Split.prototype.clone = function () { + return new Split(duplicate(this.explicit), duplicate(this.implicit)); + }; + Split.prototype.combine = function () { + // FIXME remove "as any". + // Add "as any" to avoid an error "Spread types may only be created from object types". + return __assign({}, this.explicit, this.implicit); + }; + Split.prototype.get = function (key) { + // Explicit has higher precedence + return this.explicit[key] !== undefined ? this.explicit[key] : this.implicit[key]; + }; + Split.prototype.getWithExplicit = function (key) { + // Explicit has higher precedence + if (this.explicit[key] !== undefined) { + return { explicit: true, value: this.explicit[key] }; + } + else if (this.implicit[key] !== undefined) { + return { explicit: false, value: this.implicit[key] }; + } + return { explicit: false, value: undefined }; + }; + Split.prototype.setWithExplicit = function (key, value) { + if (value.value !== undefined) { + this.set(key, value.value, value.explicit); + } + }; + Split.prototype.set = function (key, value, explicit) { + delete this[explicit ? 'implicit' : 'explicit'][key]; + this[explicit ? 'explicit' : 'implicit'][key] = value; + return this; + }; + Split.prototype.copyKeyFromSplit = function (key, s) { + // Explicit has higher precedence + if (s.explicit[key] !== undefined) { + this.set(key, s.explicit[key], true); + } + else if (s.implicit[key] !== undefined) { + this.set(key, s.implicit[key], false); + } + }; + Split.prototype.copyKeyFromObject = function (key, s) { + // Explicit has higher precedence + if (s[key] !== undefined) { + this.set(key, s[key], true); + } + }; + /** + * Merge split object into this split object. Properties from the other split + * overwrite properties from this split. + */ + Split.prototype.copyAll = function (other) { + for (var _i = 0, _a = keys(other.combine()); _i < _a.length; _i++) { + var key = _a[_i]; + var val = other.getWithExplicit(key); + this.setWithExplicit(key, val); + } + }; + return Split; + }()); + function makeExplicit(value) { + return { + explicit: true, + value: value + }; + } + function makeImplicit(value) { + return { + explicit: false, + value: value + }; + } + function tieBreakByComparing(compare) { + return function (v1, v2, property, propertyOf) { + var diff = compare(v1.value, v2.value); + if (diff > 0) { + return v1; + } + else if (diff < 0) { + return v2; + } + return defaultTieBreaker(v1, v2, property, propertyOf); + }; + } + function defaultTieBreaker(v1, v2, property, propertyOf) { + if (v1.explicit && v2.explicit) { + warn(message.mergeConflictingProperty(property, propertyOf, v1.value, v2.value)); + } + // If equal score, prefer v1. + return v1; + } + function mergeValuesWithExplicit(v1, v2, property, propertyOf, tieBreaker) { + if (tieBreaker === void 0) { tieBreaker = defaultTieBreaker; } + if (v1 === undefined || v1.value === undefined) { + // For first run + return v2; + } + if (v1.explicit && !v2.explicit) { + return v1; + } + else if (v2.explicit && !v1.explicit) { + return v2; + } + else if (stringify$2(v1.value) === stringify$2(v2.value)) { + return v1; + } + else { + return tieBreaker(v1, v2, property, propertyOf); + } + } + + var LegendComponent = /** @class */ (function (_super) { + __extends(LegendComponent, _super); + function LegendComponent() { + return _super !== null && _super.apply(this, arguments) || this; + } + return LegendComponent; + }(Split)); + + function symbols(fieldDef, symbolsSpec, model, channel, type) { + if (type === 'gradient') { + return undefined; + } + var out = __assign({}, applyMarkConfig({}, model, FILL_STROKE_CONFIG), color(model)); + switch (model.mark) { + case BAR: + case TICK: + case TEXT$1: + out.shape = { value: 'square' }; + break; + case CIRCLE: + case SQUARE: + out.shape = { value: model.mark }; + break; + case POINT: + case LINE: + case GEOSHAPE: + case AREA: + // use default circle + break; + } + var markDef = model.markDef, encoding = model.encoding; + var filled = markDef.filled; + if (out.fill) { + // for fill legend, we don't want any fill in symbol + if (channel === 'fill' || (filled && channel === COLOR)) { + delete out.fill; + } + else { + if (out.fill['field']) { + // For others, remove fill field + delete out.fill; + } + else if (isArray(out.fill)) { + var fill = getFirstConditionValue(encoding.fill || encoding.color) || markDef.fill || (filled && markDef.color); + if (fill) { + out.fill = { value: fill }; + } + } + } + } + if (out.stroke) { + if (channel === 'stroke' || (!filled && channel === COLOR)) { + delete out.stroke; + } + else { + if (out.stroke['field']) { + // For others, remove stroke field + delete out.stroke; + } + else if (isArray(out.stroke)) { + var stroke = getFirstConditionValue(encoding.stroke || encoding.color) || markDef.stroke || (!filled && markDef.color); + if (stroke) { + out.stroke = { value: stroke }; + } + } + } + } + if (out.fill && out.fill['value'] !== 'transparent' && !out.stroke) { + // for non color channel's legend, we need to override symbol stroke config from Vega config + out.stroke = { value: 'transparent' }; + } + if (channel !== SHAPE) { + var shape = getFirstConditionValue(encoding.shape) || markDef.shape; + if (shape) { + out.shape = { value: shape }; + } + } + if (channel !== OPACITY) { + var opacity = getMaxValue(encoding.opacity) || markDef.opacity; + if (opacity) { // only apply opacity if it is neither zero or undefined + out.opacity = { value: opacity }; + } + } + out = __assign({}, out, symbolsSpec); + return keys(out).length > 0 ? out : undefined; + } + function gradient(fieldDef, gradientSpec, model, channel, type) { + var out = {}; + if (type === 'gradient') { + var opacity = getMaxValue(model.encoding.opacity) || model.markDef.opacity; + if (opacity) { // only apply opacity if it is neither zero or undefined + out.opacity = { value: opacity }; + } + } + out = __assign({}, out, gradientSpec); + return keys(out).length > 0 ? out : undefined; + } + function labels(fieldDef, labelsSpec, model, channel, type) { + var legend = model.legend(channel); + var config = model.config; + var out = {}; + if (isTimeFieldDef(fieldDef)) { + var isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC; + var expr = timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat, isUTCScale); + labelsSpec = __assign({}, (expr ? { text: { signal: expr } } : {}), labelsSpec); + } + out = __assign({}, out, labelsSpec); + return keys(out).length > 0 ? out : undefined; + } + function getMaxValue(channelDef) { + return getConditionValue(channelDef, function (v, conditionalDef) { return Math.max(v, conditionalDef.value); }); + } + function getFirstConditionValue(channelDef) { + return getConditionValue(channelDef, function (v, conditionalDef) { return v !== undefined ? v : conditionalDef.value; }); + } + function getConditionValue(channelDef, reducer) { + if (hasConditionalValueDef(channelDef)) { + return (isArray(channelDef.condition) ? channelDef.condition : [channelDef.condition]) + .reduce(reducer, channelDef.value); + } + else if (isValueDef(channelDef)) { + return channelDef.value; + } + return undefined; + } + + var encode = /*#__PURE__*/Object.freeze({ + symbols: symbols, + gradient: gradient, + labels: labels + }); + + function values(legend, fieldDef) { + var vals$$1 = legend.values; + if (vals$$1) { + return valueArray(fieldDef, vals$$1); + } + return undefined; + } + function type$2(t, channel, scaleType) { + if (isColorChannel(channel) && ((t === 'quantitative' && !isBinScale(scaleType)) || + (t === 'temporal' && contains(['time', 'utc'], scaleType)))) { + return 'gradient'; + } + return undefined; + } + + function parseLegend(model) { + if (isUnitModel(model)) { + model.component.legends = parseUnitLegend(model); + } + else { + model.component.legends = parseNonUnitLegend(model); + } + } + function parseUnitLegend(model) { + var encoding = model.encoding; + return [COLOR, FILL, STROKE, SIZE, SHAPE, OPACITY].reduce(function (legendComponent, channel) { + var def = encoding[channel]; + if (model.legend(channel) && model.getScaleComponent(channel) && !(isFieldDef(def) && (channel === SHAPE && def.type === GEOJSON))) { + legendComponent[channel] = parseLegendForChannel(model, channel); + } + return legendComponent; + }, {}); + } + function getLegendDefWithScale(model, channel) { + var _a; + // For binned field with continuous scale, use a special scale so we can overrride the mark props and labels + switch (channel) { + case COLOR: + var scale = model.scaleName(COLOR); + return model.markDef.filled ? { fill: scale } : { stroke: scale }; + case FILL: + case STROKE: + case SIZE: + case SHAPE: + case OPACITY: + return _a = {}, _a[channel] = model.scaleName(channel), _a; + } + } + function parseLegendForChannel(model, channel) { + var fieldDef = model.fieldDef(channel); + var legend = model.legend(channel); + var legendCmpt = new LegendComponent({}, getLegendDefWithScale(model, channel)); + LEGEND_PROPERTIES.forEach(function (property) { + var value = getProperty(property, legend, channel, model); + if (value !== undefined) { + var explicit = + // specified legend.values is already respected, but may get transformed. + property === 'values' ? !!legend.values : + // title can be explicit if fieldDef.title is set + property === 'title' && value === model.fieldDef(channel).title ? true : + // Otherwise, things are explicit if the returned value matches the specified property + value === legend[property]; + if (explicit || model.config.legend[property] === undefined) { + legendCmpt.set(property, value, explicit); + } + } + }); + // 2) Add mark property definition groups + var legendEncoding = legend.encoding || {}; + var legendEncode = ['labels', 'legend', 'title', 'symbols', 'gradient'].reduce(function (e, part) { + var legendEncodingPart = guideEncodeEntry(legendEncoding[part] || {}, model); + var value = encode[part] ? + // TODO: replace legendCmpt with type is sufficient + encode[part](fieldDef, legendEncodingPart, model, channel, legendCmpt.get('type')) : // apply rule + legendEncodingPart; // no rule -- just default values + if (value !== undefined && keys(value).length > 0) { + e[part] = { update: value }; + } + return e; + }, {}); + if (keys(legendEncode).length > 0) { + legendCmpt.set('encode', legendEncode, !!legend.encoding); + } + return legendCmpt; + } + function getProperty(property, specifiedLegend, channel, model) { + var fieldDef = model.fieldDef(channel); + switch (property) { + case 'format': + // We don't include temporal field here as we apply format in encode block + return numberFormat(fieldDef, specifiedLegend.format, model.config); + case 'title': + // For falsy value, keep undefined so we use default, + // but use null for '', null, and false to hide the title + var specifiedTitle = fieldDef.title !== undefined ? fieldDef.title : + specifiedLegend.title || (specifiedLegend.title === undefined ? undefined : null); + return getSpecifiedOrDefaultValue(specifiedTitle, title(fieldDef, model.config)) || undefined; // make falsy value undefined so output Vega spec is shorter + case 'values': + return values(specifiedLegend, fieldDef); + case 'type': + return getSpecifiedOrDefaultValue(specifiedLegend.type, type$2(fieldDef.type, channel, model.getScaleComponent(channel).get('type'))); + } + // Otherwise, return specified property. + return specifiedLegend[property]; + } + function parseNonUnitLegend(model) { + var _a = model.component, legends = _a.legends, resolve = _a.resolve; + var _loop_1 = function (child) { + parseLegend(child); + keys(child.component.legends).forEach(function (channel) { + resolve.legend[channel] = parseGuideResolve(model.component.resolve, channel); + if (resolve.legend[channel] === 'shared') { + // If the resolve says shared (and has not been overridden) + // We will try to merge and see if there is a conflict + legends[channel] = mergeLegendComponent(legends[channel], child.component.legends[channel]); + if (!legends[channel]) { + // If merge returns nothing, there is a conflict so we cannot make the legend shared. + // Thus, mark legend as independent and remove the legend component. + resolve.legend[channel] = 'independent'; + delete legends[channel]; + } + } + }); + }; + for (var _i = 0, _b = model.children; _i < _b.length; _i++) { + var child = _b[_i]; + _loop_1(child); + } + keys(legends).forEach(function (channel) { + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + if (!child.component.legends[channel]) { + // skip if the child does not have a particular legend + continue; + } + if (resolve.legend[channel] === 'shared') { + // After merging shared legend, make sure to remove legend from child + delete child.component.legends[channel]; + } + } + }); + return legends; + } + function mergeLegendComponent(mergedLegend, childLegend) { + if (!mergedLegend) { + return childLegend.clone(); + } + var mergedOrient = mergedLegend.getWithExplicit('orient'); + var childOrient = childLegend.getWithExplicit('orient'); + if (mergedOrient.explicit && childOrient.explicit && mergedOrient.value !== childOrient.value) { + // TODO: throw warning if resolve is explicit (We don't have info about explicit/implicit resolve yet.) + // Cannot merge due to inconsistent orient + return undefined; + } + var typeMerged = false; + var _loop_2 = function (prop) { + var mergedValueWithExplicit = mergeValuesWithExplicit(mergedLegend.getWithExplicit(prop), childLegend.getWithExplicit(prop), prop, 'legend', + // Tie breaker function + function (v1, v2) { + switch (prop) { + case 'title': + return mergeTitleComponent(v1, v2); + case 'type': + // There are only two types. If we have different types, then prefer symbol over gradient. + typeMerged = true; + return makeImplicit('symbol'); + } + return defaultTieBreaker(v1, v2, prop, 'legend'); + }); + mergedLegend.setWithExplicit(prop, mergedValueWithExplicit); + }; + // Otherwise, let's merge + for (var _i = 0, VG_LEGEND_PROPERTIES_1 = VG_LEGEND_PROPERTIES; _i < VG_LEGEND_PROPERTIES_1.length; _i++) { + var prop = VG_LEGEND_PROPERTIES_1[_i]; + _loop_2(prop); + } + if (typeMerged) { + if (((mergedLegend.implicit || {}).encode || {}).gradient) { + deleteNestedProperty(mergedLegend.implicit, ['encode', 'gradient']); + } + if (((mergedLegend.explicit || {}).encode || {}).gradient) { + deleteNestedProperty(mergedLegend.explicit, ['encode', 'gradient']); + } + } + return mergedLegend; + } + + function assembleLegends(model) { + var legendComponentIndex = model.component.legends; + var legendByDomain = {}; + for (var _i = 0, _a = keys(legendComponentIndex); _i < _a.length; _i++) { + var channel = _a[_i]; + var scaleComponent = model.getScaleComponent(channel); + var domainHash = stringify$2(scaleComponent.domains); + if (legendByDomain[domainHash]) { + for (var _b = 0, _c = legendByDomain[domainHash]; _b < _c.length; _b++) { + var mergedLegendComponent = _c[_b]; + var merged = mergeLegendComponent(mergedLegendComponent, legendComponentIndex[channel]); + if (!merged) { + // If cannot merge, need to add this legend separately + legendByDomain[domainHash].push(legendComponentIndex[channel]); + } + } + } + else { + legendByDomain[domainHash] = [legendComponentIndex[channel].clone()]; + } + } + return flatten(vals(legendByDomain)).map(function (legendCmpt) { return legendCmpt.combine(); }); + } + + function assembleProjections(model) { + if (isLayerModel(model) || isConcatModel(model) || isRepeatModel(model)) { + return assembleProjectionsForModelAndChildren(model); + } + else { + return assembleProjectionForModel(model); + } + } + function assembleProjectionsForModelAndChildren(model) { + return model.children.reduce(function (projections, child) { + return projections.concat(child.assembleProjections()); + }, assembleProjectionForModel(model)); + } + function assembleProjectionForModel(model) { + var component = model.component.projection; + if (!component || component.merged) { + return []; + } + var projection = component.combine(); + var name = projection.name, rest = __rest(projection, ["name"]); // we need to extract name so that it is always present in the output and pass TS type validation + var size = { + signal: "[" + component.size.map(function (ref) { return ref.signal; }).join(', ') + "]" + }; + var fit = component.data.reduce(function (sources, data) { + var source = isVgSignalRef(data) ? data.signal : "data('" + model.lookupDataSource(data) + "')"; + if (!contains(sources, source)) { + // build a unique list of sources + sources.push(source); + } + return sources; + }, []); + if (fit.length <= 0) { + throw new Error("Projection's fit didn't find any data sources"); + } + return [__assign({ name: name, + size: size, fit: { + signal: fit.length > 1 ? "[" + fit.join(', ') + "]" : fit[0] + } }, rest)]; + } + + var PROJECTION_PROPERTIES = [ + 'type', + 'clipAngle', + 'clipExtent', + 'center', + 'rotate', + 'precision', + 'coefficient', + 'distance', + 'fraction', + 'lobes', + 'parallel', + 'radius', + 'ratio', + 'spacing', + 'tilt' + ]; + + var ProjectionComponent = /** @class */ (function (_super) { + __extends(ProjectionComponent, _super); + function ProjectionComponent(name, specifiedProjection, size, data) { + var _this = _super.call(this, __assign({}, specifiedProjection), // all explicit properties of projection + { name: name } // name as initial implicit property + ) || this; + _this.specifiedProjection = specifiedProjection; + _this.size = size; + _this.data = data; + _this.merged = false; + return _this; + } + return ProjectionComponent; + }(Split)); + + function parseProjection(model) { + if (isUnitModel(model)) { + model.component.projection = parseUnitProjection(model); + } + else { + // because parse happens from leaves up (unit specs before layer spec), + // we can be sure that the above if statement has already occurred + // and therefore we have access to child.component.projection + // for each of model's children + model.component.projection = parseNonUnitProjections(model); + } + } + function parseUnitProjection(model) { + var specifiedProjection = model.specifiedProjection, config = model.config, hasProjection = model.hasProjection; + if (hasProjection) { + var data_1 = []; + [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach(function (posssiblePair) { + if (model.channelHasField(posssiblePair[0]) || model.channelHasField(posssiblePair[1])) { + data_1.push({ + signal: model.getName("geojson_" + data_1.length) + }); + } + }); + if (model.channelHasField(SHAPE) && model.fieldDef(SHAPE).type === GEOJSON) { + data_1.push({ + signal: model.getName("geojson_" + data_1.length) + }); + } + if (data_1.length === 0) { + // main source is geojson, so we can just use that + data_1.push(model.requestDataName(MAIN)); + } + return new ProjectionComponent(model.projectionName(true), __assign({}, (config.projection || {}), (specifiedProjection || {})), [model.getSizeSignalRef('width'), model.getSizeSignalRef('height')], data_1); + } + return undefined; + } + function mergeIfNoConflict(first, second) { + var allPropertiesShared = every(PROJECTION_PROPERTIES, function (prop) { + // neither has the poperty + if (!first.explicit.hasOwnProperty(prop) && + !second.explicit.hasOwnProperty(prop)) { + return true; + } + // both have property and an equal value for property + if (first.explicit.hasOwnProperty(prop) && + second.explicit.hasOwnProperty(prop) && + // some properties might be signals or objects and require hashing for comparison + stringify$2(first.get(prop)) === stringify$2(second.get(prop))) { + return true; + } + return false; + }); + var size = stringify$2(first.size) === stringify$2(second.size); + if (size) { + if (allPropertiesShared) { + return first; + } + else if (stringify$2(first.explicit) === stringify$2({})) { + return second; + } + else if (stringify$2(second.explicit) === stringify$2({})) { + return first; + } + } + // if all properties don't match, let each unit spec have its own projection + return null; + } + function parseNonUnitProjections(model) { + if (model.children.length === 0) { + return undefined; + } + var nonUnitProjection; + var mergable = every(model.children, function (child) { + parseProjection(child); + var projection = child.component.projection; + if (!projection) { + // child layer does not use a projection + return true; + } + else if (!nonUnitProjection) { + // cached 'projection' is null, cache this one + nonUnitProjection = projection; + return true; + } + else { + var merge = mergeIfNoConflict(nonUnitProjection, projection); + if (merge) { + nonUnitProjection = merge; + } + return !!merge; + } + }); + // it cached one and all other children share the same projection, + if (nonUnitProjection && mergable) { + // so we can elevate it to the layer level + var name_1 = model.projectionName(true); + var modelProjection_1 = new ProjectionComponent(name_1, nonUnitProjection.specifiedProjection, nonUnitProjection.size, duplicate(nonUnitProjection.data)); + // rename and assign all others as merged + model.children.forEach(function (child) { + if (child.component.projection) { + modelProjection_1.data = modelProjection_1.data.concat(child.component.projection.data); + child.renameProjection(child.component.projection.get('name'), name_1); + child.component.projection.merged = true; + } + }); + return modelProjection_1; + } + return undefined; + } + + function addDimension(dims, channel, fieldDef) { + if (fieldDef.bin) { + dims[vgField(fieldDef, {})] = true; + dims[vgField(fieldDef, { binSuffix: 'end' })] = true; + if (binRequiresRange(fieldDef, channel)) { + dims[vgField(fieldDef, { binSuffix: 'range' })] = true; + } + } + else { + dims[vgField(fieldDef)] = true; + } + return dims; + } + function mergeMeasures(parentMeasures, childMeasures) { + for (var f in childMeasures) { + if (childMeasures.hasOwnProperty(f)) { + // when we merge a measure, we either have to add an aggregation operator or even a new field + var ops = childMeasures[f]; + for (var op in ops) { + if (ops.hasOwnProperty(op)) { + if (f in parentMeasures) { + // add operator to existing measure field + parentMeasures[f][op] = ops[op]; + } + else { + parentMeasures[f] = { op: ops[op] }; + } + } + } + } + } + } + var AggregateNode = /** @class */ (function (_super) { + __extends(AggregateNode, _super); + /** + * @param dimensions string set for dimensions + * @param measures dictionary mapping field name => dict of aggregation functions and names to use + */ + function AggregateNode(parent, dimensions, measures) { + var _this = _super.call(this, parent) || this; + _this.dimensions = dimensions; + _this.measures = measures; + return _this; + } + AggregateNode.prototype.clone = function () { + return new AggregateNode(null, __assign({}, this.dimensions), duplicate(this.measures)); + }; + AggregateNode.makeFromEncoding = function (parent, model) { + var isAggregate = false; + model.forEachFieldDef(function (fd) { + if (fd.aggregate) { + isAggregate = true; + } + }); + var meas = {}; + var dims = {}; + if (!isAggregate) { + // no need to create this node if the model has no aggregation + return null; + } + model.forEachFieldDef(function (fieldDef, channel) { + var aggregate = fieldDef.aggregate, field = fieldDef.field; + if (aggregate) { + if (aggregate === 'count') { + meas['*'] = meas['*'] || {}; + meas['*']['count'] = vgField(fieldDef); + } + else { + meas[field] = meas[field] || {}; + meas[field][aggregate] = vgField(fieldDef); + // For scale channel with domain === 'unaggregated', add min/max so we can use their union as unaggregated domain + if (isScaleChannel(channel) && model.scaleDomain(channel) === 'unaggregated') { + meas[field]['min'] = vgField({ field: field, aggregate: 'min' }); + meas[field]['max'] = vgField({ field: field, aggregate: 'max' }); + } + } + } + else { + addDimension(dims, channel, fieldDef); + } + }); + if ((keys(dims).length + keys(meas).length) === 0) { + return null; + } + return new AggregateNode(parent, dims, meas); + }; + AggregateNode.makeFromTransform = function (parent, t) { + var dims = {}; + var meas = {}; + for (var _i = 0, _a = t.aggregate; _i < _a.length; _i++) { + var s = _a[_i]; + var op = s.op, field = s.field, as = s.as; + if (op) { + if (op === 'count') { + meas['*'] = meas['*'] || {}; + meas['*']['count'] = as || vgField(s); + } + else { + meas[field] = meas[field] || {}; + meas[field][op] = as || vgField(s); + } + } + } + for (var _b = 0, _c = t.groupby || []; _b < _c.length; _b++) { + var s = _c[_b]; + dims[s] = true; + } + if ((keys(dims).length + keys(meas).length) === 0) { + return null; + } + return new AggregateNode(parent, dims, meas); + }; + AggregateNode.prototype.merge = function (other) { + if (!differ(this.dimensions, other.dimensions)) { + mergeMeasures(this.measures, other.measures); + other.remove(); + } + else { + debug('different dimensions, cannot merge'); + } + }; + AggregateNode.prototype.addDimensions = function (fields) { + var _this = this; + fields.forEach(function (f) { return _this.dimensions[f] = true; }); + }; + AggregateNode.prototype.dependentFields = function () { + var out = {}; + keys(this.dimensions).forEach(function (f) { return out[f] = true; }); + keys(this.measures).forEach(function (m) { return out[m] = true; }); + return out; + }; + AggregateNode.prototype.producedFields = function () { + var _this = this; + var out = {}; + keys(this.measures).forEach(function (field) { + keys(_this.measures[field]).forEach(function (op) { + out[op + "_" + field] = true; + }); + }); + return out; + }; + AggregateNode.prototype.assemble = function () { + var ops = []; + var fields = []; + var as = []; + for (var _i = 0, _a = keys(this.measures); _i < _a.length; _i++) { + var field = _a[_i]; + for (var _b = 0, _c = keys(this.measures[field]); _b < _c.length; _b++) { + var op = _c[_b]; + as.push(this.measures[field][op]); + ops.push(op); + fields.push(field); + } + } + var result = { + type: 'aggregate', + groupby: keys(this.dimensions), + ops: ops, + fields: fields, + as: as + }; + return result; + }; + return AggregateNode; + }(DataFlowNode)); + + /** + * A node that helps us track what fields we are faceting by. + */ + var FacetNode = /** @class */ (function (_super) { + __extends(FacetNode, _super); + /** + * @param model The facet model. + * @param name The name that this facet source will have. + * @param data The source data for this facet data. + */ + function FacetNode(parent, model, name, data) { + var _this = _super.call(this, parent) || this; + _this.model = model; + _this.name = name; + _this.data = data; + for (var _i = 0, _a = [COLUMN, ROW]; _i < _a.length; _i++) { + var channel = _a[_i]; + var fieldDef = model.facet[channel]; + if (fieldDef) { + var bin = fieldDef.bin, sort = fieldDef.sort; + _this[channel] = __assign({ name: model.getName(channel + "_domain"), fields: [ + vgField(fieldDef) + ].concat((bin ? [vgField(fieldDef, { binSuffix: 'end' })] : [])) }, (isSortField(sort) ? { sortField: sort } : + isArray(sort) ? { sortIndexField: sortArrayIndexField(fieldDef, channel) } : + {})); + } + } + _this.childModel = model.child; + return _this; + } + Object.defineProperty(FacetNode.prototype, "fields", { + get: function () { + return ((this.column && this.column.fields) || []).concat((this.row && this.row.fields) || []); + }, + enumerable: true, + configurable: true + }); + /** + * The name to reference this source is its name. + */ + FacetNode.prototype.getSource = function () { + return this.name; + }; + FacetNode.prototype.getChildIndependentFieldsWithStep = function () { + var childIndependentFieldsWithStep = {}; + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var channel = _a[_i]; + var childScaleComponent = this.childModel.component.scales[channel]; + if (childScaleComponent && !childScaleComponent.merged) { + var type = childScaleComponent.get('type'); + var range = childScaleComponent.get('range'); + if (hasDiscreteDomain(type) && isVgRangeStep(range)) { + var domain = assembleDomain(this.childModel, channel); + var field$$1 = getFieldFromDomain(domain); + if (field$$1) { + childIndependentFieldsWithStep[channel] = field$$1; + } + else { + warn('Unknown field for ${channel}. Cannot calculate view size.'); + } + } + } + } + return childIndependentFieldsWithStep; + }; + FacetNode.prototype.assembleRowColumnData = function (channel, crossedDataName, childIndependentFieldsWithStep) { + var childChannel = channel === 'row' ? 'y' : 'x'; + var fields = []; + var ops = []; + var as = []; + if (childIndependentFieldsWithStep[childChannel]) { + if (crossedDataName) { + // If there is a crossed data, calculate max + fields.push("distinct_" + childIndependentFieldsWithStep[childChannel]); + ops.push('max'); + } + else { + // If there is no crossed data, just calculate distinct + fields.push(childIndependentFieldsWithStep[childChannel]); + ops.push('distinct'); + } + // Although it is technically a max, just name it distinct so it's easier to refer to it + as.push("distinct_" + childIndependentFieldsWithStep[childChannel]); + } + var _a = this[channel], sortField = _a.sortField, sortIndexField = _a.sortIndexField; + if (sortField) { + var op = sortField.op, field$$1 = sortField.field; + fields.push(field$$1); + ops.push(op); + as.push(vgField(sortField)); + } + else if (sortIndexField) { + fields.push(sortIndexField); + ops.push('max'); + as.push(sortIndexField); + } + return { + name: this[channel].name, + // Use data from the crossed one if it exist + source: crossedDataName || this.data, + transform: [__assign({ type: 'aggregate', groupby: this[channel].fields }, (fields.length ? { + fields: fields, ops: ops, as: as + } : {}))] + }; + }; + FacetNode.prototype.assemble = function () { + var data = []; + var crossedDataName = null; + var childIndependentFieldsWithStep = this.getChildIndependentFieldsWithStep(); + if (this.column && this.row && (childIndependentFieldsWithStep.x || childIndependentFieldsWithStep.y)) { + // Need to create a cross dataset to correctly calculate cardinality + crossedDataName = "cross_" + this.column.name + "_" + this.row.name; + var fields = [].concat(childIndependentFieldsWithStep.x ? [childIndependentFieldsWithStep.x] : [], childIndependentFieldsWithStep.y ? [childIndependentFieldsWithStep.y] : []); + var ops = fields.map(function () { return 'distinct'; }); + data.push({ + name: crossedDataName, + source: this.data, + transform: [{ + type: 'aggregate', + groupby: this.column.fields.concat(this.row.fields), + fields: fields, + ops: ops + }] + }); + } + for (var _i = 0, _a = [COLUMN, ROW]; _i < _a.length; _i++) { + var channel = _a[_i]; + if (this[channel]) { + data.push(this.assembleRowColumnData(channel, crossedDataName, childIndependentFieldsWithStep)); + } + } + return data; + }; + return FacetNode; + }(DataFlowNode)); + + var FilterInvalidNode = /** @class */ (function (_super) { + __extends(FilterInvalidNode, _super); + function FilterInvalidNode(parent, fieldDefs) { + var _this = _super.call(this, parent) || this; + _this.fieldDefs = fieldDefs; + return _this; + } + FilterInvalidNode.prototype.clone = function () { + return new FilterInvalidNode(null, __assign({}, this.fieldDefs)); + }; + FilterInvalidNode.make = function (parent, model) { + var config = model.config, mark = model.mark; + if (config.invalidValues !== 'filter') { + return null; + } + var filter = model.reduceFieldDef(function (aggregator, fieldDef, channel) { + var scaleComponent = isScaleChannel(channel) && model.getScaleComponent(channel); + if (scaleComponent) { + var scaleType = scaleComponent.get('type'); + // While discrete domain scales can handle invalid values, continuous scales can't. + // Thus, for non-path marks, we have to filter null for scales with continuous domains. + // (For path marks, we will use "defined" property and skip these values instead.) + if (hasContinuousDomain(scaleType) && !fieldDef.aggregate && !isPathMark(mark)) { + aggregator[fieldDef.field] = fieldDef; + } + } + return aggregator; + }, {}); + if (!keys(filter).length) { + return null; + } + return new FilterInvalidNode(parent, filter); + }; + Object.defineProperty(FilterInvalidNode.prototype, "filter", { + get: function () { + return this.fieldDefs; + }, + enumerable: true, + configurable: true + }); + // create the VgTransforms for each of the filtered fields + FilterInvalidNode.prototype.assemble = function () { + var _this = this; + var filters = keys(this.filter).reduce(function (vegaFilters, field) { + var fieldDef = _this.fieldDefs[field]; + var ref = vgField(fieldDef, { expr: 'datum' }); + if (fieldDef !== null) { + vegaFilters.push(ref + " !== null"); + vegaFilters.push("!isNaN(" + ref + ")"); + } + return vegaFilters; + }, []); + return filters.length > 0 ? + { + type: 'filter', + expr: filters.join(' && ') + } : null; + }; + return FilterInvalidNode; + }(DataFlowNode)); + + /** + * @param field The field. + * @param parse What to parse the field as. + */ + function parseExpression(field$$1, parse) { + var f = accessPathWithDatum(field$$1); + if (parse === 'number') { + return "toNumber(" + f + ")"; + } + else if (parse === 'boolean') { + return "toBoolean(" + f + ")"; + } + else if (parse === 'string') { + return "toString(" + f + ")"; + } + else if (parse === 'date') { + return "toDate(" + f + ")"; + } + else if (parse === 'flatten') { + return f; + } + else if (parse.indexOf('date:') === 0) { + var specifier = parse.slice(5, parse.length); + return "timeParse(" + f + "," + specifier + ")"; + } + else if (parse.indexOf('utc:') === 0) { + var specifier = parse.slice(4, parse.length); + return "utcParse(" + f + "," + specifier + ")"; + } + else { + warn(message.unrecognizedParse(parse)); + return null; + } + } + var ParseNode = /** @class */ (function (_super) { + __extends(ParseNode, _super); + function ParseNode(parent, parse) { + var _this = _super.call(this, parent) || this; + _this._parse = parse; + return _this; + } + ParseNode.prototype.clone = function () { + return new ParseNode(null, duplicate(this._parse)); + }; + /** + * Creates a parse node from a data.format.parse and updates ancestorParse. + */ + ParseNode.makeExplicit = function (parent, model, ancestorParse) { + // Custom parse + var explicit = {}; + var data = model.data; + if (data && data.format && data.format.parse) { + explicit = data.format.parse; + } + return this.makeWithAncestors(parent, explicit, {}, ancestorParse); + }; + ParseNode.makeImplicitFromFilterTransform = function (parent, transform, ancestorParse) { + var parse = {}; + forEachLeaf(transform.filter, function (filter) { + if (isFieldPredicate(filter)) { + // Automatically add a parse node for filters with filter objects + var val = null; + // For EqualFilter, just use the equal property. + // For RangeFilter and OneOfFilter, all array members should have + // the same type, so we only use the first one. + if (isFieldEqualPredicate(filter)) { + val = filter.equal; + } + else if (isFieldRangePredicate(filter)) { + val = filter.range[0]; + } + else if (isFieldOneOfPredicate(filter)) { + val = (filter.oneOf || filter['in'])[0]; + } // else -- for filter expression, we can't infer anything + if (val) { + if (isDateTime(val)) { + parse[filter.field] = 'date'; + } + else if (isNumber(val)) { + parse[filter.field] = 'number'; + } + else if (isString(val)) { + parse[filter.field] = 'string'; + } + } + if (filter.timeUnit) { + parse[filter.field] = 'date'; + } + } + }); + if (keys(parse).length === 0) { + return null; + } + return this.makeWithAncestors(parent, {}, parse, ancestorParse); + }; + /** + * Creates a parse node for implicit parsing from a model and updates ancestorParse. + */ + ParseNode.makeImplicitFromEncoding = function (parent, model, ancestorParse) { + var implicit = {}; + if (isUnitModel(model) || isFacetModel(model)) { + // Parse encoded fields + model.forEachFieldDef(function (fieldDef) { + if (isTimeFieldDef(fieldDef)) { + implicit[fieldDef.field] = 'date'; + } + else if (isNumberFieldDef(fieldDef)) { + if (!isCountingAggregateOp(fieldDef.aggregate)) { + implicit[fieldDef.field] = 'number'; + } + } + else if (accessPathDepth(fieldDef.field) > 1) { + // For non-date/non-number (strings and booleans), derive a flattened field for a referenced nested field. + // (Parsing numbers / dates already flattens numeric and temporal fields.) + if (!(fieldDef.field in implicit)) { + implicit[fieldDef.field] = 'flatten'; + } + } + else if (isScaleFieldDef(fieldDef) && isSortField(fieldDef.sort) && accessPathDepth(fieldDef.sort.field) > 1) { + // Flatten fields that we sort by but that are not otherwise flattened. + if (!(fieldDef.sort.field in implicit)) { + implicit[fieldDef.sort.field] = 'flatten'; + } + } + }); + } + return this.makeWithAncestors(parent, {}, implicit, ancestorParse); + }; + /** + * Creates a parse node from "explicit" parse and "implicit" parse and updates ancestorParse. + */ + ParseNode.makeWithAncestors = function (parent, explicit, implicit, ancestorParse) { + // We should not parse what has already been parsed in a parent (explicitly or implicitly) or what has been derived (maked as "derived"). We also don't need to flatten a field that has already been parsed. + for (var _i = 0, _a = keys(implicit); _i < _a.length; _i++) { + var field$$1 = _a[_i]; + var parsedAs = ancestorParse.getWithExplicit(field$$1); + if (parsedAs.value !== undefined) { + // We always ignore derived fields even if they are implicitly defined because we expect users to create the right types. + if (parsedAs.explicit || parsedAs.value === implicit[field$$1] || parsedAs.value === 'derived' || implicit[field$$1] === 'flatten') { + delete implicit[field$$1]; + } + else { + warn(message.differentParse(field$$1, implicit[field$$1], parsedAs.value)); + } + } + } + for (var _b = 0, _c = keys(explicit); _b < _c.length; _b++) { + var field$$1 = _c[_b]; + var parsedAs = ancestorParse.get(field$$1); + if (parsedAs !== undefined) { + // Don't parse a field again if it has been parsed with the same type already. + if (parsedAs === explicit[field$$1]) { + delete explicit[field$$1]; + } + else { + warn(message.differentParse(field$$1, explicit[field$$1], parsedAs)); + } + } + } + var parse = new Split(explicit, implicit); + // add the format parse from this model so that children don't parse the same field again + ancestorParse.copyAll(parse); + // copy only non-null parses + var p = {}; + for (var _d = 0, _e = keys(parse.combine()); _d < _e.length; _d++) { + var key$$1 = _e[_d]; + var val = parse.get(key$$1); + if (val !== null) { + p[key$$1] = val; + } + } + if (keys(p).length === 0 || ancestorParse.parseNothing) { + return null; + } + return new ParseNode(parent, p); + }; + Object.defineProperty(ParseNode.prototype, "parse", { + get: function () { + return this._parse; + }, + enumerable: true, + configurable: true + }); + ParseNode.prototype.merge = function (other) { + this._parse = __assign({}, this._parse, other.parse); + other.remove(); + }; + /** + * Assemble an object for Vega's format.parse property. + */ + ParseNode.prototype.assembleFormatParse = function () { + var formatParse = {}; + for (var _i = 0, _a = keys(this._parse); _i < _a.length; _i++) { + var field$$1 = _a[_i]; + var p = this._parse[field$$1]; + if (accessPathDepth(field$$1) === 1) { + formatParse[field$$1] = p; + } + } + return formatParse; + }; + // format parse depends and produces all fields in its parse + ParseNode.prototype.producedFields = function () { + return toSet(keys(this._parse)); + }; + ParseNode.prototype.dependentFields = function () { + return toSet(keys(this._parse)); + }; + ParseNode.prototype.assembleTransforms = function (onlyNested) { + var _this = this; + if (onlyNested === void 0) { onlyNested = false; } + return keys(this._parse) + .filter(function (field$$1) { return onlyNested ? accessPathDepth(field$$1) > 1 : true; }) + .map(function (field$$1) { + var expr = parseExpression(field$$1, _this._parse[field$$1]); + if (!expr) { + return null; + } + var formula = { + type: 'formula', + expr: expr, + as: removePathFromField(field$$1) // Vega output is always flattened + }; + return formula; + }).filter(function (t) { return t !== null; }); + }; + return ParseNode; + }(DataFlowNode)); + + var SourceNode = /** @class */ (function (_super) { + __extends(SourceNode, _super); + function SourceNode(data) { + var _this = _super.call(this, null) || this; + data = data || { name: 'source' }; + if (isInlineData(data)) { + _this._data = { values: data.values }; + } + else if (isUrlData(data)) { + _this._data = { url: data.url }; + if (!data.format) { + data.format = {}; + } + if (!data.format || !data.format.type) { + // Extract extension from URL using snippet from + // http://stackoverflow.com/questions/680929/how-to-extract-extension-from-filename-string-in-javascript + var defaultExtension = /(?:\.([^.]+))?$/.exec(data.url)[1]; + if (!contains(['json', 'csv', 'tsv', 'dsv', 'topojson'], defaultExtension)) { + defaultExtension = 'json'; + } + // defaultExtension has type string but we ensure that it is DataFormatType above + data.format.type = defaultExtension; + } + } + else if (isNamedData(data)) { + _this._data = {}; + } + // any dataset can be named + if (data.name) { + _this._name = data.name; + } + if (data.format) { + var _a = data.format, _b = _a.parse, format = __rest(_a, ["parse"]); + _this._data.format = format; + } + return _this; + } + Object.defineProperty(SourceNode.prototype, "data", { + get: function () { + return this._data; + }, + enumerable: true, + configurable: true + }); + SourceNode.prototype.hasName = function () { + return !!this._name; + }; + Object.defineProperty(SourceNode.prototype, "dataName", { + get: function () { + return this._name; + }, + set: function (name) { + this._name = name; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SourceNode.prototype, "parent", { + set: function (parent) { + throw new Error('Source nodes have to be roots.'); + }, + enumerable: true, + configurable: true + }); + SourceNode.prototype.remove = function () { + throw new Error('Source nodes are roots and cannot be removed.'); + }; + /** + * Return a unique identifier for this data source. + */ + SourceNode.prototype.hash = function () { + if (isInlineData(this._data)) { + if (!this._hash) { + // Hashing can be expensive for large inline datasets. + this._hash = hash(this._data); + } + return this._hash; + } + else if (isUrlData(this._data)) { + return hash([this._data.url, this._data.format]); + } + else { + return this._name; + } + }; + SourceNode.prototype.assemble = function () { + return __assign({ name: this._name }, this._data, { transform: [] }); + }; + return SourceNode; + }(DataFlowNode)); + + var TimeUnitNode = /** @class */ (function (_super) { + __extends(TimeUnitNode, _super); + function TimeUnitNode(parent, formula) { + var _this = _super.call(this, parent) || this; + _this.formula = formula; + return _this; + } + TimeUnitNode.prototype.clone = function () { + return new TimeUnitNode(null, duplicate(this.formula)); + }; + TimeUnitNode.makeFromEncoding = function (parent, model) { + var formula = model.reduceFieldDef(function (timeUnitComponent, fieldDef) { + if (fieldDef.timeUnit) { + var f = vgField(fieldDef); + timeUnitComponent[f] = { + as: f, + timeUnit: fieldDef.timeUnit, + field: fieldDef.field + }; + } + return timeUnitComponent; + }, {}); + if (keys(formula).length === 0) { + return null; + } + return new TimeUnitNode(parent, formula); + }; + TimeUnitNode.makeFromTransform = function (parent, t) { + var _a; + return new TimeUnitNode(parent, (_a = {}, + _a[t.field] = { + as: t.as, + timeUnit: t.timeUnit, + field: t.field + }, + _a)); + }; + TimeUnitNode.prototype.merge = function (other) { + this.formula = __assign({}, this.formula, other.formula); + other.remove(); + }; + TimeUnitNode.prototype.producedFields = function () { + var out = {}; + vals(this.formula).forEach(function (f) { + out[f.as] = true; + }); + return out; + }; + TimeUnitNode.prototype.dependentFields = function () { + var out = {}; + vals(this.formula).forEach(function (f) { + out[f.field] = true; + }); + return out; + }; + TimeUnitNode.prototype.assemble = function () { + return vals(this.formula).map(function (c) { + return { + type: 'formula', + as: c.as, + expr: fieldExpr(c.timeUnit, c.field) + }; + }); + }; + return TimeUnitNode; + }(DataFlowNode)); + + /** + * Start optimization path at the leaves. Useful for merging up or removing things. + * + * If the callback returns true, the recursion continues. + */ + function iterateFromLeaves(f) { + function optimizeNextFromLeaves(node) { + if (node instanceof SourceNode) { + return; + } + var next = node.parent; + if (f(node)) { + optimizeNextFromLeaves(next); + } + } + return optimizeNextFromLeaves; + } + /** + * Move parse nodes up to forks. + */ + function moveParseUp(node) { + var parent = node.parent; + // move parse up by merging or swapping + if (node instanceof ParseNode) { + if (parent instanceof SourceNode) { + return false; + } + if (parent.numChildren() > 1) { + // don't move parse further up but continue with parent. + return true; + } + if (parent instanceof ParseNode) { + parent.merge(node); + } + else { + // don't swap with nodes that produce something that the parse node depends on (e.g. lookup) + if (hasIntersection(parent.producedFields(), node.dependentFields())) { + return true; + } + node.swapWithParent(); + } + } + return true; + } + /** + * Repeatedly remove leaf nodes that are not output or facet nodes. + * The reason is that we don't need subtrees that don't have any output nodes. + * Facet nodes are needed for the row or column domains. + */ + function removeUnusedSubtrees(node) { + if (node instanceof OutputNode || node.numChildren() > 0 || node instanceof FacetNode) { + // no need to continue with parent because it is output node or will have children (there was a fork) + return false; + } + else { + node.remove(); + } + return true; + } + /** + * Removes duplicate time unit nodes (as determined by the name of the + * output field) that may be generated due to selections projected over + * time units. + */ + function removeDuplicateTimeUnits(leaf) { + var fields = {}; + return iterateFromLeaves(function (node) { + if (node instanceof TimeUnitNode) { + var pfields = node.producedFields(); + var dupe = keys(pfields).every(function (k) { return !!fields[k]; }); + if (dupe) { + node.remove(); + } + else { + fields = __assign({}, fields, pfields); + } + } + return true; + })(leaf); + } + + function getStackByFields(model) { + return model.stack.stackBy.reduce(function (fields, by) { + var fieldDef = by.fieldDef; + var _field = vgField(fieldDef); + if (_field) { + fields.push(_field); + } + return fields; + }, []); + } + function isValidAsArray(as) { + return isArray(as) && as.every(function (s) { return isString(s); }) && as.length > 1; + } + var StackNode = /** @class */ (function (_super) { + __extends(StackNode, _super); + function StackNode(parent, stack) { + var _this = _super.call(this, parent) || this; + _this._stack = stack; + return _this; + } + StackNode.prototype.clone = function () { + return new StackNode(null, duplicate(this._stack)); + }; + StackNode.makeFromTransform = function (parent, stackTransform) { + var stack = stackTransform.stack, groupby = stackTransform.groupby, as = stackTransform.as, _a = stackTransform.offset, offset = _a === void 0 ? 'zero' : _a; + var sortFields = []; + var sortOrder = []; + if (stackTransform.sort !== undefined) { + for (var _i = 0, _b = stackTransform.sort; _i < _b.length; _i++) { + var sortField = _b[_i]; + sortFields.push(sortField.field); + sortOrder.push(sortField.order === undefined ? 'ascending' : sortField.order); + } + } + var sort = { + field: sortFields, + order: sortOrder, + }; + var normalizedAs; + if (isValidAsArray(as)) { + normalizedAs = as; + } + else if (isString(as)) { + normalizedAs = [as, as + '_end']; + } + else { + normalizedAs = [stackTransform.stack + '_start', stackTransform.stack + '_end']; + } + return new StackNode(parent, { + stackField: stack, + groupby: groupby, + offset: offset, + sort: sort, + facetby: [], + as: normalizedAs + }); + }; + StackNode.makeFromEncoding = function (parent, model) { + var stackProperties = model.stack; + if (!stackProperties) { + return null; + } + var dimensionFieldDef; + if (stackProperties.groupbyChannel) { + dimensionFieldDef = model.fieldDef(stackProperties.groupbyChannel); + } + var stackby = getStackByFields(model); + var orderDef = model.encoding.order; + var sort; + if (isArray(orderDef) || isFieldDef(orderDef)) { + sort = sortParams(orderDef); + } + else { + // default = descending by stackFields + // FIXME is the default here correct for binned fields? + sort = stackby.reduce(function (s, field$$1) { + s.field.push(field$$1); + s.order.push('descending'); + return s; + }, { field: [], order: [] }); + } + // Refactored to add "as" in the make phase so that we can get producedFields + // from the as property + var field$$1 = model.vgField(stackProperties.fieldChannel); + return new StackNode(parent, { + dimensionFieldDef: dimensionFieldDef, + stackField: field$$1, + facetby: [], + stackby: stackby, + sort: sort, + offset: stackProperties.offset, + impute: stackProperties.impute, + as: [field$$1 + '_start', field$$1 + '_end'] + }); + }; + Object.defineProperty(StackNode.prototype, "stack", { + get: function () { + return this._stack; + }, + enumerable: true, + configurable: true + }); + StackNode.prototype.addDimensions = function (fields) { + this._stack.facetby = this._stack.facetby.concat(fields); + }; + StackNode.prototype.dependentFields = function () { + var out = {}; + out[this._stack.stackField] = true; + this.getGroupbyFields().forEach(function (f) { return out[f] = true; }); + this._stack.facetby.forEach(function (f) { return out[f] = true; }); + var field$$1 = this._stack.sort.field; + isArray(field$$1) ? field$$1.forEach(function (f) { return out[f] = true; }) : out[field$$1] = true; + return out; + }; + StackNode.prototype.producedFields = function () { + return this._stack.as.reduce(function (result, item) { + result[item] = true; + return result; + }, {}); + }; + StackNode.prototype.getGroupbyFields = function () { + var _a = this._stack, dimensionFieldDef = _a.dimensionFieldDef, impute = _a.impute, groupby = _a.groupby; + if (dimensionFieldDef) { + if (dimensionFieldDef.bin) { + if (impute) { + // For binned group by field with impute, we calculate bin_mid + // as we cannot impute two fields simultaneously + return [vgField(dimensionFieldDef, { binSuffix: 'mid' })]; + } + return [ + // For binned group by field without impute, we need both bin (start) and bin_end + vgField(dimensionFieldDef, {}), + vgField(dimensionFieldDef, { binSuffix: 'end' }) + ]; + } + return [vgField(dimensionFieldDef)]; + } + return groupby || []; + }; + StackNode.prototype.assemble = function () { + var transform = []; + var _a = this._stack, facetby = _a.facetby, dimensionFieldDef = _a.dimensionFieldDef, field$$1 = _a.stackField, stackby = _a.stackby, sort = _a.sort, offset = _a.offset, impute = _a.impute, as = _a.as; + // Impute + if (impute && dimensionFieldDef) { + var dimensionField = dimensionFieldDef ? vgField(dimensionFieldDef, { binSuffix: 'mid' }) : undefined; + if (dimensionFieldDef.bin) { + // As we can only impute one field at a time, we need to calculate + // mid point for a binned field + transform.push({ + type: 'formula', + expr: '(' + + vgField(dimensionFieldDef, { expr: 'datum' }) + + '+' + + vgField(dimensionFieldDef, { expr: 'datum', binSuffix: 'end' }) + + ')/2', + as: dimensionField + }); + } + transform.push({ + type: 'impute', + field: field$$1, + groupby: stackby, + key: dimensionField, + method: 'value', + value: 0 + }); + } + // Stack + transform.push({ + type: 'stack', + groupby: this.getGroupbyFields().concat(facetby), + field: field$$1, + sort: sort, + as: as, + offset: offset + }); + return transform; + }; + return StackNode; + }(DataFlowNode)); + + var FACET_SCALE_PREFIX = 'scale_'; + /** + * Clones the subtree and ignores output nodes except for the leafs, which are renamed. + */ + function cloneSubtree(facet) { + function clone(node) { + if (!(node instanceof FacetNode)) { + var copy_1 = node.clone(); + if (copy_1 instanceof OutputNode) { + var newName = FACET_SCALE_PREFIX + copy_1.getSource(); + copy_1.setSource(newName); + facet.model.component.data.outputNodes[newName] = copy_1; + } + else if (copy_1 instanceof AggregateNode || copy_1 instanceof StackNode) { + copy_1.addDimensions(facet.fields); + } + flatten(node.children.map(clone)).forEach(function (n) { return n.parent = copy_1; }); + return [copy_1]; + } + return flatten(node.children.map(clone)); + } + return clone; + } + /** + * Move facet nodes down to the next fork or output node. Also pull the main output with the facet node. + * After moving down the facet node, make a copy of the subtree and make it a child of the main output. + */ + function moveFacetDown(node) { + if (node instanceof FacetNode) { + if (node.numChildren() === 1 && !(node.children[0] instanceof OutputNode)) { + // move down until we hit a fork or output node + var child = node.children[0]; + if (child instanceof AggregateNode || child instanceof StackNode) { + child.addDimensions(node.fields); + } + child.swapWithParent(); + moveFacetDown(node); + } + else { + // move main to facet + moveMainDownToFacet(node.model.component.data.main); + // replicate the subtree and place it before the facet's main node + var copy = flatten(node.children.map(cloneSubtree(node))); + copy.forEach(function (c) { return c.parent = node.model.component.data.main; }); + } + } + else { + node.children.forEach(moveFacetDown); + } + } + function moveMainDownToFacet(node) { + if (node instanceof OutputNode && node.type === MAIN) { + if (node.numChildren() === 1) { + var child = node.children[0]; + if (!(child instanceof FacetNode)) { + child.swapWithParent(); + moveMainDownToFacet(node); + } + } + } + } + /** + * Remove nodes that are not required starting from a root. + */ + function removeUnnecessaryNodes(node) { + // remove empty null filter nodes + if (node instanceof FilterInvalidNode && every(vals(node.filter), function (f) { return f === null; })) { + node.remove(); + } + // remove output nodes that are not required + if (node instanceof OutputNode && !node.isRequired()) { + node.remove(); + } + node.children.forEach(removeUnnecessaryNodes); + } + /** + * Return all leaf nodes. + */ + function getLeaves(roots) { + var leaves = []; + function append(node) { + if (node.numChildren() === 0) { + leaves.push(node); + } + else { + node.children.forEach(append); + } + } + roots.forEach(append); + return leaves; + } + /** + * Optimizes the dataflow of the passed in data component. + */ + function optimizeDataflow(dataComponent) { + var roots = vals(dataComponent.sources); + roots.forEach(removeUnnecessaryNodes); + // remove source nodes that don't have any children because they also don't have output nodes + roots = roots.filter(function (r) { return r.numChildren() > 0; }); + getLeaves(roots).forEach(iterateFromLeaves(removeUnusedSubtrees)); + roots = roots.filter(function (r) { return r.numChildren() > 0; }); + getLeaves(roots).forEach(iterateFromLeaves(moveParseUp)); + getLeaves(roots).forEach(removeDuplicateTimeUnits); + roots.forEach(moveFacetDown); + keys(dataComponent.sources).forEach(function (s) { + if (dataComponent.sources[s].numChildren() === 0) { + delete dataComponent.sources[s]; + } + }); + } + + function parseScaleDomain(model) { + if (isUnitModel(model)) { + parseUnitScaleDomain(model); + } + else { + parseNonUnitScaleDomain(model); + } + } + function parseUnitScaleDomain(model) { + var scales = model.specifiedScales; + var localScaleComponents = model.component.scales; + keys(localScaleComponents).forEach(function (channel) { + var specifiedScale = scales[channel]; + var specifiedDomain = specifiedScale ? specifiedScale.domain : undefined; + var domains = parseDomainForChannel(model, channel); + var localScaleCmpt = localScaleComponents[channel]; + localScaleCmpt.domains = domains; + if (isSelectionDomain(specifiedDomain)) { + // As scale parsing occurs before selection parsing, we use a temporary + // signal here and append the scale.domain definition. This is replaced + // with the correct domainRaw signal during scale assembly. + // For more information, see isRawSelectionDomain in selection.ts. + // FIXME: replace this with a special property in the scaleComponent + localScaleCmpt.set('domainRaw', { + signal: SELECTION_DOMAIN + hash(specifiedDomain) + }, true); + } + if (model.component.data.isFaceted) { + // get resolve from closest facet parent as this decides whether we need to refer to cloned subtree or not + var facetParent = model; + while (!isFacetModel(facetParent) && facetParent.parent) { + facetParent = facetParent.parent; + } + var resolve = facetParent.component.resolve.scale[channel]; + if (resolve === 'shared') { + for (var _i = 0, domains_1 = domains; _i < domains_1.length; _i++) { + var domain = domains_1[_i]; + // Replace the scale domain with data output from a cloned subtree after the facet. + if (isDataRefDomain(domain)) { + // use data from cloned subtree (which is the same as data but with a prefix added once) + domain.data = FACET_SCALE_PREFIX + domain.data.replace(FACET_SCALE_PREFIX, ''); + } + } + } + } + }); + } + function parseNonUnitScaleDomain(model) { + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + parseScaleDomain(child); + } + var localScaleComponents = model.component.scales; + keys(localScaleComponents).forEach(function (channel) { + var domains; + var domainRaw = null; + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + var childComponent = child.component.scales[channel]; + if (childComponent) { + if (domains === undefined) { + domains = childComponent.domains; + } + else { + domains = domains.concat(childComponent.domains); + } + var dr = childComponent.get('domainRaw'); + if (domainRaw && dr && domainRaw.signal !== dr.signal) { + warn('The same selection must be used to override scale domains in a layered view.'); + } + domainRaw = dr; + } + } + localScaleComponents[channel].domains = domains; + if (domainRaw) { + localScaleComponents[channel].set('domainRaw', domainRaw, true); + } + }); + } + /** + * Remove unaggregated domain if it is not applicable + * Add unaggregated domain if domain is not specified and config.scale.useUnaggregatedDomain is true. + */ + function normalizeUnaggregatedDomain(domain, fieldDef, scaleType, scaleConfig) { + if (domain === 'unaggregated') { + var _a = canUseUnaggregatedDomain(fieldDef, scaleType), valid = _a.valid, reason = _a.reason; + if (!valid) { + warn(reason); + return undefined; + } + } + else if (domain === undefined && scaleConfig.useUnaggregatedDomain) { + // Apply config if domain is not specified. + var valid = canUseUnaggregatedDomain(fieldDef, scaleType).valid; + if (valid) { + return 'unaggregated'; + } + } + return domain; + } + function parseDomainForChannel(model, channel) { + var scaleType = model.getScaleComponent(channel).get('type'); + var domain = normalizeUnaggregatedDomain(model.scaleDomain(channel), model.fieldDef(channel), scaleType, model.config.scale); + if (domain !== model.scaleDomain(channel)) { + model.specifiedScales[channel] = __assign({}, model.specifiedScales[channel], { domain: domain }); + } + // If channel is either X or Y then union them with X2 & Y2 if they exist + if (channel === 'x' && model.channelHasField('x2')) { + if (model.channelHasField('x')) { + return parseSingleChannelDomain(scaleType, domain, model, 'x').concat(parseSingleChannelDomain(scaleType, domain, model, 'x2')); + } + else { + return parseSingleChannelDomain(scaleType, domain, model, 'x2'); + } + } + else if (channel === 'y' && model.channelHasField('y2')) { + if (model.channelHasField('y')) { + return parseSingleChannelDomain(scaleType, domain, model, 'y').concat(parseSingleChannelDomain(scaleType, domain, model, 'y2')); + } + else { + return parseSingleChannelDomain(scaleType, domain, model, 'y2'); + } + } + return parseSingleChannelDomain(scaleType, domain, model, channel); + } + function mapDomainToDataSignal(domain, type, timeUnit) { + return domain.map(function (v) { + var data = valueExpr(v, { timeUnit: timeUnit, type: type }); + return { signal: "{data: " + data + "}" }; + }); + } + function parseSingleChannelDomain(scaleType, domain, model, channel) { + var fieldDef = model.fieldDef(channel); + if (domain && domain !== 'unaggregated' && !isSelectionDomain(domain)) { // explicit value + var type = fieldDef.type, timeUnit = fieldDef.timeUnit; + if (type === 'temporal' || timeUnit) { + return mapDomainToDataSignal(domain, type, timeUnit); + } + return [domain]; + } + var stack = model.stack; + if (stack && channel === stack.fieldChannel) { + if (stack.offset === 'normalize') { + return [[0, 1]]; + } + var data = model.requestDataName(MAIN); + return [{ + data: data, + field: model.vgField(channel, { suffix: 'start' }) + }, { + data: data, + field: model.vgField(channel, { suffix: 'end' }) + }]; + } + var sort = isScaleChannel(channel) ? domainSort(model, channel, scaleType) : undefined; + if (domain === 'unaggregated') { + var data = model.requestDataName(MAIN); + var field$$1 = fieldDef.field; + return [{ + data: data, + field: vgField({ field: field$$1, aggregate: 'min' }) + }, { + data: data, + field: vgField({ field: field$$1, aggregate: 'max' }) + }]; + } + else if (fieldDef.bin) { // bin + if (isBinScale(scaleType)) { + var signal = model.getName(binToString(fieldDef.bin) + "_" + fieldDef.field + "_bins"); + return [{ signal: "sequence(" + signal + ".start, " + signal + ".stop + " + signal + ".step, " + signal + ".step)" }]; + } + if (hasDiscreteDomain(scaleType)) { + // ordinal bin scale takes domain from bin_range, ordered by bin start + // This is useful for both axis-based scale (x/y) and legend-based scale (other channels). + return [{ + // If sort by aggregation of a specified sort field, we need to use RAW table, + // so we can aggregate values for the scale independently from the main aggregation. + data: isBoolean$1(sort) ? model.requestDataName(MAIN) : model.requestDataName(RAW), + // Use range if we added it and the scale does not support computing a range as a signal. + field: model.vgField(channel, binRequiresRange(fieldDef, channel) ? { binSuffix: 'range' } : {}), + // we have to use a sort object if sort = true to make the sort correct by bin start + sort: sort === true || !isSortField(sort) ? { + field: model.vgField(channel, {}), + op: 'min' // min or max doesn't matter since we sort by the start of the bin range + } : sort + }]; + } + else { // continuous scales + if (channel === 'x' || channel === 'y') { + if (isBinParams(fieldDef.bin) && fieldDef.bin.extent) { + return [fieldDef.bin.extent]; + } + // X/Y position have to include start and end for non-ordinal scale + var data = model.requestDataName(MAIN); + return [{ + data: data, + field: model.vgField(channel, {}) + }, { + data: data, + field: model.vgField(channel, { binSuffix: 'end' }) + }]; + } + else { + // TODO: use bin_mid + return [{ + data: model.requestDataName(MAIN), + field: model.vgField(channel, {}) + }]; + } + } + } + else if (sort) { + return [{ + // If sort by aggregation of a specified sort field, we need to use RAW table, + // so we can aggregate values for the scale independently from the main aggregation. + data: isBoolean$1(sort) ? model.requestDataName(MAIN) : model.requestDataName(RAW), + field: model.vgField(channel), + sort: sort + }]; + } + else { + return [{ + data: model.requestDataName(MAIN), + field: model.vgField(channel) + }]; + } + } + function domainSort(model, channel, scaleType) { + if (!hasDiscreteDomain(scaleType)) { + return undefined; + } + var fieldDef = model.fieldDef(channel); + var sort = fieldDef.sort; + // if the sort is specified with array, use the derived sort index field + if (isSortArray(sort)) { + return { + op: 'min', + field: sortArrayIndexField(fieldDef, channel), + order: 'ascending' + }; + } + // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale) + if (isSortField(sort)) { + // flatten nested fields + return __assign({}, sort, (sort.field ? { field: replacePathInField(sort.field) } : {})); + } + if (sort === 'descending') { + return { + op: 'min', + field: model.vgField(channel), + order: 'descending' + }; + } + if (contains(['ascending', undefined /* default =ascending*/], sort)) { + return true; + } + // sort == null + return undefined; + } + /** + * Determine if a scale can use unaggregated domain. + * @return {Boolean} Returns true if all of the following conditons applies: + * 1. `scale.domain` is `unaggregated` + * 2. Aggregation function is not `count` or `sum` + * 3. The scale is quantitative or time scale. + */ + function canUseUnaggregatedDomain(fieldDef, scaleType) { + if (!fieldDef.aggregate) { + return { + valid: false, + reason: message.unaggregateDomainHasNoEffectForRawField(fieldDef) + }; + } + if (!SHARED_DOMAIN_OP_INDEX[fieldDef.aggregate]) { + return { + valid: false, + reason: message.unaggregateDomainWithNonSharedDomainOp(fieldDef.aggregate) + }; + } + if (fieldDef.type === 'quantitative') { + if (scaleType === 'log') { + return { + valid: false, + reason: message.unaggregatedDomainWithLogScale(fieldDef) + }; + } + } + return { valid: true }; + } + /** + * Converts an array of domains to a single Vega scale domain. + */ + function mergeDomains(domains) { + var uniqueDomains = unique(domains.map(function (domain) { + // ignore sort property when computing the unique domains + if (isDataRefDomain(domain)) { + var _s = domain.sort, domainWithoutSort = __rest(domain, ["sort"]); + return domainWithoutSort; + } + return domain; + }), hash); + var sorts = unique(domains.map(function (d) { + if (isDataRefDomain(d)) { + var s = d.sort; + if (s !== undefined && !isBoolean$1(s)) { + if (s.op === 'count') { + // let's make sure that if op is count, we don't use a field + delete s.field; + } + if (s.order === 'ascending') { + // drop order: ascending as it is the default + delete s.order; + } + } + return s; + } + return undefined; + }).filter(function (s) { return s !== undefined; }), hash); + if (uniqueDomains.length === 1) { + var domain = domains[0]; + if (isDataRefDomain(domain) && sorts.length > 0) { + var sort_1 = sorts[0]; + if (sorts.length > 1) { + warn(message.MORE_THAN_ONE_SORT); + sort_1 = true; + } + return __assign({}, domain, { sort: sort_1 }); + } + return domain; + } + // only keep simple sort properties that work with unioned domains + var simpleSorts = unique(sorts.map(function (s) { + if (s === true) { + return s; + } + if (s.op === 'count') { + return s; + } + warn(message.domainSortDropped(s)); + return true; + }), hash); + var sort = undefined; + if (simpleSorts.length === 1) { + sort = simpleSorts[0]; + } + else if (simpleSorts.length > 1) { + warn(message.MORE_THAN_ONE_SORT); + sort = true; + } + var allData = unique(domains.map(function (d) { + if (isDataRefDomain(d)) { + return d.data; + } + return null; + }), function (x) { return x; }); + if (allData.length === 1 && allData[0] !== null) { + // create a union domain of different fields with a single data source + var domain = __assign({ data: allData[0], fields: uniqueDomains.map(function (d) { return d.field; }) }, (sort ? { sort: sort } : {})); + return domain; + } + return __assign({ fields: uniqueDomains }, (sort ? { sort: sort } : {})); + } + /** + * Return a field if a scale single field. + * Return `undefined` otherwise. + * + */ + function getFieldFromDomain(domain) { + if (isDataRefDomain(domain) && isString(domain.field)) { + return domain.field; + } + else if (isDataRefUnionedDomain(domain)) { + var field$$1 = void 0; + for (var _i = 0, _a = domain.fields; _i < _a.length; _i++) { + var nonUnionDomain = _a[_i]; + if (isDataRefDomain(nonUnionDomain) && isString(nonUnionDomain.field)) { + if (!field$$1) { + field$$1 = nonUnionDomain.field; + } + else if (field$$1 !== nonUnionDomain.field) { + warn('Detected faceted independent scales that union domain of multiple fields from different data sources. We will use the first field. The result view size may be incorrect.'); + return field$$1; + } + } + } + warn('Detected faceted independent scales that union domain of identical fields from different source detected. We will assume that this is the same field from a different fork of the same data source. However, if this is not case, the result view size maybe incorrect.'); + return field$$1; + } + else if (isFieldRefUnionDomain(domain)) { + warn('Detected faceted independent scales that union domain of multiple fields from the same data source. We will use the first field. The result view size may be incorrect.'); + var field$$1 = domain.fields[0]; + return isString(field$$1) ? field$$1 : undefined; + } + return undefined; + } + function assembleDomain(model, channel) { + var scaleComponent = model.component.scales[channel]; + var domains = scaleComponent.domains.map(function (domain) { + // Correct references to data as the original domain's data was determined + // in parseScale, which happens before parseData. Thus the original data + // reference can be incorrect. + if (isDataRefDomain(domain)) { + domain.data = model.lookupDataSource(domain.data); + } + return domain; + }); + // domains is an array that has to be merged into a single vega domain + return mergeDomains(domains); + } + + function assembleScales(model) { + if (isLayerModel(model) || isConcatModel(model) || isRepeatModel(model)) { + // For concat / layer / repeat, include scales of children too + return model.children.reduce(function (scales, child) { + return scales.concat(assembleScales(child)); + }, assembleScalesForModel(model)); + } + else { + // For facet, child scales would not be included in the parent's scope. + // For unit, there is no child. + return assembleScalesForModel(model); + } + } + function assembleScalesForModel(model) { + return keys(model.component.scales).reduce(function (scales, channel) { + var scaleComponent = model.component.scales[channel]; + if (scaleComponent.merged) { + // Skipped merged scales + return scales; + } + var scale = scaleComponent.combine(); + // need to separate const and non const object destruction + var domainRaw = scale.domainRaw, range = scale.range; + var name = scale.name, type = scale.type, _d = scale.domainRaw, _r = scale.range, otherScaleProps = __rest(scale, ["name", "type", "domainRaw", "range"]); + range = assembleScaleRange(range, name, model, channel); + // As scale parsing occurs before selection parsing, a temporary signal + // is used for domainRaw. Here, we detect if this temporary signal + // is set, and replace it with the correct domainRaw signal. + // For more information, see isRawSelectionDomain in selection.ts. + if (domainRaw && isRawSelectionDomain(domainRaw)) { + domainRaw = selectionScaleDomain(model, domainRaw); + } + scales.push(__assign({ name: name, + type: type, domain: assembleDomain(model, channel) }, (domainRaw ? { domainRaw: domainRaw } : {}), { range: range }, otherScaleProps)); + return scales; + }, []); + } + function assembleScaleRange(scaleRange, scaleName, model, channel) { + // add signals to x/y range + if (channel === 'x' || channel === 'y') { + if (isVgRangeStep(scaleRange)) { + // For x/y range step, use a signal created in layout assemble instead of a constant range step. + return { + step: { signal: scaleName + '_step' } + }; + } + else if (isArray(scaleRange) && scaleRange.length === 2) { + var r0 = scaleRange[0]; + var r1 = scaleRange[1]; + if (r0 === 0 && isVgSignalRef(r1)) { + // Replace width signal just in case it is renamed. + return [0, { signal: model.getSizeName(r1.signal) }]; + } + else if (isVgSignalRef(r0) && r1 === 0) { + // Replace height signal just in case it is renamed. + return [{ signal: model.getSizeName(r0.signal) }, 0]; + } + } + } + return scaleRange; + } + + var ScaleComponent = /** @class */ (function (_super) { + __extends(ScaleComponent, _super); + function ScaleComponent(name, typeWithExplicit) { + var _this = _super.call(this, {}, // no initial explicit property + { name: name } // name as initial implicit property + ) || this; + _this.merged = false; + _this.domains = []; + _this.setWithExplicit('type', typeWithExplicit); + return _this; + } + return ScaleComponent; + }(Split)); + + var RANGE_PROPERTIES = ['range', 'rangeStep', 'scheme']; + function parseScaleRange(model) { + if (isUnitModel(model)) { + parseUnitScaleRange(model); + } + else { + parseNonUnitScaleProperty(model, 'range'); + } + } + function parseUnitScaleRange(model) { + var localScaleComponents = model.component.scales; + // use SCALE_CHANNELS instead of scales[channel] to ensure that x, y come first! + SCALE_CHANNELS.forEach(function (channel) { + var localScaleCmpt = localScaleComponents[channel]; + if (!localScaleCmpt) { + return; + } + var mergedScaleCmpt = model.getScaleComponent(channel); + var specifiedScale = model.specifiedScales[channel]; + var fieldDef = model.fieldDef(channel); + // Read if there is a specified width/height + var sizeType = channel === 'x' ? 'width' : channel === 'y' ? 'height' : undefined; + var sizeSpecified = sizeType ? !!model.component.layoutSize.get(sizeType) : undefined; + var scaleType = mergedScaleCmpt.get('type'); + // if autosize is fit, size cannot be data driven + var rangeStep = contains(['point', 'band'], scaleType) || !!specifiedScale.rangeStep; + if (sizeType && model.fit && !sizeSpecified && rangeStep) { + warn(message.CANNOT_FIX_RANGE_STEP_WITH_FIT); + sizeSpecified = true; + } + var xyRangeSteps = getXYRangeStep(model); + var rangeWithExplicit = parseRangeForChannel(channel, scaleType, fieldDef.type, specifiedScale, model.config, localScaleCmpt.get('zero'), model.mark, sizeSpecified, model.getName(sizeType), xyRangeSteps); + localScaleCmpt.setWithExplicit('range', rangeWithExplicit); + }); + } + function getXYRangeStep(model) { + var xyRangeSteps = []; + var xScale = model.getScaleComponent('x'); + var xRange = xScale && xScale.get('range'); + if (xRange && isVgRangeStep(xRange) && isNumber(xRange.step)) { + xyRangeSteps.push(xRange.step); + } + var yScale = model.getScaleComponent('y'); + var yRange = yScale && yScale.get('range'); + if (yRange && isVgRangeStep(yRange) && isNumber(yRange.step)) { + xyRangeSteps.push(yRange.step); + } + return xyRangeSteps; + } + /** + * Return mixins that includes one of the range properties (range, rangeStep, scheme). + */ + function parseRangeForChannel(channel, scaleType, type, specifiedScale, config, zero$$1, mark, sizeSpecified, sizeSignal, xyRangeSteps) { + var noRangeStep = sizeSpecified || specifiedScale.rangeStep === null; + // Check if any of the range properties is specified. + // If so, check if it is compatible and make sure that we only output one of the properties + for (var _i = 0, RANGE_PROPERTIES_1 = RANGE_PROPERTIES; _i < RANGE_PROPERTIES_1.length; _i++) { + var property = RANGE_PROPERTIES_1[_i]; + if (specifiedScale[property] !== undefined) { + var supportedByScaleType = scaleTypeSupportProperty(scaleType, property); + var channelIncompatability = channelScalePropertyIncompatability(channel, property); + if (!supportedByScaleType) { + warn(message.scalePropertyNotWorkWithScaleType(scaleType, property, channel)); + } + else if (channelIncompatability) { // channel + warn(channelIncompatability); + } + else { + switch (property) { + case 'range': + return makeExplicit(specifiedScale[property]); + case 'scheme': + return makeExplicit(parseScheme(specifiedScale[property])); + case 'rangeStep': + var rangeStep = specifiedScale[property]; + if (rangeStep !== null) { + if (!sizeSpecified) { + return makeExplicit({ step: rangeStep }); + } + else { + // If top-level size is specified, we ignore specified rangeStep. + warn(message.rangeStepDropped(channel)); + } + } + } + } + } + } + return makeImplicit(defaultRange(channel, scaleType, type, config, zero$$1, mark, sizeSignal, xyRangeSteps, noRangeStep)); + } + function parseScheme(scheme) { + if (isExtendedScheme(scheme)) { + var r = { scheme: scheme.name }; + if (scheme.count) { + r.count = scheme.count; + } + if (scheme.extent) { + r.extent = scheme.extent; + } + return r; + } + return { scheme: scheme }; + } + function defaultRange(channel, scaleType, type, config, zero$$1, mark, sizeSignal, xyRangeSteps, noRangeStep) { + switch (channel) { + case X: + case Y: + if (contains(['point', 'band'], scaleType) && !noRangeStep) { + if (channel === X && mark === 'text') { + if (config.scale.textXRangeStep) { + return { step: config.scale.textXRangeStep }; + } + } + else { + if (config.scale.rangeStep) { + return { step: config.scale.rangeStep }; + } + } + } + // If range step is null, use zero to width or height. + // Note that these range signals are temporary + // as they can be merged and renamed. + // (We do not have the right size signal here since parseLayoutSize() happens after parseScale().) + // We will later replace these temporary names with + // the final name in assembleScaleRange() + if (channel === Y && hasContinuousDomain(scaleType)) { + // For y continuous scale, we have to start from the height as the bottom part has the max value. + return [{ signal: sizeSignal }, 0]; + } + else { + return [0, { signal: sizeSignal }]; + } + case SIZE: + // TODO: support custom rangeMin, rangeMax + var rangeMin = sizeRangeMin(mark, zero$$1, config); + var rangeMax = sizeRangeMax(mark, xyRangeSteps, config); + return [rangeMin, rangeMax]; + case SHAPE: + return 'symbol'; + case COLOR: + case FILL: + case STROKE: + if (scaleType === 'ordinal') { + // Only nominal data uses ordinal scale by default + return type === 'nominal' ? 'category' : 'ordinal'; + } + return mark === 'rect' || mark === 'geoshape' ? 'heatmap' : 'ramp'; + case OPACITY: + // TODO: support custom rangeMin, rangeMax + return [config.scale.minOpacity, config.scale.maxOpacity]; + } + /* istanbul ignore next: should never reach here */ + throw new Error("Scale range undefined for channel " + channel); + } + function sizeRangeMin(mark, zero$$1, config) { + if (zero$$1) { + return 0; + } + switch (mark) { + case 'bar': + case 'tick': + return config.scale.minBandSize; + case 'line': + case 'trail': + case 'rule': + return config.scale.minStrokeWidth; + case 'text': + return config.scale.minFontSize; + case 'point': + case 'square': + case 'circle': + return config.scale.minSize; + } + /* istanbul ignore next: should never reach here */ + // sizeRangeMin not implemented for the mark + throw new Error(message.incompatibleChannel('size', mark)); + } + function sizeRangeMax(mark, xyRangeSteps, config) { + var scaleConfig = config.scale; + switch (mark) { + case 'bar': + case 'tick': + if (config.scale.maxBandSize !== undefined) { + return config.scale.maxBandSize; + } + return minXYRangeStep(xyRangeSteps, config.scale) - 1; + case 'line': + case 'trail': + case 'rule': + return config.scale.maxStrokeWidth; + case 'text': + return config.scale.maxFontSize; + case 'point': + case 'square': + case 'circle': + if (config.scale.maxSize) { + return config.scale.maxSize; + } + // FIXME this case totally should be refactored + var pointStep = minXYRangeStep(xyRangeSteps, scaleConfig); + return (pointStep - 2) * (pointStep - 2); + } + /* istanbul ignore next: should never reach here */ + // sizeRangeMax not implemented for the mark + throw new Error(message.incompatibleChannel('size', mark)); + } + /** + * @returns {number} Range step of x or y or minimum between the two if both are ordinal scale. + */ + function minXYRangeStep(xyRangeSteps, scaleConfig) { + if (xyRangeSteps.length > 0) { + return Math.min.apply(null, xyRangeSteps); + } + if (scaleConfig.rangeStep) { + return scaleConfig.rangeStep; + } + return 21; // FIXME: re-evaluate the default value here. + } + + function parseScaleProperty(model, property) { + if (isUnitModel(model)) { + parseUnitScaleProperty(model, property); + } + else { + parseNonUnitScaleProperty(model, property); + } + } + function parseUnitScaleProperty(model, property) { + var localScaleComponents = model.component.scales; + keys(localScaleComponents).forEach(function (channel) { + var specifiedScale = model.specifiedScales[channel]; + var localScaleCmpt = localScaleComponents[channel]; + var mergedScaleCmpt = model.getScaleComponent(channel); + var fieldDef = model.fieldDef(channel); + var config = model.config; + var specifiedValue = specifiedScale[property]; + var sType = mergedScaleCmpt.get('type'); + var supportedByScaleType = scaleTypeSupportProperty(sType, property); + var channelIncompatability = channelScalePropertyIncompatability(channel, property); + if (specifiedValue !== undefined) { + // If there is a specified value, check if it is compatible with scale type and channel + if (!supportedByScaleType) { + warn(message.scalePropertyNotWorkWithScaleType(sType, property, channel)); + } + else if (channelIncompatability) { // channel + warn(channelIncompatability); + } + } + if (supportedByScaleType && channelIncompatability === undefined) { + if (specifiedValue !== undefined) { + // copyKeyFromObject ensure type safety + localScaleCmpt.copyKeyFromObject(property, specifiedScale); + } + else { + var value = getDefaultValue(property, channel, fieldDef, mergedScaleCmpt.get('type'), mergedScaleCmpt.get('padding'), mergedScaleCmpt.get('paddingInner'), specifiedScale.domain, model.markDef, config); + if (value !== undefined) { + localScaleCmpt.set(property, value, false); + } + } + } + }); + } + // Note: This method is used in Voyager. + function getDefaultValue(property, channel, fieldDef, scaleType, scalePadding, scalePaddingInner, specifiedDomain, markDef, config) { + var scaleConfig = config.scale; + // If we have default rule-base, determine default value first + switch (property) { + case 'nice': + return nice(scaleType, channel, fieldDef); + case 'padding': + return padding(channel, scaleType, scaleConfig, fieldDef, markDef, config.bar); + case 'paddingInner': + return paddingInner(scalePadding, channel, scaleConfig); + case 'paddingOuter': + return paddingOuter(scalePadding, channel, scaleType, scalePaddingInner, scaleConfig); + case 'reverse': + return reverse(scaleType, fieldDef.sort); + case 'zero': + return zero$1(channel, fieldDef, specifiedDomain, markDef); + } + // Otherwise, use scale config + return scaleConfig[property]; + } + function parseNonUnitScaleProperty(model, property) { + var localScaleComponents = model.component.scales; + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + if (property === 'range') { + parseScaleRange(child); + } + else { + parseScaleProperty(child, property); + } + } + keys(localScaleComponents).forEach(function (channel) { + var valueWithExplicit; + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + var childComponent = child.component.scales[channel]; + if (childComponent) { + var childValueWithExplicit = childComponent.getWithExplicit(property); + valueWithExplicit = mergeValuesWithExplicit(valueWithExplicit, childValueWithExplicit, property, 'scale', tieBreakByComparing(function (v1, v2) { + switch (property) { + case 'range': + // For range step, prefer larger step + if (v1.step && v2.step) { + return v1.step - v2.step; + } + return 0; + // TODO: precedence rule for other properties + } + return 0; + })); + } + } + localScaleComponents[channel].setWithExplicit(property, valueWithExplicit); + }); + } + function nice(scaleType, channel, fieldDef) { + if (fieldDef.bin || contains([ScaleType.TIME, ScaleType.UTC], scaleType)) { + return undefined; + } + return contains([X, Y], channel); // return true for quantitative X/Y unless binned + } + function padding(channel, scaleType, scaleConfig, fieldDef, markDef, barConfig) { + if (contains([X, Y], channel)) { + if (isContinuousToContinuous(scaleType)) { + if (scaleConfig.continuousPadding !== undefined) { + return scaleConfig.continuousPadding; + } + var type = markDef.type, orient = markDef.orient; + if (type === 'bar' && !fieldDef.bin) { + if ((orient === 'vertical' && channel === 'x') || + (orient === 'horizontal' && channel === 'y')) { + return barConfig.continuousBandSize; + } + } + } + if (scaleType === ScaleType.POINT) { + return scaleConfig.pointPadding; + } + } + return undefined; + } + function paddingInner(paddingValue, channel, scaleConfig) { + if (paddingValue !== undefined) { + // If user has already manually specified "padding", no need to add default paddingInner. + return undefined; + } + if (contains([X, Y], channel)) { + // Padding is only set for X and Y by default. + // Basically it doesn't make sense to add padding for color and size. + // paddingOuter would only be called if it's a band scale, just return the default for bandScale. + return scaleConfig.bandPaddingInner; + } + return undefined; + } + function paddingOuter(paddingValue, channel, scaleType, paddingInnerValue, scaleConfig) { + if (paddingValue !== undefined) { + // If user has already manually specified "padding", no need to add default paddingOuter. + return undefined; + } + if (contains([X, Y], channel)) { + // Padding is only set for X and Y by default. + // Basically it doesn't make sense to add padding for color and size. + if (scaleType === ScaleType.BAND) { + if (scaleConfig.bandPaddingOuter !== undefined) { + return scaleConfig.bandPaddingOuter; + } + /* By default, paddingOuter is paddingInner / 2. The reason is that + size (width/height) = step * (cardinality - paddingInner + 2 * paddingOuter). + and we want the width/height to be integer by default. + Note that step (by default) and cardinality are integers.) */ + return paddingInnerValue / 2; + } + } + return undefined; + } + function reverse(scaleType, sort) { + if (hasContinuousDomain(scaleType) && sort === 'descending') { + // For continuous domain scales, Vega does not support domain sort. + // Thus, we reverse range instead if sort is descending + return true; + } + return undefined; + } + function zero$1(channel, fieldDef, specifiedScale, markDef) { + // If users explicitly provide a domain range, we should not augment zero as that will be unexpected. + var hasCustomDomain = !!specifiedScale && specifiedScale !== 'unaggregated'; + if (hasCustomDomain) { + return false; + } + // If there is no custom domain, return true only for the following cases: + // 1) using quantitative field with size + // While this can be either ratio or interval fields, our assumption is that + // ratio are more common. + if (channel === 'size' && fieldDef.type === 'quantitative') { + return true; + } + // 2) non-binned, quantitative x-scale or y-scale + // (For binning, we should not include zero by default because binning are calculated without zero.) + if (!fieldDef.bin && contains([X, Y], channel)) { + var orient = markDef.orient, type = markDef.type; + if (contains(['bar', 'area', 'line', 'trail'], type)) { + if ((orient === 'horizontal' && channel === 'y') || + (orient === 'vertical' && channel === 'x')) { + return false; + } + } + return true; + } + return false; + } + + /** + * Determine if there is a specified scale type and if it is appropriate, + * or determine default type if type is unspecified or inappropriate. + */ + // NOTE: CompassQL uses this method. + function scaleType(specifiedType, channel, fieldDef, mark, scaleConfig) { + var defaultScaleType = defaultType$1(channel, fieldDef, mark, scaleConfig); + if (!isScaleChannel(channel)) { + // There is no scale for these channels + return null; + } + if (specifiedType !== undefined) { + // Check if explicitly specified scale type is supported by the channel + if (!channelSupportScaleType(channel, specifiedType)) { + warn(message.scaleTypeNotWorkWithChannel(channel, specifiedType, defaultScaleType)); + return defaultScaleType; + } + // Check if explicitly specified scale type is supported by the data type + if (!scaleTypeSupportDataType(specifiedType, fieldDef.type, fieldDef.bin)) { + warn(message.scaleTypeNotWorkWithFieldDef(specifiedType, defaultScaleType)); + return defaultScaleType; + } + return specifiedType; + } + return defaultScaleType; + } + /** + * Determine appropriate default scale type. + */ + // NOTE: Voyager uses this method. + function defaultType$1(channel, fieldDef, mark, scaleConfig) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + if (isColorChannel(channel) || rangeType(channel) === 'discrete') { + if (channel === 'shape' && fieldDef.type === 'ordinal') { + warn(message.discreteChannelCannotEncode(channel, 'ordinal')); + } + return 'ordinal'; + } + if (contains(['x', 'y'], channel)) { + if (contains(['rect', 'bar', 'rule'], mark)) { + // The rect/bar mark should fit into a band. + // For rule, using band scale to make rule align with axis ticks better https://github.com/vega/vega-lite/issues/3429 + return 'band'; + } + if (mark === 'bar') { + return 'band'; + } + } + // Otherwise, use ordinal point scale so we can easily get center positions of the marks. + return 'point'; + case 'temporal': + if (isColorChannel(channel)) { + return 'sequential'; + } + else if (rangeType(channel) === 'discrete') { + warn(message.discreteChannelCannotEncode(channel, 'temporal')); + // TODO: consider using quantize (equivalent to binning) once we have it + return 'ordinal'; + } + return 'time'; + case 'quantitative': + if (isColorChannel(channel)) { + if (fieldDef.bin) { + return 'bin-ordinal'; + } + // Use `sequential` as the default color scale for continuous data + // since it supports both array range and scheme range. + return 'sequential'; + } + else if (rangeType(channel) === 'discrete') { + warn(message.discreteChannelCannotEncode(channel, 'quantitative')); + // TODO: consider using quantize (equivalent to binning) once we have it + return 'ordinal'; + } + // x and y use a linear scale because selections don't work with bin scales. + // Binned scales apply discretization but pan/zoom apply transformations to a [min, max] extent domain. + if (fieldDef.bin && channel !== 'x' && channel !== 'y') { + return 'bin-linear'; + } + return 'linear'; + case 'latitude': + case 'longitude': + case 'geojson': + return undefined; + } + /* istanbul ignore next: should never reach this */ + throw new Error(message.invalidFieldType(fieldDef.type)); + } + + function parseScale(model) { + parseScaleCore(model); + parseScaleDomain(model); + for (var _i = 0, NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES_1 = NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES; _i < NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES_1.length; _i++) { + var prop = NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES_1[_i]; + parseScaleProperty(model, prop); + } + // range depends on zero + parseScaleRange(model); + } + function parseScaleCore(model) { + if (isUnitModel(model)) { + model.component.scales = parseUnitScaleCore(model); + } + else { + model.component.scales = parseNonUnitScaleCore(model); + } + } + /** + * Parse scales for all channels of a model. + */ + function parseUnitScaleCore(model) { + var encoding = model.encoding, config = model.config, mark = model.mark; + return SCALE_CHANNELS.reduce(function (scaleComponents, channel) { + var fieldDef; + var specifiedScale = undefined; + var channelDef = encoding[channel]; + // Don't generate scale for shape of geoshape + if (isFieldDef(channelDef) && mark === GEOSHAPE && + channel === SHAPE && channelDef.type === GEOJSON) { + return scaleComponents; + } + if (isFieldDef(channelDef)) { + fieldDef = channelDef; + specifiedScale = channelDef.scale; + } + else if (hasConditionalFieldDef(channelDef)) { + fieldDef = channelDef.condition; + specifiedScale = channelDef.condition['scale']; // We use ['scale'] since we know that channel here has scale for sure + } + else if (channel === X) { + fieldDef = getFieldDef(encoding.x2); + } + else if (channel === Y) { + fieldDef = getFieldDef(encoding.y2); + } + if (fieldDef && specifiedScale !== null && specifiedScale !== false) { + specifiedScale = specifiedScale || {}; + var specifiedScaleType = specifiedScale.type; + var sType = scaleType(specifiedScale.type, channel, fieldDef, mark, config.scale); + scaleComponents[channel] = new ScaleComponent(model.scaleName(channel + '', true), { value: sType, explicit: specifiedScaleType === sType }); + } + return scaleComponents; + }, {}); + } + var scaleTypeTieBreaker = tieBreakByComparing(function (st1, st2) { return (scaleTypePrecedence(st1) - scaleTypePrecedence(st2)); }); + function parseNonUnitScaleCore(model) { + var scaleComponents = model.component.scales = {}; + var scaleTypeWithExplicitIndex = {}; + var resolve = model.component.resolve; + var _loop_1 = function (child) { + parseScaleCore(child); + // Instead of always merging right away -- check if it is compatible to merge first! + keys(child.component.scales).forEach(function (channel) { + // if resolve is undefined, set default first + resolve.scale[channel] = resolve.scale[channel] || defaultScaleResolve(channel, model); + if (resolve.scale[channel] === 'shared') { + var explicitScaleType = scaleTypeWithExplicitIndex[channel]; + var childScaleType = child.component.scales[channel].getWithExplicit('type'); + if (explicitScaleType) { + if (scaleCompatible(explicitScaleType.value, childScaleType.value)) { + // merge scale component if type are compatible + scaleTypeWithExplicitIndex[channel] = mergeValuesWithExplicit(explicitScaleType, childScaleType, 'type', 'scale', scaleTypeTieBreaker); + } + else { + // Otherwise, update conflicting channel to be independent + resolve.scale[channel] = 'independent'; + // Remove from the index so they don't get merged + delete scaleTypeWithExplicitIndex[channel]; + } + } + else { + scaleTypeWithExplicitIndex[channel] = childScaleType; + } + } + }); + }; + // Parse each child scale and determine if a particular channel can be merged. + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + _loop_1(child); + } + // Merge each channel listed in the index + keys(scaleTypeWithExplicitIndex).forEach(function (channel) { + // Create new merged scale component + var name = model.scaleName(channel, true); + var typeWithExplicit = scaleTypeWithExplicitIndex[channel]; + scaleComponents[channel] = new ScaleComponent(name, typeWithExplicit); + // rename each child and mark them as merged + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + var childScale = child.component.scales[channel]; + if (childScale) { + child.renameScale(childScale.get('name'), name); + childScale.merged = true; + } + } + }); + return scaleComponents; + } + + var NameMap = /** @class */ (function () { + function NameMap() { + this.nameMap = {}; + } + NameMap.prototype.rename = function (oldName, newName) { + this.nameMap[oldName] = newName; + }; + NameMap.prototype.has = function (name) { + return this.nameMap[name] !== undefined; + }; + NameMap.prototype.get = function (name) { + // If the name appears in the _nameMap, we need to read its new name. + // We have to loop over the dict just in case the new name also gets renamed. + while (this.nameMap[name] && name !== this.nameMap[name]) { + name = this.nameMap[name]; + } + return name; + }; + return NameMap; + }()); + /* + We use type guards instead of `instanceof` as `instanceof` makes + different parts of the compiler depend on the actual implementation of + the model classes, which in turn depend on different parts of the compiler. + Thus, `instanceof` leads to circular dependency problems. + + On the other hand, type guards only make different parts of the compiler + depend on the type of the model classes, but not the actual implementation. + */ + function isUnitModel(model) { + return model && model.type === 'unit'; + } + function isFacetModel(model) { + return model && model.type === 'facet'; + } + function isRepeatModel(model) { + return model && model.type === 'repeat'; + } + function isConcatModel(model) { + return model && model.type === 'concat'; + } + function isLayerModel(model) { + return model && model.type === 'layer'; + } + var Model = /** @class */ (function () { + function Model(spec, parent, parentGivenName, config, repeater, resolve) { + var _this = this; + this.children = []; + /** + * Corrects the data references in marks after assemble. + */ + this.correctDataNames = function (mark) { + // TODO: make this correct + // for normal data references + if (mark.from && mark.from.data) { + mark.from.data = _this.lookupDataSource(mark.from.data); + } + // for access to facet data + if (mark.from && mark.from.facet && mark.from.facet.data) { + mark.from.facet.data = _this.lookupDataSource(mark.from.facet.data); + } + return mark; + }; + this.parent = parent; + this.config = config; + this.repeater = repeater; + // If name is not provided, always use parent's givenName to avoid name conflicts. + this.name = spec.name || parentGivenName; + this.title = isString(spec.title) ? { text: spec.title } : spec.title; + // Shared name maps + this.scaleNameMap = parent ? parent.scaleNameMap : new NameMap(); + this.projectionNameMap = parent ? parent.projectionNameMap : new NameMap(); + this.layoutSizeNameMap = parent ? parent.layoutSizeNameMap : new NameMap(); + this.data = spec.data; + this.description = spec.description; + this.transforms = normalizeTransform(spec.transform || []); + this.layout = isUnitSpec(spec) || isLayerSpec(spec) ? undefined : extractCompositionLayout(spec); + this.component = { + data: { + sources: parent ? parent.component.data.sources : {}, + outputNodes: parent ? parent.component.data.outputNodes : {}, + outputNodeRefCounts: parent ? parent.component.data.outputNodeRefCounts : {}, + // data is faceted if the spec is a facet spec or the parent has faceted data and no data is defined + isFaceted: isFacetSpec(spec) || (parent && parent.component.data.isFaceted && !spec.data) + }, + layoutSize: new Split(), + layoutHeaders: { row: {}, column: {} }, + mark: null, + resolve: __assign({ scale: {}, axis: {}, legend: {} }, (resolve || {})), + selection: null, + scales: null, + projection: null, + axes: {}, + legends: {}, + }; + } + Object.defineProperty(Model.prototype, "width", { + get: function () { + return this.getSizeSignalRef('width'); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Model.prototype, "height", { + get: function () { + return this.getSizeSignalRef('height'); + }, + enumerable: true, + configurable: true + }); + Model.prototype.initSize = function (size) { + var width = size.width, height = size.height; + if (width) { + this.component.layoutSize.set('width', width, true); + } + if (height) { + this.component.layoutSize.set('height', height, true); + } + }; + Model.prototype.parse = function () { + this.parseScale(); + this.parseLayoutSize(); // depends on scale + this.renameTopLevelLayoutSize(); + this.parseSelection(); + this.parseProjection(); + this.parseData(); // (pathorder) depends on markDef; selection filters depend on parsed selections; depends on projection because some transforms require the finalized projection name. + this.parseAxisAndHeader(); // depends on scale and layout size + this.parseLegend(); // depends on scale, markDef + this.parseMarkGroup(); // depends on data name, scale, layout size, axisGroup, and children's scale, axis, legend and mark. + }; + Model.prototype.parseScale = function () { + parseScale(this); + }; + Model.prototype.parseProjection = function () { + parseProjection(this); + }; + /** + * Rename top-level spec's size to be just width / height, ignoring model name. + * This essentially merges the top-level spec's width/height signals with the width/height signals + * to help us reduce redundant signals declaration. + */ + Model.prototype.renameTopLevelLayoutSize = function () { + if (this.getName('width') !== 'width') { + this.renameLayoutSize(this.getName('width'), 'width'); + } + if (this.getName('height') !== 'height') { + this.renameLayoutSize(this.getName('height'), 'height'); + } + }; + Model.prototype.parseLegend = function () { + parseLegend(this); + }; + Model.prototype.assembleGroupStyle = function () { + if (this.type === 'unit' || this.type === 'layer') { + return 'cell'; + } + return undefined; + }; + Model.prototype.assembleLayoutSize = function () { + if (this.type === 'unit' || this.type === 'layer') { + return { + width: this.getSizeSignalRef('width'), + height: this.getSizeSignalRef('height') + }; + } + return undefined; + }; + Model.prototype.assembleLayout = function () { + if (!this.layout) { + return undefined; + } + var _a = this.layout, align = _a.align, bounds = _a.bounds, center = _a.center, _b = _a.spacing, spacing = _b === void 0 ? {} : _b; + return __assign({ padding: isNumber(spacing) ? spacing : { + row: spacing.row || 10, + column: spacing.column || 10 + } }, this.assembleDefaultLayout(), (align ? { align: align } : {}), (bounds ? { bounds: bounds } : {}), (center ? { center: center } : {})); + }; + Model.prototype.assembleDefaultLayout = function () { + return {}; + }; + Model.prototype.assembleHeaderMarks = function () { + var layoutHeaders = this.component.layoutHeaders; + var headerMarks = []; + for (var _i = 0, HEADER_CHANNELS_1 = HEADER_CHANNELS; _i < HEADER_CHANNELS_1.length; _i++) { + var channel = HEADER_CHANNELS_1[_i]; + if (layoutHeaders[channel].title) { + headerMarks.push(getTitleGroup(this, channel)); + } + } + for (var _a = 0, HEADER_CHANNELS_2 = HEADER_CHANNELS; _a < HEADER_CHANNELS_2.length; _a++) { + var channel = HEADER_CHANNELS_2[_a]; + headerMarks = headerMarks.concat(getHeaderGroups(this, channel)); + } + return headerMarks; + }; + Model.prototype.assembleAxes = function () { + return assembleAxes(this.component.axes, this.config); + }; + Model.prototype.assembleLegends = function () { + return assembleLegends(this); + }; + Model.prototype.assembleProjections = function () { + return assembleProjections(this); + }; + Model.prototype.assembleTitle = function () { + var title$$1 = __assign({}, extractTitleConfig(this.config.title).nonMark, this.title); + if (title$$1.text) { + if (!contains(['unit', 'layer'], this.type)) { + // As described in https://github.com/vega/vega-lite/issues/2875: + // Due to vega/vega#960 (comment), we only support title's anchor for unit and layered spec for now. + if (title$$1.anchor && title$$1.anchor !== 'start') { + warn(message.cannotSetTitleAnchor(this.type)); + } + title$$1.anchor = 'start'; + } + return keys(title$$1).length > 0 ? title$$1 : undefined; + } + return undefined; + }; + /** + * Assemble the mark group for this model. We accept optional `signals` so that we can include concat top-level signals with the top-level model's local signals. + */ + Model.prototype.assembleGroup = function (signals) { + if (signals === void 0) { signals = []; } + var group = {}; + signals = signals.concat(this.assembleSelectionSignals()); + if (signals.length > 0) { + group.signals = signals; + } + var layout = this.assembleLayout(); + if (layout) { + group.layout = layout; + } + group.marks = [].concat(this.assembleHeaderMarks(), this.assembleMarks()); + // Only include scales if this spec is top-level or if parent is facet. + // (Otherwise, it will be merged with upper-level's scope.) + var scales = (!this.parent || isFacetModel(this.parent)) ? assembleScales(this) : []; + if (scales.length > 0) { + group.scales = scales; + } + var axes = this.assembleAxes(); + if (axes.length > 0) { + group.axes = axes; + } + var legends = this.assembleLegends(); + if (legends.length > 0) { + group.legends = legends; + } + return group; + }; + Model.prototype.hasDescendantWithFieldOnChannel = function (channel) { + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + if (isUnitModel(child)) { + if (child.channelHasField(channel)) { + return true; + } + } + else { + if (child.hasDescendantWithFieldOnChannel(channel)) { + return true; + } + } + } + return false; + }; + Model.prototype.getName = function (text) { + return varName((this.name ? this.name + '_' : '') + text); + }; + /** + * Request a data source name for the given data source type and mark that data source as required. This method should be called in parse, so that all used data source can be correctly instantiated in assembleData(). + */ + Model.prototype.requestDataName = function (name) { + var fullName = this.getName(name); + // Increase ref count. This is critical because otherwise we won't create a data source. + // We also increase the ref counts on OutputNode.getSource() calls. + var refCounts = this.component.data.outputNodeRefCounts; + refCounts[fullName] = (refCounts[fullName] || 0) + 1; + return fullName; + }; + Model.prototype.getSizeSignalRef = function (sizeType) { + if (isFacetModel(this.parent)) { + var channel = sizeType === 'width' ? 'x' : 'y'; + var scaleComponent = this.component.scales[channel]; + if (scaleComponent && !scaleComponent.merged) { // independent scale + var type = scaleComponent.get('type'); + var range = scaleComponent.get('range'); + if (hasDiscreteDomain(type) && isVgRangeStep(range)) { + var scaleName = scaleComponent.get('name'); + var domain = assembleDomain(this, channel); + var field$$1 = getFieldFromDomain(domain); + if (field$$1) { + var fieldRef = vgField({ aggregate: 'distinct', field: field$$1 }, { expr: 'datum' }); + return { + signal: sizeExpr(scaleName, scaleComponent, fieldRef) + }; + } + else { + warn('Unknown field for ${channel}. Cannot calculate view size.'); + return null; + } + } + } + } + return { + signal: this.layoutSizeNameMap.get(this.getName(sizeType)) + }; + }; + /** + * Lookup the name of the datasource for an output node. You probably want to call this in assemble. + */ + Model.prototype.lookupDataSource = function (name) { + var node = this.component.data.outputNodes[name]; + if (!node) { + // Name not found in map so let's just return what we got. + // This can happen if we already have the correct name. + return name; + } + return node.getSource(); + }; + Model.prototype.getSizeName = function (oldSizeName) { + return this.layoutSizeNameMap.get(oldSizeName); + }; + Model.prototype.renameLayoutSize = function (oldName, newName) { + this.layoutSizeNameMap.rename(oldName, newName); + }; + Model.prototype.renameScale = function (oldName, newName) { + this.scaleNameMap.rename(oldName, newName); + }; + Model.prototype.renameProjection = function (oldName, newName) { + this.projectionNameMap.rename(oldName, newName); + }; + /** + * @return scale name for a given channel after the scale has been parsed and named. + */ + Model.prototype.scaleName = function (originalScaleName, parse) { + if (parse) { + // During the parse phase always return a value + // No need to refer to rename map because a scale can't be renamed + // before it has the original name. + return this.getName(originalScaleName); + } + // If there is a scale for the channel, it should either + // be in the scale component or exist in the name map + if ( + // If there is a scale for the channel, there should be a local scale component for it + (isChannel(originalScaleName) && isScaleChannel(originalScaleName) && this.component.scales[originalScaleName]) || + // in the scale name map (the scale get merged by its parent) + this.scaleNameMap.has(this.getName(originalScaleName))) { + return this.scaleNameMap.get(this.getName(originalScaleName)); + } + return undefined; + }; + /** + * @return projection name after the projection has been parsed and named. + */ + Model.prototype.projectionName = function (parse) { + if (parse) { + // During the parse phase always return a value + // No need to refer to rename map because a projection can't be renamed + // before it has the original name. + return this.getName('projection'); + } + if ((this.component.projection && !this.component.projection.merged) || this.projectionNameMap.has(this.getName('projection'))) { + return this.projectionNameMap.get(this.getName('projection')); + } + return undefined; + }; + /** + * Traverse a model's hierarchy to get the scale component for a particular channel. + */ + Model.prototype.getScaleComponent = function (channel) { + /* istanbul ignore next: This is warning for debugging test */ + if (!this.component.scales) { + throw new Error('getScaleComponent cannot be called before parseScale(). Make sure you have called parseScale or use parseUnitModelWithScale().'); + } + var localScaleComponent = this.component.scales[channel]; + if (localScaleComponent && !localScaleComponent.merged) { + return localScaleComponent; + } + return (this.parent ? this.parent.getScaleComponent(channel) : undefined); + }; + /** + * Traverse a model's hierarchy to get a particular selection component. + */ + Model.prototype.getSelectionComponent = function (variableName, origName) { + var sel = this.component.selection[variableName]; + if (!sel && this.parent) { + sel = this.parent.getSelectionComponent(variableName, origName); + } + if (!sel) { + throw new Error(message.selectionNotFound(origName)); + } + return sel; + }; + return Model; + }()); + /** Abstract class for UnitModel and FacetModel. Both of which can contain fieldDefs as a part of its own specification. */ + var ModelWithField = /** @class */ (function (_super) { + __extends(ModelWithField, _super); + function ModelWithField() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** Get "field" reference for vega */ + ModelWithField.prototype.vgField = function (channel, opt) { + if (opt === void 0) { opt = {}; } + var fieldDef = this.fieldDef(channel); + if (!fieldDef) { + return undefined; + } + return vgField(fieldDef, opt); + }; + ModelWithField.prototype.reduceFieldDef = function (f, init, t) { + return reduce(this.getMapping(), function (acc, cd, c) { + var fieldDef = getFieldDef(cd); + if (fieldDef) { + return f(acc, fieldDef, c); + } + return acc; + }, init, t); + }; + ModelWithField.prototype.forEachFieldDef = function (f, t) { + forEach(this.getMapping(), function (cd, c) { + var fieldDef = getFieldDef(cd); + if (fieldDef) { + f(fieldDef, c); + } + }, t); + }; + return ModelWithField; + }(Model)); + + var scaleBindings = { + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.resolve === 'global' && + selCmpt.bind && selCmpt.bind === 'scales'; + }, + parse: function (model, selDef, selCmpt) { + var bound = selCmpt.scales = []; + selCmpt.project.forEach(function (p) { + var channel = p.channel; + var scale = model.getScaleComponent(channel); + var scaleType = scale ? scale.get('type') : undefined; + if (!scale || !hasContinuousDomain(scaleType) || isBinScale(scaleType)) { + warn(message.SCALE_BINDINGS_CONTINUOUS); + return; + } + scale.set('domainRaw', { signal: channelSignalName(selCmpt, channel, 'data') }, true); + bound.push(channel); + // Bind both x/y for diag plot of repeated views. + if (model.repeater && model.repeater.row === model.repeater.column) { + var scale2 = model.getScaleComponent(channel === X ? Y : X); + scale2.set('domainRaw', { signal: channelSignalName(selCmpt, channel, 'data') }, true); + } + }); + }, + topLevelSignals: function (model, selCmpt, signals) { + // Top-level signals are only needed when coordinating composed views. + if (!model.parent) { + return signals; + } + var channels = selCmpt.scales.filter(function (channel) { + return !(signals.filter(function (s) { return s.name === channelSignalName(selCmpt, channel, 'data'); }).length); + }); + return signals.concat(channels.map(function (channel) { + return { name: channelSignalName(selCmpt, channel, 'data') }; + })); + }, + signals: function (model, selCmpt, signals) { + // Nested signals need only push to top-level signals when within composed views. + if (model.parent) { + selCmpt.scales.forEach(function (channel) { + var signal = signals.filter(function (s) { return s.name === channelSignalName(selCmpt, channel, 'data'); })[0]; + signal.push = 'outer'; + delete signal.value; + delete signal.update; + }); + } + return signals; + } + }; + function domain$1(model, channel) { + var scale = $(model.scaleName(channel)); + return "domain(" + scale + ")"; + } + + var BRUSH = '_brush'; + var SCALE_TRIGGER = '_scale_trigger'; + var interval = { + predicate: 'vlInterval', + scaleDomain: 'vlIntervalDomain', + signals: function (model, selCmpt) { + var name = selCmpt.name; + var hasScales = scaleBindings.has(selCmpt); + var signals = []; + var intervals = []; + var tupleTriggers = []; + var scaleTriggers = []; + if (selCmpt.translate && !hasScales) { + var filterExpr_1 = "!event.item || event.item.mark.name !== " + $(name + BRUSH); + events(selCmpt, function (_, evt) { + var filters = evt.between[0].filter || (evt.between[0].filter = []); + if (filters.indexOf(filterExpr_1) < 0) { + filters.push(filterExpr_1); + } + }); + } + selCmpt.project.forEach(function (p) { + var channel = p.channel; + if (channel !== X && channel !== Y) { + warn('Interval selections only support x and y encoding channels.'); + return; + } + var cs = channelSignals(model, selCmpt, channel); + var dname = channelSignalName(selCmpt, channel, 'data'); + var vname = channelSignalName(selCmpt, channel, 'visual'); + var scaleStr = $(model.scaleName(channel)); + var scaleType = model.getScaleComponent(channel).get('type'); + var toNum = hasContinuousDomain(scaleType) ? '+' : ''; + signals.push.apply(signals, cs); + tupleTriggers.push(dname); + intervals.push("{encoding: " + $(channel) + ", " + + ("field: " + $(p.field) + ", extent: " + dname + "}")); + scaleTriggers.push({ + scaleName: model.scaleName(channel), + expr: "(!isArray(" + dname + ") || " + + ("(" + toNum + "invert(" + scaleStr + ", " + vname + ")[0] === " + toNum + dname + "[0] && ") + + (toNum + "invert(" + scaleStr + ", " + vname + ")[1] === " + toNum + dname + "[1]))") + }); + }); + // Proxy scale reactions to ensure that an infinite loop doesn't occur + // when an interval selection filter touches the scale. + if (!hasScales) { + signals.push({ + name: name + SCALE_TRIGGER, + update: scaleTriggers.map(function (t) { return t.expr; }).join(' && ') + + (" ? " + (name + SCALE_TRIGGER) + " : {}") + }); + } + // Only add an interval to the store if it has valid data extents. Data extents + // are set to null if pixel extents are equal to account for intervals over + // ordinal/nominal domains which, when inverted, will still produce a valid datum. + return signals.concat({ + name: name + TUPLE, + on: [{ + events: tupleTriggers.map(function (t) { return ({ signal: t }); }), + update: tupleTriggers.join(' && ') + + (" ? {unit: " + unitName(model) + ", intervals: [" + intervals.join(', ') + "]} : null") + }] + }); + }, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'true' : "{unit: " + unitName(model) + "}"); + }, + marks: function (model, selCmpt, marks) { + var name = selCmpt.name; + var _a = positionalProjections(selCmpt), xi = _a.xi, yi = _a.yi; + var store = "data(" + $(selCmpt.name + STORE) + ")"; + // Do not add a brush if we're binding to scales. + if (scaleBindings.has(selCmpt)) { + return marks; + } + var update = { + x: xi !== null ? { signal: name + "_x[0]" } : { value: 0 }, + y: yi !== null ? { signal: name + "_y[0]" } : { value: 0 }, + x2: xi !== null ? { signal: name + "_x[1]" } : { field: { group: 'width' } }, + y2: yi !== null ? { signal: name + "_y[1]" } : { field: { group: 'height' } } + }; + // If the selection is resolved to global, only a single interval is in + // the store. Wrap brush mark's encodings with a production rule to test + // this based on the `unit` property. Hide the brush mark if it corresponds + // to a unit different from the one in the store. + if (selCmpt.resolve === 'global') { + for (var _i = 0, _b = keys(update); _i < _b.length; _i++) { + var key$$1 = _b[_i]; + update[key$$1] = [__assign({ test: store + ".length && " + store + "[0].unit === " + unitName(model) }, update[key$$1]), { value: 0 }]; + } + } + // Two brush marks ensure that fill colors and other aesthetic choices do + // not interefere with the core marks, but that the brushed region can still + // be interacted with (e.g., dragging it around). + var _c = selCmpt.mark, fill = _c.fill, fillOpacity = _c.fillOpacity, stroke = __rest(_c, ["fill", "fillOpacity"]); + var vgStroke = keys(stroke).reduce(function (def, k) { + def[k] = [{ + test: [ + xi !== null && name + "_x[0] !== " + name + "_x[1]", + yi != null && name + "_y[0] !== " + name + "_y[1]", + ].filter(function (x) { return x; }).join(' && '), + value: stroke[k] + }, { value: null }]; + return def; + }, {}); + return [{ + name: name + BRUSH + '_bg', + type: 'rect', + clip: true, + encode: { + enter: { + fill: { value: fill }, + fillOpacity: { value: fillOpacity } + }, + update: update + } + }].concat(marks, { + name: name + BRUSH, + type: 'rect', + clip: true, + encode: { + enter: { + fill: { value: 'transparent' } + }, + update: __assign({}, update, vgStroke) + } + }); + } + }; + /** + * Returns the visual and data signals for an interval selection. + */ + function channelSignals(model, selCmpt, channel) { + var vname = channelSignalName(selCmpt, channel, 'visual'); + var dname = channelSignalName(selCmpt, channel, 'data'); + var hasScales = scaleBindings.has(selCmpt); + var scaleName = model.scaleName(channel); + var scaleStr = $(scaleName); + var scale = model.getScaleComponent(channel); + var scaleType = scale ? scale.get('type') : undefined; + var size = model.getSizeSignalRef(channel === X ? 'width' : 'height').signal; + var coord = channel + "(unit)"; + var on = events(selCmpt, function (def, evt) { + return def.concat({ events: evt.between[0], update: "[" + coord + ", " + coord + "]" }, // Brush Start + { events: evt, update: "[" + vname + "[0], clamp(" + coord + ", 0, " + size + ")]" } // Brush End + ); + }); + // React to pan/zooms of continuous scales. Non-continuous scales + // (bin-linear, band, point) cannot be pan/zoomed and any other changes + // to their domains (e.g., filtering) should clear the brushes. + on.push({ + events: { signal: selCmpt.name + SCALE_TRIGGER }, + update: hasContinuousDomain(scaleType) && !isBinScale(scaleType) ? + "[scale(" + scaleStr + ", " + dname + "[0]), scale(" + scaleStr + ", " + dname + "[1])]" : "[0, 0]" + }); + return hasScales ? [{ name: dname, on: [] }] : [{ + name: vname, value: [], on: on + }, { + name: dname, + on: [{ events: { signal: vname }, update: vname + "[0] === " + vname + "[1] ? null : invert(" + scaleStr + ", " + vname + ")" }] + }]; + } + function events(selCmpt, cb) { + return selCmpt.events.reduce(function (on, evt) { + if (!evt.between) { + warn(evt + " is not an ordered event stream for interval selections"); + return on; + } + return cb(on, evt); + }, []); + } + + var VORONOI = 'voronoi'; + var nearest = { + has: function (selCmpt) { + return selCmpt.type !== 'interval' && selCmpt.nearest; + }, + marks: function (model, selCmpt, marks) { + var _a = positionalProjections(selCmpt), x = _a.x, y = _a.y; + var markType = model.mark; + if (isPathMark(markType)) { + warn(message.nearestNotSupportForContinuous(markType)); + return marks; + } + var cellDef = { + name: model.getName(VORONOI), + type: 'path', + from: { data: model.getName('marks') }, + encode: { + enter: { + fill: { value: 'transparent' }, + strokeWidth: { value: 0.35 }, + stroke: { value: 'transparent' }, + isVoronoi: { value: true } + } + }, + transform: [{ + type: 'voronoi', + x: { expr: (x || (!x && !y)) ? 'datum.datum.x || 0' : '0' }, + y: { expr: (y || (!x && !y)) ? 'datum.datum.y || 0' : '0' }, + size: [model.getSizeSignalRef('width'), model.getSizeSignalRef('height')] + }] + }; + var index = 0; + var exists = false; + marks.forEach(function (mark, i) { + var name = mark.name || ''; + if (name === model.component.mark[0].name) { + index = i; + } + else if (name.indexOf(VORONOI) >= 0) { + exists = true; + } + }); + if (!exists) { + marks.splice(index + 1, 0, cellDef); + } + return marks; + } + }; + + function signals(model, selCmpt) { + var proj = selCmpt.project; + var datum = nearest.has(selCmpt) ? + '(item().isVoronoi ? datum.datum : datum)' : 'datum'; + var bins = []; + var encodings = proj.map(function (p) { return $(p.channel); }).filter(function (e) { return e; }).join(', '); + var fields = proj.map(function (p) { return $(p.field); }).join(', '); + var values = proj.map(function (p) { + var channel = p.channel; + var fieldDef = model.fieldDef(channel); + // Binned fields should capture extents, for a range test against the raw field. + return (fieldDef && fieldDef.bin) ? (bins.push(p.field), + "[" + accessPathWithDatum(model.vgField(channel, {}), datum) + ", " + + (accessPathWithDatum(model.vgField(channel, { binSuffix: 'end' }), datum) + "]")) : + "" + accessPathWithDatum(p.field, datum); + }).join(', '); + // Only add a discrete selection to the store if a datum is present _and_ + // the interaction isn't occurring on a group mark. This guards against + // polluting interactive state with invalid values in faceted displays + // as the group marks are also data-driven. We force the update to account + // for constant null states but varying toggles (e.g., shift-click in + // whitespace followed by a click in whitespace; the store should only + // be cleared on the second click). + return [{ + name: selCmpt.name + TUPLE, + value: {}, + on: [{ + events: selCmpt.events, + update: "datum && item().mark.marktype !== 'group' ? " + + ("{unit: " + unitName(model) + ", encodings: [" + encodings + "], ") + + ("fields: [" + fields + "], values: [" + values + "]") + + (bins.length ? ', ' + bins.map(function (b) { return $('bin_' + b) + ": 1"; }).join(', ') : '') + + '} : null', + force: true + }] + }]; + } + var multi = { + predicate: 'vlMulti', + scaleDomain: 'vlMultiDomain', + signals: signals, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'null' : "{unit: " + unitName(model) + "}"); + } + }; + + var single = { + predicate: 'vlSingle', + scaleDomain: 'vlSingleDomain', + signals: signals, + topLevelSignals: function (model, selCmpt, signals$$1) { + var hasSignal = signals$$1.filter(function (s) { return s.name === selCmpt.name; }); + var data = "data(" + $(selCmpt.name + STORE) + ")"; + var values = data + "[0].values"; + return hasSignal.length ? signals$$1 : signals$$1.concat({ + name: selCmpt.name, + update: data + ".length && {" + + selCmpt.project.map(function (p, i) { return p.field + ": " + values + "[" + i + "]"; }).join(', ') + '}' + }); + }, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + TUPLE; + return tpl + ', ' + + (selCmpt.resolve === 'global' ? 'true' : "{unit: " + unitName(model) + "}"); + } + }; + + var inputBindings = { + has: function (selCmpt) { + return selCmpt.type === 'single' && selCmpt.resolve === 'global' && + selCmpt.bind && selCmpt.bind !== 'scales'; + }, + topLevelSignals: function (model, selCmpt, signals) { + var name = selCmpt.name; + var proj = selCmpt.project; + var bind = selCmpt.bind; + var datum = nearest.has(selCmpt) ? + '(item().isVoronoi ? datum.datum : datum)' : 'datum'; + proj.forEach(function (p) { + var sgname = varName(name + "_" + p.field); + var hasSignal = signals.filter(function (s) { return s.name === sgname; }); + if (!hasSignal.length) { + signals.unshift({ + name: sgname, + value: '', + on: [{ + events: selCmpt.events, + update: "datum && item().mark.marktype !== 'group' ? " + accessPathWithDatum(p.field, datum) + " : null" + }], + bind: bind[p.field] || bind[p.channel] || bind + }); + } + }); + return signals; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name; + var proj = selCmpt.project; + var signal = signals.filter(function (s) { return s.name === name + TUPLE; })[0]; + var fields = proj.map(function (p) { return $(p.field); }).join(', '); + var values = proj.map(function (p) { return varName(name + "_" + p.field); }); + if (values.length) { + signal.update = values.join(' && ') + " ? {fields: [" + fields + "], values: [" + values.join(', ') + "]} : null"; + } + delete signal.value; + delete signal.on; + return signals; + } + }; + + var project = { + has: function (selDef) { + var def = selDef; + return def.fields !== undefined || def.encodings !== undefined; + }, + parse: function (model, selDef, selCmpt) { + var channels = {}; + var timeUnits = {}; + // TODO: find a possible channel mapping for these fields. + (selDef.fields || []).forEach(function (field) { return channels[field] = null; }); + (selDef.encodings || []).forEach(function (channel) { + var fieldDef = model.fieldDef(channel); + if (fieldDef) { + if (fieldDef.timeUnit) { + var tuField = model.vgField(channel); + channels[tuField] = channel; + // Construct TimeUnitComponents which will be combined into a + // TimeUnitNode. This node may need to be inserted into the + // dataflow if the selection is used across views that do not + // have these time units defined. + timeUnits[tuField] = { + as: tuField, + field: fieldDef.field, + timeUnit: fieldDef.timeUnit + }; + } + else { + channels[fieldDef.field] = channel; + } + } + else { + warn(message.cannotProjectOnChannelWithoutField(channel)); + } + }); + var projection = selCmpt.project || (selCmpt.project = []); + for (var field in channels) { + if (channels.hasOwnProperty(field)) { + projection.push({ field: field, channel: channels[field] }); + } + } + var fields = selCmpt.fields || (selCmpt.fields = {}); + projection.filter(function (p) { return p.channel; }).forEach(function (p) { return fields[p.channel] = p.field; }); + if (keys(timeUnits).length) { + selCmpt.timeUnit = new TimeUnitNode(null, timeUnits); + } + } + }; + + var TOGGLE = '_toggle'; + var toggle = { + has: function (selCmpt) { + return selCmpt.type === 'multi' && selCmpt.toggle; + }, + signals: function (model, selCmpt, signals) { + return signals.concat({ + name: selCmpt.name + TOGGLE, + value: false, + on: [{ events: selCmpt.events, update: selCmpt.toggle }] + }); + }, + modifyExpr: function (model, selCmpt, expr) { + var tpl = selCmpt.name + TUPLE; + var signal = selCmpt.name + TOGGLE; + return signal + " ? null : " + tpl + ", " + + (selCmpt.resolve === 'global' ? + signal + " ? null : true, " : + signal + " ? null : {unit: " + unitName(model) + "}, ") + + (signal + " ? " + tpl + " : null"); + } + }; + + var ANCHOR = '_translate_anchor'; + var DELTA = '_translate_delta'; + var translate = { + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.translate; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name; + var hasScales = scaleBindings.has(selCmpt); + var anchor = name + ANCHOR; + var _a = positionalProjections(selCmpt), x = _a.x, y = _a.y; + var events = parseSelector(selCmpt.translate, 'scope'); + if (!hasScales) { + events = events.map(function (e) { return (e.between[0].markname = name + BRUSH, e); }); + } + signals.push({ + name: anchor, + value: {}, + on: [{ + events: events.map(function (e) { return e.between[0]; }), + update: '{x: x(unit), y: y(unit)' + + (x !== null ? ', extent_x: ' + (hasScales ? domain$1(model, X) : + "slice(" + channelSignalName(selCmpt, 'x', 'visual') + ")") : '') + + (y !== null ? ', extent_y: ' + (hasScales ? domain$1(model, Y) : + "slice(" + channelSignalName(selCmpt, 'y', 'visual') + ")") : '') + '}' + }] + }, { + name: name + DELTA, + value: {}, + on: [{ + events: events, + update: "{x: " + anchor + ".x - x(unit), y: " + anchor + ".y - y(unit)}" + }] + }); + if (x !== null) { + onDelta(model, selCmpt, X, 'width', signals); + } + if (y !== null) { + onDelta(model, selCmpt, Y, 'height', signals); + } + return signals; + } + }; + function onDelta(model, selCmpt, channel, size, signals) { + var name = selCmpt.name; + var hasScales = scaleBindings.has(selCmpt); + var signal = signals.filter(function (s) { + return s.name === channelSignalName(selCmpt, channel, hasScales ? 'data' : 'visual'); + })[0]; + var anchor = name + ANCHOR; + var delta = name + DELTA; + var sizeSg = model.getSizeSignalRef(size).signal; + var scaleCmpt = model.getScaleComponent(channel); + var scaleType = scaleCmpt.get('type'); + var sign = hasScales && channel === X ? '-' : ''; // Invert delta when panning x-scales. + var extent = anchor + ".extent_" + channel; + var offset = "" + sign + delta + "." + channel + " / " + (hasScales ? "" + sizeSg : "span(" + extent + ")"); + var panFn = !hasScales ? 'panLinear' : + scaleType === 'log' ? 'panLog' : + scaleType === 'pow' ? 'panPow' : 'panLinear'; + var update = panFn + "(" + extent + ", " + offset + + (hasScales && scaleType === 'pow' ? ", " + (scaleCmpt.get('exponent') || 1) : '') + ')'; + signal.on.push({ + events: { signal: delta }, + update: hasScales ? update : "clampRange(" + update + ", 0, " + sizeSg + ")" + }); + } + + var ANCHOR$1 = '_zoom_anchor'; + var DELTA$1 = '_zoom_delta'; + var zoom$1 = { + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.zoom; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name; + var hasScales = scaleBindings.has(selCmpt); + var delta = name + DELTA$1; + var _a = positionalProjections(selCmpt), x = _a.x, y = _a.y; + var sx = $(model.scaleName(X)); + var sy = $(model.scaleName(Y)); + var events = parseSelector(selCmpt.zoom, 'scope'); + if (!hasScales) { + events = events.map(function (e) { return (e.markname = name + BRUSH, e); }); + } + signals.push({ + name: name + ANCHOR$1, + on: [{ + events: events, + update: !hasScales ? "{x: x(unit), y: y(unit)}" : + '{' + [ + (sx ? "x: invert(" + sx + ", x(unit))" : ''), + (sy ? "y: invert(" + sy + ", y(unit))" : '') + ].filter(function (expr) { return !!expr; }).join(', ') + '}' + }] + }, { + name: delta, + on: [{ + events: events, + force: true, + update: 'pow(1.001, event.deltaY * pow(16, event.deltaMode))' + }] + }); + if (x !== null) { + onDelta$1(model, selCmpt, 'x', 'width', signals); + } + if (y !== null) { + onDelta$1(model, selCmpt, 'y', 'height', signals); + } + return signals; + } + }; + function onDelta$1(model, selCmpt, channel, size, signals) { + var name = selCmpt.name; + var hasScales = scaleBindings.has(selCmpt); + var signal = signals.filter(function (s) { + return s.name === channelSignalName(selCmpt, channel, hasScales ? 'data' : 'visual'); + })[0]; + var sizeSg = model.getSizeSignalRef(size).signal; + var scaleCmpt = model.getScaleComponent(channel); + var scaleType = scaleCmpt.get('type'); + var base = hasScales ? domain$1(model, channel) : signal.name; + var delta = name + DELTA$1; + var anchor = "" + name + ANCHOR$1 + "." + channel; + var zoomFn = !hasScales ? 'zoomLinear' : + scaleType === 'log' ? 'zoomLog' : + scaleType === 'pow' ? 'zoomPow' : 'zoomLinear'; + var update = zoomFn + "(" + base + ", " + anchor + ", " + delta + + (hasScales && scaleType === 'pow' ? ", " + (scaleCmpt.get('exponent') || 1) : '') + ')'; + signal.on.push({ + events: { signal: delta }, + update: hasScales ? update : "clampRange(" + update + ", 0, " + sizeSg + ")" + }); + } + + var compilers = { project: project, toggle: toggle, scales: scaleBindings, + translate: translate, zoom: zoom$1, inputs: inputBindings, nearest: nearest }; + function forEachTransform(selCmpt, cb) { + for (var t in compilers) { + if (compilers[t].has(selCmpt)) { + cb(compilers[t]); + } + } + } + + var STORE = '_store'; + var TUPLE = '_tuple'; + var MODIFY = '_modify'; + var SELECTION_DOMAIN = '_selection_domain_'; + function parseUnitSelection(model, selDefs) { + var selCmpts = {}; + var selectionConfig = model.config.selection; + var _loop_1 = function (name_1) { + if (!selDefs.hasOwnProperty(name_1)) { + return "continue"; + } + var selDef = selDefs[name_1]; + var cfg = selectionConfig[selDef.type]; + // Set default values from config if a property hasn't been specified, + // or if it is true. E.g., "translate": true should use the default + // event handlers for translate. However, true may be a valid value for + // a property (e.g., "nearest": true). + for (var key$$1 in cfg) { + // A selection should contain either `encodings` or `fields`, only use + // default values for these two values if neither of them is specified. + if ((key$$1 === 'encodings' && selDef.fields) || (key$$1 === 'fields' && selDef.encodings)) { + continue; + } + if (key$$1 === 'mark') { + selDef[key$$1] = __assign({}, cfg[key$$1], selDef[key$$1]); + } + if (selDef[key$$1] === undefined || selDef[key$$1] === true) { + selDef[key$$1] = cfg[key$$1] || selDef[key$$1]; + } + } + name_1 = varName(name_1); + var selCmpt = selCmpts[name_1] = __assign({}, selDef, { name: name_1, events: isString(selDef.on) ? parseSelector(selDef.on, 'scope') : selDef.on }); + forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.parse) { + txCompiler.parse(model, selDef, selCmpt); + } + }); + }; + for (var name_1 in selDefs) { + _loop_1(name_1); + } + return selCmpts; + } + function assembleUnitSelectionSignals(model, signals$$1) { + forEachSelection(model, function (selCmpt, selCompiler) { + var name = selCmpt.name; + var modifyExpr = selCompiler.modifyExpr(model, selCmpt); + signals$$1.push.apply(signals$$1, selCompiler.signals(model, selCmpt)); + forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.signals) { + signals$$1 = txCompiler.signals(model, selCmpt, signals$$1); + } + if (txCompiler.modifyExpr) { + modifyExpr = txCompiler.modifyExpr(model, selCmpt, modifyExpr); + } + }); + signals$$1.push({ + name: name + MODIFY, + on: [{ + events: { signal: name + TUPLE }, + update: "modify(" + $(selCmpt.name + STORE) + ", " + modifyExpr + ")" + }] + }); + }); + var facetModel = getFacetModel(model); + if (signals$$1.length && facetModel) { + var name_2 = $(facetModel.getName('cell')); + signals$$1.unshift({ + name: 'facet', + value: {}, + on: [{ + events: parseSelector('mousemove', 'scope'), + update: "isTuple(facet) ? facet : group(" + name_2 + ").datum" + }] + }); + } + return signals$$1; + } + function assembleTopLevelSignals(model, signals$$1) { + var needsUnit = false; + forEachSelection(model, function (selCmpt, selCompiler) { + if (selCompiler.topLevelSignals) { + signals$$1 = selCompiler.topLevelSignals(model, selCmpt, signals$$1); + } + forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.topLevelSignals) { + signals$$1 = txCompiler.topLevelSignals(model, selCmpt, signals$$1); + } + }); + needsUnit = true; + }); + if (needsUnit) { + var hasUnit = signals$$1.filter(function (s) { return s.name === 'unit'; }); + if (!(hasUnit.length)) { + signals$$1.unshift({ + name: 'unit', + value: {}, + on: [{ events: 'mousemove', update: 'isTuple(group()) ? group() : unit' }] + }); + } + } + return signals$$1; + } + function assembleUnitSelectionData(model, data) { + forEachSelection(model, function (selCmpt) { + var contains$$1 = data.filter(function (d) { return d.name === selCmpt.name + STORE; }); + if (!contains$$1.length) { + data.push({ name: selCmpt.name + STORE }); + } + }); + return data; + } + function assembleUnitSelectionMarks(model, marks) { + forEachSelection(model, function (selCmpt, selCompiler) { + marks = selCompiler.marks ? selCompiler.marks(model, selCmpt, marks) : marks; + forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.marks) { + marks = txCompiler.marks(model, selCmpt, marks); + } + }); + }); + return marks; + } + function assembleLayerSelectionMarks(model, marks) { + model.children.forEach(function (child) { + if (isUnitModel(child)) { + marks = assembleUnitSelectionMarks(child, marks); + } + }); + return marks; + } + function selectionPredicate(model, selections, dfnode) { + var stores = []; + function expr(name) { + var vname = varName(name); + var selCmpt = model.getSelectionComponent(vname, name); + var store = $(vname + STORE); + if (selCmpt.timeUnit) { + var child = dfnode || model.component.data.raw; + var tunode = selCmpt.timeUnit.clone(); + if (child.parent) { + tunode.insertAsParentOf(child); + } + else { + child.parent = tunode; + } + } + if (selCmpt.empty !== 'none') { + stores.push(store); + } + return compiler(selCmpt.type).predicate + ("(" + store + ", datum") + + (selCmpt.resolve === 'global' ? ')' : ", " + $(selCmpt.resolve) + ")"); + } + var predicateStr = logicalExpr(selections, expr); + return (stores.length + ? '!(' + stores.map(function (s) { return "length(data(" + s + "))"; }).join(' || ') + ') || ' + : '') + ("(" + predicateStr + ")"); + } + // Selections are parsed _after_ scales. If a scale domain is set to + // use a selection, the SELECTION_DOMAIN constant is used as the + // domainRaw.signal during scale.parse and then replaced with the necessary + // selection expression function during scale.assemble. To not pollute the + // type signatures to account for this setup, the selection domain definition + // is coerced to a string and appended to SELECTION_DOMAIN. + function isRawSelectionDomain(domainRaw) { + return domainRaw.signal.indexOf(SELECTION_DOMAIN) >= 0; + } + function selectionScaleDomain(model, domainRaw) { + var selDomain = JSON.parse(domainRaw.signal.replace(SELECTION_DOMAIN, '')); + var name = varName(selDomain.selection); + var selCmpt = model.component.selection && model.component.selection[name]; + if (selCmpt) { + warn('Use "bind": "scales" to setup a binding for scales and selections within the same view.'); + } + else { + selCmpt = model.getSelectionComponent(name, selDomain.selection); + if (!selDomain.encoding && !selDomain.field) { + selDomain.field = selCmpt.project[0].field; + if (selCmpt.project.length > 1) { + warn('A "field" or "encoding" must be specified when using a selection as a scale domain. ' + + ("Using \"field\": " + $(selDomain.field) + ".")); + } + } + return { + signal: compiler(selCmpt.type).scaleDomain + + ("(" + $(name + STORE) + ", " + $(selDomain.encoding || null) + ", ") + + $(selDomain.field || null) + + (selCmpt.resolve === 'global' ? ')' : ", " + $(selCmpt.resolve) + ")") + }; + } + return { signal: 'null' }; + } + // Utility functions + function forEachSelection(model, cb) { + var selections = model.component.selection; + for (var name_3 in selections) { + if (selections.hasOwnProperty(name_3)) { + var sel = selections[name_3]; + cb(sel, compiler(sel.type)); + } + } + } + function compiler(type) { + switch (type) { + case 'single': + return single; + case 'multi': + return multi; + case 'interval': + return interval; + } + return null; + } + function getFacetModel(model) { + var parent = model.parent; + while (parent) { + if (isFacetModel(parent)) { + break; + } + parent = parent.parent; + } + return parent; + } + function unitName(model) { + var name = $(model.name); + var facet = getFacetModel(model); + if (facet) { + name += (facet.facet.row ? " + '_' + (" + accessPathWithDatum(facet.vgField('row'), 'facet') + ")" : '') + + (facet.facet.column ? " + '_' + (" + accessPathWithDatum(facet.vgField('column'), 'facet') + ")" : ''); + } + return name; + } + function requiresSelectionId(model) { + var identifier = false; + forEachSelection(model, function (selCmpt) { + identifier = identifier || selCmpt.project.some(function (proj) { return proj.field === SELECTION_ID; }); + }); + return identifier; + } + function channelSignalName(selCmpt, channel, range) { + var sgNames = selCmpt._signalNames || (selCmpt._signalNames = {}); + if (sgNames[channel] && sgNames[channel][range]) { + return sgNames[channel][range]; + } + sgNames[channel] = sgNames[channel] || {}; + var basename = varName(selCmpt.name + '_' + (range === 'visual' ? channel : selCmpt.fields[channel])); + var name = basename; + var counter = 1; + while (sgNames[name]) { + name = basename + "_" + counter++; + } + return (sgNames[name] = sgNames[channel][range] = name); + } + function positionalProjections(selCmpt) { + var x = null; + var xi = null; + var y = null; + var yi = null; + selCmpt.project.forEach(function (p, i) { + if (p.channel === X) { + x = p; + xi = i; + } + else if (p.channel === Y) { + y = p; + yi = i; + } + }); + return { x: x, xi: xi, y: y, yi: yi }; + } + + function isSelectionPredicate(predicate) { + return predicate && predicate['selection']; + } + function isFieldEqualPredicate(predicate) { + return predicate && !!predicate.field && predicate.equal !== undefined; + } + function isFieldLTPredicate(predicate) { + return predicate && !!predicate.field && predicate.lt !== undefined; + } + function isFieldLTEPredicate(predicate) { + return predicate && !!predicate.field && predicate.lte !== undefined; + } + function isFieldGTPredicate(predicate) { + return predicate && !!predicate.field && predicate.gt !== undefined; + } + function isFieldGTEPredicate(predicate) { + return predicate && !!predicate.field && predicate.gte !== undefined; + } + function isFieldRangePredicate(predicate) { + if (predicate && predicate.field) { + if (isArray(predicate.range) && predicate.range.length === 2) { + return true; + } + } + return false; + } + function isFieldOneOfPredicate(predicate) { + return predicate && !!predicate.field && (isArray(predicate.oneOf) || + isArray(predicate.in) // backward compatibility + ); + } + function isFieldPredicate(predicate) { + return isFieldOneOfPredicate(predicate) || isFieldEqualPredicate(predicate) || isFieldRangePredicate(predicate) || isFieldLTPredicate(predicate) || isFieldGTPredicate(predicate) || isFieldLTEPredicate(predicate) || isFieldGTEPredicate(predicate); + } + /** + * Converts a predicate into an expression. + */ + // model is only used for selection filters. + function expression(model, filterOp, node) { + return logicalExpr(filterOp, function (predicate) { + if (isString(predicate)) { + return predicate; + } + else if (isSelectionPredicate(predicate)) { + return selectionPredicate(model, predicate.selection, node); + } + else { // Filter Object + return fieldFilterExpression(predicate); + } + }); + } + function predicateValueExpr(v, timeUnit) { + return valueExpr(v, { timeUnit: timeUnit, time: true }); + } + function predicateValuesExpr(vals$$1, timeUnit) { + return vals$$1.map(function (v) { return predicateValueExpr(v, timeUnit); }); + } + // This method is used by Voyager. Do not change its behavior without changing Voyager. + function fieldFilterExpression(predicate, useInRange) { + if (useInRange === void 0) { useInRange = true; } + var field$$1 = predicate.field, timeUnit = predicate.timeUnit; + var fieldExpr$$1 = timeUnit ? + // For timeUnit, cast into integer with time() so we can use ===, inrange, indexOf to compare values directly. + // TODO: We calculate timeUnit on the fly here. Consider if we would like to consolidate this with timeUnit pipeline + // TODO: support utc + ('time(' + fieldExpr(timeUnit, field$$1) + ')') : + vgField(predicate, { expr: 'datum' }); + if (isFieldEqualPredicate(predicate)) { + return fieldExpr$$1 + '===' + predicateValueExpr(predicate.equal, timeUnit); + } + else if (isFieldLTPredicate(predicate)) { + var upper = predicate.lt; + return fieldExpr$$1 + "<" + predicateValueExpr(upper, timeUnit); + } + else if (isFieldGTPredicate(predicate)) { + var lower = predicate.gt; + return fieldExpr$$1 + ">" + predicateValueExpr(lower, timeUnit); + } + else if (isFieldLTEPredicate(predicate)) { + var upper = predicate.lte; + return fieldExpr$$1 + "<=" + predicateValueExpr(upper, timeUnit); + } + else if (isFieldGTEPredicate(predicate)) { + var lower = predicate.gte; + return fieldExpr$$1 + ">=" + predicateValueExpr(lower, timeUnit); + } + else if (isFieldOneOfPredicate(predicate)) { + // "oneOf" was formerly "in" -- so we need to add backward compatibility + var oneOf = predicate.oneOf; + oneOf = oneOf || predicate['in']; + return 'indexof([' + + predicateValuesExpr(oneOf, timeUnit).join(',') + + '], ' + fieldExpr$$1 + ') !== -1'; + } + else if (isFieldRangePredicate(predicate)) { + var lower = predicate.range[0]; + var upper = predicate.range[1]; + if (lower !== null && upper !== null && useInRange) { + return 'inrange(' + fieldExpr$$1 + ', [' + + predicateValueExpr(lower, timeUnit) + ', ' + + predicateValueExpr(upper, timeUnit) + '])'; + } + var exprs = []; + if (lower !== null) { + exprs.push(fieldExpr$$1 + " >= " + predicateValueExpr(lower, timeUnit)); + } + if (upper !== null) { + exprs.push(fieldExpr$$1 + " <= " + predicateValueExpr(upper, timeUnit)); + } + return exprs.length > 0 ? exprs.join(' && ') : 'true'; + } + /* istanbul ignore next: it should never reach here */ + throw new Error("Invalid field predicate: " + JSON.stringify(predicate)); + } + function normalizePredicate(f) { + if (isFieldPredicate(f) && f.timeUnit) { + return __assign({}, f, { timeUnit: normalizeTimeUnit(f.timeUnit) }); + } + return f; + } + + function isFilter(t) { + return t['filter'] !== undefined; + } + function isLookup(t) { + return t['lookup'] !== undefined; + } + function isWindow(t) { + return t['window'] !== undefined; + } + function isCalculate(t) { + return t['calculate'] !== undefined; + } + function isBin(t) { + return !!t['bin']; + } + function isTimeUnit$1(t) { + return t['timeUnit'] !== undefined; + } + function isAggregate$1(t) { + return t['aggregate'] !== undefined; + } + function isStack(t) { + return t['stack'] !== undefined; + } + function normalizeTransform(transform) { + return transform.map(function (t) { + if (isFilter(t)) { + return { + filter: normalizeLogicalOperand(t.filter, normalizePredicate) + }; + } + return t; + }); + } + + var transform = /*#__PURE__*/Object.freeze({ + isFilter: isFilter, + isLookup: isLookup, + isWindow: isWindow, + isCalculate: isCalculate, + isBin: isBin, + isTimeUnit: isTimeUnit$1, + isAggregate: isAggregate$1, + isStack: isStack, + normalizeTransform: normalizeTransform + }); + + function rangeFormula(model, fieldDef, channel, config) { + if (binRequiresRange(fieldDef, channel)) { + // read format from axis or legend, if there is no format then use config.numberFormat + var guide = isUnitModel(model) ? (model.axis(channel) || model.legend(channel) || {}) : {}; + var startField = vgField(fieldDef, { expr: 'datum', }); + var endField = vgField(fieldDef, { expr: 'datum', binSuffix: 'end' }); + return { + formulaAs: vgField(fieldDef, { binSuffix: 'range' }), + formula: binFormatExpression(startField, endField, guide.format, config) + }; + } + return {}; + } + function binKey(bin, field$$1) { + return binToString(bin) + "_" + field$$1; + } + function getSignalsFromModel(model, key$$1) { + return { + signal: model.getName(key$$1 + "_bins"), + extentSignal: model.getName(key$$1 + "_extent") + }; + } + function isBinTransform(t) { + return 'as' in t; + } + function createBinComponent(t, model) { + var as; + if (isBinTransform(t)) { + as = isString(t.as) ? [t.as, t.as + "_end"] : [t.as[0], t.as[1]]; + } + else { + as = [vgField(t, {}), vgField(t, { binSuffix: 'end' })]; + } + var bin = normalizeBin(t.bin, undefined) || {}; + var key$$1 = binKey(bin, t.field); + var _a = getSignalsFromModel(model, key$$1), signal = _a.signal, extentSignal = _a.extentSignal; + var binComponent = __assign({ bin: bin, field: t.field, as: as }, signal ? { signal: signal } : {}, extentSignal ? { extentSignal: extentSignal } : {}); + return { key: key$$1, binComponent: binComponent }; + } + var BinNode = /** @class */ (function (_super) { + __extends(BinNode, _super); + function BinNode(parent, bins) { + var _this = _super.call(this, parent) || this; + _this.bins = bins; + return _this; + } + BinNode.prototype.clone = function () { + return new BinNode(null, duplicate(this.bins)); + }; + BinNode.makeFromEncoding = function (parent, model) { + var bins = model.reduceFieldDef(function (binComponentIndex, fieldDef, channel) { + if (fieldDef.bin) { + var _a = createBinComponent(fieldDef, model), key$$1 = _a.key, binComponent = _a.binComponent; + binComponentIndex[key$$1] = __assign({}, binComponent, binComponentIndex[key$$1], rangeFormula(model, fieldDef, channel, model.config)); + } + return binComponentIndex; + }, {}); + if (keys(bins).length === 0) { + return null; + } + return new BinNode(parent, bins); + }; + /** + * Creates a bin node from BinTransform. + * The optional parameter should provide + */ + BinNode.makeFromTransform = function (parent, t, model) { + var _a; + var _b = createBinComponent(t, model), key$$1 = _b.key, binComponent = _b.binComponent; + return new BinNode(parent, (_a = {}, + _a[key$$1] = binComponent, + _a)); + }; + BinNode.prototype.merge = function (other) { + this.bins = __assign({}, this.bins, other.bins); + other.remove(); + }; + BinNode.prototype.producedFields = function () { + var out = {}; + vals(this.bins).forEach(function (c) { + c.as.forEach(function (f) { return out[f] = true; }); + }); + return out; + }; + BinNode.prototype.dependentFields = function () { + var out = {}; + vals(this.bins).forEach(function (c) { + out[c.field] = true; + }); + return out; + }; + BinNode.prototype.assemble = function () { + return flatten(vals(this.bins).map(function (bin) { + var transform = []; + var binTrans = __assign({ type: 'bin', field: bin.field, as: bin.as, signal: bin.signal }, bin.bin); + if (!bin.bin.extent && bin.extentSignal) { + transform.push({ + type: 'extent', + field: bin.field, + signal: bin.extentSignal + }); + binTrans.extent = { signal: bin.extentSignal }; + } + transform.push(binTrans); + if (bin.formula) { + transform.push({ + type: 'formula', + expr: bin.formula, + as: bin.formulaAs + }); + } + return transform; + })); + }; + return BinNode; + }(DataFlowNode)); + + var FilterNode = /** @class */ (function (_super) { + __extends(FilterNode, _super); + function FilterNode(parent, model, filter) { + var _this = _super.call(this, parent) || this; + _this.model = model; + _this.filter = filter; + _this.expr = expression(_this.model, _this.filter, _this); + return _this; + } + FilterNode.prototype.clone = function () { + return new FilterNode(null, this.model, duplicate(this.filter)); + }; + FilterNode.prototype.assemble = function () { + return { + type: 'filter', + expr: this.expr + }; + }; + return FilterNode; + }(DataFlowNode)); + + var GeoJSONNode = /** @class */ (function (_super) { + __extends(GeoJSONNode, _super); + function GeoJSONNode(parent, fields, geojson, signal) { + var _this = _super.call(this, parent) || this; + _this.fields = fields; + _this.geojson = geojson; + _this.signal = signal; + return _this; + } + GeoJSONNode.prototype.clone = function () { + return new GeoJSONNode(null, duplicate(this.fields), this.geojson, this.signal); + }; + GeoJSONNode.parseAll = function (parent, model) { + var geoJsonCounter = 0; + [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach(function (coordinates) { + var pair = coordinates.map(function (channel) { return model.channelHasField(channel) ? model.fieldDef(channel).field : undefined; }); + if (pair[0] || pair[1]) { + parent = new GeoJSONNode(parent, pair, null, model.getName("geojson_" + geoJsonCounter++)); + } + }); + if (model.channelHasField(SHAPE)) { + var fieldDef = model.fieldDef(SHAPE); + if (fieldDef.type === GEOJSON) { + parent = new GeoJSONNode(parent, null, fieldDef.field, model.getName("geojson_" + geoJsonCounter++)); + } + } + return parent; + }; + GeoJSONNode.prototype.assemble = function () { + return __assign({ type: 'geojson' }, (this.fields ? { fields: this.fields } : {}), (this.geojson ? { geojson: this.geojson } : {}), { signal: this.signal }); + }; + return GeoJSONNode; + }(DataFlowNode)); + + var GeoPointNode = /** @class */ (function (_super) { + __extends(GeoPointNode, _super); + function GeoPointNode(parent, projection, fields, as) { + var _this = _super.call(this, parent) || this; + _this.projection = projection; + _this.fields = fields; + _this.as = as; + return _this; + } + GeoPointNode.prototype.clone = function () { + return new GeoPointNode(null, this.projection, duplicate(this.fields), duplicate(this.as)); + }; + GeoPointNode.parseAll = function (parent, model) { + if (!model.projectionName()) { + return parent; + } + [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach(function (coordinates) { + var pair = coordinates.map(function (channel) { return model.channelHasField(channel) ? model.fieldDef(channel).field : undefined; }); + var suffix = coordinates[0] === LONGITUDE2 ? '2' : ''; + if (pair[0] || pair[1]) { + parent = new GeoPointNode(parent, model.projectionName(), pair, [model.getName('x' + suffix), model.getName('y' + suffix)]); + } + }); + return parent; + }; + GeoPointNode.prototype.assemble = function () { + return { + type: 'geopoint', + projection: this.projection, + fields: this.fields, + as: this.as + }; + }; + return GeoPointNode; + }(DataFlowNode)); + + var IdentifierNode = /** @class */ (function (_super) { + __extends(IdentifierNode, _super); + function IdentifierNode(parent) { + return _super.call(this, parent) || this; + } + IdentifierNode.prototype.clone = function () { + return new IdentifierNode(null); + }; + IdentifierNode.prototype.producedFields = function () { + var _a; + return _a = {}, _a[SELECTION_ID] = true, _a; + }; + IdentifierNode.prototype.assemble = function () { + return { type: 'identifier', as: SELECTION_ID }; + }; + return IdentifierNode; + }(DataFlowNode)); + + /** + * Class to track interesting properties (see https://15721.courses.cs.cmu.edu/spring2016/papers/graefe-ieee1995.pdf) + * about how fields have been parsed or whether they have been derived in a transforms. We use this to not parse the + * same field again (or differently). + */ + var AncestorParse = /** @class */ (function (_super) { + __extends(AncestorParse, _super); + function AncestorParse(explicit, implicit, parseNothing) { + if (explicit === void 0) { explicit = {}; } + if (implicit === void 0) { implicit = {}; } + if (parseNothing === void 0) { parseNothing = false; } + var _this = _super.call(this, explicit, implicit) || this; + _this.explicit = explicit; + _this.implicit = implicit; + _this.parseNothing = parseNothing; + return _this; + } + AncestorParse.prototype.clone = function () { + var clone = _super.prototype.clone.call(this); + clone.parseNothing = this.parseNothing; + return clone; + }; + return AncestorParse; + }(Split)); + + var LookupNode = /** @class */ (function (_super) { + __extends(LookupNode, _super); + function LookupNode(parent, transform, secondary) { + var _this = _super.call(this, parent) || this; + _this.transform = transform; + _this.secondary = secondary; + return _this; + } + LookupNode.make = function (parent, model, transform, counter) { + var sources = model.component.data.sources; + var s = new SourceNode(transform.from.data); + var fromSource = sources[s.hash()]; + if (!fromSource) { + sources[s.hash()] = s; + fromSource = s; + } + var fromOutputName = model.getName("lookup_" + counter); + var fromOutputNode = new OutputNode(fromSource, fromOutputName, 'lookup', model.component.data.outputNodeRefCounts); + model.component.data.outputNodes[fromOutputName] = fromOutputNode; + return new LookupNode(parent, transform, fromOutputNode.getSource()); + }; + LookupNode.prototype.producedFields = function () { + return toSet(this.transform.from.fields || ((this.transform.as instanceof Array) ? this.transform.as : [this.transform.as])); + }; + LookupNode.prototype.assemble = function () { + var foreign; + if (this.transform.from.fields) { + // lookup a few fields and add create a flat output + foreign = __assign({ values: this.transform.from.fields }, this.transform.as ? { as: ((this.transform.as instanceof Array) ? this.transform.as : [this.transform.as]) } : {}); + } + else { + // lookup full record and nest it + var asName = this.transform.as; + if (!isString(asName)) { + warn(message.NO_FIELDS_NEEDS_AS); + asName = '_lookup'; + } + foreign = { + as: [asName] + }; + } + return __assign({ type: 'lookup', from: this.secondary, key: this.transform.from.key, fields: [this.transform.lookup] }, foreign, (this.transform.default ? { default: this.transform.default } : {})); + }; + return LookupNode; + }(DataFlowNode)); + + function makeWalkTree(data) { + // to name datasources + var datasetIndex = 0; + /** + * Recursively walk down the tree. + */ + function walkTree(node, dataSource) { + if (node instanceof SourceNode) { + // If the source is a named data source or a data source with values, we need + // to put it in a different data source. Otherwise, Vega may override the data. + if (!isUrlData(node.data)) { + data.push(dataSource); + var newData = { + name: null, + source: dataSource.name, + transform: [] + }; + dataSource = newData; + } + } + if (node instanceof ParseNode) { + if (node.parent instanceof SourceNode && !dataSource.source) { + // If node's parent is a root source and the data source does not refer to another data source, use normal format parse + dataSource.format = __assign({}, dataSource.format || {}, { parse: node.assembleFormatParse() }); + // add calculates for all nested fields + dataSource.transform = dataSource.transform.concat(node.assembleTransforms(true)); + } + else { + // Otherwise use Vega expression to parse + dataSource.transform = dataSource.transform.concat(node.assembleTransforms()); + } + } + if (node instanceof FacetNode) { + if (!dataSource.name) { + dataSource.name = "data_" + datasetIndex++; + } + if (!dataSource.source || dataSource.transform.length > 0) { + data.push(dataSource); + node.data = dataSource.name; + } + else { + node.data = dataSource.source; + } + node.assemble().forEach(function (d) { return data.push(d); }); + // break here because the rest of the tree has to be taken care of by the facet. + return; + } + if (node instanceof FilterNode || + node instanceof CalculateNode || + node instanceof GeoPointNode || + node instanceof GeoJSONNode || + node instanceof AggregateNode || + node instanceof LookupNode || + node instanceof WindowTransformNode || + node instanceof IdentifierNode) { + dataSource.transform.push(node.assemble()); + } + if (node instanceof FilterInvalidNode || + node instanceof BinNode || + node instanceof TimeUnitNode || + node instanceof StackNode) { + dataSource.transform = dataSource.transform.concat(node.assemble()); + } + if (node instanceof AggregateNode) { + if (!dataSource.name) { + dataSource.name = "data_" + datasetIndex++; + } + } + if (node instanceof OutputNode) { + if (dataSource.source && dataSource.transform.length === 0) { + node.setSource(dataSource.source); + } + else if (node.parent instanceof OutputNode) { + // Note that an output node may be required but we still do not assemble a + // separate data source for it. + node.setSource(dataSource.name); + } + else { + if (!dataSource.name) { + dataSource.name = "data_" + datasetIndex++; + } + // Here we set the name of the datasource we generated. From now on + // other assemblers can use it. + node.setSource(dataSource.name); + // if this node has more than one child, we will add a datasource automatically + if (node.numChildren() === 1) { + data.push(dataSource); + var newData = { + name: null, + source: dataSource.name, + transform: [] + }; + dataSource = newData; + } + } + } + switch (node.numChildren()) { + case 0: + // done + if (node instanceof OutputNode && (!dataSource.source || dataSource.transform.length > 0)) { + // do not push empty datasources that are simply references + data.push(dataSource); + } + break; + case 1: + walkTree(node.children[0], dataSource); + break; + default: + if (!dataSource.name) { + dataSource.name = "data_" + datasetIndex++; + } + var source_1 = dataSource.name; + if (!dataSource.source || dataSource.transform.length > 0) { + data.push(dataSource); + } + else { + source_1 = dataSource.source; + } + node.children.forEach(function (child) { + var newData = { + name: null, + source: source_1, + transform: [] + }; + walkTree(child, newData); + }); + break; + } + } + return walkTree; + } + /** + * Assemble data sources that are derived from faceted data. + */ + function assembleFacetData(root) { + var data = []; + var walkTree = makeWalkTree(data); + root.children.forEach(function (child) { return walkTree(child, { + source: root.name, + name: null, + transform: [] + }); }); + return data; + } + /** + * Create Vega Data array from a given compiled model and append all of them to the given array + * + * @param model + * @param data array + * @return modified data array + */ + function assembleRootData(dataComponent, datasets) { + var roots = vals(dataComponent.sources); + var data = []; + // roots.forEach(debug); + var walkTree = makeWalkTree(data); + var sourceIndex = 0; + roots.forEach(function (root) { + // assign a name if the source does not have a name yet + if (!root.hasName()) { + root.dataName = "source_" + sourceIndex++; + } + var newData = root.assemble(); + walkTree(root, newData); + }); + // remove empty transform arrays for cleaner output + data.forEach(function (d) { + if (d.transform.length === 0) { + delete d.transform; + } + }); + // move sources without transforms (the ones that are potentially used in lookups) to the beginning + var whereTo = 0; + for (var i = 0; i < data.length; i++) { + var d = data[i]; + if ((d.transform || []).length === 0 && !d.source) { + data.splice(whereTo++, 0, data.splice(i, 1)[0]); + } + } + // now fix the from references in lookup transforms + for (var _i = 0, data_1 = data; _i < data_1.length; _i++) { + var d = data_1[_i]; + for (var _a = 0, _b = d.transform || []; _a < _b.length; _a++) { + var t = _b[_a]; + if (t.type === 'lookup') { + t.from = dataComponent.outputNodes[t.from].getSource(); + } + } + } + // inline values for datasets that are in the datastore + for (var _c = 0, data_2 = data; _c < data_2.length; _c++) { + var d = data_2[_c]; + if (d.name in datasets) { + d.values = datasets[d.name]; + } + } + return data; + } + + function parseLayerLayoutSize(model) { + parseChildrenLayoutSize(model); + var layoutSizeCmpt = model.component.layoutSize; + layoutSizeCmpt.setWithExplicit('width', parseNonUnitLayoutSizeForChannel(model, 'width')); + layoutSizeCmpt.setWithExplicit('height', parseNonUnitLayoutSizeForChannel(model, 'height')); + } + var parseRepeatLayoutSize = parseLayerLayoutSize; + function parseConcatLayoutSize(model) { + parseChildrenLayoutSize(model); + var layoutSizeCmpt = model.component.layoutSize; + var sizeTypeToMerge = model.isVConcat ? 'width' : 'height'; + layoutSizeCmpt.setWithExplicit(sizeTypeToMerge, parseNonUnitLayoutSizeForChannel(model, sizeTypeToMerge)); + } + function parseChildrenLayoutSize(model) { + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseLayoutSize(); + } + } + function parseNonUnitLayoutSizeForChannel(model, sizeType) { + var channel = sizeType === 'width' ? 'x' : 'y'; + var resolve = model.component.resolve; + var mergedSize; + // Try to merge layout size + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + var childSize = child.component.layoutSize.getWithExplicit(sizeType); + var scaleResolve = resolve.scale[channel]; + if (scaleResolve === 'independent' && childSize.value === 'range-step') { + // Do not merge independent scales with range-step as their size depends + // on the scale domains, which can be different between scales. + mergedSize = undefined; + break; + } + if (mergedSize) { + if (scaleResolve === 'independent' && mergedSize.value !== childSize.value) { + // For independent scale, only merge if all the sizes are the same. + // If the values are different, abandon the merge! + mergedSize = undefined; + break; + } + mergedSize = mergeValuesWithExplicit(mergedSize, childSize, sizeType, ''); + } + else { + mergedSize = childSize; + } + } + if (mergedSize) { + // If merged, rename size and set size of all children. + for (var _b = 0, _c = model.children; _b < _c.length; _b++) { + var child = _c[_b]; + model.renameLayoutSize(child.getName(sizeType), model.getName(sizeType)); + child.component.layoutSize.set(sizeType, 'merged', false); + } + return mergedSize; + } + else { + // Otherwise, there is no merged size. + return { + explicit: false, + value: undefined + }; + } + } + function parseUnitLayoutSize(model) { + var layoutSizeComponent = model.component.layoutSize; + if (!layoutSizeComponent.explicit.width) { + var width = defaultUnitSize(model, 'width'); + layoutSizeComponent.set('width', width, false); + } + if (!layoutSizeComponent.explicit.height) { + var height = defaultUnitSize(model, 'height'); + layoutSizeComponent.set('height', height, false); + } + } + function defaultUnitSize(model, sizeType) { + var channel = sizeType === 'width' ? 'x' : 'y'; + var config = model.config; + var scaleComponent = model.getScaleComponent(channel); + if (scaleComponent) { + var scaleType = scaleComponent.get('type'); + var range = scaleComponent.get('range'); + if (hasDiscreteDomain(scaleType) && isVgRangeStep(range)) { + // For discrete domain with range.step, use dynamic width/height + return 'range-step'; + } + else { + return config.view[sizeType]; + } + } + else if (model.hasProjection) { + return config.view[sizeType]; + } + else { + // No scale - set default size + if (sizeType === 'width' && model.mark === 'text') { + // width for text mark without x-field is a bit wider than typical range step + return config.scale.textXRangeStep; + } + // Set width/height equal to rangeStep config or if rangeStep is null, use value from default scale config. + return config.scale.rangeStep || defaultScaleConfig.rangeStep; + } + } + + function replaceRepeaterInFacet(facet, repeater) { + return replaceRepeater(facet, repeater); + } + function replaceRepeaterInEncoding(encoding, repeater) { + return replaceRepeater(encoding, repeater); + } + /** + * Replaces repeated value and returns if the repeated value is valid. + */ + function replaceRepeat(o, repeater) { + if (isRepeatRef(o.field)) { + if (o.field.repeat in repeater) { + // any needed to calm down ts compiler + return __assign({}, o, { field: repeater[o.field.repeat] }); + } + else { + warn(message.noSuchRepeatedValue(o.field.repeat)); + return undefined; + } + } + return o; + } + /** + * Replace repeater values in a field def with the concrete field name. + */ + function replaceRepeaterInFieldDef(fieldDef, repeater) { + fieldDef = replaceRepeat(fieldDef, repeater); + if (fieldDef === undefined) { + // the field def should be ignored + return undefined; + } + if (fieldDef.sort && isSortField(fieldDef.sort)) { + var sort = replaceRepeat(fieldDef.sort, repeater); + fieldDef = __assign({}, fieldDef, (sort ? { sort: sort } : {})); + } + return fieldDef; + } + function replaceRepeaterInChannelDef(channelDef, repeater) { + if (isFieldDef(channelDef)) { + var fd = replaceRepeaterInFieldDef(channelDef, repeater); + if (fd) { + return fd; + } + else if (isConditionalDef(channelDef)) { + return { condition: channelDef.condition }; + } + } + else { + if (hasConditionalFieldDef(channelDef)) { + var fd = replaceRepeaterInFieldDef(channelDef.condition, repeater); + if (fd) { + return __assign({}, channelDef, { condition: fd }); + } + else { + var condition = channelDef.condition, channelDefWithoutCondition = __rest(channelDef, ["condition"]); + return channelDefWithoutCondition; + } + } + return channelDef; + } + return undefined; + } + function replaceRepeater(mapping, repeater) { + var out = {}; + for (var channel in mapping) { + if (mapping.hasOwnProperty(channel)) { + var channelDef = mapping[channel]; + if (isArray(channelDef)) { + // array cannot have condition + out[channel] = channelDef.map(function (cd) { return replaceRepeaterInChannelDef(cd, repeater); }) + .filter(function (cd) { return cd; }); + } + else { + var cd = replaceRepeaterInChannelDef(channelDef, repeater); + if (cd) { + out[channel] = cd; + } + } + } + } + return out; + } + + function facetSortFieldName(fieldDef, sort, expr) { + return vgField(sort, { expr: expr, suffix: "by_" + vgField(fieldDef) }); + } + var FacetModel = /** @class */ (function (_super) { + __extends(FacetModel, _super); + function FacetModel(spec, parent, parentGivenName, repeater, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, repeater, spec.resolve) || this; + _this.type = 'facet'; + _this.child = buildModel(spec.spec, _this, _this.getName('child'), undefined, repeater, config, false); + _this.children = [_this.child]; + var facet = replaceRepeaterInFacet(spec.facet, repeater); + _this.facet = _this.initFacet(facet); + return _this; + } + FacetModel.prototype.initFacet = function (facet) { + // clone to prevent side effect to the original spec + return reduce(facet, function (normalizedFacet, fieldDef, channel) { + if (!contains([ROW, COLUMN], channel)) { + // Drop unsupported channel + warn(message.incompatibleChannel(channel, 'facet')); + return normalizedFacet; + } + if (fieldDef.field === undefined) { + warn(message.emptyFieldDef(fieldDef, channel)); + return normalizedFacet; + } + // Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + normalizedFacet[channel] = normalize(fieldDef, channel); + return normalizedFacet; + }, {}); + }; + FacetModel.prototype.channelHasField = function (channel) { + return !!this.facet[channel]; + }; + FacetModel.prototype.fieldDef = function (channel) { + return this.facet[channel]; + }; + FacetModel.prototype.parseData = function () { + this.component.data = parseData(this); + this.child.parseData(); + }; + FacetModel.prototype.parseLayoutSize = function () { + parseChildrenLayoutSize(this); + }; + FacetModel.prototype.parseSelection = function () { + // As a facet has a single child, the selection components are the same. + // The child maintains its selections to assemble signals, which remain + // within its unit. + this.child.parseSelection(); + this.component.selection = this.child.component.selection; + }; + FacetModel.prototype.parseMarkGroup = function () { + this.child.parseMarkGroup(); + }; + FacetModel.prototype.parseAxisAndHeader = function () { + this.child.parseAxisAndHeader(); + this.parseHeader('column'); + this.parseHeader('row'); + this.mergeChildAxis('x'); + this.mergeChildAxis('y'); + }; + FacetModel.prototype.parseHeader = function (channel) { + if (this.channelHasField(channel)) { + var fieldDef = this.facet[channel]; + var header = fieldDef.header || {}; + var title$$1 = fieldDef.title !== undefined ? fieldDef.title : + header.title !== undefined ? header.title : title(fieldDef, this.config); + if (this.child.component.layoutHeaders[channel].title) { + // merge title with child to produce "Title / Subtitle / Sub-subtitle" + title$$1 += ' / ' + this.child.component.layoutHeaders[channel].title; + this.child.component.layoutHeaders[channel].title = null; + } + this.component.layoutHeaders[channel] = { + title: title$$1, + facetFieldDef: fieldDef, + // TODO: support adding label to footer as well + header: [this.makeHeaderComponent(channel, true)] + }; + } + }; + FacetModel.prototype.makeHeaderComponent = function (channel, labels) { + var sizeType = channel === 'row' ? 'height' : 'width'; + return { + labels: labels, + sizeSignal: this.child.component.layoutSize.get(sizeType) ? this.child.getSizeSignalRef(sizeType) : undefined, + axes: [] + }; + }; + FacetModel.prototype.mergeChildAxis = function (channel) { + var child = this.child; + if (child.component.axes[channel]) { + var _a = this.component, layoutHeaders = _a.layoutHeaders, resolve = _a.resolve; + resolve.axis[channel] = parseGuideResolve(resolve, channel); + if (resolve.axis[channel] === 'shared') { + // For shared axis, move the axes to facet's header or footer + var headerChannel = channel === 'x' ? 'column' : 'row'; + var layoutHeader = layoutHeaders[headerChannel]; + for (var _i = 0, _b = child.component.axes[channel]; _i < _b.length; _i++) { + var axisComponent = _b[_i]; + var headerType = getHeaderType(axisComponent.get('orient')); + layoutHeader[headerType] = layoutHeader[headerType] || + [this.makeHeaderComponent(headerChannel, false)]; + var mainAxis = assembleAxis(axisComponent, 'main', this.config, { header: true }); + // LayoutHeader no longer keep track of property precedence, thus let's combine. + layoutHeader[headerType][0].axes.push(mainAxis); + axisComponent.mainExtracted = true; + } + } + } + }; + FacetModel.prototype.assembleSelectionTopLevelSignals = function (signals) { + return this.child.assembleSelectionTopLevelSignals(signals); + }; + FacetModel.prototype.assembleSelectionSignals = function () { + this.child.assembleSelectionSignals(); + return []; + }; + FacetModel.prototype.assembleSelectionData = function (data) { + return this.child.assembleSelectionData(data); + }; + FacetModel.prototype.getHeaderLayoutMixins = function () { + var _this = this; + var layoutMixins = {}; + ['row', 'column'].forEach(function (channel) { + ['header', 'footer'].forEach(function (headerType) { + var layoutHeaderComponent = _this.component.layoutHeaders[channel]; + var headerComponent = layoutHeaderComponent[headerType]; + if (headerComponent && headerComponent[0]) { + // set header/footerBand + var sizeType = channel === 'row' ? 'height' : 'width'; + var bandType = headerType === 'header' ? 'headerBand' : 'footerBand'; + if (!_this.child.component.layoutSize.get(sizeType)) { + // If facet child does not have size signal, then apply headerBand + layoutMixins[bandType] = layoutMixins[bandType] || {}; + layoutMixins[bandType][channel] = 0.5; + } + if (layoutHeaderComponent.title) { + layoutMixins.offset = layoutMixins.offset || {}; + layoutMixins.offset[channel === 'row' ? 'rowTitle' : 'columnTitle'] = 10; + } + } + }); + }); + return layoutMixins; + }; + FacetModel.prototype.assembleDefaultLayout = function () { + var columns = this.channelHasField('column') ? this.columnDistinctSignal() : 1; + // TODO: determine default align based on shared / independent scales + return __assign({}, this.getHeaderLayoutMixins(), { columns: columns, bounds: 'full', align: 'all' }); + }; + FacetModel.prototype.assembleLayoutSignals = function () { + // FIXME(https://github.com/vega/vega-lite/issues/1193): this can be incorrect if we have independent scales. + return this.child.assembleLayoutSignals(); + }; + FacetModel.prototype.columnDistinctSignal = function () { + if (this.parent && (this.parent instanceof FacetModel)) { + // For nested facet, we will add columns to group mark instead + // See discussion in https://github.com/vega/vega/issues/952 + // and https://github.com/vega/vega-view/releases/tag/v1.2.6 + return undefined; + } + else { + // In facetNode.assemble(), the name is always this.getName('column') + '_layout'. + var facetLayoutDataName = this.getName('column_domain'); + return { signal: "length(data('" + facetLayoutDataName + "'))" }; + } + }; + FacetModel.prototype.assembleGroup = function (signals) { + if (this.parent && (this.parent instanceof FacetModel)) { + // Provide number of columns for layout. + // See discussion in https://github.com/vega/vega/issues/952 + // and https://github.com/vega/vega-view/releases/tag/v1.2.6 + return __assign({}, (this.channelHasField('column') ? { + encode: { + update: { + // TODO(https://github.com/vega/vega-lite/issues/2759): + // Correct the signal for facet of concat of facet_column + columns: { field: vgField(this.facet.column, { prefix: 'distinct' }) } + } + } + } : {}), _super.prototype.assembleGroup.call(this, signals)); + } + return _super.prototype.assembleGroup.call(this, signals); + }; + /** + * Aggregate cardinality for calculating size + */ + FacetModel.prototype.getCardinalityAggregateForChild = function () { + var fields = []; + var ops = []; + var as = []; + if (this.child instanceof FacetModel) { + if (this.child.channelHasField('column')) { + var field$$1 = vgField(this.child.facet.column); + fields.push(field$$1); + ops.push('distinct'); + as.push("distinct_" + field$$1); + } + } + else { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var channel = _a[_i]; + var childScaleComponent = this.child.component.scales[channel]; + if (childScaleComponent && !childScaleComponent.merged) { + var type = childScaleComponent.get('type'); + var range = childScaleComponent.get('range'); + if (hasDiscreteDomain(type) && isVgRangeStep(range)) { + var domain = assembleDomain(this.child, channel); + var field$$1 = getFieldFromDomain(domain); + if (field$$1) { + fields.push(field$$1); + ops.push('distinct'); + as.push("distinct_" + field$$1); + } + else { + warn('Unknown field for ${channel}. Cannot calculate view size.'); + } + } + } + } + } + return { fields: fields, ops: ops, as: as }; + }; + FacetModel.prototype.assembleFacet = function () { + var _this = this; + var _a = this.component.data.facetRoot, name = _a.name, data = _a.data; + var _b = this.facet, row = _b.row, column = _b.column; + var _c = this.getCardinalityAggregateForChild(), fields = _c.fields, ops = _c.ops, as = _c.as; + var groupby = []; + ['row', 'column'].forEach(function (channel) { + var fieldDef = _this.facet[channel]; + if (fieldDef) { + groupby.push(vgField(fieldDef)); + var sort = fieldDef.sort; + if (isSortField(sort)) { + var field$$1 = sort.field, op = sort.op; + var outputName = facetSortFieldName(fieldDef, sort); + if (row && column) { + // For crossed facet, use pre-calculate field as it requires a different groupby + // For each calculated field, apply max and assign them to the same name as + // all values of the same group should be the same anyway. + fields.push(outputName); + ops.push('max'); + as.push(outputName); + } + else { + fields.push(field$$1); + ops.push(op); + as.push(outputName); + } + } + else if (isArray(sort)) { + var outputName = sortArrayIndexField(fieldDef, channel); + fields.push(outputName); + ops.push('max'); + as.push(outputName); + } + } + }); + var cross = !!row && !!column; + return __assign({ name: name, + data: data, + groupby: groupby }, (cross || fields.length ? { + aggregate: __assign({}, (cross ? { cross: cross } : {}), (fields.length ? { fields: fields, ops: ops, as: as } : {})) + } : {})); + }; + FacetModel.prototype.headerSortFields = function (channel) { + var facet = this.facet; + var fieldDef = facet[channel]; + if (fieldDef) { + if (isSortField(fieldDef.sort)) { + return [facetSortFieldName(fieldDef, fieldDef.sort, 'datum')]; + } + else if (isArray(fieldDef.sort)) { + return [sortArrayIndexField(fieldDef, channel, 'datum')]; + } + return [vgField(fieldDef, { expr: 'datum' })]; + } + return []; + }; + FacetModel.prototype.headerSortOrder = function (channel) { + var facet = this.facet; + var fieldDef = facet[channel]; + if (fieldDef) { + var sort = fieldDef.sort; + var order = (isSortField(sort) ? sort.order : !isArray(sort) && sort) || 'ascending'; + return [order]; + } + return []; + }; + FacetModel.prototype.assembleMarks = function () { + var child = this.child; + var facetRoot = this.component.data.facetRoot; + var data = assembleFacetData(facetRoot); + // If we facet by two dimensions, we need to add a cross operator to the aggregation + // so that we create all groups + var layoutSizeEncodeEntry = child.assembleLayoutSize(); + var title$$1 = child.assembleTitle(); + var style = child.assembleGroupStyle(); + var markGroup = __assign({ name: this.getName('cell'), type: 'group' }, (title$$1 ? { title: title$$1 } : {}), (style ? { style: style } : {}), { from: { + facet: this.assembleFacet() + }, + // TODO: move this to after data + sort: { + field: this.headerSortFields('row').concat(this.headerSortFields('column')), + order: this.headerSortOrder('row').concat(this.headerSortOrder('column')) + } }, (data.length > 0 ? { data: data } : {}), (layoutSizeEncodeEntry ? { encode: { update: layoutSizeEncodeEntry } } : {}), child.assembleGroup()); + return [markGroup]; + }; + FacetModel.prototype.getMapping = function () { + return this.facet; + }; + return FacetModel; + }(ModelWithField)); + + /** + * A class for the window transform nodes + */ + var WindowTransformNode = /** @class */ (function (_super) { + __extends(WindowTransformNode, _super); + function WindowTransformNode(parent, transform) { + var _this = _super.call(this, parent) || this; + _this.transform = transform; + return _this; + } + WindowTransformNode.makeFromFacet = function (parent, facet) { + var row = facet.row, column = facet.column; + if (row && column) { + var newParent = null; + // only need to make one for crossed facet + for (var _i = 0, _a = [row, column]; _i < _a.length; _i++) { + var fieldDef = _a[_i]; + if (isSortField(fieldDef.sort)) { + var _b = fieldDef.sort, field = _b.field, op = _b.op; + parent = newParent = new WindowTransformNode(parent, { + window: [{ + op: op, + field: field, + as: facetSortFieldName(fieldDef, fieldDef.sort) + }], + groupby: [vgField(fieldDef)], + frame: [null, null] + }); + } + } + return newParent; + } + return null; + }; + WindowTransformNode.prototype.clone = function () { + return new WindowTransformNode(this.parent, duplicate(this.transform)); + }; + WindowTransformNode.prototype.producedFields = function () { + var _this = this; + var out = {}; + this.transform.window.forEach(function (windowFieldDef) { + out[_this.getDefaultName(windowFieldDef)] = true; + }); + return out; + }; + WindowTransformNode.prototype.getDefaultName = function (windowFieldDef) { + return windowFieldDef.as || vgField(windowFieldDef); + }; + WindowTransformNode.prototype.assemble = function () { + var fields = []; + var ops = []; + var as = []; + var params = []; + for (var _i = 0, _a = this.transform.window; _i < _a.length; _i++) { + var window_1 = _a[_i]; + ops.push(window_1.op); + as.push(this.getDefaultName(window_1)); + params.push(window_1.param === undefined ? null : window_1.param); + fields.push(window_1.field === undefined ? null : window_1.field); + } + var frame = this.transform.frame; + var groupby = this.transform.groupby; + var sortFields = []; + var sortOrder = []; + if (this.transform.sort !== undefined) { + for (var _b = 0, _c = this.transform.sort; _b < _c.length; _b++) { + var sortField = _c[_b]; + sortFields.push(sortField.field); + sortOrder.push(sortField.order || 'ascending'); + } + } + var sort = { + field: sortFields, + order: sortOrder, + }; + var ignorePeers = this.transform.ignorePeers; + var result = { + type: 'window', + params: params, + as: as, + ops: ops, + fields: fields, + sort: sort, + }; + if (ignorePeers !== undefined) { + result.ignorePeers = ignorePeers; + } + if (groupby !== undefined) { + result.groupby = groupby; + } + if (frame !== undefined) { + result.frame = frame; + } + return result; + }; + return WindowTransformNode; + }(DataFlowNode)); + + function parseRoot(model, sources) { + if (model.data || !model.parent) { + // if the model defines a data source or is the root, create a source node + var source = new SourceNode(model.data); + var hash$$1 = source.hash(); + if (hash$$1 in sources) { + // use a reference if we already have a source + return sources[hash$$1]; + } + else { + // otherwise add a new one + sources[hash$$1] = source; + return source; + } + } + else { + // If we don't have a source defined (overriding parent's data), use the parent's facet root or main. + return model.parent.component.data.facetRoot ? model.parent.component.data.facetRoot : model.parent.component.data.main; + } + } + /** + * Parses a transforms array into a chain of connected dataflow nodes. + */ + function parseTransformArray(head, model, ancestorParse) { + var lookupCounter = 0; + model.transforms.forEach(function (t) { + if (isCalculate(t)) { + head = new CalculateNode(head, t); + ancestorParse.set(t.as, 'derived', false); + } + else if (isFilter(t)) { + head = ParseNode.makeImplicitFromFilterTransform(head, t, ancestorParse) || head; + head = new FilterNode(head, model, t.filter); + } + else if (isBin(t)) { + var bin = head = BinNode.makeFromTransform(head, t, model); + for (var _i = 0, _a = keys(bin.producedFields()); _i < _a.length; _i++) { + var field = _a[_i]; + ancestorParse.set(field, 'number', false); + } + } + else if (isTimeUnit$1(t)) { + head = TimeUnitNode.makeFromTransform(head, t); + ancestorParse.set(t.as, 'date', false); + } + else if (isAggregate$1(t)) { + var agg = head = AggregateNode.makeFromTransform(head, t); + if (requiresSelectionId(model)) { + head = new IdentifierNode(head); + } + for (var _b = 0, _c = keys(agg.producedFields()); _b < _c.length; _b++) { + var field = _c[_b]; + ancestorParse.set(field, 'derived', false); + } + } + else if (isLookup(t)) { + var lookup = head = LookupNode.make(head, model, t, lookupCounter++); + for (var _d = 0, _e = keys(lookup.producedFields()); _d < _e.length; _d++) { + var field = _e[_d]; + ancestorParse.set(field, 'derived', false); + } + } + else if (isWindow(t)) { + var window_1 = head = new WindowTransformNode(head, t); + for (var _f = 0, _g = keys(window_1.producedFields()); _f < _g.length; _f++) { + var field = _g[_f]; + ancestorParse.set(field, 'derived', false); + } + } + else if (isStack(t)) { + var stack = head = StackNode.makeFromTransform(head, t); + for (var _h = 0, _j = keys(stack.producedFields()); _h < _j.length; _h++) { + var field = _j[_h]; + ancestorParse.set(field, 'derived', false); + } + } + else { + warn(message.invalidTransformIgnored(t)); + return; + } + }); + return head; + } + /* + Description of the dataflow (http://asciiflow.com/): + +--------+ + | Source | + +---+----+ + | + v + FormatParse + (explicit) + | + v + Transforms + (Filter, Calculate, Binning, TimeUnit, Aggregate, Window, ...) + | + v + FormatParse + (implicit) + | + v + Binning (in `encoding`) + | + v + Timeunit (in `encoding`) + | + v + Formula From Sort Array + | + v + +--+--+ + | Raw | + +-----+ + | + v + Aggregate (in `encoding`) + | + v + Stack (in `encoding`) + | + v + Invalid Filter + | + v + +----------+ + | Main | + +----------+ + | + v + +-------+ + | Facet |----> "column", "column-layout", and "row" + +-------+ + | + v + ...Child data... + */ + function parseData(model) { + var head = parseRoot(model, model.component.data.sources); + var _a = model.component.data, outputNodes = _a.outputNodes, outputNodeRefCounts = _a.outputNodeRefCounts; + var ancestorParse = model.parent ? model.parent.component.data.ancestorParse.clone() : new AncestorParse(); + // format.parse: null means disable parsing + if (model.data && model.data.format && model.data.format.parse === null) { + ancestorParse.parseNothing = true; + } + head = ParseNode.makeExplicit(head, model, ancestorParse) || head; + // Default discrete selections require an identifier transform to + // uniquely identify data points as the _id field is volatile. Add + // this transform at the head of our pipeline such that the identifier + // field is available for all subsequent datasets. Additional identifier + // transforms will be necessary when new tuples are constructed + // (e.g., post-aggregation). + if (requiresSelectionId(model) && (isUnitModel(model) || isLayerModel(model))) { + head = new IdentifierNode(head); + } + // HACK: This is equivalent for merging bin extent for union scale. + // FIXME(https://github.com/vega/vega-lite/issues/2270): Correctly merge extent / bin node for shared bin scale + var parentIsLayer = model.parent && isLayerModel(model.parent); + if (isUnitModel(model) || isFacetModel(model)) { + if (parentIsLayer) { + head = BinNode.makeFromEncoding(head, model) || head; + } + } + if (model.transforms.length > 0) { + head = parseTransformArray(head, model, ancestorParse); + } + head = ParseNode.makeImplicitFromEncoding(head, model, ancestorParse) || head; + if (isUnitModel(model)) { + head = GeoJSONNode.parseAll(head, model); + head = GeoPointNode.parseAll(head, model); + } + if (isUnitModel(model) || isFacetModel(model)) { + if (!parentIsLayer) { + head = BinNode.makeFromEncoding(head, model) || head; + } + head = TimeUnitNode.makeFromEncoding(head, model) || head; + head = CalculateNode.parseAllForSortIndex(head, model); + } + // add an output node pre aggregation + var rawName = model.getName(RAW); + var raw = new OutputNode(head, rawName, RAW, outputNodeRefCounts); + outputNodes[rawName] = raw; + head = raw; + if (isUnitModel(model)) { + var agg = AggregateNode.makeFromEncoding(head, model); + if (agg) { + head = agg; + if (requiresSelectionId(model)) { + head = new IdentifierNode(head); + } + } + head = StackNode.makeFromEncoding(head, model) || head; + } + if (isUnitModel(model)) { + head = FilterInvalidNode.make(head, model) || head; + } + // output node for marks + var mainName = model.getName(MAIN); + var main = new OutputNode(head, mainName, MAIN, outputNodeRefCounts); + outputNodes[mainName] = main; + head = main; + // add facet marker + var facetRoot = null; + if (isFacetModel(model)) { + var facetName = model.getName('facet'); + // Derive new sort index field for facet's sort array + head = CalculateNode.parseAllForSortIndex(head, model); + // Derive new aggregate (via window) for facet's sort field + // TODO: use JoinAggregate once we have it + // augment data source with new fields for crossed facet + head = WindowTransformNode.makeFromFacet(head, model.facet) || head; + facetRoot = new FacetNode(head, model, facetName, main.getSource()); + outputNodes[facetName] = facetRoot; + head = facetRoot; + } + return __assign({}, model.component.data, { outputNodes: outputNodes, + outputNodeRefCounts: outputNodeRefCounts, + raw: raw, + main: main, + facetRoot: facetRoot, + ancestorParse: ancestorParse }); + } + + var BaseConcatModel = /** @class */ (function (_super) { + __extends(BaseConcatModel, _super); + function BaseConcatModel(spec, parent, parentGivenName, config, repeater, resolve) { + return _super.call(this, spec, parent, parentGivenName, config, repeater, resolve) || this; + } + BaseConcatModel.prototype.parseData = function () { + this.component.data = parseData(this); + this.children.forEach(function (child) { + child.parseData(); + }); + }; + BaseConcatModel.prototype.parseSelection = function () { + var _this = this; + // Merge selections up the hierarchy so that they may be referenced + // across unit specs. Persist their definitions within each child + // to assemble signals which remain within output Vega unit groups. + this.component.selection = {}; + var _loop_1 = function (child) { + child.parseSelection(); + keys(child.component.selection).forEach(function (key) { + _this.component.selection[key] = child.component.selection[key]; + }); + }; + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + _loop_1(child); + } + }; + BaseConcatModel.prototype.parseMarkGroup = function () { + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseMarkGroup(); + } + }; + BaseConcatModel.prototype.parseAxisAndHeader = function () { + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseAxisAndHeader(); + } + // TODO(#2415): support shared axes + }; + BaseConcatModel.prototype.assembleSelectionTopLevelSignals = function (signals) { + return this.children.reduce(function (sg, child) { return child.assembleSelectionTopLevelSignals(sg); }, signals); + }; + BaseConcatModel.prototype.assembleSelectionSignals = function () { + this.children.forEach(function (child) { return child.assembleSelectionSignals(); }); + return []; + }; + BaseConcatModel.prototype.assembleLayoutSignals = function () { + return this.children.reduce(function (signals, child) { + return signals.concat(child.assembleLayoutSignals()); + }, assembleLayoutSignals(this)); + }; + BaseConcatModel.prototype.assembleSelectionData = function (data) { + return this.children.reduce(function (db, child) { return child.assembleSelectionData(db); }, data); + }; + BaseConcatModel.prototype.assembleMarks = function () { + // only children have marks + return this.children.map(function (child) { + var title = child.assembleTitle(); + var style = child.assembleGroupStyle(); + var layoutSizeEncodeEntry = child.assembleLayoutSize(); + return __assign({ type: 'group', name: child.getName('group') }, (title ? { title: title } : {}), (style ? { style: style } : {}), (layoutSizeEncodeEntry ? { + encode: { + update: layoutSizeEncodeEntry + } + } : {}), child.assembleGroup()); + }); + }; + return BaseConcatModel; + }(Model)); + + var ConcatModel = /** @class */ (function (_super) { + __extends(ConcatModel, _super); + function ConcatModel(spec, parent, parentGivenName, repeater, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, repeater, spec.resolve) || this; + _this.type = 'concat'; + if (spec.resolve && spec.resolve.axis && (spec.resolve.axis.x === 'shared' || spec.resolve.axis.y === 'shared')) { + warn(message.CONCAT_CANNOT_SHARE_AXIS); + } + _this.isVConcat = isVConcatSpec(spec); + _this.children = (isVConcatSpec(spec) ? spec.vconcat : spec.hconcat).map(function (child, i) { + return buildModel(child, _this, _this.getName('concat_' + i), undefined, repeater, config, false); + }); + return _this; + } + ConcatModel.prototype.parseLayoutSize = function () { + parseConcatLayoutSize(this); + }; + ConcatModel.prototype.parseAxisGroup = function () { + return null; + }; + ConcatModel.prototype.assembleDefaultLayout = function () { + return __assign({}, (this.isVConcat ? { columns: 1 } : {}), { bounds: 'full', + // Use align each so it can work with multiple plots with different size + align: 'each' }); + }; + return ConcatModel; + }(BaseConcatModel)); + + function isFalseOrNull(v) { + return v === false || v === null; + } + var AxisComponent = /** @class */ (function (_super) { + __extends(AxisComponent, _super); + function AxisComponent(explicit, implicit, mainExtracted) { + if (explicit === void 0) { explicit = {}; } + if (implicit === void 0) { implicit = {}; } + if (mainExtracted === void 0) { mainExtracted = false; } + var _this = _super.call(this) || this; + _this.explicit = explicit; + _this.implicit = implicit; + _this.mainExtracted = mainExtracted; + return _this; + } + AxisComponent.prototype.clone = function () { + return new AxisComponent(duplicate(this.explicit), duplicate(this.implicit), this.mainExtracted); + }; + AxisComponent.prototype.hasAxisPart = function (part) { + // FIXME(https://github.com/vega/vega-lite/issues/2552) this method can be wrong if users use a Vega theme. + if (part === 'axis') { // always has the axis container part + return true; + } + if (part === 'grid' || part === 'title') { + return !!this.get(part); + } + // Other parts are enabled by default, so they should not be false or null. + return !isFalseOrNull(this.get(part)); + }; + return AxisComponent; + }(Split)); + + function getAxisConfig(property, config, channel, orient, scaleType) { + if (orient === void 0) { orient = ''; } + // configTypes to loop, starting from higher precedence + var configTypes = (scaleType === 'band' ? ['axisBand'] : []).concat([ + channel === 'x' ? 'axisX' : 'axisY', + 'axis' + orient.substr(0, 1).toUpperCase() + orient.substr(1), + 'axis' + ]); + for (var _i = 0, configTypes_1 = configTypes; _i < configTypes_1.length; _i++) { + var configType = configTypes_1[_i]; + if (config[configType] && config[configType][property] !== undefined) { + return config[configType][property]; + } + } + return undefined; + } + + function labels$1(model, channel, specifiedLabelsSpec, orient) { + var fieldDef = model.fieldDef(channel) || + (channel === 'x' ? model.fieldDef('x2') : + channel === 'y' ? model.fieldDef('y2') : + undefined); + var axis = model.axis(channel); + var config = model.config; + var labelsSpec = {}; + // Text + if (isTimeFieldDef(fieldDef)) { + var isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC; + var expr = timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat, isUTCScale); + if (expr) { + labelsSpec.text = { signal: expr }; + } + } + // Label Angle + var angle = getAxisConfig('labelAngle', model.config, channel, orient, model.getScaleComponent(channel).get('type')); + if (angle === undefined) { + angle = labelAngle(axis, channel, fieldDef); + if (angle) { + labelsSpec.angle = { value: angle }; + } + } + if (angle !== undefined) { + var align = labelAlign$1(angle, orient); + if (align) { + labelsSpec.align = { value: align }; + } + labelsSpec.baseline = labelBaseline$1(angle, orient); + } + labelsSpec = __assign({}, labelsSpec, specifiedLabelsSpec); + return keys(labelsSpec).length === 0 ? undefined : labelsSpec; + } + function labelBaseline$1(angle, orient) { + if (orient === 'top' || orient === 'bottom') { + if (angle <= 45 || 315 <= angle) { + return { value: orient === 'top' ? 'bottom' : 'top' }; + } + else if (135 <= angle && angle <= 225) { + return { value: orient === 'top' ? 'top' : 'bottom' }; + } + else { + return { value: 'middle' }; + } + } + else { + if ((angle <= 45 || 315 <= angle) || (135 <= angle && angle <= 225)) { + return { value: 'middle' }; + } + else if (45 <= angle && angle <= 135) { + return { value: orient === 'left' ? 'top' : 'bottom' }; + } + else { + return { value: orient === 'left' ? 'bottom' : 'top' }; + } + } + } + function labelAngle(axis, channel, fieldDef) { + if (axis.labelAngle !== undefined) { + // Make angle within [0,360) + return ((axis.labelAngle % 360) + 360) % 360; + } + else { + if (channel === X && contains([NOMINAL, ORDINAL], fieldDef.type)) { + return 270; + } + } + return undefined; + } + function labelAlign$1(angle, orient) { + angle = ((angle % 360) + 360) % 360; + if (orient === 'top' || orient === 'bottom') { + if (angle % 180 === 0) { + return 'center'; + } + else if (0 < angle && angle < 180) { + return orient === 'top' ? 'right' : 'left'; + } + else { + return orient === 'top' ? 'left' : 'right'; + } + } + else { + if ((angle + 90) % 180 === 0) { + return 'center'; + } + else if (90 <= angle && angle < 270) { + return orient === 'left' ? 'left' : 'right'; + } + else { + return orient === 'left' ? 'right' : 'left'; + } + } + } + + // TODO: we need to refactor this method after we take care of config refactoring + /** + * Default rules for whether to show a grid should be shown for a channel. + * If `grid` is unspecified, the default value is `true` for ordinal scales that are not binned + */ + function grid(scaleType, fieldDef) { + return !hasDiscreteDomain(scaleType) && !fieldDef.bin; + } + function gridScale(model, channel) { + var gridChannel = channel === 'x' ? 'y' : 'x'; + if (model.getScaleComponent(gridChannel)) { + return model.scaleName(gridChannel); + } + return undefined; + } + function labelFlush(fieldDef, channel, specifiedAxis) { + if (specifiedAxis.labelFlush !== undefined) { + return specifiedAxis.labelFlush; + } + if (channel === 'x' && contains(['quantitative', 'temporal'], fieldDef.type)) { + return true; + } + return undefined; + } + function labelOverlap(fieldDef, specifiedAxis, channel, scaleType) { + if (specifiedAxis.labelOverlap !== undefined) { + return specifiedAxis.labelOverlap; + } + // do not prevent overlap for nominal data because there is no way to infer what the missing labels are + if (fieldDef.type !== 'nominal') { + if (scaleType === 'log') { + return 'greedy'; + } + return true; + } + return undefined; + } + function orient(channel) { + switch (channel) { + case X: + return 'bottom'; + case Y: + return 'left'; + } + /* istanbul ignore next: This should never happen. */ + throw new Error(message.INVALID_CHANNEL_FOR_AXIS); + } + function tickCount(channel, fieldDef, scaleType, size) { + if (!hasDiscreteDomain(scaleType) && scaleType !== 'log' && !contains(['month', 'hours', 'day', 'quarter'], fieldDef.timeUnit)) { + if (fieldDef.bin) { + // for binned data, we don't want more ticks than maxbins + return { signal: "ceil(" + size.signal + "/20)" }; + } + return { signal: "ceil(" + size.signal + "/40)" }; + } + return undefined; + } + function values$1(specifiedAxis, model, fieldDef, channel) { + var vals$$1 = specifiedAxis.values; + if (vals$$1) { + return valueArray(fieldDef, vals$$1); + } + if (fieldDef.bin && fieldDef.type === QUANTITATIVE) { + var domain = model.scaleDomain(channel); + if (domain && domain !== 'unaggregated' && !isSelectionDomain(domain)) { // explicit value + return undefined; + } + var signal = model.getName(binToString(fieldDef.bin) + "_" + fieldDef.field + "_bins"); + return { signal: "sequence(" + signal + ".start, " + signal + ".stop + " + signal + ".step, " + signal + ".step)" }; + } + return undefined; + } + + function parseUnitAxis(model) { + return POSITION_SCALE_CHANNELS.reduce(function (axis, channel) { + if (model.component.scales[channel] && model.axis(channel)) { + axis[channel] = [parseAxis(channel, model)]; + } + return axis; + }, {}); + } + var OPPOSITE_ORIENT = { + bottom: 'top', + top: 'bottom', + left: 'right', + right: 'left' + }; + function parseLayerAxis(model) { + var _a = model.component, axes = _a.axes, resolve = _a.resolve; + var axisCount = { top: 0, bottom: 0, right: 0, left: 0 }; + for (var _i = 0, _b = model.children; _i < _b.length; _i++) { + var child = _b[_i]; + child.parseAxisAndHeader(); + for (var _c = 0, _d = keys(child.component.axes); _c < _d.length; _c++) { + var channel = _d[_c]; + resolve.axis[channel] = parseGuideResolve(model.component.resolve, channel); + if (resolve.axis[channel] === 'shared') { + // If the resolve says shared (and has not been overridden) + // We will try to merge and see if there is a conflict + axes[channel] = mergeAxisComponents(axes[channel], child.component.axes[channel]); + if (!axes[channel]) { + // If merge returns nothing, there is a conflict so we cannot make the axis shared. + // Thus, mark axis as independent and remove the axis component. + resolve.axis[channel] = 'independent'; + delete axes[channel]; + } + } + } + } + // Move axes to layer's axis component and merge shared axes + for (var _e = 0, _f = [X, Y]; _e < _f.length; _e++) { + var channel = _f[_e]; + for (var _g = 0, _h = model.children; _g < _h.length; _g++) { + var child = _h[_g]; + if (!child.component.axes[channel]) { + // skip if the child does not have a particular axis + continue; + } + if (resolve.axis[channel] === 'independent') { + // If axes are independent, concat the axisComponent array. + axes[channel] = (axes[channel] || []).concat(child.component.axes[channel]); + // Automatically adjust orient + for (var _j = 0, _k = child.component.axes[channel]; _j < _k.length; _j++) { + var axisComponent = _k[_j]; + var _l = axisComponent.getWithExplicit('orient'), orient$$1 = _l.value, explicit = _l.explicit; + if (axisCount[orient$$1] > 0 && !explicit) { + // Change axis orient if the number do not match + var oppositeOrient = OPPOSITE_ORIENT[orient$$1]; + if (axisCount[orient$$1] > axisCount[oppositeOrient]) { + axisComponent.set('orient', oppositeOrient, false); + } + } + axisCount[orient$$1]++; + // TODO(https://github.com/vega/vega-lite/issues/2634): automaticaly add extra offset? + } + } + // After merging, make sure to remove axes from child + delete child.component.axes[channel]; + } + } + } + function mergeAxisComponents(mergedAxisCmpts, childAxisCmpts) { + if (mergedAxisCmpts) { + // FIXME: this is a bit wrong once we support multiple axes + if (mergedAxisCmpts.length !== childAxisCmpts.length) { + return undefined; // Cannot merge axis component with different number of axes. + } + var length_1 = mergedAxisCmpts.length; + for (var i = 0; i < length_1; i++) { + var merged = mergedAxisCmpts[i]; + var child = childAxisCmpts[i]; + if ((!!merged) !== (!!child)) { + return undefined; + } + else if (merged && child) { + var mergedOrient = merged.getWithExplicit('orient'); + var childOrient = child.getWithExplicit('orient'); + if (mergedOrient.explicit && childOrient.explicit && mergedOrient.value !== childOrient.value) { + // TODO: throw warning if resolve is explicit (We don't have info about explicit/implicit resolve yet.) + // Cannot merge due to inconsistent orient + return undefined; + } + else { + mergedAxisCmpts[i] = mergeAxisComponent(merged, child); + } + } + } + } + else { + // For first one, return a copy of the child + return childAxisCmpts.map(function (axisComponent) { return axisComponent.clone(); }); + } + return mergedAxisCmpts; + } + function mergeAxisComponent(merged, child) { + var _loop_1 = function (prop) { + var mergedValueWithExplicit = mergeValuesWithExplicit(merged.getWithExplicit(prop), child.getWithExplicit(prop), prop, 'axis', + // Tie breaker function + function (v1, v2) { + switch (prop) { + case 'title': + return mergeTitleComponent(v1, v2); + case 'gridScale': + return { + explicit: v1.explicit, + value: v1.value || v2.value + }; + } + return defaultTieBreaker(v1, v2, prop, 'axis'); + }); + merged.setWithExplicit(prop, mergedValueWithExplicit); + }; + for (var _i = 0, VG_AXIS_PROPERTIES_1 = VG_AXIS_PROPERTIES; _i < VG_AXIS_PROPERTIES_1.length; _i++) { + var prop = VG_AXIS_PROPERTIES_1[_i]; + _loop_1(prop); + } + return merged; + } + function getFieldDefTitle(model, channel) { + var channel2 = channel === 'x' ? 'x2' : 'y2'; + var fieldDef = model.fieldDef(channel); + var fieldDef2 = model.fieldDef(channel2); + var title1 = fieldDef ? fieldDef.title : undefined; + var title2 = fieldDef2 ? fieldDef2.title : undefined; + if (title1 && title2) { + return mergeTitle(title1, title2); + } + else if (title1) { + return title1; + } + else if (title2) { + return title2; + } + else if (title1 !== undefined) { // falsy value to disable config + return title1; + } + else if (title2 !== undefined) { // falsy value to disable config + return title2; + } + return undefined; + } + function parseAxis(channel, model) { + var axis = model.axis(channel); + var axisComponent = new AxisComponent(); + // 1.2. Add properties + VG_AXIS_PROPERTIES.forEach(function (property) { + var value = getProperty$1(property, axis, channel, model); + if (value !== undefined) { + var explicit = + // specified axis.values is already respected, but may get transformed. + property === 'values' ? !!axis.values : + // both VL axis.encoding and axis.labelAngle affect VG axis.encode + property === 'encode' ? !!axis.encoding || !!axis.labelAngle : + // title can be explicit if fieldDef.title is set + property === 'title' && value === getFieldDefTitle(model, channel) ? true : + // Otherwise, things are explicit if the returned value matches the specified property + value === axis[property]; + var configValue = getAxisConfig(property, model.config, channel, axisComponent.get('orient'), model.getScaleComponent(channel).get('type')); + // only set property if it is explicitly set or has no config value (otherwise we will accidentally override config) + if (explicit || configValue === undefined) { + // Do not apply implicit rule if there is a config value + axisComponent.set(property, value, explicit); + } + else if (property === 'grid' && configValue) { + // Grid is an exception because we need to set grid = true to generate another grid axis + axisComponent.set(property, configValue, false); + } + } + }); + // 2) Add guide encode definition groups + var axisEncoding = axis.encoding || {}; + var axisEncode = AXIS_PARTS.reduce(function (e, part) { + if (!axisComponent.hasAxisPart(part)) { + // No need to create encode for a disabled part. + return e; + } + var axisEncodingPart = guideEncodeEntry(axisEncoding[part] || {}, model); + var value = part === 'labels' ? + labels$1(model, channel, axisEncodingPart, axisComponent.get('orient')) : + axisEncodingPart; + if (value !== undefined && keys(value).length > 0) { + e[part] = { update: value }; + } + return e; + }, {}); + // FIXME: By having encode as one property, we won't have fine grained encode merging. + if (keys(axisEncode).length > 0) { + axisComponent.set('encode', axisEncode, !!axis.encoding || axis.labelAngle !== undefined); + } + return axisComponent; + } + function getProperty$1(property, specifiedAxis, channel, model) { + var fieldDef = model.fieldDef(channel); + switch (property) { + case 'scale': + return model.scaleName(channel); + case 'gridScale': + return gridScale(model, channel); + case 'format': + // We don't include temporal field here as we apply format in encode block + return numberFormat(fieldDef, specifiedAxis.format, model.config); + case 'grid': { + var scaleType = model.getScaleComponent(channel).get('type'); + return getSpecifiedOrDefaultValue(specifiedAxis.grid, grid(scaleType, fieldDef)); + } + case 'labelFlush': + return labelFlush(fieldDef, channel, specifiedAxis); + case 'labelOverlap': { + var scaleType = model.getScaleComponent(channel).get('type'); + return labelOverlap(fieldDef, specifiedAxis, channel, scaleType); + } + case 'orient': + return getSpecifiedOrDefaultValue(specifiedAxis.orient, orient(channel)); + case 'tickCount': { + var scaleType = model.getScaleComponent(channel).get('type'); + var sizeType = channel === 'x' ? 'width' : channel === 'y' ? 'height' : undefined; + var size = sizeType ? model.getSizeSignalRef(sizeType) + : undefined; + return getSpecifiedOrDefaultValue(specifiedAxis.tickCount, tickCount(channel, fieldDef, scaleType, size)); + } + case 'title': + var channel2 = channel === 'x' ? 'x2' : 'y2'; + var fieldDef2 = model.fieldDef(channel2); + // Keep undefined so we use default if title is unspecified. + // For other falsy value, keep them so we will hide the title. + var fieldDefTitle = getFieldDefTitle(model, channel); + var specifiedTitle = fieldDefTitle !== undefined ? fieldDefTitle : + specifiedAxis.title === undefined ? undefined : specifiedAxis.title; + return getSpecifiedOrDefaultValue(specifiedTitle, + // If title not specified, store base parts of fieldDef (and fieldDef2 if exists) + mergeTitleFieldDefs([toFieldDefBase(fieldDef)], fieldDef2 ? [toFieldDefBase(fieldDef2)] : [])); + case 'values': + return values$1(specifiedAxis, model, fieldDef, channel); + } + // Otherwise, return specified property. + return isAxisProperty(property) ? specifiedAxis[property] : undefined; + } + + function normalizeMarkDef(mark, encoding, config) { + var markDef = isMarkDef(mark) ? __assign({}, mark) : { type: mark }; + // set orient, which can be overridden by rules as sometimes the specified orient is invalid. + var specifiedOrient = markDef.orient || getMarkConfig('orient', markDef, config); + markDef.orient = orient$1(markDef.type, encoding, specifiedOrient); + if (specifiedOrient !== undefined && specifiedOrient !== markDef.orient) { + warn(message.orientOverridden(markDef.orient, specifiedOrient)); + } + // set opacity and filled if not specified in mark config + var specifiedOpacity = markDef.opacity !== undefined ? markDef.opacity : getMarkConfig('opacity', markDef, config); + if (specifiedOpacity === undefined) { + markDef.opacity = opacity(markDef.type, encoding); + } + var specifiedFilled = markDef.filled; + if (specifiedFilled === undefined) { + markDef.filled = filled(markDef, config); + } + // set cursor, which should be pointer if href channel is present unless otherwise specified + var specifiedCursor = markDef.cursor || getMarkConfig('cursor', markDef, config); + if (specifiedCursor === undefined) { + markDef.cursor = cursor(markDef, encoding, config); + } + return markDef; + } + function cursor(markDef, encoding, config) { + if (encoding.href || markDef.href || getMarkConfig('href', markDef, config)) { + return 'pointer'; + } + return markDef.cursor; + } + function opacity(mark, encoding) { + if (contains([POINT, TICK, CIRCLE, SQUARE], mark)) { + // point-based marks + if (!isAggregate(encoding)) { + return 0.7; + } + } + return undefined; + } + function filled(markDef, config) { + var filledConfig = getMarkConfig('filled', markDef, config); + var mark = markDef.type; + return filledConfig !== undefined ? filledConfig : mark !== POINT && mark !== LINE && mark !== RULE; + } + function orient$1(mark, encoding, specifiedOrient) { + switch (mark) { + case POINT: + case CIRCLE: + case SQUARE: + case TEXT$1: + case RECT: + // orient is meaningless for these marks. + return undefined; + } + var yIsRange = encoding.y2; + var xIsRange = encoding.x2; + switch (mark) { + case BAR: + if (yIsRange || xIsRange) { + // Ranged bar does not always have clear orientation, so we allow overriding + if (specifiedOrient) { + return specifiedOrient; + } + // If y is range and x is non-range, non-bin Q, y is likely a prebinned field + var xDef = encoding.x; + if (!xIsRange && isFieldDef(xDef) && xDef.type === QUANTITATIVE && !xDef.bin) { + return 'horizontal'; + } + // If x is range and y is non-range, non-bin Q, x is likely a prebinned field + var yDef = encoding.y; + if (!yIsRange && isFieldDef(yDef) && yDef.type === QUANTITATIVE && !yDef.bin) { + return 'vertical'; + } + } + /* tslint:disable */ + case RULE: // intentionally fall through + // return undefined for line segment rule and bar with both axis ranged + if (xIsRange && yIsRange) { + return undefined; + } + case AREA: // intentionally fall through + // If there are range for both x and y, y (vertical) has higher precedence. + if (yIsRange) { + return 'vertical'; + } + else if (xIsRange) { + return 'horizontal'; + } + else if (mark === RULE) { + if (encoding.x && !encoding.y) { + return 'vertical'; + } + else if (encoding.y && !encoding.x) { + return 'horizontal'; + } + } + case LINE: // intentional fall through + case TICK: // Tick is opposite to bar, line, area and never have ranged mark. + /* tslint:enable */ + var xIsContinuous = isFieldDef(encoding.x) && isContinuous(encoding.x); + var yIsContinuous = isFieldDef(encoding.y) && isContinuous(encoding.y); + if (xIsContinuous && !yIsContinuous) { + return mark !== 'tick' ? 'horizontal' : 'vertical'; + } + else if (!xIsContinuous && yIsContinuous) { + return mark !== 'tick' ? 'vertical' : 'horizontal'; + } + else if (xIsContinuous && yIsContinuous) { + var xDef = encoding.x; // we can cast here since they are surely fieldDef + var yDef = encoding.y; + var xIsTemporal = xDef.type === TEMPORAL; + var yIsTemporal = yDef.type === TEMPORAL; + // temporal without timeUnit is considered continuous, but better serves as dimension + if (xIsTemporal && !yIsTemporal) { + return mark !== 'tick' ? 'vertical' : 'horizontal'; + } + else if (!xIsTemporal && yIsTemporal) { + return mark !== 'tick' ? 'horizontal' : 'vertical'; + } + if (!xDef.aggregate && yDef.aggregate) { + return mark !== 'tick' ? 'vertical' : 'horizontal'; + } + else if (xDef.aggregate && !yDef.aggregate) { + return mark !== 'tick' ? 'horizontal' : 'vertical'; + } + if (specifiedOrient) { + // When ambiguous, use user specified one. + return specifiedOrient; + } + return 'vertical'; + } + else { + // Discrete x Discrete case + if (specifiedOrient) { + // When ambiguous, use user specified one. + return specifiedOrient; + } + return undefined; + } + } + return 'vertical'; + } + + var area = { + vgMark: 'area', + encodeEntry: function (model) { + return __assign({}, baseEncodeEntry(model, { size: 'ignore', orient: 'include' }), pointPosition('x', model, 'zeroOrMin'), pointPosition('y', model, 'zeroOrMin'), pointPosition2(model, 'zeroOrMin', model.markDef.orient === 'horizontal' ? 'x2' : 'y2'), defined(model)); + } + }; + + var bar = { + vgMark: 'rect', + encodeEntry: function (model) { + return __assign({}, baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), x(model), y(model)); + } + }; + function x(model) { + var config = model.config, encoding = model.encoding, markDef = model.markDef, width = model.width; + var orient = markDef.orient; + var sizeDef = encoding.size; + var xDef = encoding.x; + var x2Def = encoding.x2; + var xScaleName = model.scaleName(X); + var xScale = model.getScaleComponent(X); + // x, x2, and width -- we must specify two of these in all conditions + if (orient === 'horizontal' || x2Def) { + return __assign({}, pointPosition('x', model, 'zeroOrMin'), pointPosition2(model, 'zeroOrMin', 'x2')); + } + else { // vertical + if (isFieldDef(xDef)) { + var xScaleType = xScale.get('type'); + if (xDef.bin && !sizeDef && !hasDiscreteDomain(xScaleType)) { + return binnedPosition(xDef, 'x', model.scaleName('x'), markDef.binSpacing === undefined ? config.bar.binSpacing : markDef.binSpacing, xScale.get('reverse')); + } + else { + if (xScaleType === ScaleType.BAND) { + return bandPosition(xDef, 'x', model); + } + } + } + // sized bin, normal point-ordinal axis, quantitative x-axis, or no x + return centeredBandPosition('x', model, __assign({}, mid(width)), defaultSizeRef(markDef, xScaleName, xScale, config)); + } + } + function y(model) { + var config = model.config, encoding = model.encoding, height = model.height, markDef = model.markDef; + var orient = markDef.orient; + var sizeDef = encoding.size; + var yDef = encoding.y; + var y2Def = encoding.y2; + var yScaleName = model.scaleName(Y); + var yScale = model.getScaleComponent(Y); + // y, y2 & height -- we must specify two of these in all conditions + if (orient === 'vertical' || y2Def) { + return __assign({}, pointPosition('y', model, 'zeroOrMin'), pointPosition2(model, 'zeroOrMin', 'y2')); + } + else { + if (isFieldDef(yDef)) { + var yScaleType = yScale.get('type'); + if (yDef.bin && !sizeDef && !hasDiscreteDomain(yScaleType)) { + return binnedPosition(yDef, 'y', model.scaleName('y'), markDef.binSpacing === undefined ? config.bar.binSpacing : markDef.binSpacing, yScale.get('reverse')); + } + else if (yScaleType === ScaleType.BAND) { + return bandPosition(yDef, 'y', model); + } + } + return centeredBandPosition('y', model, mid(height), defaultSizeRef(markDef, yScaleName, yScale, config)); + } + } + function defaultSizeRef(markDef, scaleName, scale, config) { + if (markDef.size !== undefined) { + return { value: markDef.size }; + } + else if (config.bar.discreteBandSize) { + return { value: config.bar.discreteBandSize }; + } + else if (scale) { + var scaleType = scale.get('type'); + if (scaleType === ScaleType.POINT) { + var scaleRange = scale.get('range'); + if (isVgRangeStep(scaleRange) && isNumber(scaleRange.step)) { + return { value: scaleRange.step - 1 }; + } + warn(message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL); + } + else if (scaleType === ScaleType.BAND) { + return bandRef(scaleName); + } + else { // non-ordinal scale + return { value: config.bar.continuousBandSize }; + } + } + else if (config.scale.rangeStep && config.scale.rangeStep !== null) { + return { value: config.scale.rangeStep - 1 }; + } + return { value: 20 }; + } + + var geoshape = { + vgMark: 'shape', + encodeEntry: function (model) { + return __assign({}, baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' })); + }, + postEncodingTransform: function (model) { + var encoding = model.encoding; + var shapeDef = encoding.shape; + var transform = __assign({ type: 'geoshape', projection: model.projectionName() }, (shapeDef && isFieldDef(shapeDef) && shapeDef.type === GEOJSON ? { field: vgField(shapeDef, { expr: 'datum' }) } : {})); + return [transform]; + } + }; + + var line = { + vgMark: 'line', + encodeEntry: function (model) { + var width = model.width, height = model.height; + return __assign({}, baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), pointPosition('x', model, mid(width)), pointPosition('y', model, mid(height)), nonPosition('size', model, { + vgChannel: 'strokeWidth' // VL's line size is strokeWidth + }), defined(model)); + } + }; + var trail = { + vgMark: 'trail', + encodeEntry: function (model) { + var width = model.width, height = model.height; + return __assign({}, baseEncodeEntry(model, { size: 'include', orient: 'ignore' }), pointPosition('x', model, mid(width)), pointPosition('y', model, mid(height)), nonPosition('size', model), defined(model)); + } + }; + + function encodeEntry(model, fixedShape) { + var config = model.config, width = model.width, height = model.height; + return __assign({}, baseEncodeEntry(model, { size: 'include', orient: 'ignore' }), pointPosition('x', model, mid(width)), pointPosition('y', model, mid(height)), nonPosition('size', model), shapeMixins(model, config, fixedShape)); + } + function shapeMixins(model, config, fixedShape) { + if (fixedShape) { + return { shape: { value: fixedShape } }; + } + return nonPosition('shape', model, { defaultValue: getMarkConfig('shape', model.markDef, config) }); + } + var point = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model); + } + }; + var circle = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model, 'circle'); + } + }; + var square = { + vgMark: 'symbol', + encodeEntry: function (model) { + return encodeEntry(model, 'square'); + } + }; + + var rect = { + vgMark: 'rect', + encodeEntry: function (model) { + return __assign({}, baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), x$1(model), y$1(model)); + } + }; + function x$1(model) { + var xDef = model.encoding.x; + var x2Def = model.encoding.x2; + var xScale = model.getScaleComponent(X); + var xScaleType = xScale ? xScale.get('type') : undefined; + if (isFieldDef(xDef) && xDef.bin && !x2Def) { + return binnedPosition(xDef, 'x', model.scaleName('x'), 0, xScale.get('reverse')); + } + else if (isFieldDef(xDef) && xScale && hasDiscreteDomain(xScaleType)) { + /* istanbul ignore else */ + if (xScaleType === ScaleType.BAND) { + return bandPosition(xDef, 'x', model); + } + else { + // We don't support rect mark with point/ordinal scale + throw new Error(message.scaleTypeNotWorkWithMark(RECT, xScaleType)); + } + } + else { // continuous scale or no scale + return __assign({}, pointPosition('x', model, 'zeroOrMax'), pointPosition2(model, 'zeroOrMin', 'x2')); + } + } + function y$1(model) { + var yDef = model.encoding.y; + var y2Def = model.encoding.y2; + var yScale = model.getScaleComponent(Y); + var yScaleType = yScale ? yScale.get('type') : undefined; + if (isFieldDef(yDef) && yDef.bin && !y2Def) { + return binnedPosition(yDef, 'y', model.scaleName('y'), 0, yScale.get('reverse')); + } + else if (isFieldDef(yDef) && yScale && hasDiscreteDomain(yScaleType)) { + /* istanbul ignore else */ + if (yScaleType === ScaleType.BAND) { + return bandPosition(yDef, 'y', model); + } + else { + // We don't support rect mark with point/ordinal scale + throw new Error(message.scaleTypeNotWorkWithMark(RECT, yScaleType)); + } + } + else { // continuous scale or no scale + return __assign({}, pointPosition('y', model, 'zeroOrMax'), pointPosition2(model, 'zeroOrMin', 'y2')); + } + } + + var rule = { + vgMark: 'rule', + encodeEntry: function (model) { + var _config = model.config, markDef = model.markDef, width = model.width, height = model.height; + var orient = markDef.orient; + if (!model.encoding.x && !model.encoding.y && !model.encoding.latitude && !model.encoding.longitude) { + // Show nothing if we have none of x, y, lat, and long. + return {}; + } + return __assign({}, baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), pointPosition('x', model, orient === 'horizontal' ? 'zeroOrMin' : mid(width)), pointPosition('y', model, orient === 'vertical' ? 'zeroOrMin' : mid(height)), (orient !== 'vertical' ? pointPosition2(model, 'zeroOrMax', 'x2') : {}), (orient !== 'horizontal' ? pointPosition2(model, 'zeroOrMax', 'y2') : {}), nonPosition('size', model, { + vgChannel: 'strokeWidth', + defaultValue: markDef.size + })); + } + }; + + var text$3 = { + vgMark: 'text', + encodeEntry: function (model) { + var config = model.config, encoding = model.encoding, width = model.width, height = model.height, markDef = model.markDef; + return __assign({}, baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), pointPosition('x', model, mid(width)), pointPosition('y', model, mid(height)), text$2(model), nonPosition('size', model, __assign({}, (markDef.size ? { defaultValue: markDef.size } : {}), { vgChannel: 'fontSize' // VL's text size is fontSize + })), valueIfDefined('align', align(model.markDef, encoding, config))); + } + }; + function align(markDef, encoding, config) { + var a = markDef.align || getMarkConfig('align', markDef, config); + if (a === undefined) { + return 'center'; + } + // If there is a config, Vega-parser will process this already. + return undefined; + } + + var tick = { + vgMark: 'rect', + encodeEntry: function (model) { + var _a; + var config = model.config, markDef = model.markDef, width = model.width, height = model.height; + var orient = markDef.orient; + var vgSizeChannel = orient === 'horizontal' ? 'width' : 'height'; + var vgThicknessChannel = orient === 'horizontal' ? 'height' : 'width'; + return __assign({}, baseEncodeEntry(model, { size: 'ignore', orient: 'ignore' }), pointPosition('x', model, mid(width), 'xc'), pointPosition('y', model, mid(height), 'yc'), nonPosition('size', model, { + defaultValue: defaultSize(model), + vgChannel: vgSizeChannel + }), (_a = {}, _a[vgThicknessChannel] = { value: markDef.thickness || config.tick.thickness }, _a)); + } + }; + function defaultSize(model) { + var config = model.config, markDef = model.markDef; + var orient = markDef.orient; + var scale = model.getScaleComponent(orient === 'horizontal' ? 'x' : 'y'); + if (markDef.size !== undefined) { + return markDef.size; + } + else if (config.tick.bandSize !== undefined) { + return config.tick.bandSize; + } + else { + var scaleRange = scale ? scale.get('range') : undefined; + var rangeStep = scaleRange && isVgRangeStep(scaleRange) ? + scaleRange.step : + config.scale.rangeStep; + if (typeof rangeStep !== 'number') { + // FIXME consolidate this log + throw new Error('Function does not handle non-numeric rangeStep'); + } + return rangeStep / 1.5; + } + } + + var markCompiler = { + area: area, + bar: bar, + circle: circle, + geoshape: geoshape, + line: line, + point: point, + rect: rect, + rule: rule, + square: square, + text: text$3, + tick: tick, + trail: trail + }; + function parseMarkGroup(model) { + if (contains([LINE, AREA, TRAIL], model.mark)) { + return parsePathMark(model); + } + else { + return getMarkGroups(model); + } + } + var FACETED_PATH_PREFIX = 'faceted_path_'; + function parsePathMark(model) { + var details = pathGroupingFields(model.mark, model.encoding); + var pathMarks = getMarkGroups(model, { + // If has subfacet for line/area group, need to use faceted data from below. + fromPrefix: (details.length > 0 ? FACETED_PATH_PREFIX : '') + }); + if (details.length > 0) { // have level of details - need to facet line into subgroups + // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?) + return [{ + name: model.getName('pathgroup'), + type: 'group', + from: { + facet: { + name: FACETED_PATH_PREFIX + model.requestDataName(MAIN), + data: model.requestDataName(MAIN), + groupby: details, + } + }, + encode: { + update: { + width: { field: { group: 'width' } }, + height: { field: { group: 'height' } } + } + }, + marks: pathMarks + }]; + } + else { + return pathMarks; + } + } + function getSort$1(model) { + var encoding = model.encoding, stack = model.stack, mark = model.mark, markDef = model.markDef; + var order = encoding.order; + if (!isArray(order) && isValueDef(order)) { + return undefined; + } + else if ((isArray(order) || isFieldDef(order)) && !stack) { + // Sort by the order field if it is specified and the field is not stacked. (For stacked field, order specify stack order.) + return sortParams(order, { expr: 'datum' }); + } + else if (isPathMark(mark)) { + // For both line and area, we sort values based on dimension by default + var dimensionChannelDef = encoding[markDef.orient === 'horizontal' ? 'y' : 'x']; + if (isFieldDef(dimensionChannelDef)) { + var s = dimensionChannelDef.sort; + var sortField = isSortField(s) ? + vgField({ + // FIXME: this op might not already exist? + // FIXME: what if dimensionChannel (x or y) contains custom domain? + aggregate: isAggregate(model.encoding) ? s.op : undefined, + field: s.field + }, { expr: 'datum' }) : + vgField(dimensionChannelDef, { + // For stack with imputation, we only have bin_mid + binSuffix: model.stack && model.stack.impute ? 'mid' : undefined, + expr: 'datum' + }); + return { + field: sortField, + order: 'descending' + }; + } + return undefined; + } + return undefined; + } + function getMarkGroups(model, opt) { + if (opt === void 0) { opt = { fromPrefix: '' }; } + var mark = model.mark; + var clip = model.markDef.clip !== undefined ? + !!model.markDef.clip : scaleClip(model); + var style = getStyles(model.markDef); + var key$$1 = model.encoding.key; + var sort = getSort$1(model); + var postEncodingTransform = markCompiler[mark].postEncodingTransform ? markCompiler[mark].postEncodingTransform(model) : null; + return [__assign({ name: model.getName('marks'), type: markCompiler[mark].vgMark }, (clip ? { clip: true } : {}), (style ? { style: style } : {}), (key$$1 ? { key: { field: key$$1.field } } : {}), (sort ? { sort: sort } : {}), { from: { data: opt.fromPrefix + model.requestDataName(MAIN) }, encode: { + update: markCompiler[mark].encodeEntry(model) + } }, (postEncodingTransform ? { + transform: postEncodingTransform + } : {}))]; + } + /** + * Returns list of path grouping fields + * that the model's spec contains. + */ + function pathGroupingFields(mark, encoding) { + return keys(encoding).reduce(function (details, channel) { + switch (channel) { + // x, y, x2, y2, lat, long, lat1, long2, order, tooltip, href, cursor should not cause lines to group + case 'x': + case 'y': + case 'order': + case 'tooltip': + case 'href': + case 'x2': + case 'y2': + case 'latitude': + case 'longitude': + case 'latitude2': + case 'longitude2': + // TODO: case 'cursor': + // text, shape, shouldn't be a part of line/trail/area + case 'text': + case 'shape': + return details; + case 'detail': + case 'key': + var channelDef = encoding[channel]; + if (channelDef) { + (isArray(channelDef) ? channelDef : [channelDef]).forEach(function (fieldDef) { + if (!fieldDef.aggregate) { + details.push(vgField(fieldDef, {})); + } + }); + } + return details; + case 'size': + if (mark === 'trail') { + // For trail, size should not group trail lines. + return details; + } + // For line, it should group lines. + /* tslint:disable */ + // intentional fall through + case 'color': + case 'fill': + case 'stroke': + case 'opacity': + // TODO strokeDashOffset: + /* tslint:enable */ + var fieldDef = getFieldDef(encoding[channel]); + if (fieldDef && !fieldDef.aggregate) { + details.push(vgField(fieldDef, {})); + } + return details; + default: + throw new Error("Bug: Channel " + channel + " unimplemented for line mark"); + } + }, []); + } + /** + * If scales are bound to interval selections, we want to automatically clip + * marks to account for panning/zooming interactions. We identify bound scales + * by the domainRaw property, which gets added during scale parsing. + */ + function scaleClip(model) { + var xScale = model.getScaleComponent('x'); + var yScale = model.getScaleComponent('y'); + return (xScale && xScale.get('domainRaw')) || + (yScale && yScale.get('domainRaw')) ? true : false; + } + + /** + * Internal model of Vega-Lite specification for the compiler. + */ + var UnitModel = /** @class */ (function (_super) { + __extends(UnitModel, _super); + function UnitModel(spec, parent, parentGivenName, parentGivenSize, repeater, config, fit) { + if (parentGivenSize === void 0) { parentGivenSize = {}; } + var _this = _super.call(this, spec, parent, parentGivenName, config, repeater, undefined) || this; + _this.fit = fit; + _this.type = 'unit'; + _this.specifiedScales = {}; + _this.specifiedAxes = {}; + _this.specifiedLegends = {}; + _this.specifiedProjection = {}; + _this.selection = {}; + _this.children = []; + _this.initSize(__assign({}, parentGivenSize, (spec.width ? { width: spec.width } : {}), (spec.height ? { height: spec.height } : {}))); + var mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var encoding = _this.encoding = normalizeEncoding(replaceRepeaterInEncoding(spec.encoding || {}, repeater), mark); + _this.markDef = normalizeMarkDef(spec.mark, encoding, config); + // calculate stack properties + _this.stack = stack(mark, encoding, _this.config.stack); + _this.specifiedScales = _this.initScales(mark, encoding); + _this.specifiedAxes = _this.initAxes(encoding); + _this.specifiedLegends = _this.initLegend(encoding); + _this.specifiedProjection = spec.projection; + // Selections will be initialized upon parse. + _this.selection = spec.selection; + return _this; + } + Object.defineProperty(UnitModel.prototype, "hasProjection", { + get: function () { + var encoding = this.encoding; + var isGeoShapeMark = this.mark === GEOSHAPE; + var hasGeoPosition = encoding && GEOPOSITION_CHANNELS.some(function (channel) { return isFieldDef(encoding[channel]); }); + return isGeoShapeMark || hasGeoPosition; + }, + enumerable: true, + configurable: true + }); + /** + * Return specified Vega-lite scale domain for a particular channel + * @param channel + */ + UnitModel.prototype.scaleDomain = function (channel) { + var scale = this.specifiedScales[channel]; + return scale ? scale.domain : undefined; + }; + UnitModel.prototype.axis = function (channel) { + return this.specifiedAxes[channel]; + }; + UnitModel.prototype.legend = function (channel) { + return this.specifiedLegends[channel]; + }; + UnitModel.prototype.initScales = function (mark, encoding) { + return SCALE_CHANNELS.reduce(function (scales, channel) { + var fieldDef; + var specifiedScale; + var channelDef = encoding[channel]; + if (isFieldDef(channelDef)) { + fieldDef = channelDef; + specifiedScale = channelDef.scale; + } + else if (hasConditionalFieldDef(channelDef)) { + fieldDef = channelDef.condition; + specifiedScale = channelDef.condition['scale']; + } + else if (channel === 'x') { + fieldDef = getFieldDef(encoding.x2); + } + else if (channel === 'y') { + fieldDef = getFieldDef(encoding.y2); + } + if (fieldDef) { + scales[channel] = specifiedScale || {}; + } + return scales; + }, {}); + }; + UnitModel.prototype.initAxes = function (encoding) { + return [X, Y].reduce(function (_axis, channel) { + // Position Axis + // TODO: handle ConditionFieldDef + var channelDef = encoding[channel]; + if (isFieldDef(channelDef) || + (channel === X && isFieldDef(encoding.x2)) || + (channel === Y && isFieldDef(encoding.y2))) { + var axisSpec = isFieldDef(channelDef) ? channelDef.axis : null; + // We no longer support false in the schema, but we keep false here for backward compatibility. + if (axisSpec !== null && axisSpec !== false) { + _axis[channel] = __assign({}, axisSpec); + } + } + return _axis; + }, {}); + }; + UnitModel.prototype.initLegend = function (encoding) { + return NONPOSITION_SCALE_CHANNELS.reduce(function (_legend, channel) { + var channelDef = encoding[channel]; + if (channelDef) { + var legend = isFieldDef(channelDef) ? channelDef.legend : + (hasConditionalFieldDef(channelDef)) ? channelDef.condition['legend'] : null; + if (legend !== null && legend !== false) { + _legend[channel] = __assign({}, legend); + } + } + return _legend; + }, {}); + }; + UnitModel.prototype.parseData = function () { + this.component.data = parseData(this); + }; + UnitModel.prototype.parseLayoutSize = function () { + parseUnitLayoutSize(this); + }; + UnitModel.prototype.parseSelection = function () { + this.component.selection = parseUnitSelection(this, this.selection); + }; + UnitModel.prototype.parseMarkGroup = function () { + this.component.mark = parseMarkGroup(this); + }; + UnitModel.prototype.parseAxisAndHeader = function () { + this.component.axes = parseUnitAxis(this); + }; + UnitModel.prototype.assembleSelectionTopLevelSignals = function (signals) { + return assembleTopLevelSignals(this, signals); + }; + UnitModel.prototype.assembleSelectionSignals = function () { + return assembleUnitSelectionSignals(this, []); + }; + UnitModel.prototype.assembleSelectionData = function (data) { + return assembleUnitSelectionData(this, data); + }; + UnitModel.prototype.assembleLayout = function () { + return null; + }; + UnitModel.prototype.assembleLayoutSignals = function () { + return assembleLayoutSignals(this); + }; + UnitModel.prototype.assembleMarks = function () { + var marks = this.component.mark || []; + // If this unit is part of a layer, selections should augment + // all in concert rather than each unit individually. This + // ensures correct interleaving of clipping and brushed marks. + if (!this.parent || !isLayerModel(this.parent)) { + marks = assembleUnitSelectionMarks(this, marks); + } + return marks.map(this.correctDataNames); + }; + UnitModel.prototype.assembleLayoutSize = function () { + return { + width: this.getSizeSignalRef('width'), + height: this.getSizeSignalRef('height') + }; + }; + UnitModel.prototype.getMapping = function () { + return this.encoding; + }; + UnitModel.prototype.toSpec = function (excludeConfig, excludeData) { + var encoding = duplicate(this.encoding); + var spec; + spec = { + mark: this.markDef, + encoding: encoding + }; + if (!excludeConfig) { + spec.config = duplicate(this.config); + } + if (!excludeData) { + spec.data = duplicate(this.data); + } + // remove defaults + return spec; + }; + Object.defineProperty(UnitModel.prototype, "mark", { + get: function () { + return this.markDef.type; + }, + enumerable: true, + configurable: true + }); + UnitModel.prototype.channelHasField = function (channel) { + return channelHasField(this.encoding, channel); + }; + UnitModel.prototype.fieldDef = function (channel) { + var channelDef = this.encoding[channel]; + return getFieldDef(channelDef); + }; + return UnitModel; + }(ModelWithField)); + + var LayerModel = /** @class */ (function (_super) { + __extends(LayerModel, _super); + function LayerModel(spec, parent, parentGivenName, parentGivenSize, repeater, config, fit) { + var _this = _super.call(this, spec, parent, parentGivenName, config, repeater, spec.resolve) || this; + _this.type = 'layer'; + var layoutSize = __assign({}, parentGivenSize, (spec.width ? { width: spec.width } : {}), (spec.height ? { height: spec.height } : {})); + _this.initSize(layoutSize); + _this.children = spec.layer.map(function (layer, i) { + if (isLayerSpec(layer)) { + return new LayerModel(layer, _this, _this.getName('layer_' + i), layoutSize, repeater, config, fit); + } + if (isUnitSpec(layer)) { + return new UnitModel(layer, _this, _this.getName('layer_' + i), layoutSize, repeater, config, fit); + } + throw new Error(message.INVALID_SPEC); + }); + return _this; + } + LayerModel.prototype.parseData = function () { + this.component.data = parseData(this); + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseData(); + } + }; + LayerModel.prototype.parseLayoutSize = function () { + parseLayerLayoutSize(this); + }; + LayerModel.prototype.parseSelection = function () { + var _this = this; + // Merge selections up the hierarchy so that they may be referenced + // across unit specs. Persist their definitions within each child + // to assemble signals which remain within output Vega unit groups. + this.component.selection = {}; + var _loop_1 = function (child) { + child.parseSelection(); + keys(child.component.selection).forEach(function (key) { + _this.component.selection[key] = child.component.selection[key]; + }); + }; + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + _loop_1(child); + } + }; + LayerModel.prototype.parseMarkGroup = function () { + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + child.parseMarkGroup(); + } + }; + LayerModel.prototype.parseAxisAndHeader = function () { + parseLayerAxis(this); + }; + LayerModel.prototype.assembleSelectionTopLevelSignals = function (signals) { + return this.children.reduce(function (sg, child) { return child.assembleSelectionTopLevelSignals(sg); }, signals); + }; + // TODO: Support same named selections across children. + LayerModel.prototype.assembleSelectionSignals = function () { + return this.children.reduce(function (signals, child) { + return signals.concat(child.assembleSelectionSignals()); + }, []); + }; + LayerModel.prototype.assembleLayoutSignals = function () { + return this.children.reduce(function (signals, child) { + return signals.concat(child.assembleLayoutSignals()); + }, assembleLayoutSignals(this)); + }; + LayerModel.prototype.assembleSelectionData = function (data) { + return this.children.reduce(function (db, child) { return child.assembleSelectionData(db); }, data); + }; + LayerModel.prototype.assembleTitle = function () { + var title = _super.prototype.assembleTitle.call(this); + if (title) { + return title; + } + // If title does not provide layer, look into children + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + title = child.assembleTitle(); + if (title) { + return title; + } + } + return undefined; + }; + LayerModel.prototype.assembleLayout = function () { + return null; + }; + LayerModel.prototype.assembleMarks = function () { + return assembleLayerSelectionMarks(this, flatten(this.children.map(function (child) { + return child.assembleMarks(); + }))); + }; + LayerModel.prototype.assembleLegends = function () { + return this.children.reduce(function (legends, child) { + return legends.concat(child.assembleLegends()); + }, assembleLegends(this)); + }; + return LayerModel; + }(Model)); + + var RepeatModel = /** @class */ (function (_super) { + __extends(RepeatModel, _super); + function RepeatModel(spec, parent, parentGivenName, repeatValues, config) { + var _this = _super.call(this, spec, parent, parentGivenName, config, repeatValues, spec.resolve) || this; + _this.type = 'repeat'; + if (spec.resolve && spec.resolve.axis && (spec.resolve.axis.x === 'shared' || spec.resolve.axis.y === 'shared')) { + warn(message.REPEAT_CANNOT_SHARE_AXIS); + } + _this.repeat = spec.repeat; + _this.children = _this._initChildren(spec, _this.repeat, repeatValues, config); + return _this; + } + RepeatModel.prototype._initChildren = function (spec, repeat, repeater, config) { + var children = []; + var row = repeat.row || [repeater ? repeater.row : null]; + var column = repeat.column || [repeater ? repeater.column : null]; + // cross product + for (var _i = 0, row_1 = row; _i < row_1.length; _i++) { + var rowField = row_1[_i]; + for (var _a = 0, column_1 = column; _a < column_1.length; _a++) { + var columnField = column_1[_a]; + var name_1 = (rowField ? '_' + rowField : '') + (columnField ? '_' + columnField : ''); + var childRepeat = { + row: rowField, + column: columnField + }; + children.push(buildModel(spec.spec, this, this.getName('child' + name_1), undefined, childRepeat, config, false)); + } + } + return children; + }; + RepeatModel.prototype.parseLayoutSize = function () { + parseRepeatLayoutSize(this); + }; + RepeatModel.prototype.assembleDefaultLayout = function () { + return { + columns: this.repeat && this.repeat.column ? this.repeat.column.length : 1, + bounds: 'full', + align: 'all' + }; + }; + return RepeatModel; + }(BaseConcatModel)); + + function buildModel(spec, parent, parentGivenName, unitSize, repeater, config, fit) { + if (isFacetSpec(spec)) { + return new FacetModel(spec, parent, parentGivenName, repeater, config); + } + if (isLayerSpec(spec)) { + return new LayerModel(spec, parent, parentGivenName, unitSize, repeater, config, fit); + } + if (isUnitSpec(spec)) { + return new UnitModel(spec, parent, parentGivenName, unitSize, repeater, config, fit); + } + if (isRepeatSpec(spec)) { + return new RepeatModel(spec, parent, parentGivenName, repeater, config); + } + if (isConcatSpec(spec)) { + return new ConcatModel(spec, parent, parentGivenName, repeater, config); + } + throw new Error(message.INVALID_SPEC); + } + + /** + * Vega-Lite's main function, for compiling Vega-lite spec into Vega spec. + * + * At a high-level, we make the following transformations in different phases: + * + * Input spec + * | + * | (Normalization) + * v + * Normalized Spec (Row/Column channels in single-view specs becomes faceted specs, composite marks becomes layered specs.) + * | + * | (Build Model) + * v + * A model tree of the spec + * | + * | (Parse) + * v + * A model tree with parsed components (intermediate structure of visualization primitives in a format that can be easily merged) + * | + * | (Optimize) + * v + * A model tree with parsed components with the data component optimized + * | + * | (Assemble) + * v + * Vega spec + */ + function compile(inputSpec, opt) { + if (opt === void 0) { opt = {}; } + // 0. Augment opt with default opts + if (opt.logger) { + // set the singleton logger to the provided logger + set(opt.logger); + } + if (opt.fieldTitle) { + // set the singleton field title formatter + setTitleFormatter(opt.fieldTitle); + } + try { + // 1. Initialize config by deep merging default config with the config provided via option and the input spec. + var config = initConfig(mergeDeep({}, opt.config, inputSpec.config)); + // 2. Normalize: Convert input spec -> normalized spec + // - Decompose all extended unit specs into composition of unit spec. For example, a box plot get expanded into multiple layers of bars, ticks, and rules. The shorthand row/column channel is also expanded to a facet spec. + var spec = normalize$2(inputSpec, config); + // - Normalize autosize to be a autosize properties object. + var autosize = normalizeAutoSize(inputSpec.autosize, config.autosize, isLayerSpec(spec) || isUnitSpec(spec)); + // 3. Build Model: normalized spec -> Model (a tree structure) + // This phases instantiates the models with default config by doing a top-down traversal. This allows us to pass properties that child models derive from their parents via their constructors. + // See the abstract `Model` class and its children (UnitModel, LayerModel, FacetModel, RepeatModel, ConcatModel) for different types of models. + var model = buildModel(spec, null, '', undefined, undefined, config, autosize.type === 'fit'); + // 4 Parse: Model --> Model with components + // Note that components = intermediate representations that are equivalent to Vega specs. + // We need these intermediate representation because we need to merge many visualizaiton "components" like projections, scales, axes, and legends. + // We will later convert these components into actual Vega specs in the assemble phase. + // In this phase, we do a bottom-up traversal over the whole tree to + // parse for each type of components once (e.g., data, layout, mark, scale). + // By doing bottom-up traversal, we start parsing components of unit specs and + // then merge child components of parent composite specs. + // + // Please see inside model.parse() for order of different components parsed. + model.parse(); + // 5. Optimize the dataflow. This will modify the data component of the model. + optimizeDataflow(model.component.data); + // 6. Assemble: convert model components --> Vega Spec. + return assembleTopLevelModel(model, getTopLevelProperties(inputSpec, config, autosize)); + } + finally { + // Reset the singleton logger if a logger is provided + if (opt.logger) { + reset(); + } + // Reset the singleton field title formatter if provided + if (opt.fieldTitle) { + resetTitleFormatter(); + } + } + } + function getTopLevelProperties(topLevelSpec, config, autosize) { + return __assign({ autosize: keys(autosize).length === 1 && autosize.type ? autosize.type : autosize }, extractTopLevelProperties(config), extractTopLevelProperties(topLevelSpec)); + } + /* + * Assemble the top-level model. + * + * Note: this couldn't be `model.assemble()` since the top-level model + * needs some special treatment to generate top-level properties. + */ + function assembleTopLevelModel(model, topLevelProperties) { + // TODO: change type to become VgSpec + // Config with Vega-Lite only config removed. + var vgConfig = model.config ? stripAndRedirectConfig(model.config) : undefined; + var data = [].concat(model.assembleSelectionData([]), + // only assemble data in the root + assembleRootData(model.component.data, topLevelProperties.datasets || {})); + delete topLevelProperties.datasets; + var projections = model.assembleProjections(); + var title$$1 = model.assembleTitle(); + var style = model.assembleGroupStyle(); + var layoutSignals = model.assembleLayoutSignals(); + // move width and height signals with values to top level + layoutSignals = layoutSignals.filter(function (signal) { + if ((signal.name === 'width' || signal.name === 'height') && signal.value !== undefined) { + topLevelProperties[signal.name] = +signal.value; + return false; + } + return true; + }); + var output = __assign({ $schema: 'https://vega.github.io/schema/vega/v3.json' }, (model.description ? { description: model.description } : {}), topLevelProperties, (title$$1 ? { title: title$$1 } : {}), (style ? { style: style } : {}), { data: data }, (projections.length > 0 ? { projections: projections } : {}), model.assembleGroup(layoutSignals.concat(model.assembleSelectionTopLevelSignals([]))), (vgConfig ? { config: vgConfig } : {})); + return { + spec: output + // TODO: add warning / errors here + }; + } + + + + var facet = /*#__PURE__*/Object.freeze({ + + }); + + /** + * Required Encoding Channels for each mark type + */ + var DEFAULT_REQUIRED_CHANNEL_MAP = { + text: ['text'], + line: ['x', 'y'], + trail: ['x', 'y'], + area: ['x', 'y'] + }; + /** + * Supported Encoding Channel for each mark type + */ + var DEFAULT_SUPPORTED_CHANNEL_TYPE = { + bar: toSet(['row', 'column', 'x', 'y', 'size', 'color', 'fill', 'stroke', 'detail']), + line: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'color', 'detail']), + trail: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'color', 'detail', 'size']), + area: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'detail']), + tick: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'detail']), + circle: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail']), + square: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail']), + point: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail', 'shape']), + geoshape: toSet(['row', 'column', 'color', 'fill', 'stroke', 'detail', 'shape']), + text: toSet(['row', 'column', 'size', 'color', 'fill', 'stroke', 'text']) // TODO(#724) revise + }; + // TODO: consider if we should add validate method and + // requires ZSchema in the main vega-lite repo + /** + * Further check if encoding mapping of a spec is invalid and + * return error if it is invalid. + * + * This checks if + * (1) all the required encoding channels for the mark type are specified + * (2) all the specified encoding channels are supported by the mark type + * @param {[type]} spec [description] + * @param {RequiredChannelMap = DefaultRequiredChannelMap} requiredChannelMap + * @param {SupportedChannelMap = DefaultSupportedChannelMap} supportedChannelMap + * @return {String} Return one reason why the encoding is invalid, + * or null if the encoding is valid. + */ + function getEncodingMappingError(spec, requiredChannelMap, supportedChannelMap) { + if (requiredChannelMap === void 0) { requiredChannelMap = DEFAULT_REQUIRED_CHANNEL_MAP; } + if (supportedChannelMap === void 0) { supportedChannelMap = DEFAULT_SUPPORTED_CHANNEL_TYPE; } + var mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var encoding = spec.encoding; + var requiredChannels = requiredChannelMap[mark]; + var supportedChannels = supportedChannelMap[mark]; + for (var i in requiredChannels) { // all required channels are in encoding` + if (!(requiredChannels[i] in encoding)) { + return 'Missing encoding channel \"' + requiredChannels[i] + + '\" for mark \"' + mark + '\"'; + } + } + for (var channel in encoding) { // all channels in encoding are supported + if (!supportedChannels[channel]) { + return 'Encoding channel \"' + channel + + '\" is not supported by mark type \"' + mark + '\"'; + } + } + if (mark === BAR && !encoding.x && !encoding.y) { + return 'Missing both x and y for bar'; + } + return null; + } + + var validate = /*#__PURE__*/Object.freeze({ + DEFAULT_REQUIRED_CHANNEL_MAP: DEFAULT_REQUIRED_CHANNEL_MAP, + DEFAULT_SUPPORTED_CHANNEL_TYPE: DEFAULT_SUPPORTED_CHANNEL_TYPE, + getEncodingMappingError: getEncodingMappingError + }); + + var name = "vega-lite"; + var author = "Jeffrey Heer, Dominik Moritz, Kanit \"Ham\" Wongsuphasawat"; + var version = "2.6.0"; + var collaborators = [ + "Kanit Wongsuphasawat (http://kanitw.yellowpigz.com)", + "Dominik Moritz (https://www.domoritz.de)", + "Jeffrey Heer (http://jheer.org)" + ]; + var homepage = "https://vega.github.io/vega-lite/"; + var description = "Vega-Lite is a concise high-level language for interactive visualization."; + var main$1 = "build/vega-lite.js"; + var unpkg = "build/vega-lite.min.js"; + var jsdelivr = "build/vega-lite.min.js"; + var module$1 = "build/src/index"; + var types = "build/src/index.d.ts"; + var bin$2 = { + vl2png: "./bin/vl2png", + vl2svg: "./bin/vl2svg", + vl2vg: "./bin/vl2vg" + }; + var directories = { + test: "test" + }; + var scripts = { + prebuild: "mkdir -p build/src", + build: "npm run build:only", + "build:only": "tsc && rollup -c", + postbuild: "uglifyjs build/vega-lite.js -cm --source-map content=build/vega-lite.js.map,filename=build/vega-lite.min.js.map -o build/vega-lite.min.js && npm run schema", + "build:examples": "npm run data && TZ=America/Los_Angeles scripts/build-examples.sh", + "build:examples-full": "TZ=America/Los_Angeles scripts/build-examples.sh 1", + "build:example": "TZ=America/Los_Angeles scripts/build-example.sh", + "build:toc": "bundle exec jekyll build -q && scripts/generate-toc", + "build:site": "tsc -p site && webpack --config site/webpack.config.js", + "build:versions": "scripts/update-version.sh", + "check:examples": "scripts/check-examples.sh", + "check:schema": "scripts/check-schema.sh", + clean: "rm -rf build && rm -f examples/compiled/*.png && find site/examples ! -name 'index.md' -type f -delete", + data: "rsync -r node_modules/vega-datasets/data/* data", + deploy: "scripts/deploy.sh", + "deploy:gh": "scripts/deploy-gh.sh", + "deploy:schema": "scripts/deploy-schema.sh", + preschema: "npm run prebuild", + schema: "node --stack-size=1200 ./node_modules/.bin/ts-json-schema-generator --path tsconfig.json --type TopLevelSpec > build/vega-lite-schema.json && npm run renameschema && cp build/vega-lite-schema.json _data/", + renameschema: "scripts/rename-schema.sh", + presite: "npm run prebuild && npm run data && npm run build:site && npm run build:toc && npm run build:versions && scripts/create-example-pages", + site: "bundle exec jekyll serve --incremental", + lint: "tslint -p . -e 'package.json'", + test: "jest test/ && npm run lint && npm run schema && jest examples/ && npm run test:runtime", + "test:inspect": "node --inspect-brk ./node_modules/.bin/jest --runInBand test", + "test:runtime": "TZ=America/Los_Angeles TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' wdio wdio.conf.js", + "test:runtime:generate": "rm -Rf test-runtime/resources && VL_GENERATE_TESTS=true npm run test:runtime", + "watch:build": "npm run build:only && concurrently --kill-others -n Typescript,Rollup 'tsc -w' 'rollup -c -w'", + "watch:site": "concurrently --kill-others -n Typescript,Webpack 'tsc -p site --watch' 'webpack --config site/webpack.config.js --mode development --watch'", + "watch:test": "jest --watch" + }; + var repository = { + type: "git", + url: "https://github.com/vega/vega-lite.git" + }; + var license = "BSD-3-Clause"; + var bugs = { + url: "https://github.com/vega/vega-lite/issues" + }; + var devDependencies = { + "@types/chai": "^4.1.4", + "@types/d3": "^5.0.0", + "@types/highlight.js": "^9.12.3", + "@types/jest": "^23.1.1", + "@types/mkdirp": "^0.5.2", + "@types/node": "^9.0.0", + "@types/webdriverio": "^4.10.2", + ajv: "^6.5.1", + chai: "^4.1.2", + cheerio: "^1.0.0-rc.2", + chromedriver: "^2.40.0", + codecov: "^3.0.2", + concurrently: "^3.6.0", + d3: "^5.5.0", + "highlight.js": "^9.12.0", + jest: "^23.1.0", + mkdirp: "^0.5.1", + rollup: "^0.59.4", + "rollup-plugin-commonjs": "^9.1.3", + "rollup-plugin-json": "^3.0.0", + "rollup-plugin-node-resolve": "^3.3.0", + "rollup-plugin-sourcemaps": "^0.4.2", + "source-map-support": "^0.5.6", + "svg2png-many": "^0.0.7", + "ts-jest": "^22.4.6", + "ts-json-schema-generator": "^0.28.0", + "ts-node": "^6.1.1", + tslint: "5.10.0", + "tslint-eslint-rules": "^5.3.1", + typescript: "^2.9.2", + "uglify-js": "^3.4.1", + vega: "^4.0.0-rc.3", + "vega-datasets": "^1.19.0", + "vega-embed": "^3.16.0", + "vega-tooltip": "^0.11.0", + "wdio-chromedriver-service": "^0.1.3", + "wdio-dot-reporter": "0.0.9", + "wdio-mocha-framework": "^0.5.13", + "wdio-static-server-service": "^1.0.1", + webdriverio: "^4.13.0", + webpack: "^4.12.0", + "webpack-cli": "^3.0.8", + "yaml-front-matter": "^4.0.0" + }; + var dependencies = { + "@types/json-stable-stringify": "^1.0.32", + "json-stable-stringify": "^1.0.1", + tslib: "^1.9.2", + "vega-event-selector": "^2.0.0", + "vega-typings": "^0.3.17", + "vega-util": "^1.7.0", + yargs: "^11.0.0" + }; + var jest = { + transform: { + "^.+\\.tsx?$": "ts-jest" + }, + testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", + moduleFileExtensions: [ + "ts", + "tsx", + "js", + "jsx", + "json", + "node" + ], + testPathIgnorePatterns: [ + "node_modules", + "test-runtime", + "/build", + "_site", + "src" + ], + coverageDirectory: "./coverage/", + collectCoverage: false + }; + var pkg = { + name: name, + author: author, + version: version, + collaborators: collaborators, + homepage: homepage, + description: description, + main: main$1, + unpkg: unpkg, + jsdelivr: jsdelivr, + module: module$1, + types: types, + bin: bin$2, + directories: directories, + scripts: scripts, + repository: repository, + license: license, + bugs: bugs, + devDependencies: devDependencies, + dependencies: dependencies, + jest: jest + }; + + var version$1 = pkg.version; + + exports.aggregate = aggregate; + exports.axis = axis; + exports.bin = bin; + exports.channel = channel; + exports.compositeMark = index; + exports.config = config; + exports.data = data; + exports.datetime = datetime; + exports.encoding = encoding; + exports.facet = facet; + exports.fieldDef = fielddef; + exports.header = header; + exports.legend = legend; + exports.mark = mark; + exports.scale = scale; + exports.sort = sort; + exports.spec = spec; + exports.stack = stack$1; + exports.timeUnit = timeunit; + exports.transform = transform; + exports.type = type; + exports.util = util; + exports.validate = validate; + exports.version = version$1; + exports.compile = compile; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); +//# sourceMappingURL=vega-lite.js.map diff --git a/build/vega-lite.js.map b/build/vega-lite.js.map new file mode 100644 index 0000000000..ba6d4b1926 --- /dev/null +++ b/build/vega-lite.js.map @@ -0,0 +1 @@ +{"version":3,"file":"vega-lite.js","sources":["../node_modules/vega-util/src/accessor.js","../node_modules/vega-util/src/error.js","../node_modules/vega-util/src/splitAccessPath.js","../node_modules/vega-util/src/isArray.js","../node_modules/vega-util/src/isObject.js","../node_modules/vega-util/src/isString.js","../node_modules/vega-util/src/stringValue.js","../node_modules/vega-util/src/field.js","../node_modules/vega-util/src/accessors.js","../node_modules/vega-util/src/logger.js","../node_modules/vega-util/src/isFunction.js","../node_modules/vega-util/src/isBoolean.js","../node_modules/vega-util/src/isNumber.js","../node_modules/vega-util/src/toSet.js","../node_modules/tslib/tslib.es6.js","../node_modules/jsonify/lib/parse.js","../node_modules/jsonify/lib/stringify.js","../node_modules/jsonify/index.js","../node_modules/json-stable-stringify/index.js","../src/logical.ts","../src/util.ts","../src/aggregate.ts","../src/axis.ts","../src/channel.ts","../src/bin.ts","../src/mark.ts","../src/log.ts","../src/datetime.ts","../src/timeunit.ts","../src/type.ts","../src/fielddef.ts","../src/encoding.ts","../src/compositemark/common.ts","../src/compositemark/boxplot.ts","../src/compositemark/errorbar.ts","../src/compositemark/index.ts","../src/guide.ts","../src/legend.ts","../src/scale.ts","../src/selection.ts","../src/title.ts","../src/config.ts","../src/stack.ts","../src/spec.ts","../src/toplevelprops.ts","../src/data.ts","../node_modules/vega-event-selector/src/event-selector.js","../src/vega.schema.ts","../src/compile/axis/assemble.ts","../src/header.ts","../src/sort.ts","../src/compile/mark/valueref.ts","../src/compile/mark/mixins.ts","../src/compile/common.ts","../src/compile/data/dataflow.ts","../src/compile/data/calculate.ts","../src/compile/header/index.ts","../src/compile/layoutsize/assemble.ts","../src/compile/resolve.ts","../src/compile/split.ts","../src/compile/legend/component.ts","../src/compile/legend/encode.ts","../src/compile/legend/properties.ts","../src/compile/legend/parse.ts","../src/compile/legend/assemble.ts","../src/compile/projection/assemble.ts","../src/projection.ts","../src/compile/projection/component.ts","../src/compile/projection/parse.ts","../src/compile/data/aggregate.ts","../src/compile/data/facet.ts","../src/compile/data/filterinvalid.ts","../src/compile/data/formatparse.ts","../src/compile/data/source.ts","../src/compile/data/timeunit.ts","../src/compile/data/optimizers.ts","../src/compile/data/stack.ts","../src/compile/data/optimize.ts","../src/compile/scale/domain.ts","../src/compile/scale/assemble.ts","../src/compile/scale/component.ts","../src/compile/scale/range.ts","../src/compile/scale/properties.ts","../src/compile/scale/type.ts","../src/compile/scale/parse.ts","../src/compile/model.ts","../src/compile/selection/transforms/scales.ts","../src/compile/selection/interval.ts","../src/compile/selection/transforms/nearest.ts","../src/compile/selection/multi.ts","../src/compile/selection/single.ts","../src/compile/selection/transforms/inputs.ts","../src/compile/selection/transforms/project.ts","../src/compile/selection/transforms/toggle.ts","../src/compile/selection/transforms/translate.ts","../src/compile/selection/transforms/zoom.ts","../src/compile/selection/transforms/transforms.ts","../src/compile/selection/selection.ts","../src/predicate.ts","../src/transform.ts","../src/compile/data/bin.ts","../src/compile/data/filter.ts","../src/compile/data/geojson.ts","../src/compile/data/geopoint.ts","../src/compile/data/identifier.ts","../src/compile/data/index.ts","../src/compile/data/lookup.ts","../src/compile/data/assemble.ts","../src/compile/layoutsize/parse.ts","../src/compile/repeater.ts","../src/compile/facet.ts","../src/compile/data/window.ts","../src/compile/data/parse.ts","../src/compile/baseconcat.ts","../src/compile/concat.ts","../src/compile/axis/component.ts","../src/compile/axis/config.ts","../src/compile/axis/encode.ts","../src/compile/axis/properties.ts","../src/compile/axis/parse.ts","../src/compile/mark/init.ts","../src/compile/mark/area.ts","../src/compile/mark/bar.ts","../src/compile/mark/geoshape.ts","../src/compile/mark/line.ts","../src/compile/mark/point.ts","../src/compile/mark/rect.ts","../src/compile/mark/rule.ts","../src/compile/mark/text.ts","../src/compile/mark/tick.ts","../src/compile/mark/mark.ts","../src/compile/unit.ts","../src/compile/layer.ts","../src/compile/repeat.ts","../src/compile/buildmodel.ts","../src/compile/compile.ts","../src/validate.ts","../src/index.ts"],"sourcesContent":["export default function(fn, fields, name) {\n fn.fields = fields || [];\n fn.fname = name;\n return fn;\n}\n\nexport function accessorName(fn) {\n return fn == null ? null : fn.fname;\n}\n\nexport function accessorFields(fn) {\n return fn == null ? null : fn.fields;\n}\n","export default function(message) {\n throw Error(message);\n}\n","import error from './error';\n\nexport default function(p) {\n var path = [],\n q = null,\n b = 0,\n n = p.length,\n s = '',\n i, j, c;\n\n p = p + '';\n\n function push() {\n path.push(s + p.substring(i, j));\n s = '';\n i = j + 1;\n }\n\n for (i=j=0; j i) {\n push();\n } else {\n i = j + 1;\n }\n } else if (c === '[') {\n if (j > i) push();\n b = i = j + 1;\n } else if (c === ']') {\n if (!b) error('Access path missing open bracket: ' + p);\n if (b > 0) push();\n b = 0;\n i = j + 1;\n }\n }\n\n if (b) error('Access path missing closing bracket: ' + p);\n if (q) error('Access path missing closing quote: ' + p);\n\n if (j > i) {\n j++;\n push();\n }\n\n return path;\n}\n","export default Array.isArray;\n","export default function(_) {\n return _ === Object(_);\n}\n","export default function(_) {\n return typeof _ === 'string';\n}\n","import isArray from './isArray';\nimport isObject from './isObject';\nimport isString from './isString';\n\nexport default function $(x) {\n return isArray(x) ? '[' + x.map($) + ']'\n : isObject(x) || isString(x) ?\n // Output valid JSON and JS source strings.\n // See http://timelessrepo.com/json-isnt-a-javascript-subset\n JSON.stringify(x).replace('\\u2028','\\\\u2028').replace('\\u2029', '\\\\u2029')\n : x;\n}\n","import accessor from './accessor';\nimport splitAccessPath from './splitAccessPath';\nimport stringValue from './stringValue';\n\nexport default function(field, name) {\n var path = splitAccessPath(field),\n code = 'return _[' + path.map(stringValue).join('][') + '];';\n\n return accessor(\n Function('_', code),\n [(field = path.length===1 ? path[0] : field)],\n name || field\n );\n}\n","import accessor from './accessor';\nimport field from './field';\n\nvar empty = [];\n\nexport var id = field('id');\n\nexport var identity = accessor(function(_) { return _; }, empty, 'identity');\n\nexport var zero = accessor(function() { return 0; }, empty, 'zero');\n\nexport var one = accessor(function() { return 1; }, empty, 'one');\n\nexport var truthy = accessor(function() { return true; }, empty, 'true');\n\nexport var falsy = accessor(function() { return false; }, empty, 'false');\n","function log(method, level, input) {\n var args = [level].concat([].slice.call(input));\n console[method].apply(console, args); // eslint-disable-line no-console\n}\n\nexport var None = 0;\nexport var Error = 1;\nexport var Warn = 2;\nexport var Info = 3;\nexport var Debug = 4;\n\nexport default function(_) {\n var level = _ || None;\n return {\n level: function(_) {\n if (arguments.length) {\n level = +_;\n return this;\n } else {\n return level;\n }\n },\n error: function() {\n if (level >= Error) log('error', 'ERROR', arguments);\n return this;\n },\n warn: function() {\n if (level >= Warn) log('warn', 'WARN', arguments);\n return this;\n },\n info: function() {\n if (level >= Info) log('log', 'INFO', arguments);\n return this;\n },\n debug: function() {\n if (level >= Debug) log('log', 'DEBUG', arguments);\n return this;\n }\n }\n}\n","export default function(_) {\n return typeof _ === 'function';\n}\n","export default function(_) {\n return typeof _ === 'boolean';\n}\n","export default function(_) {\n return typeof _ === 'number';\n}\n","export default function(_) {\n for (var s={}, i=0, n=_.length; i= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n","var at, // The index of the current character\n ch, // The current character\n escapee = {\n '\"': '\"',\n '\\\\': '\\\\',\n '/': '/',\n b: '\\b',\n f: '\\f',\n n: '\\n',\n r: '\\r',\n t: '\\t'\n },\n text,\n\n error = function (m) {\n // Call error when something is wrong.\n throw {\n name: 'SyntaxError',\n message: m,\n at: at,\n text: text\n };\n },\n \n next = function (c) {\n // If a c parameter is provided, verify that it matches the current character.\n if (c && c !== ch) {\n error(\"Expected '\" + c + \"' instead of '\" + ch + \"'\");\n }\n \n // Get the next character. When there are no more characters,\n // return the empty string.\n \n ch = text.charAt(at);\n at += 1;\n return ch;\n },\n \n number = function () {\n // Parse a number value.\n var number,\n string = '';\n \n if (ch === '-') {\n string = '-';\n next('-');\n }\n while (ch >= '0' && ch <= '9') {\n string += ch;\n next();\n }\n if (ch === '.') {\n string += '.';\n while (next() && ch >= '0' && ch <= '9') {\n string += ch;\n }\n }\n if (ch === 'e' || ch === 'E') {\n string += ch;\n next();\n if (ch === '-' || ch === '+') {\n string += ch;\n next();\n }\n while (ch >= '0' && ch <= '9') {\n string += ch;\n next();\n }\n }\n number = +string;\n if (!isFinite(number)) {\n error(\"Bad number\");\n } else {\n return number;\n }\n },\n \n string = function () {\n // Parse a string value.\n var hex,\n i,\n string = '',\n uffff;\n \n // When parsing for string values, we must look for \" and \\ characters.\n if (ch === '\"') {\n while (next()) {\n if (ch === '\"') {\n next();\n return string;\n } else if (ch === '\\\\') {\n next();\n if (ch === 'u') {\n uffff = 0;\n for (i = 0; i < 4; i += 1) {\n hex = parseInt(next(), 16);\n if (!isFinite(hex)) {\n break;\n }\n uffff = uffff * 16 + hex;\n }\n string += String.fromCharCode(uffff);\n } else if (typeof escapee[ch] === 'string') {\n string += escapee[ch];\n } else {\n break;\n }\n } else {\n string += ch;\n }\n }\n }\n error(\"Bad string\");\n },\n\n white = function () {\n\n// Skip whitespace.\n\n while (ch && ch <= ' ') {\n next();\n }\n },\n\n word = function () {\n\n// true, false, or null.\n\n switch (ch) {\n case 't':\n next('t');\n next('r');\n next('u');\n next('e');\n return true;\n case 'f':\n next('f');\n next('a');\n next('l');\n next('s');\n next('e');\n return false;\n case 'n':\n next('n');\n next('u');\n next('l');\n next('l');\n return null;\n }\n error(\"Unexpected '\" + ch + \"'\");\n },\n\n value, // Place holder for the value function.\n\n array = function () {\n\n// Parse an array value.\n\n var array = [];\n\n if (ch === '[') {\n next('[');\n white();\n if (ch === ']') {\n next(']');\n return array; // empty array\n }\n while (ch) {\n array.push(value());\n white();\n if (ch === ']') {\n next(']');\n return array;\n }\n next(',');\n white();\n }\n }\n error(\"Bad array\");\n },\n\n object = function () {\n\n// Parse an object value.\n\n var key,\n object = {};\n\n if (ch === '{') {\n next('{');\n white();\n if (ch === '}') {\n next('}');\n return object; // empty object\n }\n while (ch) {\n key = string();\n white();\n next(':');\n if (Object.hasOwnProperty.call(object, key)) {\n error('Duplicate key \"' + key + '\"');\n }\n object[key] = value();\n white();\n if (ch === '}') {\n next('}');\n return object;\n }\n next(',');\n white();\n }\n }\n error(\"Bad object\");\n };\n\nvalue = function () {\n\n// Parse a JSON value. It could be an object, an array, a string, a number,\n// or a word.\n\n white();\n switch (ch) {\n case '{':\n return object();\n case '[':\n return array();\n case '\"':\n return string();\n case '-':\n return number();\n default:\n return ch >= '0' && ch <= '9' ? number() : word();\n }\n};\n\n// Return the json_parse function. It will have access to all of the above\n// functions and variables.\n\nmodule.exports = function (source, reviver) {\n var result;\n \n text = source;\n at = 0;\n ch = ' ';\n result = value();\n white();\n if (ch) {\n error(\"Syntax error\");\n }\n\n // If there is a reviver function, we recursively walk the new structure,\n // passing each name/value pair to the reviver function for possible\n // transformation, starting with a temporary root object that holds the result\n // in an empty key. If there is not a reviver function, we simply return the\n // result.\n\n return typeof reviver === 'function' ? (function walk(holder, key) {\n var k, v, value = holder[key];\n if (value && typeof value === 'object') {\n for (k in value) {\n if (Object.prototype.hasOwnProperty.call(value, k)) {\n v = walk(value, k);\n if (v !== undefined) {\n value[k] = v;\n } else {\n delete value[k];\n }\n }\n }\n }\n return reviver.call(holder, key, value);\n }({'': result}, '')) : result;\n};\n","var cx = /[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n escapable = /[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n gap,\n indent,\n meta = { // table of character substitutions\n '\\b': '\\\\b',\n '\\t': '\\\\t',\n '\\n': '\\\\n',\n '\\f': '\\\\f',\n '\\r': '\\\\r',\n '\"' : '\\\\\"',\n '\\\\': '\\\\\\\\'\n },\n rep;\n\nfunction quote(string) {\n // If the string contains no control characters, no quote characters, and no\n // backslash characters, then we can safely slap some quotes around it.\n // Otherwise we must also replace the offending characters with safe escape\n // sequences.\n \n escapable.lastIndex = 0;\n return escapable.test(string) ? '\"' + string.replace(escapable, function (a) {\n var c = meta[a];\n return typeof c === 'string' ? c :\n '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n }) + '\"' : '\"' + string + '\"';\n}\n\nfunction str(key, holder) {\n // Produce a string from holder[key].\n var i, // The loop counter.\n k, // The member key.\n v, // The member value.\n length,\n mind = gap,\n partial,\n value = holder[key];\n \n // If the value has a toJSON method, call it to obtain a replacement value.\n if (value && typeof value === 'object' &&\n typeof value.toJSON === 'function') {\n value = value.toJSON(key);\n }\n \n // If we were called with a replacer function, then call the replacer to\n // obtain a replacement value.\n if (typeof rep === 'function') {\n value = rep.call(holder, key, value);\n }\n \n // What happens next depends on the value's type.\n switch (typeof value) {\n case 'string':\n return quote(value);\n \n case 'number':\n // JSON numbers must be finite. Encode non-finite numbers as null.\n return isFinite(value) ? String(value) : 'null';\n \n case 'boolean':\n case 'null':\n // If the value is a boolean or null, convert it to a string. Note:\n // typeof null does not produce 'null'. The case is included here in\n // the remote chance that this gets fixed someday.\n return String(value);\n \n case 'object':\n if (!value) return 'null';\n gap += indent;\n partial = [];\n \n // Array.isArray\n if (Object.prototype.toString.apply(value) === '[object Array]') {\n length = value.length;\n for (i = 0; i < length; i += 1) {\n partial[i] = str(i, value) || 'null';\n }\n \n // Join all of the elements together, separated with commas, and\n // wrap them in brackets.\n v = partial.length === 0 ? '[]' : gap ?\n '[\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + ']' :\n '[' + partial.join(',') + ']';\n gap = mind;\n return v;\n }\n \n // If the replacer is an array, use it to select the members to be\n // stringified.\n if (rep && typeof rep === 'object') {\n length = rep.length;\n for (i = 0; i < length; i += 1) {\n k = rep[i];\n if (typeof k === 'string') {\n v = str(k, value);\n if (v) {\n partial.push(quote(k) + (gap ? ': ' : ':') + v);\n }\n }\n }\n }\n else {\n // Otherwise, iterate through all of the keys in the object.\n for (k in value) {\n if (Object.prototype.hasOwnProperty.call(value, k)) {\n v = str(k, value);\n if (v) {\n partial.push(quote(k) + (gap ? ': ' : ':') + v);\n }\n }\n }\n }\n \n // Join all of the member texts together, separated with commas,\n // and wrap them in braces.\n\n v = partial.length === 0 ? '{}' : gap ?\n '{\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + '}' :\n '{' + partial.join(',') + '}';\n gap = mind;\n return v;\n }\n}\n\nmodule.exports = function (value, replacer, space) {\n var i;\n gap = '';\n indent = '';\n \n // If the space parameter is a number, make an indent string containing that\n // many spaces.\n if (typeof space === 'number') {\n for (i = 0; i < space; i += 1) {\n indent += ' ';\n }\n }\n // If the space parameter is a string, it will be used as the indent string.\n else if (typeof space === 'string') {\n indent = space;\n }\n\n // If there is a replacer, it must be a function or an array.\n // Otherwise, throw an error.\n rep = replacer;\n if (replacer && typeof replacer !== 'function'\n && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) {\n throw new Error('JSON.stringify');\n }\n \n // Make a fake root object containing our value under the key of ''.\n // Return the result of stringifying the value.\n return str('', {'': value});\n};\n","exports.parse = require('./lib/parse');\nexports.stringify = require('./lib/stringify');\n","var json = typeof JSON !== 'undefined' ? JSON : require('jsonify');\n\nmodule.exports = function (obj, opts) {\n if (!opts) opts = {};\n if (typeof opts === 'function') opts = { cmp: opts };\n var space = opts.space || '';\n if (typeof space === 'number') space = Array(space+1).join(' ');\n var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;\n var replacer = opts.replacer || function(key, value) { return value; };\n\n var cmp = opts.cmp && (function (f) {\n return function (node) {\n return function (a, b) {\n var aobj = { key: a, value: node[a] };\n var bobj = { key: b, value: node[b] };\n return f(aobj, bobj);\n };\n };\n })(opts.cmp);\n\n var seen = [];\n return (function stringify (parent, key, node, level) {\n var indent = space ? ('\\n' + new Array(level + 1).join(space)) : '';\n var colonSeparator = space ? ': ' : ':';\n\n if (node && node.toJSON && typeof node.toJSON === 'function') {\n node = node.toJSON();\n }\n\n node = replacer.call(parent, key, node);\n\n if (node === undefined) {\n return;\n }\n if (typeof node !== 'object' || node === null) {\n return json.stringify(node);\n }\n if (isArray(node)) {\n var out = [];\n for (var i = 0; i < node.length; i++) {\n var item = stringify(node, i, node[i], level+1) || json.stringify(null);\n out.push(indent + space + item);\n }\n return '[' + out.join(',') + indent + ']';\n }\n else {\n if (seen.indexOf(node) !== -1) {\n if (cycles) return json.stringify('__cycle__');\n throw new TypeError('Converting circular structure to JSON');\n }\n else seen.push(node);\n\n var keys = objectKeys(node).sort(cmp && cmp(node));\n var out = [];\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = stringify(node, key, node[key], level+1);\n\n if(!value) continue;\n\n var keyValue = json.stringify(key)\n + colonSeparator\n + value;\n ;\n out.push(indent + space + keyValue);\n }\n seen.splice(seen.indexOf(node), 1);\n return '{' + out.join(',') + indent + '}';\n }\n })({ '': obj }, '', obj, 0);\n};\n\nvar isArray = Array.isArray || function (x) {\n return {}.toString.call(x) === '[object Array]';\n};\n\nvar objectKeys = Object.keys || function (obj) {\n var has = Object.prototype.hasOwnProperty || function () { return true };\n var keys = [];\n for (var key in obj) {\n if (has.call(obj, key)) keys.push(key);\n }\n return keys;\n};\n","export type LogicalOperand = LogicalNot | LogicalAnd | LogicalOr | T;\n\nexport interface LogicalOr {\n or: LogicalOperand[];\n}\n\nexport interface LogicalAnd {\n and: LogicalOperand[];\n}\n\nexport interface LogicalNot {\n not: LogicalOperand;\n}\n\nexport function isLogicalOr(op: LogicalOperand): op is LogicalOr {\n return !!op.or;\n}\n\nexport function isLogicalAnd(op: LogicalOperand): op is LogicalAnd {\n return !!op.and;\n}\n\nexport function isLogicalNot(op: LogicalOperand): op is LogicalNot {\n return !!op.not;\n}\n\nexport function forEachLeaf(op: LogicalOperand, fn: (op: T) => void) {\n if (isLogicalNot(op)) {\n forEachLeaf(op.not, fn);\n } else if (isLogicalAnd(op)) {\n for (const subop of op.and) {\n forEachLeaf(subop, fn);\n }\n } else if (isLogicalOr(op)) {\n for (const subop of op.or) {\n forEachLeaf(subop, fn);\n }\n } else {\n fn(op);\n }\n}\n\nexport function normalizeLogicalOperand(op: LogicalOperand, normalizer: (o: T) => T): LogicalOperand {\n if (isLogicalNot(op)) {\n return {not: normalizeLogicalOperand(op.not, normalizer)};\n } else if (isLogicalAnd(op)) {\n return {and: op.and.map(o => normalizeLogicalOperand(o, normalizer))};\n } else if (isLogicalOr(op)) {\n return {or: op.or.map(o => normalizeLogicalOperand(o, normalizer))};\n } else {\n return normalizer(op);\n }\n}\n","import stableStringify from 'json-stable-stringify';\nimport {isArray, isNumber, isString, splitAccessPath, stringValue} from 'vega-util';\nimport {isLogicalAnd, isLogicalNot, isLogicalOr, LogicalOperand} from './logical';\n\n/**\n * Creates an object composed of the picked object properties.\n *\n * Example: (from lodash)\n *\n * var object = {'a': 1, 'b': '2', 'c': 3};\n * pick(object, ['a', 'c']);\n * // → {'a': 1, 'c': 3}\n *\n */\nexport function pick(obj: T, props: K[]): Pick {\n const copy: any = {};\n for (const prop of props) {\n if (obj.hasOwnProperty(prop)) {\n copy[prop] = obj[prop];\n }\n }\n return copy;\n}\n\n/**\n * The opposite of _.pick; this method creates an object composed of the own\n * and inherited enumerable string keyed properties of object that are not omitted.\n */\nexport function omit(obj: T, props: K[]): Omit {\n const copy = {...obj as any};\n for (const prop of props) {\n delete copy[prop];\n }\n return copy;\n}\n\n/**\n * Converts any object into a string representation that can be consumed by humans.\n */\nexport const stringify = stableStringify;\n\n/**\n * Converts any object into a string of limited size, or a number.\n */\nexport function hash(a: any) {\n if (isNumber(a)) {\n return a;\n }\n\n const str = isString(a) ? a : stableStringify(a);\n\n // short strings can be used as hash directly, longer strings are hashed to reduce memory usage\n if (str.length < 100) {\n return str;\n }\n\n // from http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/\n let h = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n h = ((h<<5)-h)+char;\n h = h & h; // Convert to 32bit integer\n }\n return h;\n}\n\nexport function contains(array: T[], item: T) {\n return array.indexOf(item) > -1;\n}\n\n/** Returns the array without the elements in item */\nexport function without(array: T[], excludedItems: T[]) {\n return array.filter(item => !contains(excludedItems, item));\n}\n\nexport function union(array: T[], other: T[]) {\n return array.concat(without(other, array));\n}\n\n/**\n * Returns true if any item returns true.\n */\nexport function some(arr: T[], f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (let k = 0; k(arr: T[], f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (let k = 0; k(dest: T, ...src: Partial[]): T {\n for (const s of src) {\n dest = deepMerge_(dest, s);\n }\n return dest;\n}\n\n// recursively merges src into dest\nfunction deepMerge_(dest: any, src: any) {\n if (typeof src !== 'object' || src === null) {\n return dest;\n }\n\n for (const p in src) {\n if (!src.hasOwnProperty(p)) {\n continue;\n }\n if (src[p] === undefined) {\n continue;\n }\n if (typeof src[p] !== 'object' || isArray(src[p]) || src[p] === null) {\n dest[p] = src[p];\n } else if (typeof dest[p] !== 'object' || dest[p] === null) {\n dest[p] = mergeDeep(isArray(src[p].constructor) ? [] : {}, src[p]);\n } else {\n mergeDeep(dest[p], src[p]);\n }\n }\n return dest;\n}\n\nexport function unique(values: T[], f: (item: T) => string | number): T[] {\n const results: any[] = [];\n const u = {};\n let v: string | number;\n for (const val of values) {\n v = f(val);\n if (v in u) {\n continue;\n }\n u[v] = 1;\n results.push(val);\n }\n return results;\n}\n\nexport interface Dict {\n [key: string]: T;\n}\n\nexport type StringSet = Dict;\n\n/**\n * Returns true if the two dictionaries disagree. Applies only to defined values.\n */\nexport function differ(dict: Dict, other: Dict) {\n for (const key in dict) {\n if (dict.hasOwnProperty(key)) {\n if (other[key] && dict[key] && other[key] !== dict[key]) {\n return true;\n }\n }\n }\n return false;\n}\n\nexport function hasIntersection(a: StringSet, b: StringSet) {\n for (const key in a) {\n if (key in b) {\n return true;\n }\n }\n return false;\n}\n\nexport function isNumeric(num: string | number) {\n return !isNaN(num as any);\n}\n\nexport function differArray(array: T[], other: T[]) {\n if (array.length !== other.length) {\n return true;\n }\n\n array.sort();\n other.sort();\n\n for (let i = 0; i < array.length; i++) {\n if (other[i] !== array[i]) {\n return true;\n }\n }\n\n return false;\n}\n\n// This is a stricter version of Object.keys but with better types. See https://github.com/Microsoft/TypeScript/pull/12253#issuecomment-263132208\nexport const keys = Object.keys as (o: T) => (Extract)[];\n\nexport function vals(x: {[key: string]: T}): T[] {\n const _vals: T[] = [];\n for (const k in x) {\n if (x.hasOwnProperty(k)) {\n _vals.push(x[k]);\n }\n }\n return _vals;\n}\n\n// Using mapped type to declare a collect of flags for a string literal type S\n// https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types\nexport type Flag = {\n [K in S]: 1\n};\n\nexport function flagKeys(f: Flag): S[] {\n return keys(f) as S[];\n}\n\nexport function duplicate(obj: T): T {\n return JSON.parse(JSON.stringify(obj));\n}\n\nexport function isBoolean(b: any): b is boolean {\n return b === true || b === false;\n}\n\n/**\n * Convert a string into a valid variable name\n */\nexport function varName(s: string): string {\n // Replace non-alphanumeric characters (anything besides a-zA-Z0-9_) with _\n const alphanumericS = s.replace(/\\W/g, '_');\n\n // Add _ if the string has leading numbers.\n return (s.match(/^\\d+/) ? '_' : '') + alphanumericS;\n}\n\nexport function logicalExpr(op: LogicalOperand, cb: Function): string {\n if (isLogicalNot(op)) {\n return '!(' + logicalExpr(op.not, cb) + ')';\n } else if (isLogicalAnd(op)) {\n return '(' + op.and.map((and: LogicalOperand) => logicalExpr(and, cb)).join(') && (') + ')';\n } else if (isLogicalOr(op)) {\n return '(' + op.or.map((or: LogicalOperand) => logicalExpr(or, cb)).join(') || (') + ')';\n } else {\n return cb(op);\n }\n}\n\nexport type Omit = Pick>;\n\n/**\n * Delete nested property of an object, and delete the ancestors of the property if they become empty.\n */\nexport function deleteNestedProperty(obj: any, orderedProps: string[]) {\n if (orderedProps.length === 0) {\n return true;\n }\n const prop = orderedProps.shift();\n if (deleteNestedProperty(obj[prop], orderedProps)) {\n delete obj[prop];\n }\n return Object.keys(obj).length === 0;\n}\n\nexport function titlecase(s: string) {\n return s.charAt(0).toUpperCase() + s.substr(1);\n}\n\n/**\n * Converts a path to an access path with datum.\n * @param path The field name.\n * @param datum The string to use for `datum`.\n */\nexport function accessPathWithDatum(path: string, datum='datum') {\n const pieces = splitAccessPath(path);\n const prefixes = [];\n for (let i = 1; i <= pieces.length; i++) {\n const prefix = `[${pieces.slice(0,i).map(stringValue).join('][')}]`;\n prefixes.push(`${datum}${prefix}`);\n }\n return prefixes.join(' && ');\n}\n\n/**\n * Return access with datum to the falttened field.\n * @param path The field name.\n * @param datum The string to use for `datum`.\n */\nexport function flatAccessWithDatum(path: string, datum='datum') {\n return `${datum}[${stringValue(splitAccessPath(path).join('.'))}]`;\n}\n\n/**\n * Replaces path accesses with access to non-nested field.\n * For example, `foo[\"bar\"].baz` becomes `foo\\\\.bar\\\\.baz`.\n */\nexport function replacePathInField(path: string) {\n return `${splitAccessPath(path).map(p => p.replace('.', '\\\\.')).join('\\\\.')}`;\n}\n\n/**\n * Remove path accesses with access from field.\n * For example, `foo[\"bar\"].baz` becomes `foo.bar.baz`.\n */\nexport function removePathFromField(path: string) {\n return `${splitAccessPath(path).join('.')}`;\n}\n\n/**\n * Count the depth of the path. Returns 1 for fields that are not nested.\n */\nexport function accessPathDepth(path: string) {\n if (!path) {\n return 0;\n }\n return splitAccessPath(path).length;\n}\n","import {AggregateOp} from 'vega';\nimport {toSet} from 'vega-util';\nimport {contains, Flag, flagKeys} from './util';\n\nconst AGGREGATE_OP_INDEX: Flag = {\n argmax: 1,\n argmin: 1,\n average: 1,\n count: 1,\n distinct: 1,\n max: 1,\n mean: 1,\n median: 1,\n min: 1,\n missing: 1,\n q1: 1,\n q3: 1,\n ci0: 1,\n ci1: 1,\n stderr: 1,\n stdev: 1,\n stdevp: 1,\n sum: 1,\n valid: 1,\n values: 1,\n variance: 1,\n variancep: 1,\n};\n\nexport const AGGREGATE_OPS = flagKeys(AGGREGATE_OP_INDEX);\n\nexport function isAggregateOp(a: string): a is AggregateOp {\n return !!AGGREGATE_OP_INDEX[a];\n}\n\nexport const COUNTING_OPS: AggregateOp[] = ['count', 'valid', 'missing', 'distinct'];\n\nexport function isCountingAggregateOp(aggregate: string): boolean {\n return aggregate && contains(COUNTING_OPS, aggregate);\n}\n\n/** Additive-based aggregation operations. These can be applied to stack. */\nexport const SUM_OPS: AggregateOp[] = [\n 'count',\n 'sum',\n 'distinct',\n 'valid',\n 'missing'\n];\n\n/**\n * Aggregation operators that always produce values within the range [domainMin, domainMax].\n */\nexport const SHARED_DOMAIN_OPS: AggregateOp[] = [\n 'mean',\n 'average',\n 'median',\n 'q1',\n 'q3',\n 'min',\n 'max',\n];\n\nexport const SHARED_DOMAIN_OP_INDEX = toSet(SHARED_DOMAIN_OPS);\n","import {DateTime} from './datetime';\nimport {Guide, GuideEncodingEntry, VlOnlyGuideConfig} from './guide';\nimport {Flag, flagKeys} from './util';\nimport {AxisOrient, VgAxis, VgAxisBase, VgAxisConfig} from './vega.schema';\n\n\n\nexport interface AxisConfig extends VgAxisConfig, VlOnlyGuideConfig {}\n\nexport interface Axis extends VgAxisBase, Guide {\n /**\n * The orientation of the axis. One of `\"top\"`, `\"bottom\"`, `\"left\"` or `\"right\"`. The orientation can be used to further specialize the axis type (e.g., a y axis oriented for the right edge of the chart).\n *\n * __Default value:__ `\"bottom\"` for x-axes and `\"left\"` for y-axes.\n */\n orient?: AxisOrient;\n\n /**\n * The offset, in pixels, by which to displace the axis from the edge of the enclosing group or data rectangle.\n *\n * __Default value:__ derived from the [axis config](https://vega.github.io/vega-lite/docs/config.html#facet-scale-config)'s `offset` (`0` by default)\n */\n offset?: number;\n\n /**\n * The anchor position of the axis in pixels. For x-axis with top or bottom orientation, this sets the axis group x coordinate. For y-axis with left or right orientation, this sets the axis group y coordinate.\n *\n * __Default value__: `0`\n */\n position?: number;\n\n\n /**\n * The rotation angle of the axis labels.\n *\n * __Default value:__ `-90` for nominal and ordinal fields; `0` otherwise.\n *\n * @minimum -360\n * @maximum 360\n */\n labelAngle?: number;\n\n /**\n * A desired number of ticks, for axes visualizing quantitative scales. The resulting number may be different so that values are \"nice\" (multiples of 2, 5, 10) and lie within the underlying scale's range.\n * @minimum 0\n *\n * __Default value__: Determine using a formula `ceil(width/40)` for x and `ceil(height/40)` for y.\n */\n tickCount?: number;\n\n /**\n * Explicitly set the visible axis tick values.\n */\n values?: number[] | string[] | boolean[] | DateTime[];\n\n /**\n * A non-positive integer indicating z-index of the axis.\n * If zindex is 0, axes should be drawn behind all chart elements.\n * To put them in front, use `\"zindex = 1\"`.\n *\n * __Default value:__ `1` (in front of the marks) for actual axis and `0` (behind the marks) for grids.\n *\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n\n /**\n * Mark definitions for custom axis encoding.\n *\n * @hide\n */\n encoding?: AxisEncoding;\n}\n\n\nexport type AxisPart = keyof AxisEncoding;\nexport const AXIS_PARTS: AxisPart[] = ['domain', 'grid', 'labels', 'ticks', 'title'];\n\n\n\n/**\n * A dictionary listing whether a certain axis property is applicable for only main axes or only grid axes.\n * (Properties not listed are applicable for both)\n */\nexport const AXIS_PROPERTY_TYPE: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in keyof VgAxis]: 'main' | 'grid' | 'both'\n} = {\n grid: 'grid',\n gridScale: 'grid',\n\n domain: 'main',\n labels: 'main',\n labelFlush: 'main',\n labelOverlap: 'main',\n minExtent: 'main',\n maxExtent: 'main',\n offset: 'main',\n ticks: 'main',\n title: 'main',\n values: 'both',\n\n scale: 'both',\n zindex: 'both' // this is actually set afterward, so it doesn't matter\n};\n\nexport interface AxisEncoding {\n /**\n * Custom encoding for the axis container.\n */\n axis?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the axis domain rule mark.\n */\n domain?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis gridline rule marks.\n */\n grid?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis label text marks.\n */\n labels?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis tick rule marks.\n */\n ticks?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the axis title text mark.\n */\n title?: GuideEncodingEntry;\n}\n\nconst COMMON_AXIS_PROPERTIES_INDEX: Flag = {\n orient: 1, // other things can depend on orient\n\n domain: 1,\n format: 1,\n grid: 1,\n labelBound: 1,\n labelFlush: 1,\n labelPadding: 1,\n labels: 1,\n labelOverlap: 1,\n maxExtent: 1,\n minExtent: 1,\n offset: 1,\n position: 1,\n tickCount: 1,\n ticks: 1,\n tickSize: 1,\n title: 1,\n titlePadding: 1,\n values: 1,\n zindex: 1,\n};\n\nconst AXIS_PROPERTIES_INDEX: Flag = {\n ...COMMON_AXIS_PROPERTIES_INDEX,\n encoding: 1,\n labelAngle: 1,\n titleMaxLength: 1\n};\n\nconst VG_AXIS_PROPERTIES_INDEX: Flag = {\n scale: 1,\n ...COMMON_AXIS_PROPERTIES_INDEX,\n gridScale: 1,\n encode: 1\n};\n\nexport function isAxisProperty(prop: string): prop is keyof Axis {\n return !!AXIS_PROPERTIES_INDEX[prop];\n}\n\nexport const VG_AXIS_PROPERTIES = flagKeys(VG_AXIS_PROPERTIES_INDEX);\n\n// Export for dependent projects\nexport const AXIS_PROPERTIES = flagKeys(AXIS_PROPERTIES_INDEX);\n\nexport interface AxisConfigMixins {\n /**\n * Axis configuration, which determines default properties for all `x` and `y` [axes](https://vega.github.io/vega-lite/docs/axis.html). For a full list of axis configuration options, please see the [corresponding section of the axis documentation](https://vega.github.io/vega-lite/docs/axis.html#config).\n */\n axis?: AxisConfig;\n\n /**\n * X-axis specific config.\n */\n axisX?: VgAxisConfig;\n\n /**\n * Y-axis specific config.\n */\n axisY?: VgAxisConfig;\n\n /**\n * Specific axis config for y-axis along the left edge of the chart.\n */\n axisLeft?: VgAxisConfig;\n\n /**\n * Specific axis config for y-axis along the right edge of the chart.\n */\n axisRight?: VgAxisConfig;\n\n /**\n * Specific axis config for x-axis along the top edge of the chart.\n */\n axisTop?: VgAxisConfig;\n\n /**\n * Specific axis config for x-axis along the bottom edge of the chart.\n */\n axisBottom?: VgAxisConfig;\n\n /**\n * Specific axis config for axes with \"band\" scales.\n */\n axisBand?: VgAxisConfig;\n}\n","/*\n * Constants and utilities for encoding channels (Visual variables)\n * such as 'x', 'y', 'color'.\n */\n\nimport {RangeType} from './compile/scale/type';\nimport {Encoding} from './encoding';\nimport {FacetMapping} from './facet';\nimport {Mark} from './mark';\nimport {Flag, flagKeys} from './util';\n\nexport namespace Channel {\n // Facet\n export const ROW: 'row' = 'row';\n export const COLUMN: 'column' = 'column';\n\n // Position\n export const X: 'x' = 'x';\n export const Y: 'y' = 'y';\n export const X2: 'x2' = 'x2';\n export const Y2: 'y2' = 'y2';\n\n // Geo Position\n export const LATITUDE: 'latitude' = 'latitude';\n export const LONGITUDE: 'longitude' = 'longitude';\n export const LATITUDE2: 'latitude2' = 'latitude2';\n export const LONGITUDE2: 'longitude2' = 'longitude2';\n\n // Mark property with scale\n export const COLOR: 'color' = 'color';\n\n export const FILL: 'fill' = 'fill';\n\n export const STROKE: 'stroke' = 'stroke';\n\n export const SHAPE: 'shape' = 'shape';\n export const SIZE: 'size' = 'size';\n export const OPACITY: 'opacity' = 'opacity';\n\n // Non-scale channel\n export const TEXT: 'text' = 'text';\n export const ORDER: 'order' = 'order';\n export const DETAIL: 'detail' = 'detail';\n export const KEY: 'key' = 'key';\n\n export const TOOLTIP: 'tooltip' = 'tooltip';\n export const HREF: 'href' = 'href';\n}\n\nexport type Channel = keyof Encoding | keyof FacetMapping;\n\nexport const X = Channel.X;\nexport const Y = Channel.Y;\nexport const X2 = Channel.X2;\nexport const Y2 = Channel.Y2;\n\nexport const LATITUDE = Channel.LATITUDE;\nexport const LATITUDE2 = Channel.LATITUDE2;\nexport const LONGITUDE = Channel.LONGITUDE;\nexport const LONGITUDE2 = Channel.LONGITUDE2;\n\nexport const ROW = Channel.ROW;\nexport const COLUMN = Channel.COLUMN;\nexport const SHAPE = Channel.SHAPE;\nexport const SIZE = Channel.SIZE;\nexport const COLOR = Channel.COLOR;\n\nexport const FILL = Channel.FILL;\nexport const STROKE = Channel.STROKE;\nexport const TEXT = Channel.TEXT;\nexport const DETAIL = Channel.DETAIL;\nexport const KEY = Channel.KEY;\nexport const ORDER = Channel.ORDER;\nexport const OPACITY = Channel.OPACITY;\nexport const TOOLTIP = Channel.TOOLTIP;\nexport const HREF = Channel.HREF;\n\nexport type GeoPositionChannel = 'longitude' | 'latitude' | 'longitude2' | 'latitude2';\n\nexport const GEOPOSITION_CHANNEL_INDEX: Flag = {\n longitude: 1,\n longitude2: 1,\n latitude: 1,\n latitude2: 1,\n};\n\nexport const GEOPOSITION_CHANNELS = flagKeys(GEOPOSITION_CHANNEL_INDEX);\n\nconst UNIT_CHANNEL_INDEX: Flag> = {\n // position\n x: 1,\n y: 1,\n x2: 1,\n y2: 1,\n\n ...GEOPOSITION_CHANNEL_INDEX,\n\n // color\n color: 1,\n fill: 1,\n stroke: 1,\n\n // other non-position with scale\n opacity: 1,\n size: 1,\n shape: 1,\n\n // channels without scales\n order: 1,\n text: 1,\n detail: 1,\n key: 1,\n tooltip: 1,\n href: 1,\n};\n\nexport type ColorChannel = 'color' | 'fill' | 'stroke';\n\nexport function isColorChannel(channel: Channel): channel is ColorChannel {\n return channel === 'color' || channel === 'fill' || channel === 'stroke';\n}\n\nconst FACET_CHANNEL_INDEX: Flag> = {\n row: 1,\n column: 1\n};\n\nconst CHANNEL_INDEX = {\n ...UNIT_CHANNEL_INDEX,\n ...FACET_CHANNEL_INDEX\n};\n\nexport const CHANNELS = flagKeys(CHANNEL_INDEX);\n\nconst {order: _o, detail: _d, ...SINGLE_DEF_CHANNEL_INDEX} = CHANNEL_INDEX;\n/**\n * Channels that cannot have an array of channelDef.\n * model.fieldDef, getFieldDef only work for these channels.\n *\n * (The only two channels that can have an array of channelDefs are \"detail\" and \"order\".\n * Since there can be multiple fieldDefs for detail and order, getFieldDef/model.fieldDef\n * are not applicable for them. Similarly, selection projection won't work with \"detail\" and \"order\".)\n */\n\nexport const SINGLE_DEF_CHANNELS: SingleDefChannel[] = flagKeys(SINGLE_DEF_CHANNEL_INDEX);\n\n// Using the following line leads to TypeError: Cannot read property 'elementTypes' of undefined\n// when running the schema generator\n// export type SingleDefChannel = typeof SINGLE_DEF_CHANNELS[0];\nexport type SingleDefChannel = 'x' | 'y' | 'x2' | 'y2' |\n 'longitude' | 'latitude' | 'longitude2' | 'latitude2' |\n 'row' | 'column' |\n 'color' | 'fill' | 'stroke' |\n 'size' | 'shape' | 'opacity' |\n 'text' | 'tooltip' | 'href' | 'key';\n\nexport function isChannel(str: string): str is Channel {\n return !!CHANNEL_INDEX[str];\n}\n\n// CHANNELS without COLUMN, ROW\nexport const UNIT_CHANNELS = flagKeys(UNIT_CHANNEL_INDEX);\n\n\n// NONPOSITION_CHANNELS = UNIT_CHANNELS without X, Y, X2, Y2;\nconst {\n x: _x, y: _y,\n // x2 and y2 share the same scale as x and y\n x2: _x2, y2: _y2,\n latitude: _latitude, longitude: _longitude,\n latitude2: _latitude2, longitude2: _longitude2,\n // The rest of unit channels then have scale\n ...NONPOSITION_CHANNEL_INDEX\n} = UNIT_CHANNEL_INDEX;\n\nexport const NONPOSITION_CHANNELS = flagKeys(NONPOSITION_CHANNEL_INDEX);\nexport type NonPositionChannel = typeof NONPOSITION_CHANNELS[0];\n\n// POSITION_SCALE_CHANNELS = X and Y;\nconst POSITION_SCALE_CHANNEL_INDEX: {x:1, y:1} = {x:1, y:1};\nexport const POSITION_SCALE_CHANNELS = flagKeys(POSITION_SCALE_CHANNEL_INDEX);\nexport type PositionScaleChannel = typeof POSITION_SCALE_CHANNELS[0];\n\n// NON_POSITION_SCALE_CHANNEL = SCALE_CHANNELS without X, Y\nconst {\n // x2 and y2 share the same scale as x and y\n // text and tooltip have format instead of scale,\n // href has neither format, nor scale\n text: _t, tooltip: _tt, href: _hr,\n // detail and order have no scale\n detail: _dd, key: _k, order: _oo,\n ...NONPOSITION_SCALE_CHANNEL_INDEX\n} = NONPOSITION_CHANNEL_INDEX;\nexport const NONPOSITION_SCALE_CHANNELS = flagKeys(NONPOSITION_SCALE_CHANNEL_INDEX);\nexport type NonPositionScaleChannel = typeof NONPOSITION_SCALE_CHANNELS[0];\n\n// Declare SCALE_CHANNEL_INDEX\nconst SCALE_CHANNEL_INDEX = {\n ...POSITION_SCALE_CHANNEL_INDEX,\n ...NONPOSITION_SCALE_CHANNEL_INDEX\n};\n\n/** List of channels with scales */\nexport const SCALE_CHANNELS = flagKeys(SCALE_CHANNEL_INDEX);\nexport type ScaleChannel = typeof SCALE_CHANNELS[0];\n\nexport function isScaleChannel(channel: Channel): channel is ScaleChannel {\n return !!SCALE_CHANNEL_INDEX[channel];\n}\n\nexport type SupportedMark = {\n [mark in Mark]?: boolean\n};\n\n/**\n * Return whether a channel supports a particular mark type.\n * @param channel channel name\n * @param mark the mark type\n * @return whether the mark supports the channel\n */\nexport function supportMark(channel: Channel, mark: Mark) {\n return mark in getSupportedMark(channel);\n}\n\n/**\n * Return a dictionary showing whether a channel supports mark type.\n * @param channel\n * @return A dictionary mapping mark types to boolean values.\n */\nexport function getSupportedMark(channel: Channel): SupportedMark {\n switch (channel) {\n case COLOR:\n case FILL:\n case STROKE:\n\n case DETAIL:\n case KEY:\n case TOOLTIP:\n case HREF:\n case ORDER: // TODO: revise (order might not support rect, which is not stackable?)\n case OPACITY:\n case ROW:\n case COLUMN:\n return { // all marks\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, rect: true, line: true, trail: true, area: true, text: true, geoshape: true\n };\n case X:\n case Y:\n case LATITUDE:\n case LONGITUDE:\n return { // all marks except geoshape. geoshape does not use X, Y -- it uses a projection\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, rect: true, line: true, trail: true, area: true, text: true\n };\n case X2:\n case Y2:\n case LATITUDE2:\n case LONGITUDE2:\n return {\n rule: true, bar: true, rect: true, area: true\n };\n case SIZE:\n return {\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, text: true, line: true, trail: true\n };\n case SHAPE:\n return {point: true, geoshape: true};\n case TEXT:\n return {text: true};\n }\n}\n\nexport function rangeType(channel: Channel): RangeType {\n switch (channel) {\n case X:\n case Y:\n case SIZE:\n case OPACITY:\n // X2 and Y2 use X and Y scales, so they similarly have continuous range.\n case X2:\n case Y2:\n return 'continuous';\n\n case ROW:\n case COLUMN:\n case SHAPE:\n // TEXT, TOOLTIP, and HREF have no scale but have discrete output\n case TEXT:\n case TOOLTIP:\n case HREF:\n return 'discrete';\n\n // Color can be either continuous or discrete, depending on scale type.\n case COLOR:\n case FILL:\n case STROKE:\n return 'flexible';\n\n // No scale, no range type.\n\n case LATITUDE:\n case LONGITUDE:\n case LATITUDE2:\n case LONGITUDE2:\n case DETAIL:\n case KEY:\n case ORDER:\n return undefined;\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('rangeType not implemented for ' + channel);\n}\n","import {isBoolean} from 'vega-util';\nimport {Channel, COLOR, COLUMN, FILL, OPACITY, ROW, SHAPE, SIZE, STROKE} from './channel';\nimport {keys, varName} from './util';\n\n\nexport interface BaseBin {\n /**\n * The number base to use for automatic bin determination (default is base 10).\n *\n * __Default value:__ `10`\n *\n */\n base?: number;\n /**\n * An exact step size to use between bins.\n *\n * __Note:__ If provided, options such as maxbins will be ignored.\n */\n step?: number;\n /**\n * An array of allowable step sizes to choose from.\n * @minItems 1\n */\n steps?: number[];\n /**\n * A minimum allowable step size (particularly useful for integer values).\n */\n minstep?: number;\n /**\n * Scale factors indicating allowable subdivisions. The default value is [5, 2], which indicates that for base 10 numbers (the default base), the method may consider dividing bin sizes by 5 and/or 2. For example, for an initial step size of 10, the method can check if bin sizes of 2 (= 10/5), 5 (= 10/2), or 1 (= 10/(5*2)) might also satisfy the given constraints.\n *\n * __Default value:__ `[5, 2]`\n *\n * @minItems 1\n */\n divide?: number[];\n /**\n * Maximum number of bins.\n *\n * __Default value:__ `6` for `row`, `column` and `shape` channels; `10` for other channels\n *\n * @minimum 2\n */\n maxbins?: number;\n /**\n * A value in the binned domain at which to anchor the bins, shifting the bin boundaries if necessary to ensure that a boundary aligns with the anchor value.\n *\n * __Default Value:__ the minimum bin extent value\n */\n anchor?: number;\n /**\n * If true (the default), attempts to make the bin boundaries use human-friendly boundaries, such as multiples of ten.\n */\n nice?: boolean;\n}\n\n\n/**\n * Binning properties or boolean flag for determining whether to bin data or not.\n */\nexport interface BinParams extends BaseBin {\n /**\n * A two-element (`[min, max]`) array indicating the range of desired bin values.\n * @minItems 2\n * @maxItems 2\n */\n extent?: number[]; // VgBinTransform uses a different extent so we need to pull this out.\n}\n\nexport function binToString(bin: BinParams | boolean) {\n if (isBoolean(bin)) {\n return 'bin';\n }\n return 'bin' + keys(bin).map(p => varName(`_${p}_${bin[p]}`)).join('');\n}\n\nexport function isBinParams(bin: BinParams | boolean): bin is BinParams {\n return bin && !isBoolean(bin);\n}\n\nexport function autoMaxBins(channel: Channel): number {\n switch (channel) {\n case ROW:\n case COLUMN:\n case SIZE:\n case COLOR:\n case FILL:\n case STROKE:\n case OPACITY:\n // Facets and Size shouldn't have too many bins\n // We choose 6 like shape to simplify the rule\n case SHAPE:\n return 6; // Vega's \"shape\" has 6 distinct values\n default:\n return 10;\n }\n}\n","import {toSet} from 'vega-util';\nimport {CompositeMark, CompositeMarkDef} from './compositemark/index';\nimport {contains, flagKeys} from './util';\nimport {VgMarkConfig} from './vega.schema';\n\nexport namespace Mark {\n export const AREA: 'area' = 'area';\n export const BAR: 'bar' = 'bar';\n export const LINE: 'line' = 'line';\n export const POINT: 'point' = 'point';\n export const RECT: 'rect' = 'rect';\n export const RULE: 'rule' = 'rule';\n export const TEXT: 'text' = 'text';\n export const TICK: 'tick' = 'tick';\n export const TRAIL: 'trail' = 'trail';\n export const CIRCLE: 'circle' = 'circle';\n export const SQUARE: 'square' = 'square';\n export const GEOSHAPE: 'geoshape' = 'geoshape';\n}\n\n/**\n * All types of primitive marks.\n */\nexport type Mark = typeof Mark.AREA | typeof Mark.BAR | typeof Mark.LINE | typeof Mark.TRAIL | typeof Mark.POINT | typeof Mark.TEXT | typeof Mark.TICK | typeof Mark.RECT | typeof Mark.RULE | typeof Mark.CIRCLE | typeof Mark.SQUARE | typeof Mark.GEOSHAPE;\n\n\nexport const AREA = Mark.AREA;\nexport const BAR = Mark.BAR;\nexport const LINE = Mark.LINE;\nexport const POINT = Mark.POINT;\nexport const TEXT = Mark.TEXT;\nexport const TICK = Mark.TICK;\nexport const TRAIL = Mark.TRAIL;\nexport const RECT = Mark.RECT;\nexport const RULE = Mark.RULE;\nexport const GEOSHAPE = Mark.GEOSHAPE;\n\nexport const CIRCLE = Mark.CIRCLE;\nexport const SQUARE = Mark.SQUARE;\n\n// Using mapped type to declare index, ensuring we always have all marks when we add more.\nconst MARK_INDEX: {[M in Mark]: 1} = {\n area: 1,\n bar: 1,\n line: 1,\n point: 1,\n text: 1,\n tick: 1,\n trail: 1,\n rect: 1,\n geoshape: 1,\n rule: 1,\n circle: 1,\n square: 1\n};\n\nexport function isMark(m: string): m is Mark {\n return !!MARK_INDEX[m];\n}\n\nexport function isPathMark(m: Mark | CompositeMark): m is 'line' | 'area' | 'trail' {\n return contains(['line', 'area', 'trail'], m);\n}\n\nexport const PRIMITIVE_MARKS = flagKeys(MARK_INDEX);\n\n\nexport interface MarkConfig extends VgMarkConfig {\n // ---------- Color ----------\n /**\n * Whether the mark's color should be used as fill color instead of stroke color.\n *\n * __Default value:__ `true` for all marks except `point` and `false` for `point`.\n *\n * __Applicable for:__ `bar`, `point`, `circle`, `square`, and `area` marks.\n *\n * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n *\n */\n filled?: boolean;\n\n /**\n * Default color. Note that `fill` and `stroke` have higher precedence than `color` and will override `color`.\n *\n * __Default value:__ `\"#4682b4\"`\n *\n * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n */\n color?: string;\n}\n\nexport interface BarBinSpacingMixins {\n /**\n * Offset between bars for binned field. Ideal value for this is either 0 (Preferred by statisticians) or 1 (Vega-Lite Default, D3 example style).\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n binSpacing?: number;\n}\n\n\n/** @hide */\nexport type HiddenComposite = CompositeMark | CompositeMarkDef;\n\nexport type AnyMark =\n HiddenComposite |\n Mark |\n MarkDef;\n\nexport function isMarkDef(mark: AnyMark): mark is (MarkDef | CompositeMarkDef) {\n return mark['type'];\n}\n\nconst PRIMITIVE_MARK_INDEX = toSet(PRIMITIVE_MARKS);\n\nexport function isPrimitiveMark(mark: CompositeMark | CompositeMarkDef | Mark | MarkDef): mark is Mark {\n const markType = isMarkDef(mark) ? mark.type : mark;\n return markType in PRIMITIVE_MARK_INDEX;\n}\n\nexport const STROKE_CONFIG = ['stroke', 'strokeWidth',\n 'strokeDash', 'strokeDashOffset', 'strokeOpacity', 'strokeJoin', 'strokeMiterLimit'];\n\nexport const FILL_CONFIG = ['fill', 'fillOpacity'];\n\nexport const FILL_STROKE_CONFIG = [].concat(STROKE_CONFIG, FILL_CONFIG);\n\nexport const VL_ONLY_MARK_CONFIG_PROPERTIES: (keyof MarkConfig)[] = ['filled', 'color'];\n\nexport const VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX: {\n [k in (typeof PRIMITIVE_MARKS[0])]?: (keyof MarkConfigMixins[k])[]\n} = {\n area: ['line', 'point'],\n bar: ['binSpacing', 'continuousBandSize', 'discreteBandSize'],\n line: ['point'],\n text: ['shortTimeLabels'],\n tick: ['bandSize', 'thickness']\n};\n\nexport const defaultMarkConfig: MarkConfig = {\n color: '#4c78a8',\n};\n\nexport interface MarkConfigMixins {\n /** Mark Config */\n mark?: MarkConfig;\n\n // MARK-SPECIFIC CONFIGS\n /** Area-Specific Config */\n area?: AreaConfig;\n\n /** Bar-Specific Config */\n bar?: BarConfig;\n\n /** Circle-Specific Config */\n circle?: MarkConfig;\n\n /** Line-Specific Config */\n line?: LineConfig;\n\n /** Point-Specific Config */\n point?: MarkConfig;\n\n /** Rect-Specific Config */\n rect?: MarkConfig;\n\n /** Rule-Specific Config */\n rule?: MarkConfig;\n\n /** Square-Specific Config */\n square?: MarkConfig;\n\n /** Text-Specific Config */\n text?: TextConfig;\n\n /** Tick-Specific Config */\n tick?: TickConfig;\n\n /** Trail-Specific Config */\n trail?: LineConfig;\n\n /** Geoshape-Specific Config */\n geoshape?: MarkConfig;\n}\n\n\nexport interface BarConfig extends BarBinSpacingMixins, MarkConfig {\n\n /**\n * The default size of the bars on continuous scales.\n *\n * __Default value:__ `5`\n *\n * @minimum 0\n */\n continuousBandSize?: number;\n\n /**\n * The size of the bars. If unspecified, the default size is `bandSize-1`,\n * which provides 1 pixel offset between bars.\n * @minimum 0\n */\n discreteBandSize?: number;\n}\n\nexport type OverlayMarkDef = MarkConfig & MarkDefMixins;\n\nexport interface PointOverlayMixins {\n /**\n * A flag for overlaying points on top of line or area marks, or an object defining the properties of the overlayed points.\n *\n * - If this property is `\"transparent\"`, transparent points will be used (for enhancing tooltips and selections).\n *\n * - If this property is an empty object (`{}`) or `true`, filled points with default properties will be used.\n *\n * - If this property is `false`, no points would be automatically added to line or area marks.\n *\n * __Default value:__ `false`.\n */\n point?: boolean | OverlayMarkDef | 'transparent';\n}\n\nexport interface LineConfig extends MarkConfig, PointOverlayMixins {}\n\nexport interface LineOverlayMixins {\n /**\n * A flag for overlaying line on top of area marks, or an object defining the properties of the overlayed lines.\n *\n * - If this value is an empty object (`{}`) or `true`, lines with default properties will be used.\n *\n * - If this value is `false`, no lines would be automatically added to area marks.\n *\n * __Default value:__ `false`.\n */\n line?: boolean | OverlayMarkDef;\n}\n\nexport interface AreaConfig extends MarkConfig, PointOverlayMixins, LineOverlayMixins {}\n\nexport interface TickThicknessMixins {\n /**\n * Thickness of the tick mark.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n thickness?: number;\n}\n\nexport interface MarkDefMixins {\n /**\n * A string or array of strings indicating the name of custom styles to apply to the mark. A style is a named collection of mark property defaults defined within the [style configuration](https://vega.github.io/vega-lite/docs/mark.html#style-config). If style is an array, later styles will override earlier styles. Any [mark properties](https://vega.github.io/vega-lite/docs/encoding.html#mark-prop) explicitly defined within the `encoding` will override a style default.\n *\n * __Default value:__ The mark's name. For example, a bar mark will have style `\"bar\"` by default.\n * __Note:__ Any specified style will augment the default style. For example, a bar mark with `\"style\": \"foo\"` will receive from `config.style.bar` and `config.style.foo` (the specified style `\"foo\"` has higher precedence).\n */\n style?: string | string[];\n\n /**\n * Whether a mark be clipped to the enclosing group’s width and height.\n */\n clip?: boolean;\n\n // Offset properties should not be a part of config\n\n /**\n * Offset for x-position.\n */\n xOffset?: number;\n\n /**\n * Offset for y-position.\n */\n yOffset?: number;\n\n /**\n * Offset for x2-position.\n */\n x2Offset?: number;\n\n /**\n * Offset for y2-position.\n */\n y2Offset?: number;\n}\n\n// Point/Line OverlayMixins are only for area, line, and trail but we don't want to declare multiple types of MarkDef\nexport interface MarkDef extends BarBinSpacingMixins, MarkConfig, PointOverlayMixins, LineOverlayMixins, TickThicknessMixins, MarkDefMixins {\n /**\n * The mark type.\n * One of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"geoshape\"`, `\"rule\"`, and `\"text\"`.\n */\n type: Mark;\n}\n\nexport const defaultBarConfig: BarConfig = {\n binSpacing: 1,\n continuousBandSize: 5\n};\n\nexport interface TextConfig extends MarkConfig {\n /**\n * Whether month names and weekday names should be abbreviated.\n */\n shortTimeLabels?: boolean;\n}\n\nexport interface TickConfig extends MarkConfig, TickThicknessMixins {\n /**\n * The width of the ticks.\n *\n * __Default value:__ 2/3 of rangeStep.\n * @minimum 0\n */\n bandSize?: number;\n}\n\nexport const defaultTickConfig: TickConfig = {\n thickness: 1\n};\n","/**\n * Vega-Lite's singleton logger utility.\n */\n\nimport {AggregateOp} from 'vega';\nimport {logger, LoggerInterface, Warn} from 'vega-util';\nimport {Channel, GeoPositionChannel} from './channel';\nimport {CompositeMark} from './compositemark';\nimport {DateTime, DateTimeExpr} from './datetime';\nimport {FieldDef} from './fielddef';\nimport {Mark} from './mark';\nimport {Projection} from './projection';\nimport {ScaleType} from './scale';\nimport {Type} from './type';\nimport {stringify} from './util';\nimport {VgSortField} from './vega.schema';\n\n\nexport {LoggerInterface} from 'vega-util';\n\n/**\n * Main (default) Vega Logger instance for Vega-Lite\n */\nconst main = logger(Warn);\nlet current: LoggerInterface = main;\n\n/**\n * Logger tool for checking if the code throws correct warning\n */\nexport class LocalLogger implements LoggerInterface {\n public warns: any[] = [];\n public infos: any[] = [];\n public debugs: any[] = [];\n\n public level() {\n return this;\n }\n\n public warn(...args: any[]) {\n this.warns.push(...args);\n return this;\n }\n\n public info(...args: any[]) {\n this.infos.push(...args);\n return this;\n }\n\n public debug(...args: any[]) {\n this.debugs.push(...args);\n return this;\n }\n}\n\nexport function wrap(f: (logger: LocalLogger) => void) {\n return () => {\n current = new LocalLogger();\n f(current as LocalLogger);\n reset();\n };\n}\n\n/**\n * Set the singleton logger to be a custom logger\n */\nexport function set(newLogger: LoggerInterface) {\n current = newLogger;\n return current;\n}\n\n/**\n * Reset the main logger to use the default Vega Logger\n */\nexport function reset() {\n current = main;\n return current;\n}\n\nexport function warn(..._: any[]) {\n current.warn.apply(current, arguments);\n}\n\nexport function info(..._: any[]) {\n current.info.apply(current, arguments);\n}\n\nexport function debug(..._: any[]) {\n current.debug.apply(current, arguments);\n}\n\n/**\n * Collection of all Vega-Lite Error Messages\n */\nexport namespace message {\n export const INVALID_SPEC = 'Invalid spec';\n\n // FIT\n export const FIT_NON_SINGLE = 'Autosize \"fit\" only works for single views and layered views.';\n\n export const CANNOT_FIX_RANGE_STEP_WITH_FIT = 'Cannot use a fixed value of \"rangeStep\" when \"autosize\" is \"fit\".';\n\n // SELECTION\n export function cannotProjectOnChannelWithoutField(channel: Channel) {\n return `Cannot project a selection on encoding channel \"${channel}\", which has no field.`;\n }\n\n export function nearestNotSupportForContinuous(mark: string) {\n return `The \"nearest\" transform is not supported for ${mark} marks.`;\n }\n\n export function selectionNotFound(name: string) {\n return `Cannot find a selection named \"${name}\"`;\n }\n\n export const SCALE_BINDINGS_CONTINUOUS = 'Scale bindings are currently only supported for scales with unbinned, continuous domains.';\n\n // REPEAT\n export function noSuchRepeatedValue(field: string) {\n return `Unknown repeated value \"${field}\".`;\n }\n\n // CONCAT\n export const CONCAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in concatenated views.';\n\n // REPEAT\n export const REPEAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in repeated views.';\n\n // TITLE\n export function cannotSetTitleAnchor(type: string) {\n return `Cannot set title \"anchor\" for a ${type} spec`;\n }\n\n // DATA\n export function unrecognizedParse(p: string) {\n return `Unrecognized parse \"${p}\".`;\n }\n\n export function differentParse(field: string, local: string, ancestor: string) {\n return `An ancestor parsed field \"${field}\" as ${ancestor} but a child wants to parse the field as ${local}.`;\n }\n\n // TRANSFORMS\n export function invalidTransformIgnored(transform: any) {\n return `Ignoring an invalid transform: ${stringify(transform)}.`;\n }\n\n export const NO_FIELDS_NEEDS_AS = 'If \"from.fields\" is not specified, \"as\" has to be a string that specifies the key to be used for the data from the secondary source.';\n\n // ENCODING & FACET\n\n export function encodingOverridden(channels: Channel[]) {\n return `Layer's shared ${channels.join(',')} channel ${channels.length === 1 ? 'is' : 'are'} overriden`;\n }\n export function projectionOverridden(opt: {parentProjection: Projection, projection: Projection}) {\n const {parentProjection, projection} = opt;\n return `Layer's shared projection ${stringify(parentProjection)} is overridden by a child projection ${stringify(projection)}.`;\n }\n\n export function primitiveChannelDef(channel: Channel, type: 'string' | 'number' | 'boolean', value: string | number | boolean) {\n return `Channel ${channel} is a ${type}. Converted to {value: ${stringify(value)}}.`;\n }\n\n export function invalidFieldType(type: Type) {\n return `Invalid field type \"${type}\"`;\n }\n\n export function nonZeroScaleUsedWithLengthMark(\n mark: 'bar' | 'area', channel: Channel,\n opt: {scaleType?: ScaleType, zeroFalse?: boolean}\n ) {\n const scaleText = opt.scaleType ? `${opt.scaleType} scale` :\n opt.zeroFalse ? 'scale with zero=false' :\n 'scale with custom domain that excludes zero';\n\n return `A ${scaleText} is used to encode ${mark}'s ${channel}. This can be misleading as the ${channel === 'x' ? 'width' : 'height'} of the ${mark} can be arbitrary based on the scale domain. You may want to use point mark instead.`;\n }\n\n export function invalidFieldTypeForCountAggregate(type: Type, aggregate: string) {\n return `Invalid field type \"${type}\" for aggregate: \"${aggregate}\", using \"quantitative\" instead.`;\n }\n\n export function invalidAggregate(aggregate: AggregateOp | string) {\n return `Invalid aggregation operator \"${aggregate}\"`;\n }\n\n export function emptyOrInvalidFieldType(type: Type | string, channel: Channel, newType: Type) {\n return `Invalid field type \"${type}\" for channel \"${channel}\", using \"${newType}\" instead.`;\n }\n export function droppingColor(type: 'encoding' | 'property', opt: {fill?: boolean, stroke?: boolean}) {\n const {fill, stroke} = opt;\n return `Dropping color ${type} as the plot also has ` + (\n fill && stroke ? 'fill and stroke' : fill ? 'fill' : 'stroke'\n );\n }\n\n export function emptyFieldDef(fieldDef: FieldDef, channel: Channel) {\n return `Dropping ${stringify(fieldDef)} from channel \"${channel}\" since it does not contain data field or value.`;\n }\n export function latLongDeprecated(channel: Channel, type: Type, newChannel: GeoPositionChannel) {\n return `${channel}-encoding with type ${type} is deprecated. Replacing with ${newChannel}-encoding.`;\n }\n\n export const LINE_WITH_VARYING_SIZE = 'Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.';\n\n export function incompatibleChannel(channel: Channel, markOrFacet: Mark | 'facet' | CompositeMark, when?: string) {\n return `${channel} dropped as it is incompatible with \"${markOrFacet}\"${when ? ` when ${when}` : ''}.`;\n }\n\n export function invalidEncodingChannel(channel: string) {\n return `${channel}-encoding is dropped as ${channel} is not a valid encoding channel.`;\n }\n\n export function facetChannelShouldBeDiscrete(channel: string) {\n return `${channel} encoding should be discrete (ordinal / nominal / binned).`;\n }\n\n export function discreteChannelCannotEncode(channel: Channel, type: Type) {\n return `Using discrete channel \"${channel}\" to encode \"${type}\" field can be misleading as it does not encode ${type === 'ordinal' ? 'order' : 'magnitude'}.`;\n }\n\n // Mark\n export const BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.';\n\n export function lineWithRange(hasX2: boolean, hasY2: boolean) {\n const channels = hasX2 && hasY2 ? 'x2 and y2' : hasX2 ? 'x2' : 'y2';\n return `Line mark is for continuous lines and thus cannot be used with ${channels}. We will use the rule mark (line segments) instead.`;\n }\n\n export function orientOverridden(original: string, actual: string) {\n return `Specified orient \"${original}\" overridden with \"${actual}\"`;\n }\n\n // SCALE\n export const CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = 'custom domain scale cannot be unioned with default field-based domain';\n\n export function cannotUseScalePropertyWithNonColor(prop: string) {\n return `Cannot use the scale property \"${prop}\" with non-color channel.`;\n }\n\n export function unaggregateDomainHasNoEffectForRawField(fieldDef: FieldDef) {\n return `Using unaggregated domain with raw field has no effect (${stringify(fieldDef)}).`;\n }\n\n export function unaggregateDomainWithNonSharedDomainOp(aggregate: string) {\n return `Unaggregated domain not applicable for \"${aggregate}\" since it produces values outside the origin domain of the source data.`;\n }\n\n export function unaggregatedDomainWithLogScale(fieldDef: FieldDef) {\n return `Unaggregated domain is currently unsupported for log scale (${stringify(fieldDef)}).`;\n }\n\n export function cannotApplySizeToNonOrientedMark(mark: Mark) {\n return `Cannot apply size to non-oriented mark \"${mark}\".`;\n }\n\n export function rangeStepDropped(channel: Channel) {\n return `rangeStep for \"${channel}\" is dropped as top-level ${\n channel === 'x' ? 'width' : 'height'} is provided.`;\n }\n\n export function scaleTypeNotWorkWithChannel(channel: Channel, scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `Channel \"${channel}\" does not work with \"${scaleType}\" scale. We are using \"${defaultScaleType}\" scale instead.`;\n }\n\n export function scaleTypeNotWorkWithFieldDef(scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `FieldDef does not work with \"${scaleType}\" scale. We are using \"${defaultScaleType}\" scale instead.`;\n }\n\n export function scalePropertyNotWorkWithScaleType(scaleType: ScaleType, propName: string, channel: Channel) {\n return `${channel}-scale's \"${propName}\" is dropped as it does not work with ${scaleType} scale.`;\n }\n\n export function scaleTypeNotWorkWithMark(mark: Mark, scaleType: ScaleType) {\n return `Scale type \"${scaleType}\" does not work with mark \"${mark}\".`;\n }\n\n export function mergeConflictingProperty(property: string | number | symbol, propertyOf: string | number | symbol, v1: T, v2: T) {\n return `Conflicting ${propertyOf.toString()} property \"${property.toString()}\" (${stringify(v1)} and ${stringify(v2)}). Using ${stringify(v1)}.`;\n }\n\n export function independentScaleMeansIndependentGuide(channel: Channel) {\n return `Setting the scale to be independent for \"${channel}\" means we also have to set the guide (axis or legend) to be independent.`;\n }\n\n export function domainSortDropped(sort: VgSortField) {\n return `Dropping sort property ${stringify(sort)} as unioned domains only support boolean or op 'count'.`;\n }\n\n export const UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains';\n\n export const MORE_THAN_ONE_SORT = 'Domains that should be unioned has conflicting sort properties. Sort will be set to true.';\n\n // AXIS\n export const INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.';\n\n // STACK\n export function cannotStackRangedMark(channel: Channel) {\n return `Cannot stack \"${channel}\" if there is already \"${channel}2\"`;\n }\n\n export function cannotStackNonLinearScale(scaleType: ScaleType) {\n return `Cannot stack non-linear scale (${scaleType})`;\n }\n\n export function stackNonSummativeAggregate(aggregate: string) {\n return `Stacking is applied even though the aggregate function is non-summative (\"${aggregate}\")`;\n }\n\n // TIMEUNIT\n export function invalidTimeUnit(unitName: string, value: string | number) {\n return `Invalid ${unitName}: ${stringify(value)}`;\n }\n\n export function dayReplacedWithDate(fullTimeUnit: string) {\n return `Time unit \"${fullTimeUnit}\" is not supported. We are replacing it with ${\n fullTimeUnit.replace('day', 'date')}.`;\n }\n\n export function droppedDay(d: DateTime | DateTimeExpr) {\n return `Dropping day from datetime ${stringify(d)} as day cannot be combined with other units.`;\n }\n}\n\n","// DateTime definition object\n\nimport {isNumber} from 'vega-util';\nimport * as log from './log';\nimport {duplicate, keys} from './util';\n\n\n/*\n * A designated year that starts on Sunday.\n */\nconst SUNDAY_YEAR = 2006;\n\n/**\n * @minimum 1\n * @maximum 12\n * @TJS-type integer\n */\nexport type Month = number;\n\n/**\n * @minimum 1\n * @maximum 7\n */\nexport type Day = number;\n\n/**\n * Object for defining datetime in Vega-Lite Filter.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n * We accept string for month and day names.\n */\nexport interface DateTime {\n /**\n * Integer value representing the year.\n * @TJS-type integer\n */\n year?: number;\n\n /**\n * Integer value representing the quarter of the year (from 1-4).\n * @minimum 1\n * @maximum 4\n * @TJS-type integer\n */\n quarter?: number;\n\n /** One of: (1) integer value representing the month from `1`-`12`. `1` represents January; (2) case-insensitive month name (e.g., `\"January\"`); (3) case-insensitive, 3-character short month name (e.g., `\"Jan\"`). */\n month?: Month | string;\n\n /**\n * Integer value representing the date from 1-31.\n * @minimum 1\n * @maximum 31\n * @TJS-type integer\n */\n date?: number;\n\n /**\n * Value representing the day of a week. This can be one of: (1) integer value -- `1` represents Monday; (2) case-insensitive day name (e.g., `\"Monday\"`); (3) case-insensitive, 3-character short day name (e.g., `\"Mon\"`).
**Warning:** A DateTime definition object with `day`** should not be combined with `year`, `quarter`, `month`, or `date`.\n */\n day?: Day | string;\n\n /**\n * Integer value representing the hour of a day from 0-23.\n * @minimum 0\n * @maximum 23\n * @TJS-type integer\n */\n hours?: number;\n\n /**\n * Integer value representing the minute segment of time from 0-59.\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n minutes?: number;\n\n /**\n * Integer value representing the second segment (0-59) of a time value\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n seconds?: number;\n\n /**\n * Integer value representing the millisecond segment of time.\n * @minimum 0\n * @maximum 999\n * @TJS-type integer\n */\n milliseconds?: number;\n\n /**\n * A boolean flag indicating if date time is in utc time. If false, the date time is in local time\n */\n utc?: boolean;\n}\n\n\n/**\n * Internal Object for defining datetime expressions.\n * This is an expression version of DateTime.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n */\nexport interface DateTimeExpr {\n year?: string;\n quarter?: string;\n month?: string;\n date?: string;\n day?: string;\n hours?: string;\n minutes?: string;\n seconds?: string;\n milliseconds?: string;\n utc?: boolean;\n}\n\nexport function isDateTime(o: any): o is DateTime {\n return !!o && (!!o.year || !!o.quarter || !!o.month || !!o.date || !!o.day ||\n !!o.hours || !!o.minutes || !!o.seconds || !!o.milliseconds);\n}\n\nexport const MONTHS = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];\nexport const SHORT_MONTHS = MONTHS.map((m) => m.substr(0, 3));\n\nexport const DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];\nexport const SHORT_DAYS = DAYS.map((d) => d.substr(0,3));\n\nfunction normalizeQuarter(q: number | string) {\n if (isNumber(q)) {\n if (q > 4) {\n log.warn(log.message.invalidTimeUnit('quarter', q));\n }\n // We accept 1-based quarter, so need to readjust to 0-based quarter\n return (q - 1) + '';\n } else {\n // Invalid quarter\n throw new Error(log.message.invalidTimeUnit('quarter', q));\n }\n}\n\nfunction normalizeMonth(m: string | number) {\n if (isNumber(m)) {\n // We accept 1-based month, so need to readjust to 0-based month\n return (m - 1) + '';\n } else {\n const lowerM = m.toLowerCase();\n const monthIndex = MONTHS.indexOf(lowerM);\n if (monthIndex !== -1) {\n return monthIndex + ''; // 0 for january, ...\n }\n const shortM = lowerM.substr(0, 3);\n const shortMonthIndex = SHORT_MONTHS.indexOf(shortM);\n if (shortMonthIndex !== -1) {\n return shortMonthIndex + '';\n }\n // Invalid month\n throw new Error(log.message.invalidTimeUnit('month', m));\n }\n}\n\nfunction normalizeDay(d: string | number) {\n if (isNumber(d)) {\n // mod so that this can be both 0-based where 0 = sunday\n // and 1-based where 7=sunday\n return (d % 7) + '';\n } else {\n const lowerD = d.toLowerCase();\n const dayIndex = DAYS.indexOf(lowerD);\n if (dayIndex !== -1) {\n return dayIndex + ''; // 0 for january, ...\n }\n const shortD = lowerD.substr(0, 3);\n const shortDayIndex = SHORT_DAYS.indexOf(shortD);\n if (shortDayIndex !== -1) {\n return shortDayIndex + '';\n }\n // Invalid day\n throw new Error(log.message.invalidTimeUnit('day', d));\n }\n}\n\n/**\n * Return Vega Expression for a particular date time.\n * @param d\n * @param normalize whether to normalize quarter, month, day.\n */\nexport function dateTimeExpr(d: DateTime | DateTimeExpr, normalize = false) {\n const units: (string | number)[] = [];\n\n if (normalize && d.day !== undefined) {\n if (keys(d).length > 1) {\n log.warn(log.message.droppedDay(d));\n d = duplicate(d);\n delete d.day;\n }\n }\n\n if (d.year !== undefined) {\n units.push(d.year);\n } else if (d.day !== undefined) {\n // Set year to 2006 for working with day since January 1 2006 is a Sunday\n units.push(SUNDAY_YEAR);\n } else {\n units.push(0);\n }\n\n if (d.month !== undefined) {\n const month = normalize ? normalizeMonth(d.month) : d.month;\n units.push(month);\n } else if (d.quarter !== undefined) {\n const quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter;\n units.push(quarter + '*3');\n } else {\n units.push(0); // months start at zero in JS\n }\n\n if (d.date !== undefined) {\n units.push(d.date);\n } else if (d.day !== undefined) {\n // HACK: Day only works as a standalone unit\n // This is only correct because we always set year to 2006 for day\n const day = normalize ? normalizeDay(d.day) : d.day;\n units.push(day + '+1');\n } else {\n units.push(1); // Date starts at 1 in JS\n }\n\n // Note: can't use TimeUnit enum here as importing it will create\n // circular dependency problem!\n for (const timeUnit of ['hours', 'minutes', 'seconds', 'milliseconds']) {\n if (d[timeUnit] !== undefined) {\n units.push(d[timeUnit]);\n } else {\n units.push(0);\n }\n }\n\n if (d.utc) {\n return `utc(${units.join(', ')})`;\n } else {\n return `datetime(${units.join(', ')})`;\n }\n}\n","import {DateTimeExpr, dateTimeExpr} from './datetime';\nimport * as log from './log';\nimport {accessPathWithDatum, Flag, flagKeys} from './util';\n\nexport namespace TimeUnit {\n export const YEAR: 'year' = 'year';\n export const MONTH: 'month' = 'month';\n export const DAY: 'day' = 'day';\n export const DATE: 'date' = 'date';\n export const HOURS: 'hours' = 'hours';\n export const MINUTES: 'minutes' = 'minutes';\n export const SECONDS: 'seconds' = 'seconds';\n export const MILLISECONDS: 'milliseconds' = 'milliseconds';\n export const YEARMONTH: 'yearmonth' = 'yearmonth';\n export const YEARMONTHDATE: 'yearmonthdate' = 'yearmonthdate';\n export const YEARMONTHDATEHOURS: 'yearmonthdatehours' = 'yearmonthdatehours';\n export const YEARMONTHDATEHOURSMINUTES: 'yearmonthdatehoursminutes' = 'yearmonthdatehoursminutes';\n export const YEARMONTHDATEHOURSMINUTESSECONDS: 'yearmonthdatehoursminutesseconds' = 'yearmonthdatehoursminutesseconds';\n\n // MONTHDATE always include 29 February since we use year 0th (which is a leap year);\n export const MONTHDATE: 'monthdate' = 'monthdate';\n export const HOURSMINUTES: 'hoursminutes' = 'hoursminutes';\n export const HOURSMINUTESSECONDS: 'hoursminutesseconds' = 'hoursminutesseconds';\n export const MINUTESSECONDS: 'minutesseconds' = 'minutesseconds';\n export const SECONDSMILLISECONDS: 'secondsmilliseconds' = 'secondsmilliseconds';\n export const QUARTER: 'quarter' = 'quarter';\n export const YEARQUARTER: 'yearquarter' = 'yearquarter';\n export const QUARTERMONTH: 'quartermonth' = 'quartermonth';\n export const YEARQUARTERMONTH: 'yearquartermonth' = 'yearquartermonth';\n export const UTCYEAR: 'utcyear' = 'utcyear';\n export const UTCMONTH: 'utcmonth' = 'utcmonth';\n export const UTCDAY: 'utcday' = 'utcday';\n export const UTCDATE: 'utcdate' = 'utcdate';\n export const UTCHOURS: 'utchours' = 'utchours';\n export const UTCMINUTES: 'utcminutes' = 'utcminutes';\n export const UTCSECONDS: 'utcseconds' = 'utcseconds';\n export const UTCMILLISECONDS: 'utcmilliseconds' = 'utcmilliseconds';\n export const UTCYEARMONTH: 'utcyearmonth' = 'utcyearmonth';\n export const UTCYEARMONTHDATE: 'utcyearmonthdate' = 'utcyearmonthdate';\n export const UTCYEARMONTHDATEHOURS: 'utcyearmonthdatehours' = 'utcyearmonthdatehours';\n export const UTCYEARMONTHDATEHOURSMINUTES: 'utcyearmonthdatehoursminutes' = 'utcyearmonthdatehoursminutes';\n export const UTCYEARMONTHDATEHOURSMINUTESSECONDS: 'utcyearmonthdatehoursminutesseconds' = 'utcyearmonthdatehoursminutesseconds';\n\n // MONTHDATE always include 29 February since we use year 0th (which is a leap year);\n export const UTCMONTHDATE: 'utcmonthdate' = 'utcmonthdate';\n export const UTCHOURSMINUTES: 'utchoursminutes' = 'utchoursminutes';\n export const UTCHOURSMINUTESSECONDS: 'utchoursminutesseconds' = 'utchoursminutesseconds';\n export const UTCMINUTESSECONDS: 'utcminutesseconds' = 'utcminutesseconds';\n export const UTCSECONDSMILLISECONDS: 'utcsecondsmilliseconds' = 'utcsecondsmilliseconds';\n export const UTCQUARTER: 'utcquarter' = 'utcquarter';\n export const UTCYEARQUARTER: 'utcyearquarter' = 'utcyearquarter';\n export const UTCQUARTERMONTH: 'utcquartermonth' = 'utcquartermonth';\n export const UTCYEARQUARTERMONTH: 'utcyearquartermonth' = 'utcyearquartermonth';\n}\n\nexport type LocalSingleTimeUnit =\n typeof TimeUnit.YEAR |\n typeof TimeUnit.QUARTER |\n typeof TimeUnit.MONTH |\n typeof TimeUnit.DAY |\n typeof TimeUnit.DATE |\n typeof TimeUnit.HOURS |\n typeof TimeUnit.MINUTES |\n typeof TimeUnit.SECONDS |\n typeof TimeUnit.MILLISECONDS;\n\n/** Time Unit that only corresponds to only one part of Date objects. */\nconst LOCAL_SINGLE_TIMEUNIT_INDEX: Flag = {\n year: 1,\n quarter: 1,\n month: 1,\n day: 1,\n date: 1,\n hours: 1,\n minutes: 1,\n seconds: 1,\n milliseconds: 1\n};\n\nexport const TIMEUNIT_PARTS = flagKeys(LOCAL_SINGLE_TIMEUNIT_INDEX);\n\nexport function isLocalSingleTimeUnit(timeUnit: string): timeUnit is LocalSingleTimeUnit {\n return !!LOCAL_SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport type UtcSingleTimeUnit =\n typeof TimeUnit.UTCYEAR |\n typeof TimeUnit.UTCQUARTER |\n typeof TimeUnit.UTCMONTH |\n typeof TimeUnit.UTCDAY |\n typeof TimeUnit.UTCDATE |\n typeof TimeUnit.UTCHOURS |\n typeof TimeUnit.UTCMINUTES |\n typeof TimeUnit.UTCSECONDS |\n typeof TimeUnit.UTCMILLISECONDS;\n\nconst UTC_SINGLE_TIMEUNIT_INDEX: Flag = {\n utcyear: 1,\n utcquarter: 1,\n utcmonth: 1,\n utcday: 1,\n utcdate: 1,\n utchours: 1,\n utcminutes: 1,\n utcseconds: 1,\n utcmilliseconds: 1\n};\n\nexport function isUtcSingleTimeUnit(timeUnit: string): timeUnit is UtcSingleTimeUnit {\n return !!UTC_SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport type SingleTimeUnit = LocalSingleTimeUnit | UtcSingleTimeUnit;\n\nexport type LocalMultiTimeUnit =\n // Local Time\n typeof TimeUnit.YEARQUARTER | typeof TimeUnit.YEARQUARTERMONTH |\n typeof TimeUnit.YEARMONTH | typeof TimeUnit.YEARMONTHDATE | typeof TimeUnit.YEARMONTHDATEHOURS | typeof TimeUnit.YEARMONTHDATEHOURSMINUTES| typeof TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS |\n typeof TimeUnit.QUARTERMONTH |\n typeof TimeUnit.MONTHDATE |\n typeof TimeUnit.HOURSMINUTES | typeof TimeUnit.HOURSMINUTESSECONDS |\n typeof TimeUnit.MINUTESSECONDS |\n typeof TimeUnit.SECONDSMILLISECONDS;\n\nconst LOCAL_MULTI_TIMEUNIT_INDEX: Flag = {\n yearquarter: 1,\n yearquartermonth: 1,\n\n yearmonth: 1,\n yearmonthdate: 1,\n yearmonthdatehours: 1,\n yearmonthdatehoursminutes: 1,\n yearmonthdatehoursminutesseconds: 1,\n\n quartermonth: 1,\n\n monthdate: 1,\n\n hoursminutes: 1,\n hoursminutesseconds: 1,\n\n minutesseconds: 1,\n\n secondsmilliseconds: 1\n};\n\nexport type UtcMultiTimeUnit =\n typeof TimeUnit.UTCYEARQUARTER | typeof TimeUnit.UTCYEARQUARTERMONTH |\n typeof TimeUnit.UTCYEARMONTH | typeof TimeUnit.UTCYEARMONTHDATE | typeof TimeUnit.UTCYEARMONTHDATEHOURS | typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTES| typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTESSECONDS |\n typeof TimeUnit.UTCQUARTERMONTH |\n typeof TimeUnit.UTCMONTHDATE |\n typeof TimeUnit.UTCHOURSMINUTES | typeof TimeUnit.UTCHOURSMINUTESSECONDS |\n typeof TimeUnit.UTCMINUTESSECONDS |\n typeof TimeUnit.UTCSECONDSMILLISECONDS;\n\nconst UTC_MULTI_TIMEUNIT_INDEX: Flag = {\n utcyearquarter: 1,\n utcyearquartermonth: 1,\n\n utcyearmonth: 1,\n utcyearmonthdate: 1,\n utcyearmonthdatehours: 1,\n utcyearmonthdatehoursminutes: 1,\n utcyearmonthdatehoursminutesseconds: 1,\n\n utcquartermonth: 1,\n\n utcmonthdate: 1,\n\n utchoursminutes: 1,\n utchoursminutesseconds: 1,\n\n utcminutesseconds: 1,\n\n utcsecondsmilliseconds: 1\n};\n\nexport type MultiTimeUnit = LocalMultiTimeUnit | UtcMultiTimeUnit;\n\n\nexport type LocalTimeUnit = LocalSingleTimeUnit | LocalMultiTimeUnit;\nexport type UtcTimeUnit = UtcSingleTimeUnit | UtcMultiTimeUnit;\n\nconst UTC_TIMEUNIT_INDEX: Flag = {\n ...UTC_SINGLE_TIMEUNIT_INDEX,\n ...UTC_MULTI_TIMEUNIT_INDEX\n};\n\nexport function isUTCTimeUnit(t: string): t is UtcTimeUnit {\n return !!UTC_TIMEUNIT_INDEX[t];\n}\n\nexport function getLocalTimeUnit(t: UtcTimeUnit): LocalTimeUnit {\n return t.substr(3) as LocalTimeUnit;\n}\n\nexport type TimeUnit = SingleTimeUnit | MultiTimeUnit;\n\nconst TIMEUNIT_INDEX: Flag = {\n ...LOCAL_SINGLE_TIMEUNIT_INDEX,\n ...UTC_SINGLE_TIMEUNIT_INDEX,\n ...LOCAL_MULTI_TIMEUNIT_INDEX,\n ...UTC_MULTI_TIMEUNIT_INDEX\n};\n\nexport const TIMEUNITS = flagKeys(TIMEUNIT_INDEX);\n\nexport function isTimeUnit(t: string): t is TimeUnit {\n return !!TIMEUNIT_INDEX[t];\n}\n\ntype DateMethodName = keyof Date;\n\nconst SET_DATE_METHOD: Record = {\n year: 'setFullYear',\n month: 'setMonth',\n date: 'setDate',\n hours: 'setHours',\n minutes: 'setMinutes',\n seconds: 'setSeconds',\n milliseconds: 'setMilliseconds',\n // Day and quarter have their own special cases\n quarter: null,\n day: null,\n};\n\n/**\n * Converts a date to only have the measurements relevant to the specified unit\n * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00'\n * Note: the base date is Jan 01 1900 00:00:00\n */\nexport function convert(unit: TimeUnit, date: Date): Date {\n const isUTC = isUTCTimeUnit(unit);\n const result: Date = isUTC ?\n // start with uniform date\n new Date(Date.UTC(0, 0, 1, 0, 0, 0, 0)) :\n new Date(0, 0, 1, 0, 0, 0, 0);\n for (const timeUnitPart of TIMEUNIT_PARTS) {\n if (containsTimeUnit(unit, timeUnitPart)) {\n switch (timeUnitPart) {\n case TimeUnit.DAY:\n throw new Error('Cannot convert to TimeUnits containing \\'day\\'');\n case TimeUnit.QUARTER: {\n const {getDateMethod, setDateMethod} = dateMethods('month', isUTC);\n // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3)\n result[setDateMethod]((Math.floor(date[getDateMethod]() / 3)) * 3);\n break;\n }\n default:\n const {getDateMethod, setDateMethod} = dateMethods(timeUnitPart, isUTC);\n result[setDateMethod](date[getDateMethod]());\n }\n }\n }\n return result;\n}\n\nfunction dateMethods(singleUnit: SingleTimeUnit, isUtc: boolean) {\n const rawSetDateMethod = SET_DATE_METHOD[singleUnit];\n const setDateMethod = isUtc ? 'setUTC' + rawSetDateMethod.substr(3) : rawSetDateMethod;\n const getDateMethod = 'get' + (isUtc ? 'UTC' : '') + rawSetDateMethod.substr(3);\n return {setDateMethod, getDateMethod};\n}\n\nexport function getTimeUnitParts(timeUnit: TimeUnit) {\n return TIMEUNIT_PARTS.reduce((parts, part) => {\n if (containsTimeUnit(timeUnit, part)) {\n return parts.concat(part);\n }\n return parts;\n }, []);\n}\n\n/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */\nexport function containsTimeUnit(fullTimeUnit: TimeUnit, timeUnit: TimeUnit) {\n const index = fullTimeUnit.indexOf(timeUnit);\n return index > -1 &&\n (\n timeUnit !== TimeUnit.SECONDS ||\n index === 0 ||\n fullTimeUnit.charAt(index-1) !== 'i' // exclude milliseconds\n );\n}\n\n/**\n * Returns Vega expresssion for a given timeUnit and fieldRef\n */\nexport function fieldExpr(fullTimeUnit: TimeUnit, field: string): string {\n const fieldRef = accessPathWithDatum(field);\n\n const utc = isUTCTimeUnit(fullTimeUnit) ? 'utc' : '';\n function func(timeUnit: TimeUnit) {\n if (timeUnit === TimeUnit.QUARTER) {\n // quarter starting at 0 (0,3,6,9).\n return `(${utc}quarter(${fieldRef})-1)`;\n } else {\n return `${utc}${timeUnit}(${fieldRef})`;\n }\n }\n\n const d = TIMEUNIT_PARTS.reduce((dateExpr: DateTimeExpr, tu: TimeUnit) => {\n if (containsTimeUnit(fullTimeUnit, tu)) {\n dateExpr[tu] = func(tu);\n }\n return dateExpr;\n }, {} as {[key in SingleTimeUnit]: string});\n\n return dateTimeExpr(d);\n}\n\n/**\n * returns the signal expression used for axis labels for a time unit\n */\nexport function formatExpression(timeUnit: TimeUnit, field: string, shortTimeLabels: boolean, isUTCScale: boolean): string {\n if (!timeUnit) {\n return undefined;\n }\n\n const dateComponents: string[] = [];\n let expression = '';\n const hasYear = containsTimeUnit(timeUnit, TimeUnit.YEAR);\n\n if (containsTimeUnit(timeUnit, TimeUnit.QUARTER)) {\n // special expression for quarter as prefix\n expression = `'Q' + quarter(${field})`;\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) {\n // By default use short month name\n dateComponents.push(shortTimeLabels !== false ? '%b' : '%B');\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.DAY)) {\n dateComponents.push(shortTimeLabels ? '%a' : '%A');\n } else if (containsTimeUnit(timeUnit, TimeUnit.DATE)) {\n dateComponents.push('%d' + (hasYear ? ',' : '')); // add comma if there is year\n }\n\n if (hasYear) {\n dateComponents.push(shortTimeLabels ? '%y' : '%Y');\n }\n\n const timeComponents: string[] = [];\n\n if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) {\n timeComponents.push('%H');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) {\n timeComponents.push('%M');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) {\n timeComponents.push('%S');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MILLISECONDS)) {\n timeComponents.push('%L');\n }\n\n const dateTimeComponents: string[] = [];\n if (dateComponents.length > 0) {\n dateTimeComponents.push(dateComponents.join(' '));\n }\n if (timeComponents.length > 0) {\n dateTimeComponents.push(timeComponents.join(':'));\n }\n\n if (dateTimeComponents.length > 0) {\n if (expression) {\n // Add space between quarter and main time format\n expression += ` + ' ' + `;\n }\n\n // We only use utcFormat for utc scale\n // For utc time units, the data is already converted as a part of timeUnit transform.\n // Thus, utc time units should use timeFormat to avoid shifting the time twice.\n if (isUTCScale) {\n expression += `utcFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n } else {\n expression += `timeFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n }\n }\n\n // If expression is still an empty string, return undefined instead.\n return expression || undefined;\n}\n\nexport function normalizeTimeUnit(timeUnit: TimeUnit): TimeUnit {\n if (timeUnit !== 'day' && timeUnit.indexOf('day') >= 0) {\n log.warn(log.message.dayReplacedWithDate(timeUnit));\n return timeUnit.replace('day', 'date') as TimeUnit;\n }\n return timeUnit;\n}\n","import {Flag} from './util';\n/** Constants and utilities for data type */\n/** Data type based on level of measurement */\n\nexport namespace Type {\n export const QUANTITATIVE: 'quantitative' = 'quantitative';\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const TEMPORAL: 'temporal' = 'temporal';\n export const NOMINAL: 'nominal' = 'nominal';\n\n export const LATITUDE: 'latitude' = 'latitude';\n export const LONGITUDE: 'longitude' = 'longitude';\n export const GEOJSON: 'geojson' = 'geojson';\n}\nexport type BasicType = typeof Type.QUANTITATIVE | typeof Type.ORDINAL | typeof Type.TEMPORAL | typeof Type.NOMINAL;\nexport type GeoType = typeof Type.LATITUDE | typeof Type.LONGITUDE | typeof Type.GEOJSON;\n\nexport type Type = BasicType | GeoType;\n\nexport const TYPE_INDEX: Flag = {\n quantitative: 1,\n ordinal: 1,\n temporal: 1,\n nominal: 1,\n latitude: 1,\n longitude: 1,\n geojson: 1\n};\n\nexport function isType(t: any): t is Type {\n return !!TYPE_INDEX[t];\n}\n\nexport const QUANTITATIVE = Type.QUANTITATIVE;\nexport const ORDINAL = Type.ORDINAL;\nexport const TEMPORAL = Type.TEMPORAL;\nexport const NOMINAL = Type.NOMINAL;\n\nexport const GEOJSON = Type.GEOJSON;\n\n/**\n * Get full, lowercase type name for a given type.\n * @param type\n * @return Full type name.\n */\nexport function getFullName(type: Type|string): Type {\n if (type) {\n type = type.toLowerCase();\n switch (type) {\n case 'q':\n case QUANTITATIVE:\n return 'quantitative';\n case 't':\n case TEMPORAL:\n return 'temporal';\n case 'o':\n case ORDINAL:\n return 'ordinal';\n case 'n':\n case NOMINAL:\n return 'nominal';\n case Type.LATITUDE:\n return 'latitude';\n case Type.LONGITUDE:\n return 'longitude';\n case GEOJSON:\n return 'geojson';\n }\n }\n // If we get invalid input, return undefined type.\n return undefined;\n}\n","// Declaration and utility for variants of a field definition object\nimport {AggregateOp} from 'vega';\nimport {isArray, isBoolean, isNumber, isString} from 'vega-util';\nimport {isAggregateOp, isCountingAggregateOp} from './aggregate';\nimport {Axis} from './axis';\nimport {autoMaxBins, BinParams, binToString} from './bin';\nimport {Channel, rangeType} from './channel';\nimport {CompositeAggregate} from './compositemark';\nimport {Config} from './config';\nimport {DateTime, dateTimeExpr, isDateTime} from './datetime';\nimport {TitleMixins} from './guide';\nimport {Legend} from './legend';\nimport * as log from './log';\nimport {LogicalOperand} from './logical';\nimport {Predicate} from './predicate';\nimport {Scale} from './scale';\nimport {Sort, SortOrder} from './sort';\nimport {StackOffset} from './stack';\nimport {getLocalTimeUnit, getTimeUnitParts, isLocalSingleTimeUnit, isUtcSingleTimeUnit, normalizeTimeUnit, TimeUnit} from './timeunit';\nimport {AggregatedFieldDef, WindowFieldDef} from './transform';\nimport {getFullName, QUANTITATIVE, Type} from './type';\nimport {flatAccessWithDatum, replacePathInField, titlecase} from './util';\n\n\n/**\n * Definition object for a constant value of an encoding channel.\n */\nexport interface ValueDef {\n /**\n * A constant value in visual domain (e.g., `\"red\"` / \"#0099ff\" for color, values between `0` to `1` for opacity).\n */\n value: number | string | boolean;\n}\n\n/**\n * Generic type for conditional channelDef.\n * F defines the underlying FieldDef type.\n */\nexport type ChannelDefWithCondition> = FieldDefWithCondition | ValueDefWithCondition;\n\nexport type Conditional = ConditionalPredicate | ConditionalSelection;\n\nexport type ConditionalPredicate = {\n test: LogicalOperand;\n} & T;\n\nexport type ConditionalSelection = {\n /**\n * A [selection name](https://vega.github.io/vega-lite/docs/selection.html), or a series of [composed selections](https://vega.github.io/vega-lite/docs/selection.html#compose).\n */\n selection: LogicalOperand;\n} & T;\n\nexport function isConditionalSelection(c: Conditional): c is ConditionalSelection {\n return c['selection'];\n}\n\nexport interface ConditionValueDefMixins {\n /**\n * One or more value definition(s) with a selection predicate.\n *\n * __Note:__ A field definition's `condition` property can only contain [value definitions](https://vega.github.io/vega-lite/docs/encoding.html#value-def)\n * since Vega-Lite only allows at most one encoded field per encoding channel.\n */\n condition?: Conditional | Conditional[];\n}\n\n/**\n * A FieldDef with Condition\n * {\n * condition: {value: ...},\n * field: ...,\n * ...\n * }\n */\n\nexport type FieldDefWithCondition> = F & ConditionValueDefMixins;\n\n/**\n * A ValueDef with Condition\n * {\n * condition: {field: ...} | {value: ...},\n * value: ...,\n * }\n */\nexport interface ValueDefWithCondition> {\n /**\n * A field definition or one or more value definition(s) with a selection predicate.\n */\n condition?: Conditional | Conditional | Conditional[];\n\n /**\n * A constant value in visual domain.\n */\n value?: number | string | boolean;\n}\n\n/**\n * Reference to a repeated value.\n */\nexport type RepeatRef = {\n repeat: 'row' | 'column'\n};\n\nexport type Field = string | RepeatRef;\n\nexport function isRepeatRef(field: Field): field is RepeatRef {\n return field && !isString(field) && 'repeat' in field;\n}\n\n/** @hide */\nexport type HiddenCompositeAggregate = CompositeAggregate;\n\nexport type Aggregate = AggregateOp | HiddenCompositeAggregate;\n\nexport interface FieldDefBase {\n\n /**\n * __Required.__ A string defining the name of the field from which to pull a data value\n * or an object defining iterated values from the [`repeat`](https://vega.github.io/vega-lite/docs/repeat.html) operator.\n *\n * __Note:__ Dots (`.`) and brackets (`[` and `]`) can be used to access nested objects (e.g., `\"field\": \"foo.bar\"` and `\"field\": \"foo['bar']\"`).\n * If field names contain dots or brackets but are not nested, you can use `\\\\` to escape dots and brackets (e.g., `\"a\\\\.b\"` and `\"a\\\\[0\\\\]\"`).\n * See more details about escaping in the [field documentation](https://vega.github.io/vega-lite/docs/field.html).\n *\n * __Note:__ `field` is not required if `aggregate` is `count`.\n */\n field?: F;\n\n // function\n\n /**\n * Time unit (e.g., `year`, `yearmonth`, `month`, `hours`) for a temporal field.\n * or [a temporal field that gets casted as ordinal](https://vega.github.io/vega-lite/docs/type.html#cast).\n *\n * __Default value:__ `undefined` (None)\n */\n timeUnit?: TimeUnit;\n\n /**\n * A flag for binning a `quantitative` field, or [an object defining binning parameters](https://vega.github.io/vega-lite/docs/bin.html#params).\n * If `true`, default [binning parameters](https://vega.github.io/vega-lite/docs/bin.html) will be applied.\n *\n * __Default value:__ `false`\n */\n bin?: boolean | BinParams;\n\n /**\n * Aggregation function for the field\n * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).\n *\n * __Default value:__ `undefined` (None)\n */\n aggregate?: Aggregate;\n}\n\nexport function toFieldDefBase(fieldDef: FieldDef): FieldDefBase {\n const {field, timeUnit, bin, aggregate} = fieldDef;\n return {\n ...(timeUnit ? {timeUnit} : {}),\n ...(bin ? {bin} : {}),\n ...(aggregate ? {aggregate} : {}),\n field\n };\n}\n\n/**\n * Definition object for a data field, its type and transformation of an encoding channel.\n */\nexport interface FieldDef extends FieldDefBase, TitleMixins {\n /**\n * The encoded field's type of measurement (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, or `\"nominal\"`).\n * It can also be a `\"geojson\"` type for encoding ['geoshape'](https://vega.github.io/vega-lite/docs/geoshape.html).\n */\n // * or an initial character of the type name (`\"Q\"`, `\"T\"`, `\"O\"`, `\"N\"`).\n // * This property is case-insensitive.\n type: Type;\n}\n\nexport interface SortableFieldDef extends FieldDef {\n /**\n * Sort order for the encoded field.\n *\n * For continuous fields (quantitative or temporal), `sort` can be either `\"ascending\"` or `\"descending\"`.\n *\n * For discrete fields, `sort` can be one of the following:\n * - `\"ascending\"` or `\"descending\"` -- for sorting by the values' natural order in Javascript.\n * - [A sort field definition](https://vega.github.io/vega-lite/docs/sort.html#sort-field) for sorting by another field.\n * - [An array specifying the field values in preferred order](https://vega.github.io/vega-lite/docs/sort.html#sort-array). In this case, the sort order will obey the values in the array, followed by any unspecified values in their original order. For discrete time field, values in the sort array can be [date-time definition objects](types#datetime). In addition, for time units `\"month\"` and `\"day\"`, the values can be the month or day names (case insensitive) or their 3-letter initials (e.g., `\"Mon\"`, `\"Tue\"`).\n * - `null` indicating no sort.\n *\n * __Default value:__ `\"ascending\"`\n *\n * __Note:__ `null` is not supported for `row` and `column`.\n */\n sort?: Sort;\n}\n\nexport interface ScaleFieldDef extends SortableFieldDef {\n /**\n * An object defining properties of the channel's scale, which is the function that transforms values in the data domain (numbers, dates, strings, etc) to visual values (pixels, colors, sizes) of the encoding channels.\n *\n * If `null`, the scale will be [disabled and the data value will be directly encoded](https://vega.github.io/vega-lite/docs/scale.html#disable).\n *\n * __Default value:__ If undefined, default [scale properties](https://vega.github.io/vega-lite/docs/scale.html) are applied.\n */\n scale?: Scale | null;\n}\n\nexport interface PositionFieldDef extends ScaleFieldDef {\n /**\n * An object defining properties of axis's gridlines, ticks and labels.\n * If `null`, the axis for the encoding channel will be removed.\n *\n * __Default value:__ If undefined, default [axis properties](https://vega.github.io/vega-lite/docs/axis.html) are applied.\n */\n axis?: Axis | null;\n\n /**\n * Type of stacking offset if the field should be stacked.\n * `stack` is only applicable for `x` and `y` channels with continuous domains.\n * For example, `stack` of `y` can be used to customize stacking for a vertical bar chart.\n *\n * `stack` can be one of the following values:\n * - `\"zero\"`: stacking with baseline offset at zero value of the scale (for creating typical stacked [bar](https://vega.github.io/vega-lite/docs/stack.html#bar) and [area](https://vega.github.io/vega-lite/docs/stack.html#area) chart).\n * - `\"normalize\"` - stacking with normalized domain (for creating [normalized stacked bar and area charts](https://vega.github.io/vega-lite/docs/stack.html#normalized).
\n * -`\"center\"` - stacking with center baseline (for [streamgraph](https://vega.github.io/vega-lite/docs/stack.html#streamgraph)).\n * - `null` - No-stacking. This will produce layered [bar](https://vega.github.io/vega-lite/docs/stack.html#layered-bar-chart) and area chart.\n *\n * __Default value:__ `zero` for plots with all of the following conditions are true:\n * (1) the mark is `bar` or `area`;\n * (2) the stacked measure channel (x or y) has a linear scale;\n * (3) At least one of non-position channels mapped to an unaggregated field that is different from x and y. Otherwise, `null` by default.\n */\n stack?: StackOffset | null;\n}\n\n/**\n * Field definition of a mark property, which can contain a legend.\n */\nexport interface MarkPropFieldDef extends ScaleFieldDef {\n /**\n * An object defining properties of the legend.\n * If `null`, the legend for the encoding channel will be removed.\n *\n * __Default value:__ If undefined, default [legend properties](https://vega.github.io/vega-lite/docs/legend.html) are applied.\n */\n legend?: Legend | null;\n}\n\n// Detail\n\n// Order Path have no scale\n\nexport interface OrderFieldDef extends FieldDef {\n /**\n * The sort order. One of `\"ascending\"` (default) or `\"descending\"`.\n */\n sort?: SortOrder;\n}\n\nexport interface TextFieldDef extends FieldDef {\n /**\n * The [formatting pattern](https://vega.github.io/vega-lite/docs/format.html) for a text field. If not defined, this will be determined automatically.\n */\n format?: string;\n}\n\nexport type ChannelDef = ChannelDefWithCondition>;\n\nexport function isConditionalDef(channelDef: ChannelDef): channelDef is ChannelDefWithCondition> {\n return !!channelDef && !!channelDef.condition;\n}\n\n/**\n * Return if a channelDef is a ConditionalValueDef with ConditionFieldDef\n */\nexport function hasConditionalFieldDef(channelDef: ChannelDef): channelDef is (ValueDef & {condition: Conditional>}) {\n return !!channelDef && !!channelDef.condition && !isArray(channelDef.condition) && isFieldDef(channelDef.condition);\n}\n\nexport function hasConditionalValueDef(channelDef: ChannelDef): channelDef is (ValueDef & {condition: Conditional | Conditional[]}) {\n return !!channelDef && !!channelDef.condition && (\n isArray(channelDef.condition) || isValueDef(channelDef.condition)\n );\n}\n\nexport function isFieldDef(channelDef: ChannelDef): channelDef is FieldDef | PositionFieldDef | ScaleFieldDef | MarkPropFieldDef | OrderFieldDef | TextFieldDef {\n return !!channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count');\n}\n\nexport function isStringFieldDef(fieldDef: ChannelDef): fieldDef is FieldDef {\n return isFieldDef(fieldDef) && isString(fieldDef.field);\n}\n\nexport function isValueDef(channelDef: ChannelDef): channelDef is ValueDef {\n return channelDef && 'value' in channelDef && channelDef['value'] !== undefined;\n}\n\nexport function isScaleFieldDef(channelDef: ChannelDef): channelDef is ScaleFieldDef {\n return !!channelDef && (!!channelDef['scale'] || !!channelDef['sort']);\n}\n\nexport interface FieldRefOption {\n /** exclude bin, aggregate, timeUnit */\n nofn?: boolean;\n /** Wrap the field with datum or parent (e.g., datum['...'] for Vega Expression */\n expr?: 'datum' | 'parent';\n /** prepend fn with custom function prefix */\n prefix?: string;\n /** append suffix to the field ref for bin (default='start') */\n binSuffix?: 'end' | 'range' | 'mid';\n /** append suffix to the field ref (general) */\n suffix?: string;\n}\n\nfunction isOpFieldDef(fieldDef: FieldDefBase | WindowFieldDef | AggregatedFieldDef): fieldDef is WindowFieldDef | AggregatedFieldDef {\n return !!fieldDef['op'];\n}\n\nexport function vgField(fieldDef: FieldDefBase | WindowFieldDef | AggregatedFieldDef, opt: FieldRefOption = {}): string {\n let field = fieldDef.field;\n const prefix = opt.prefix;\n let suffix = opt.suffix;\n\n if (isCount(fieldDef)) {\n field = 'count_*';\n } else {\n let fn: string = undefined;\n\n if (!opt.nofn) {\n if (isOpFieldDef(fieldDef)) {\n fn = fieldDef.op;\n } else if (fieldDef.bin) {\n fn = binToString(fieldDef.bin);\n suffix = opt.binSuffix || '';\n } else if (fieldDef.aggregate) {\n fn = String(fieldDef.aggregate);\n } else if (fieldDef.timeUnit) {\n fn = String(fieldDef.timeUnit);\n }\n }\n\n if (fn) {\n field = field ? `${fn}_${field}` : fn;\n }\n }\n\n if (suffix) {\n field = `${field}_${suffix}`;\n }\n\n if (prefix) {\n field = `${prefix}_${field}`;\n }\n\n if (opt.expr) {\n // Expression to access flattened field. No need to escape dots.\n return flatAccessWithDatum(field, opt.expr);\n } else {\n // We flattened all fields so paths should have become dot.\n return replacePathInField(field);\n }\n}\n\nexport function isDiscrete(fieldDef: FieldDef) {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n case 'geojson':\n return true;\n case 'quantitative':\n return !!fieldDef.bin;\n case 'latitude':\n case 'longitude':\n case 'temporal':\n return false;\n }\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n\nexport function isContinuous(fieldDef: FieldDef) {\n return !isDiscrete(fieldDef);\n}\n\nexport function isCount(fieldDef: FieldDefBase) {\n return fieldDef.aggregate === 'count';\n}\n\nexport type FieldTitleFormatter = (fieldDef: FieldDefBase, config: Config) => string;\n\nexport function verbalTitleFormatter(fieldDef: FieldDefBase, config: Config) {\n const {field: field, bin, timeUnit, aggregate} = fieldDef;\n if (aggregate === 'count') {\n return config.countTitle;\n } else if (bin) {\n return `${field} (binned)`;\n } else if (timeUnit) {\n const units = getTimeUnitParts(timeUnit).join('-');\n return `${field} (${units})`;\n } else if (aggregate) {\n return `${titlecase(aggregate)} of ${field}`;\n }\n return field;\n}\n\nexport function functionalTitleFormatter(fieldDef: FieldDefBase, config: Config) {\n const fn = fieldDef.aggregate || fieldDef.timeUnit || (fieldDef.bin && 'bin');\n if (fn) {\n return fn.toUpperCase() + '(' + fieldDef.field + ')';\n } else {\n return fieldDef.field;\n }\n}\n\nexport const defaultTitleFormatter: FieldTitleFormatter = (fieldDef: FieldDefBase, config: Config) => {\n switch (config.fieldTitle) {\n case 'plain':\n return fieldDef.field;\n case 'functional':\n return functionalTitleFormatter(fieldDef, config);\n default:\n return verbalTitleFormatter(fieldDef, config);\n }\n};\n\nlet titleFormatter = defaultTitleFormatter;\n\nexport function setTitleFormatter(formatter: FieldTitleFormatter) {\n titleFormatter = formatter;\n}\n\nexport function resetTitleFormatter() {\n setTitleFormatter(defaultTitleFormatter);\n}\n\nexport function title(fieldDef: FieldDefBase, config: Config) {\n return titleFormatter(fieldDef, config);\n}\n\nexport function defaultType(fieldDef: FieldDef, channel: Channel): Type {\n if (fieldDef.timeUnit) {\n return 'temporal';\n }\n if (fieldDef.bin) {\n return 'quantitative';\n }\n switch (rangeType(channel)) {\n case 'continuous':\n return 'quantitative';\n case 'discrete':\n return 'nominal';\n case 'flexible': // color\n return 'nominal';\n default:\n return 'quantitative';\n }\n}\n\n/**\n * Returns the fieldDef -- either from the outer channelDef or from the condition of channelDef.\n * @param channelDef\n */\nexport function getFieldDef(channelDef: ChannelDef): FieldDef {\n if (isFieldDef(channelDef)) {\n return channelDef;\n } else if (hasConditionalFieldDef(channelDef)) {\n return channelDef.condition;\n }\n return undefined;\n}\n\n/**\n * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n */\nexport function normalize(channelDef: ChannelDef, channel: Channel): ChannelDef {\n if (isString(channelDef) || isNumber(channelDef) || isBoolean(channelDef)) {\n const primitiveType = isString(channelDef) ? 'string' :\n isNumber(channelDef) ? 'number' : 'boolean';\n log.warn(log.message.primitiveChannelDef(channel, primitiveType, channelDef));\n return {value: channelDef};\n }\n\n // If a fieldDef contains a field, we need type.\n if (isFieldDef(channelDef)) {\n return normalizeFieldDef(channelDef, channel);\n } else if (hasConditionalFieldDef(channelDef)) {\n return {\n ...channelDef,\n // Need to cast as normalizeFieldDef normally return FieldDef, but here we know that it is definitely Condition\n condition: normalizeFieldDef(channelDef.condition, channel) as Conditional>\n };\n }\n return channelDef;\n}\nexport function normalizeFieldDef(fieldDef: FieldDef, channel: Channel) {\n // Drop invalid aggregate\n if (fieldDef.aggregate && !isAggregateOp(fieldDef.aggregate)) {\n const {aggregate, ...fieldDefWithoutAggregate} = fieldDef;\n log.warn(log.message.invalidAggregate(fieldDef.aggregate));\n fieldDef = fieldDefWithoutAggregate;\n }\n\n // Normalize Time Unit\n if (fieldDef.timeUnit) {\n fieldDef = {\n ...fieldDef,\n timeUnit: normalizeTimeUnit(fieldDef.timeUnit)\n };\n }\n\n // Normalize bin\n if (fieldDef.bin) {\n fieldDef = {\n ...fieldDef,\n bin: normalizeBin(fieldDef.bin, channel)\n };\n }\n\n // Normalize Type\n if (fieldDef.type) {\n const fullType = getFullName(fieldDef.type);\n if (fieldDef.type !== fullType) {\n // convert short type to full type\n fieldDef = {\n ...fieldDef,\n type: fullType\n };\n }\n if (fieldDef.type !== 'quantitative') {\n if (isCountingAggregateOp(fieldDef.aggregate)) {\n log.warn(log.message.invalidFieldTypeForCountAggregate(fieldDef.type, fieldDef.aggregate));\n fieldDef = {\n ...fieldDef,\n type: 'quantitative'\n };\n }\n }\n } else {\n // If type is empty / invalid, then augment with default type\n const newType = defaultType(fieldDef, channel);\n log.warn(log.message.emptyOrInvalidFieldType(fieldDef.type, channel, newType));\n fieldDef = {\n ...fieldDef,\n type: newType\n };\n }\n\n const {compatible, warning} = channelCompatibility(fieldDef, channel);\n if (!compatible) {\n log.warn(warning);\n }\n return fieldDef;\n}\n\nexport function normalizeBin(bin: BinParams|boolean, channel: Channel) {\n if (isBoolean(bin)) {\n return {maxbins: autoMaxBins(channel)};\n } else if (!bin.maxbins && !bin.step) {\n return {...bin, maxbins: autoMaxBins(channel)};\n } else {\n return bin;\n }\n}\n\nconst COMPATIBLE = {compatible: true};\nexport function channelCompatibility(fieldDef: FieldDef, channel: Channel): {compatible: boolean; warning?: string;} {\n const type = fieldDef.type;\n\n switch (channel) {\n case 'row':\n case 'column':\n if (isContinuous(fieldDef)) {\n return {\n compatible: false,\n warning: log.message.facetChannelShouldBeDiscrete(channel)\n };\n }\n return COMPATIBLE;\n\n case 'x':\n case 'y':\n case 'color':\n case 'fill':\n case 'stroke':\n case 'text':\n case 'detail':\n case 'key':\n case 'tooltip':\n case 'href':\n return COMPATIBLE;\n\n case 'longitude':\n case 'longitude2':\n case 'latitude':\n case 'latitude2':\n if (type !== QUANTITATIVE) {\n return {\n compatible: false,\n warning: `Channel ${channel} should be used with a quantitative field only, not ${fieldDef.type} field.`\n };\n }\n return COMPATIBLE;\n\n case 'opacity':\n case 'size':\n case 'x2':\n case 'y2':\n if ((type === 'nominal' && !fieldDef['sort']) || type === 'geojson') {\n return {\n compatible: false,\n warning: `Channel ${channel} should not be used with an unsorted discrete field.`\n };\n }\n return COMPATIBLE;\n\n case 'shape':\n if (fieldDef.type !== 'nominal' && fieldDef.type !== 'geojson') {\n return {\n compatible: false,\n warning: 'Shape channel should be used with only either nominal or geojson data'\n };\n }\n return COMPATIBLE;\n\n case 'order':\n if (fieldDef.type === 'nominal' && !('sort' in fieldDef)) {\n return {\n compatible: false,\n warning: `Channel order is inappropriate for nominal field, which has no inherent order.`\n };\n }\n return COMPATIBLE;\n }\n throw new Error('channelCompatability not implemented for channel ' + channel);\n}\n\nexport function isNumberFieldDef(fieldDef: FieldDef) {\n return fieldDef.type === 'quantitative' || !!fieldDef.bin;\n}\n\nexport function isTimeFieldDef(fieldDef: FieldDef) {\n return fieldDef.type === 'temporal' || !!fieldDef.timeUnit;\n}\n\n\n/**\n * Getting a value associated with a fielddef.\n * Convert the value to Vega expression if applicable (for datetime object, or string if the field def is temporal or has timeUnit)\n */\nexport function valueExpr(\n v: number | string | boolean | DateTime,\n {timeUnit, type, time, undefinedIfExprNotRequired}: {\n timeUnit: TimeUnit,\n type?: Type,\n time?: boolean\n undefinedIfExprNotRequired?: boolean\n }\n): string {\n\n let expr = undefined;\n if (isDateTime(v)) {\n expr = dateTimeExpr(v, true);\n } else if (isString(v) || isNumber(v)) {\n if (timeUnit || type === 'temporal') {\n if (isLocalSingleTimeUnit(timeUnit)) {\n expr = dateTimeExpr({[timeUnit]: v}, true);\n } else if (isUtcSingleTimeUnit(timeUnit)) {\n // FIXME is this really correct?\n expr = valueExpr(v, {timeUnit: getLocalTimeUnit(timeUnit)});\n } else {\n // just pass the string to date function (which will call JS Date.parse())\n expr = `datetime(${JSON.stringify(v)})`;\n }\n }\n }\n if (expr) {\n return time ? `time(${expr})` : expr;\n }\n // number or boolean or normal string\n return undefinedIfExprNotRequired ? undefined : JSON.stringify(v);\n}\n\n/**\n * Standardize value array -- convert each value to Vega expression if applicable\n */\nexport function valueArray(\n fieldDef: FieldDef,\n values: (number | string | boolean | DateTime)[]\n) {\n const {timeUnit, type} = fieldDef;\n return values.map(v => {\n const expr = valueExpr(v, {timeUnit, type, undefinedIfExprNotRequired: true});\n // return signal for the expression if we need an expression\n if (expr !== undefined) {\n return {signal: expr};\n }\n // otherwise just return the original value\n return v;\n });\n}\n","\nimport {isArray} from 'vega-util';\nimport {Channel, CHANNELS, isChannel, supportMark} from './channel';\nimport {FacetMapping} from './facet';\nimport {\n ChannelDef,\n Field,\n FieldDef,\n FieldDefWithCondition,\n getFieldDef,\n hasConditionalFieldDef,\n isConditionalDef,\n isFieldDef,\n isValueDef,\n MarkPropFieldDef,\n normalize,\n normalizeFieldDef,\n OrderFieldDef,\n PositionFieldDef,\n TextFieldDef,\n ValueDef,\n ValueDefWithCondition\n} from './fielddef';\nimport * as log from './log';\nimport {Mark} from './mark';\nimport {Type} from './type';\nimport {contains, keys, some} from './util';\n\nexport interface Encoding {\n /**\n * X coordinates of the marks, or width of horizontal `\"bar\"` and `\"area\"`.\n */\n x?: PositionFieldDef | ValueDef;\n\n /**\n * Y coordinates of the marks, or height of vertical `\"bar\"` and `\"area\"`.\n */\n y?: PositionFieldDef | ValueDef;\n\n /**\n * X2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n // TODO: Ham need to add default behavior\n x2?: FieldDef | ValueDef;\n\n /**\n * Y2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n // TODO: Ham need to add default behavior\n y2?: FieldDef | ValueDef;\n\n\n /**\n * Longitude position of geographically projected marks.\n */\n longitude?: FieldDef;\n\n /**\n * Latitude position of geographically projected marks.\n */\n latitude?: FieldDef;\n\n /**\n * Longitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n longitude2?: FieldDef;\n\n /**\n * Latitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n latitude2?: FieldDef;\n\n /**\n * Color of the marks – either fill or stroke color based on the `filled` property of mark definition.\n * By default, `color` represents fill color for `\"area\"`, `\"bar\"`, `\"tick\"`,\n * `\"text\"`, `\"trail\"`, `\"circle\"`, and `\"square\"` / stroke color for `\"line\"` and `\"point\"`.\n *\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_\n * 1) For fine-grained control over both fill and stroke colors of the marks, please use the `fill` and `stroke` channels. If either `fill` or `stroke` channel is specified, `color` channel will be ignored.\n * 2) See the scale documentation for more information about customizing [color scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme).\n */\n color?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * Fill color of the marks.\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_ When using `fill` channel, `color ` channel will be ignored. To customize both fill and stroke, please use `fill` and `stroke` channels (not `fill` and `color`).\n */\n fill?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n\n /**\n * Stroke color of the marks.\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_ When using `stroke` channel, `color ` channel will be ignored. To customize both stroke and fill, please use `stroke` and `fill` channels (not `stroke` and `color`).\n */\n stroke?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n\n /**\n * Opacity of the marks – either can be a value or a range.\n *\n * __Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `opacity` property.\n */\n opacity?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * Size of the mark.\n * - For `\"point\"`, `\"square\"` and `\"circle\"`, – the symbol size, or pixel area of the mark.\n * - For `\"bar\"` and `\"tick\"` – the bar and tick's size.\n * - For `\"text\"` – the text's font size.\n * - Size is unsupported for `\"line\"`, `\"area\"`, and `\"rect\"`. (Use `\"trail\"` instead of line with varying size)\n */\n size?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * For `point` marks the supported values are\n * `\"circle\"` (default), `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`,\n * or `\"triangle-down\"`, or else a custom SVG path string.\n * For `geoshape` marks it should be a field definition of the geojson data\n *\n * __Default value:__ If undefined, the default shape depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#point-config)'s `shape` property.\n */\n shape?: FieldDefWithCondition> | ValueDefWithCondition>; // TODO: maybe distinguish ordinal-only\n\n /**\n * Additional levels of detail for grouping data in aggregate views and\n * in line, trail, and area marks without mapping data to a specific visual channel.\n */\n detail?: FieldDef | FieldDef[];\n\n /**\n * A data field to use as a unique key for data binding. When a visualization’s data is updated, the key value will be used to match data elements to existing mark instances. Use a key channel to enable object constancy for transitions over dynamic data.\n */\n key?: FieldDef;\n\n /**\n * Text of the `text` mark.\n */\n text?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * The tooltip text to show upon mouse hover.\n */\n tooltip?: FieldDefWithCondition> | ValueDefWithCondition> | TextFieldDef[];\n\n /**\n * A URL to load upon mouse click.\n */\n href?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * Order of the marks.\n * - For stacked marks, this `order` channel encodes [stack order](https://vega.github.io/vega-lite/docs/stack.html#order).\n * - For line and trail marks, this `order` channel encodes order of data points in the lines. This can be useful for creating [a connected scatterplot](https://vega.github.io/vega-lite/examples/connected_scatterplot.html). Setting `order` to `{\"value\": null}` makes the line marks use the original order in the data sources.\n * - Otherwise, this `order` channel encodes layer order of the marks.\n *\n * __Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping.\n */\n order?: OrderFieldDef | OrderFieldDef[] | ValueDef;\n}\n\nexport interface EncodingWithFacet extends Encoding, FacetMapping {}\n\nexport function channelHasField(encoding: EncodingWithFacet, channel: Channel): boolean {\n const channelDef = encoding && encoding[channel];\n if (channelDef) {\n if (isArray(channelDef)) {\n return some(channelDef, (fieldDef) => !!fieldDef.field);\n } else {\n return isFieldDef(channelDef) || hasConditionalFieldDef(channelDef);\n }\n }\n return false;\n}\n\n\nexport function isAggregate(encoding: EncodingWithFacet) {\n return some(CHANNELS, (channel) => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n if (isArray(channelDef)) {\n return some(channelDef, (fieldDef) => !!fieldDef.aggregate);\n } else {\n const fieldDef = getFieldDef(channelDef);\n return fieldDef && !!fieldDef.aggregate;\n }\n }\n return false;\n });\n}\n\nexport function normalizeEncoding(encoding: Encoding, mark: Mark): Encoding {\n return keys(encoding).reduce((normalizedEncoding: Encoding, channel: Channel | string) => {\n if (!isChannel(channel)) {\n // Drop invalid channel\n log.warn(log.message.invalidEncodingChannel(channel));\n return normalizedEncoding;\n }\n\n if (!supportMark(channel, mark)) {\n // Drop unsupported channel\n\n log.warn(log.message.incompatibleChannel(channel, mark));\n return normalizedEncoding;\n }\n\n // Drop line's size if the field is aggregated.\n if (channel === 'size' && mark === 'line') {\n const fieldDef = getFieldDef(encoding[channel]);\n if (fieldDef && fieldDef.aggregate) {\n log.warn(log.message.LINE_WITH_VARYING_SIZE);\n return normalizedEncoding;\n }\n }\n\n // Drop color if either fill or stroke is specified\n if (channel === 'color' && ('fill' in encoding || 'stroke' in encoding) ) {\n log.warn(log.message.droppingColor('encoding', {fill: 'fill' in encoding, stroke: 'stroke' in encoding}));\n return normalizedEncoding;\n }\n\n const channelDef = encoding[channel];\n if (\n channel === 'detail' ||\n (channel === 'order' && !isArray(channelDef) && !isValueDef(channelDef)) ||\n (channel === 'tooltip' && isArray(channelDef))\n ) {\n if (channelDef) {\n // Array of fieldDefs for detail channel (or production rule)\n normalizedEncoding[channel] = (isArray(channelDef) ? channelDef : [channelDef])\n .reduce((defs: FieldDef[], fieldDef: FieldDef) => {\n if (!isFieldDef(fieldDef)) {\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n } else {\n defs.push(normalizeFieldDef(fieldDef, channel));\n }\n return defs;\n }, []);\n }\n } else {\n\n const fieldDef = getFieldDef(encoding[channel]);\n if (fieldDef && contains([Type.LATITUDE, Type.LONGITUDE], fieldDef.type)) {\n const {[channel]: _, ...newEncoding} = normalizedEncoding;\n const newChannel = channel === 'x' ? 'longitude' :\n channel === 'y' ? 'latitude' :\n channel === 'x2' ? 'longitude2' :\n channel === 'y2' ? 'latitude2' : undefined;\n log.warn(log.message.latLongDeprecated(channel, fieldDef.type, newChannel));\n return {\n ...newEncoding,\n [newChannel]: {\n ...normalize(fieldDef as any, channel),\n type: 'quantitative'\n }\n };\n }\n\n if (!isFieldDef(channelDef) && !isValueDef(channelDef) && !isConditionalDef(channelDef)) {\n log.warn(log.message.emptyFieldDef(channelDef, channel));\n return normalizedEncoding;\n }\n normalizedEncoding[channel] = normalize(channelDef as ChannelDef, channel);\n }\n return normalizedEncoding;\n }, {});\n}\n\n\nexport function isRanged(encoding: EncodingWithFacet) {\n return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2));\n}\n\nexport function fieldDefs(encoding: EncodingWithFacet): FieldDef[] {\n const arr: FieldDef[] = [];\n CHANNELS.forEach(function(channel) {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((def) => {\n if (isFieldDef(def)) {\n arr.push(def);\n } else if (hasConditionalFieldDef(def)) {\n arr.push(def.condition);\n }\n });\n }\n });\n return arr;\n}\n\nexport function forEach(mapping: any,\n f: (fd: FieldDef, c: Channel) => void,\n thisArg?: any) {\n if (!mapping) {\n return;\n }\n\n for (const channel of keys(mapping)) {\n if (isArray(mapping[channel])) {\n mapping[channel].forEach(function(channelDef: ChannelDef) {\n f.call(thisArg, channelDef, channel);\n });\n } else {\n f.call(thisArg, mapping[channel], channel);\n }\n }\n}\n\nexport function reduce(mapping: U,\n f: (acc: any, fd: FieldDef, c: Channel) => U,\n init: T, thisArg?: any) {\n if (!mapping) {\n return init;\n }\n\n return keys(mapping).reduce((r, channel) => {\n const map = mapping[channel];\n if (isArray(map)) {\n return map.reduce((r1: T, channelDef: ChannelDef) => {\n return f.call(thisArg, r1, channelDef, channel);\n }, r);\n } else {\n return f.call(thisArg, r, map, channel);\n }\n }, init);\n}\n","import {NonPositionChannel} from '../channel';\nimport {MarkConfig} from '../mark';\n\nexport function getMarkSpecificConfigMixins(markSpecificConfig: MarkConfig, channel: NonPositionChannel) {\n const value = markSpecificConfig[channel];\n return value !== undefined ? {[channel]: {value}} : {};\n}\n","import {isNumber} from 'vega-util';\nimport {Channel} from '../channel';\nimport {Config} from '../config';\nimport {reduce} from '../encoding';\nimport {AggregatedFieldDef, BinTransform, CalculateTransform, TimeUnitTransform} from '../transform';\nimport {Encoding, forEach} from './../encoding';\nimport {Field, FieldDef, isContinuous, isFieldDef, PositionFieldDef, vgField} from './../fielddef';\nimport * as log from './../log';\nimport {MarkConfig} from './../mark';\nimport {GenericUnitSpec, NormalizedLayerSpec} from './../spec';\nimport {Orient} from './../vega.schema';\nimport {getMarkSpecificConfigMixins} from './common';\n\n\nexport const BOXPLOT: 'box-plot' = 'box-plot';\nexport type BOXPLOT = typeof BOXPLOT;\nexport type BoxPlotStyle = 'boxWhisker' | 'box' | 'boxMid';\n\n\nexport interface BoxPlotDef {\n /**\n * Type of the mark. For box plots, this should always be `\"box-plot\"`.\n * [boxplot](https://vega.github.io/vega-lite/docs/compositemark.html#boxplot)\n */\n type: BOXPLOT;\n\n /**\n * Orientation of the box plot. This is normally automatically determined, but can be specified when the orientation is ambiguous and cannot be automatically determined.\n */\n orient?: Orient;\n\n /**\n * Extent is used to determine where the whiskers extend to. The options are\n * - `\"min-max\": min and max are the lower and upper whiskers respectively.\n * - A scalar (integer or floating point number) that will be multiplied by the IQR and the product will be added to the third quartile to get the upper whisker and subtracted from the first quartile to get the lower whisker.\n * __Default value:__ `\"1.5\"`.\n */\n extent?: 'min-max' | number;\n}\n\nexport function isBoxPlotDef(mark: BOXPLOT | BoxPlotDef): mark is BoxPlotDef {\n return !!mark['type'];\n}\n\nexport const BOXPLOT_STYLES: BoxPlotStyle[] = ['boxWhisker', 'box', 'boxMid'];\n\nexport interface BoxPlotConfig extends MarkConfig {\n /** Size of the box and mid tick of a box plot */\n size?: number;\n /** The default extent, which is used to determine where the whiskers extend to. The options are\n * - `\"min-max\": min and max are the lower and upper whiskers respectively.\n * - `\"number\": A scalar (integer or floating point number) that will be multiplied by the IQR and the product will be added to the third quartile to get the upper whisker and subtracted from the first quartile to get the lower whisker.\n */\n extent?: 'min-max' | number;\n}\n\nexport interface BoxPlotConfigMixins {\n /**\n * Box Config\n * @hide\n */\n box?: BoxPlotConfig;\n\n /**\n * @hide\n */\n boxWhisker?: MarkConfig;\n\n /**\n * @hide\n */\n boxMid?: MarkConfig;\n}\n\nexport const VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX: {\n [k in keyof BoxPlotConfigMixins]?: (keyof BoxPlotConfigMixins[k])[]\n} = {\n box: ['size', 'color', 'extent'],\n boxWhisker: ['color'],\n boxMid: ['color']\n};\n\nconst supportedChannels: Channel[] = ['x', 'y', 'color', 'detail', 'opacity', 'size'];\nexport function filterUnsupportedChannels(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>): GenericUnitSpec, BOXPLOT | BoxPlotDef> {\n return {\n ...spec,\n encoding: reduce(spec.encoding, (newEncoding, fieldDef, channel) => {\n if (supportedChannels.indexOf(channel) > -1) {\n newEncoding[channel] = fieldDef;\n } else {\n log.warn(log.message.incompatibleChannel(channel, BOXPLOT));\n }\n return newEncoding;\n }, {}),\n };\n}\n\nexport function normalizeBoxPlot(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>, config: Config): NormalizedLayerSpec {\n spec = filterUnsupportedChannels(spec);\n // TODO: use selection\n const {mark, encoding, selection, projection: _p, ...outerSpec} = spec;\n\n let kIQRScalar: number = undefined;\n if (isNumber(config.box.extent)) {\n kIQRScalar = config.box.extent;\n }\n\n if (isBoxPlotDef(mark)) {\n if (mark.extent) {\n if(mark.extent === 'min-max') {\n kIQRScalar = undefined;\n }\n }\n }\n\n const orient: Orient = boxOrient(spec);\n const {transform, continuousAxisChannelDef, continuousAxis, encodingWithoutContinuousAxis} = boxParams(spec, orient, kIQRScalar);\n\n const {color, size, ...encodingWithoutSizeColorAndContinuousAxis} = encodingWithoutContinuousAxis;\n\n // Size encoding or the default config.box.size is applied to box and boxMid\n const sizeMixins = size ? {size} : getMarkSpecificConfigMixins(config.box, 'size');\n\n const continuousAxisScaleAndAxis = {};\n if (continuousAxisChannelDef.scale) {\n continuousAxisScaleAndAxis['scale'] = continuousAxisChannelDef.scale;\n }\n if (continuousAxisChannelDef.axis) {\n continuousAxisScaleAndAxis['axis'] = continuousAxisChannelDef.axis;\n }\n\n return {\n ...outerSpec,\n transform,\n layer: [\n { // lower whisker\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n encoding: {\n [continuousAxis]: {\n field: 'lower_whisker_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type,\n ...continuousAxisScaleAndAxis\n },\n [continuousAxis + '2']: {\n field: 'lower_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutSizeColorAndContinuousAxis,\n ...getMarkSpecificConfigMixins(config.boxWhisker, 'color')\n }\n }, { // upper whisker\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n encoding: {\n [continuousAxis]: {\n field: 'upper_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n [continuousAxis + '2']: {\n field: 'upper_whisker_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutSizeColorAndContinuousAxis,\n ...getMarkSpecificConfigMixins(config.boxWhisker, 'color')\n }\n }, { // box (q1 to q3)\n ...(selection ? {selection} : {}),\n mark: {\n type: 'bar',\n style: 'box'\n },\n encoding: {\n [continuousAxis]: {\n field: 'lower_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n [continuousAxis + '2']: {\n field: 'upper_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutContinuousAxis,\n ...(encodingWithoutContinuousAxis.color ? {} : getMarkSpecificConfigMixins(config.box, 'color')),\n ...sizeMixins,\n }\n }, { // mid tick\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n encoding: {\n [continuousAxis]: {\n field: 'mid_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutSizeColorAndContinuousAxis,\n ...getMarkSpecificConfigMixins(config.boxMid, 'color'),\n ...sizeMixins,\n }\n }\n ]\n };\n}\n\nfunction boxOrient(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>): Orient {\n const {mark: mark, encoding: encoding, projection: _p, ..._outerSpec} = spec;\n\n if (isFieldDef(encoding.x) && isContinuous(encoding.x)) {\n // x is continuous\n if (isFieldDef(encoding.y) && isContinuous(encoding.y)) {\n // both x and y are continuous\n if (encoding.x.aggregate === undefined && encoding.y.aggregate === BOXPLOT) {\n return 'vertical';\n } else if (encoding.y.aggregate === undefined && encoding.x.aggregate === BOXPLOT) {\n return 'horizontal';\n } else if (encoding.x.aggregate === BOXPLOT && encoding.y.aggregate === BOXPLOT) {\n throw new Error('Both x and y cannot have aggregate');\n } else {\n if (isBoxPlotDef(mark) && mark.orient) {\n return mark.orient;\n }\n\n // default orientation = vertical\n return 'vertical';\n }\n }\n\n // x is continuous but y is not\n return 'horizontal';\n } else if (isFieldDef(encoding.y) && isContinuous(encoding.y)) {\n // y is continuous but x is not\n return 'vertical';\n } else {\n // Neither x nor y is continuous.\n throw new Error('Need a valid continuous axis for boxplots');\n }\n}\n\n\nfunction boxContinousAxis(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>, orient: Orient) {\n const {mark: mark, encoding: encoding, projection: _p, ..._outerSpec} = spec;\n\n let continuousAxisChannelDef: PositionFieldDef;\n let continuousAxis: 'x' | 'y';\n\n if (orient === 'vertical') {\n continuousAxis = 'y';\n continuousAxisChannelDef = encoding.y as FieldDef; // Safe to cast because if y is not continuous fielddef, the orient would not be vertical.\n } else {\n continuousAxis = 'x';\n continuousAxisChannelDef = encoding.x as FieldDef; // Safe to cast because if x is not continuous fielddef, the orient would not be horizontal.\n }\n\n if (continuousAxisChannelDef && continuousAxisChannelDef.aggregate) {\n const {aggregate, ...continuousAxisWithoutAggregate} = continuousAxisChannelDef;\n if (aggregate !== BOXPLOT) {\n log.warn(`Continuous axis should not have customized aggregation function ${aggregate}`);\n }\n continuousAxisChannelDef = continuousAxisWithoutAggregate;\n }\n\n return {\n continuousAxisChannelDef,\n continuousAxis\n };\n}\n\nfunction boxParams(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>, orient: Orient, kIQRScalar: 'min-max' | number) {\n\n const {continuousAxisChannelDef, continuousAxis} = boxContinousAxis(spec, orient);\n const encoding = spec.encoding;\n\n const isMinMax = kIQRScalar === undefined;\n const aggregate: AggregatedFieldDef[] = [\n {\n op: 'q1',\n field: continuousAxisChannelDef.field,\n as: 'lower_box_' + continuousAxisChannelDef.field\n },\n {\n op: 'q3',\n field: continuousAxisChannelDef.field,\n as: 'upper_box_' + continuousAxisChannelDef.field\n },\n {\n op: 'median',\n field: continuousAxisChannelDef.field,\n as: 'mid_box_' + continuousAxisChannelDef.field\n }\n ];\n let postAggregateCalculates: CalculateTransform[] = [];\n\n aggregate.push({\n op: 'min',\n field: continuousAxisChannelDef.field,\n as: (isMinMax ? 'lower_whisker_' : 'min_') + continuousAxisChannelDef.field\n });\n aggregate.push({\n op: 'max',\n field: continuousAxisChannelDef.field,\n as: (isMinMax ? 'upper_whisker_' : 'max_') + continuousAxisChannelDef.field\n });\n\n if (!isMinMax) {\n postAggregateCalculates = [\n {\n calculate: `datum.upper_box_${continuousAxisChannelDef.field} - datum.lower_box_${continuousAxisChannelDef.field}`,\n as: 'iqr_' + continuousAxisChannelDef.field\n },\n {\n calculate: `min(datum.upper_box_${continuousAxisChannelDef.field} + datum.iqr_${continuousAxisChannelDef.field} * ${kIQRScalar}, datum.max_${continuousAxisChannelDef.field})`,\n as: 'upper_whisker_' + continuousAxisChannelDef.field\n },\n {\n calculate: `max(datum.lower_box_${continuousAxisChannelDef.field} - datum.iqr_${continuousAxisChannelDef.field} * ${kIQRScalar}, datum.min_${continuousAxisChannelDef.field})`,\n as: 'lower_whisker_' + continuousAxisChannelDef.field\n }\n ];\n }\n\n const groupby: string[] = [];\n const bins: BinTransform[] = [];\n const timeUnits: TimeUnitTransform[] = [];\n\n const encodingWithoutContinuousAxis: Encoding = {};\n forEach(encoding, (channelDef, channel) => {\n if (channel === continuousAxis) {\n // Skip continuous axis as we already handle it separately\n return;\n }\n if (isFieldDef(channelDef)) {\n if (channelDef.aggregate && channelDef.aggregate !== BOXPLOT) {\n aggregate.push({\n op: channelDef.aggregate,\n field: channelDef.field,\n as: vgField(channelDef)\n });\n } else if (channelDef.aggregate === undefined) {\n const transformedField = vgField(channelDef);\n\n // Add bin or timeUnit transform if applicable\n const bin = channelDef.bin;\n if (bin) {\n const {field} = channelDef;\n bins.push({bin, field, as: transformedField});\n } else if (channelDef.timeUnit) {\n const {timeUnit, field} = channelDef;\n timeUnits.push({timeUnit, field, as: transformedField});\n }\n\n groupby.push(transformedField);\n }\n // now the field should refer to post-transformed field instead\n encodingWithoutContinuousAxis[channel] = {\n field: vgField(channelDef),\n type: channelDef.type\n };\n } else {\n // For value def, just copy\n encodingWithoutContinuousAxis[channel] = encoding[channel];\n }\n });\n\n return {\n transform: [].concat(\n bins,\n timeUnits,\n [{aggregate, groupby}],\n postAggregateCalculates\n ),\n continuousAxisChannelDef,\n continuousAxis,\n encodingWithoutContinuousAxis\n };\n}\n","import {Field} from '../fielddef';\nimport {Encoding} from './../encoding';\nimport {GenericUnitSpec, NormalizedLayerSpec} from './../spec';\n\n\nexport const ERRORBAR: 'error-bar' = 'error-bar';\nexport type ERRORBAR = typeof ERRORBAR;\n\nexport function normalizeErrorBar(spec: GenericUnitSpec, ERRORBAR>): NormalizedLayerSpec {\n // TODO: use selection\n const {mark: _m, selection: _sel, projection: _p, encoding, ...outerSpec} = spec;\n const {size: _s, ...encodingWithoutSize} = encoding;\n const {x2: _x2, y2: _y2, ...encodingWithoutX2Y2} = encoding;\n const {x: _x, y: _y, ...encodingWithoutX_X2_Y_Y2} = encodingWithoutX2Y2;\n\n if (!encoding.x2 && !encoding.y2) {\n throw new Error('Neither x2 or y2 provided');\n }\n\n return {\n ...outerSpec,\n layer: [\n {\n mark: 'rule',\n encoding: encodingWithoutSize\n },{ // Lower tick\n mark: 'tick',\n encoding: encodingWithoutX2Y2\n }, { // Upper tick\n mark: 'tick',\n encoding: encoding.x2 ? {\n x: encoding.x2,\n y: encoding.y,\n ...encodingWithoutX_X2_Y_Y2\n } : {\n x: encoding.x,\n y: encoding.y2,\n ...encodingWithoutX_X2_Y_Y2\n }\n }\n ]\n };\n}\n","import {Config} from './../config';\nimport {AnyMark, isMarkDef} from './../mark';\nimport {GenericUnitSpec, NormalizedLayerSpec} from './../spec';\nimport {BOXPLOT, BoxPlotConfigMixins, BoxPlotDef, normalizeBoxPlot, VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX} from './boxplot';\nimport {ERRORBAR, normalizeErrorBar} from './errorbar';\n\n// This package import below makes the generated .d.ts file compatible with\n// Typescript 2.7 so that libraries requiring us can use Typedoc (which\n// currently is limited to Typescript 2.7). This comment and import can be\n// removed when Typedoc is updated to Typescript 2.9 or later. See\n// https://github.com/vega/vega-lite/issues/3862 for more details.\nimport * as boxplot from './boxplot';\n\nexport {BoxPlotConfig} from './boxplot';\nexport type UnitNormalizer = (spec: GenericUnitSpec, config: Config)=> NormalizedLayerSpec;\n\n/**\n * Registry index for all composite mark's normalizer\n */\nconst normalizerRegistry: {[mark: string]: UnitNormalizer} = {};\n\nexport function add(mark: string, normalizer: UnitNormalizer) {\n normalizerRegistry[mark] = normalizer;\n}\n\nexport function remove(mark: string) {\n delete normalizerRegistry[mark];\n}\n\nexport type CompositeMark = BOXPLOT | ERRORBAR;\n\nexport type CompositeMarkDef = BoxPlotDef;\n\nexport type CompositeAggregate = BOXPLOT;\n\nexport const COMPOSITE_MARK_STYLES = boxplot.BOXPLOT_STYLES;\nexport type CompositeMarkStyle = typeof COMPOSITE_MARK_STYLES[0];\n\nexport interface CompositeMarkConfigMixins extends BoxPlotConfigMixins {}\n\nexport const VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = {\n ...VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX\n};\n\nadd(BOXPLOT, normalizeBoxPlot);\nadd(ERRORBAR, normalizeErrorBar);\n\n/**\n * Transform a unit spec with composite mark into a normal layer spec.\n */\nexport function normalize(\n // This GenericUnitSpec has any as Encoding because unit specs with composite mark can have additional encoding channels.\n spec: GenericUnitSpec,\n config: Config\n ): NormalizedLayerSpec {\n\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n const normalizer = normalizerRegistry[mark];\n if (normalizer) {\n return normalizer(spec, config);\n }\n\n throw new Error(`Invalid mark type \"${mark}\"`);\n}\n","import {ConditionValueDefMixins, ValueDef} from './fielddef';\nimport {VgEncodeChannel} from './vega.schema';\n\nexport interface TitleMixins {\n /**\n * A title for the field. If `null`, the title will be removed.\n *\n * __Default value:__ derived from the field's name and transformation function (`aggregate`, `bin` and `timeUnit`). If the field has an aggregate function, the function is displayed as part of the title (e.g., `\"Sum of Profit\"`). If the field is binned or has a time unit applied, the applied function is shown in parentheses (e.g., `\"Profit (binned)\"`, `\"Transaction Date (year-month)\"`). Otherwise, the title is simply the field name.\n *\n * __Notes__:\n *\n * 1) You can customize the default field title format by providing the [`fieldTitle` property in the [config](https://vega.github.io/vega-lite/docs/config.html) or [`fieldTitle` function via the `compile` function's options](https://vega.github.io/vega-lite/docs/compile.html#field-title).\n *\n * 2) If both field definition's `title` and axis, header, or legend `title` are defined, axis/header/legend title will be used.\n */\n title?: string | null;\n}\n\nexport interface Guide extends TitleMixins {\n /**\n * The formatting pattern for labels. This is D3's [number format pattern](https://github.com/d3/d3-format#locale_format) for quantitative fields and D3's [time format pattern](https://github.com/d3/d3-time-format#locale_format) for time field.\n *\n * See the [format documentation](https://vega.github.io/vega-lite/docs/format.html) for more information.\n *\n * __Default value:__ derived from [numberFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for quantitative fields and from [timeFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for temporal fields.\n */\n format?: string;\n}\nexport interface VlOnlyGuideConfig {\n\n /**\n * Whether month names and weekday names should be abbreviated.\n *\n * __Default value:__ `false`\n */\n shortTimeLabels?: boolean;\n}\n\n\nexport type GuideEncodingEntry = {\n [k in VgEncodeChannel]?: ValueDef & ConditionValueDefMixins;\n};\n\nexport const VL_ONLY_GUIDE_CONFIG: (keyof VlOnlyGuideConfig)[] = ['shortTimeLabels'];\n","import {DateTime} from './datetime';\nimport {Guide, GuideEncodingEntry, VlOnlyGuideConfig} from './guide';\nimport {Flag, flagKeys} from './util';\nimport {VgLegend, VgLegendBase, VgLegendConfig} from './vega.schema';\n\n\nexport interface LegendConfig extends VgLegendConfig, VlOnlyGuideConfig {}\n\n/**\n * Properties of a legend or boolean flag for determining whether to show it.\n */\nexport interface Legend extends VgLegendBase, Guide {\n /**\n * Mark definitions for custom legend encoding.\n *\n * @hide\n */\n encoding?: LegendEncoding;\n\n /**\n * The desired number of tick values for quantitative legends.\n */\n tickCount?: number;\n\n /**\n * Explicitly set the visible legend values.\n */\n values?: number[] | string[] | boolean[] | DateTime[];\n\n /**\n * The type of the legend. Use `\"symbol\"` to create a discrete legend and `\"gradient\"` for a continuous color gradient.\n *\n * __Default value:__ `\"gradient\"` for non-binned quantitative fields and temporal fields; `\"symbol\"` otherwise.\n */\n type?: 'symbol' | 'gradient';\n\n /**\n * A non-positive integer indicating z-index of the legend.\n * If zindex is 0, legend should be drawn behind all chart elements.\n * To put them in front, use zindex = 1.\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n}\n\nexport type LegendEncoding = {\n /**\n * Custom encoding for the legend container.\n * This can be useful for creating legend with custom x, y position.\n */\n legend?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the legend title text mark.\n */\n title?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend label text marks.\n */\n labels?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend symbol marks.\n */\n symbols?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend gradient filled rect marks.\n */\n gradient?: GuideEncodingEntry;\n};\n\nexport const defaultLegendConfig: LegendConfig = {};\n\nconst COMMON_LEGEND_PROPERTY_INDEX: Flag = {\n entryPadding: 1,\n format: 1,\n offset: 1,\n orient: 1,\n padding: 1,\n tickCount: 1,\n title: 1,\n type: 1,\n values: 1,\n zindex: 1\n};\n\nconst VG_LEGEND_PROPERTY_INDEX: Flag = {\n ...COMMON_LEGEND_PROPERTY_INDEX,\n // channel scales\n opacity: 1,\n shape: 1,\n stroke: 1,\n fill: 1,\n size: 1,\n // encode\n encode: 1\n};\n\nexport const LEGEND_PROPERTIES = flagKeys(COMMON_LEGEND_PROPERTY_INDEX);\n\nexport const VG_LEGEND_PROPERTIES = flagKeys(VG_LEGEND_PROPERTY_INDEX);\n","import {toSet} from 'vega-util';\nimport {BinParams} from './bin';\nimport {Channel, CHANNELS, isColorChannel} from './channel';\nimport {DateTime} from './datetime';\nimport * as log from './log';\nimport {Type, TYPE_INDEX} from './type';\nimport {contains, Flag, flagKeys, keys} from './util';\nimport {ScaleInterpolate, ScaleInterpolateParams} from './vega.schema';\n\nexport namespace ScaleType {\n // Continuous - Quantitative\n export const LINEAR: 'linear' = 'linear';\n export const BIN_LINEAR: 'bin-linear' = 'bin-linear';\n export const LOG: 'log' = 'log';\n export const POW: 'pow' = 'pow';\n export const SQRT: 'sqrt' = 'sqrt';\n // Continuous - Time\n export const TIME: 'time' = 'time';\n export const UTC: 'utc' = 'utc';\n // sequential\n export const SEQUENTIAL: 'sequential' = 'sequential';\n\n // Quantile, Quantize, threshold\n export const QUANTILE: 'quantile' = 'quantile';\n export const QUANTIZE: 'quantize' = 'quantize';\n export const THRESHOLD: 'threshold' = 'threshold';\n\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const BIN_ORDINAL: 'bin-ordinal' = 'bin-ordinal';\n export const POINT: 'point' = 'point';\n export const BAND: 'band' = 'band';\n}\n\nexport type ScaleType = typeof ScaleType.LINEAR | typeof ScaleType.BIN_LINEAR |\n typeof ScaleType.LOG | typeof ScaleType.POW | typeof ScaleType.SQRT |\n typeof ScaleType.TIME | typeof ScaleType.UTC |\n // TODO: add 'quantize', 'quantile', 'threshold' back when we really support them\n typeof ScaleType.SEQUENTIAL | // typeof ScaleType.QUANTILE | typeof ScaleType.QUANTIZE | typeof ScaleType.THRESHOLD |\n typeof ScaleType.ORDINAL | typeof ScaleType.BIN_ORDINAL | typeof ScaleType.POINT | typeof ScaleType.BAND;\n\n\n/**\n * Index for scale categories -- only scale of the same categories can be merged together.\n * Current implementation is trying to be conservative and avoid merging scale type that might not work together\n */\nconst SCALE_CATEGORY_INDEX: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleType]: ScaleType | 'numeric' | 'ordinal-position'\n} = {\n linear: 'numeric',\n log: 'numeric',\n pow: 'numeric',\n sqrt: 'numeric',\n 'bin-linear': 'bin-linear', // TODO: should bin-linear support merging with other\n time: 'time',\n utc: 'time',\n sequential: 'sequential',\n ordinal: 'ordinal',\n 'bin-ordinal': 'bin-ordinal', // TODO: should bin-ordinal support merging with other\n point: 'ordinal-position',\n band: 'ordinal-position'\n};\n\nexport const SCALE_TYPES = keys(SCALE_CATEGORY_INDEX) as ScaleType[];\n\n/**\n * Whether the two given scale types can be merged together.\n */\nexport function scaleCompatible(scaleType1: ScaleType, scaleType2: ScaleType) {\n const scaleCategory1 = SCALE_CATEGORY_INDEX[scaleType1];\n const scaleCategory2 = SCALE_CATEGORY_INDEX[scaleType2];\n return scaleCategory1 === scaleCategory2 ||\n (scaleCategory1 === 'ordinal-position' && scaleCategory2 === 'time') ||\n (scaleCategory2 === 'ordinal-position' && scaleCategory1 === 'time');\n}\n\n/**\n * Index for scale precedence -- high score = higher priority for merging.\n */\nconst SCALE_PRECEDENCE_INDEX: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleType]: number\n} = {\n // numeric\n linear: 0,\n log: 1,\n pow: 1,\n sqrt: 1,\n // time\n time: 0,\n utc: 0,\n // ordinal-position -- these have higher precedence than continuous scales as they support more types of data\n point: 10,\n band: 11, // band has higher precedence as it is better for interaction\n // non grouped types\n 'bin-linear': 0,\n sequential: 0,\n ordinal: 0,\n 'bin-ordinal': 0,\n};\n\n/**\n * Return scale categories -- only scale of the same categories can be merged together.\n */\nexport function scaleTypePrecedence(scaleType: ScaleType): number {\n return SCALE_PRECEDENCE_INDEX[scaleType];\n}\n\nexport const CONTINUOUS_TO_CONTINUOUS_SCALES: ScaleType[] = ['linear', 'bin-linear', 'log', 'pow', 'sqrt', 'time', 'utc'];\nconst CONTINUOUS_TO_CONTINUOUS_INDEX = toSet(CONTINUOUS_TO_CONTINUOUS_SCALES);\n\nexport const CONTINUOUS_DOMAIN_SCALES: ScaleType[] = CONTINUOUS_TO_CONTINUOUS_SCALES.concat(['sequential' /* TODO add 'quantile', 'quantize', 'threshold'*/]);\nconst CONTINUOUS_DOMAIN_INDEX = toSet(CONTINUOUS_DOMAIN_SCALES);\n\nexport const DISCRETE_DOMAIN_SCALES: ScaleType[] = ['ordinal', 'bin-ordinal', 'point', 'band'];\nconst DISCRETE_DOMAIN_INDEX = toSet(DISCRETE_DOMAIN_SCALES);\n\nconst BIN_SCALES_INDEX = toSet(['bin-linear', 'bin-ordinal']);\n\nexport const TIME_SCALE_TYPES: ScaleType[] = ['time', 'utc'];\n\nexport function hasDiscreteDomain(type: ScaleType): type is 'ordinal' | 'bin-ordinal' | 'point' | 'band' {\n return type in DISCRETE_DOMAIN_INDEX;\n}\n\nexport function isBinScale(type: ScaleType): type is 'bin-linear' | 'bin-ordinal' {\n return type in BIN_SCALES_INDEX;\n}\n\nexport function hasContinuousDomain(type: ScaleType):\n type is 'linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc'|\n 'sequential' /* TODO add | 'quantile' | 'quantize' | 'threshold' */ {\n return type in CONTINUOUS_DOMAIN_INDEX;\n}\n\nexport function isContinuousToContinuous(type: ScaleType): type is 'linear' | 'bin-linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc' {\n return type in CONTINUOUS_TO_CONTINUOUS_INDEX;\n}\n\nexport type NiceTime = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year';\n\nexport interface ScaleConfig {\n /**\n * If true, rounds numeric output values to integers.\n * This can be helpful for snapping to the pixel grid.\n * (Only available for `x`, `y`, and `size` scales.)\n */\n round?: boolean;\n\n /**\n * If true, values that exceed the data domain are clamped to either the minimum or maximum range value\n */\n clamp?: boolean;\n /**\n * Default range step for `x` band and point scales of text marks.\n *\n * __Default value:__ `90`\n *\n * @minimum 0\n */\n textXRangeStep?: number; // FIXME: consider if we will rename this \"tableColumnWidth\"\n\n /**\n * Default range step for band and point scales of (1) the `y` channel\n * and (2) the `x` channel when the mark is not `text`.\n *\n * __Default value:__ `21`\n *\n * @minimum 0\n */\n rangeStep?: number | null;\n\n /**\n * Default inner padding for `x` and `y` band-ordinal scales.\n *\n * __Default value:__ `0.1`\n *\n * @minimum 0\n * @maximum 1\n */\n bandPaddingInner?: number;\n\n /**\n * Default outer padding for `x` and `y` band-ordinal scales.\n * If not specified, by default, band scale's paddingOuter is paddingInner/2.\n * @minimum 0\n * @maximum 1\n */\n bandPaddingOuter?: number;\n\n /**\n * Default padding for continuous scales.\n *\n * __Default:__ `5` for continuous x-scale of a vertical bar and continuous y-scale of a horizontal bar.; `0` otherwise.\n *\n * @minimum 0\n */\n continuousPadding?: number;\n\n /**\n * Default outer padding for `x` and `y` point-ordinal scales.\n *\n * __Default value:__ `0.5`\n *\n * @minimum 0\n * @maximum 1\n */\n pointPadding?: number;\n\n /**\n * Use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis.\n *\n * This is equivalent to setting `domain` to `\"unaggregate\"` for aggregated _quantitative_ fields by default.\n *\n * This property only works with aggregate functions that produce values within the raw data domain (`\"mean\"`, `\"average\"`, `\"median\"`, `\"q1\"`, `\"q3\"`, `\"min\"`, `\"max\"`). For other aggregations that produce values outside of the raw data domain (e.g. `\"count\"`, `\"sum\"`), this property is ignored.\n *\n * __Default value:__ `false`\n */\n useUnaggregatedDomain?: boolean;\n\n // nice should depends on type (quantitative or temporal), so\n // let's not make a config.\n\n // Configs for Range\n\n /**\n * The default max value for mapping quantitative fields to bar's size/bandSize.\n *\n * If undefined (default), we will use the scale's `rangeStep` - 1.\n * @minimum 0\n */\n maxBandSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to bar and tick's size/bandSize scale with zero=false.\n *\n * __Default value:__ `2`\n *\n * @minimum 0\n */\n minBandSize?: number;\n\n /**\n * The default max value for mapping quantitative fields to text's size/fontSize.\n *\n * __Default value:__ `40`\n *\n * @minimum 0\n */\n maxFontSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to tick's size/fontSize scale with zero=false\n *\n * __Default value:__ `8`\n *\n * @minimum 0\n */\n minFontSize?: number;\n\n /**\n * Default minimum opacity for mapping a field to opacity.\n *\n * __Default value:__ `0.3`\n *\n * @minimum 0\n * @maximum 1\n */\n minOpacity?: number;\n\n /**\n * Default max opacity for mapping a field to opacity.\n *\n * __Default value:__ `0.8`\n *\n * @minimum 0\n * @maximum 1\n */\n maxOpacity?: number;\n\n\n /**\n * Default minimum value for point size scale with zero=false.\n *\n * __Default value:__ `9`\n *\n * @minimum 0\n */\n minSize?: number;\n\n /**\n * Default max value for point size scale.\n * @minimum 0\n */\n maxSize?: number;\n\n /**\n * Default minimum strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks with zero=false.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n minStrokeWidth?: number;\n\n /**\n * Default max strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks.\n *\n * __Default value:__ `4`\n *\n * @minimum 0\n */\n maxStrokeWidth?: number;\n}\n\nexport const defaultScaleConfig = {\n textXRangeStep: 90,\n rangeStep: 21,\n pointPadding: 0.5,\n bandPaddingInner: 0.1,\n facetSpacing: 16,\n\n minBandSize: 2,\n\n minFontSize: 8,\n maxFontSize: 40,\n\n minOpacity: 0.3,\n maxOpacity: 0.8,\n\n // FIXME: revise if these *can* become ratios of rangeStep\n minSize: 9, // Point size is area. For square point, 9 = 3 pixel ^ 2, not too small!\n\n minStrokeWidth: 1,\n maxStrokeWidth: 4\n};\n\nexport interface SchemeParams {\n /**\n * A color scheme name for sequential/ordinal scales (e.g., `\"category10\"` or `\"viridis\"`).\n *\n * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference.\n */\n name: string;\n\n /**\n * For sequential and diverging schemes only, determines the extent of the color range to use. For example `[0.2, 1]` will rescale the color scheme such that color values in the range _[0, 0.2)_ are excluded from the scheme.\n */\n extent?: number[];\n\n /**\n * The number of colors to use in the scheme. This can be useful for scale types such as `\"quantize\"`, which use the length of the scale range to determine the number of discrete bins for the scale domain.\n *\n * @hide\n */\n count?: number;\n}\n\nexport type SelectionDomain = {\n /**\n * The name of a selection.\n */\n selection: string,\n /**\n * The field name to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html)\n * over multiple fields or encodings.\n */\n field?: string\n} | {\n /**\n * The name of a selection.\n */\n selection: string,\n /**\n * The encoding channel to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html)\n * over multiple fields or encodings.\n */\n encoding?: string\n};\n\nexport type Domain = number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain;\nexport type Scheme = string | SchemeParams;\n\nexport type Range = number[] | string[] | string;\n\nexport function isExtendedScheme(scheme: string | SchemeParams): scheme is SchemeParams {\n return scheme && !!scheme['name'];\n}\n\nexport function isSelectionDomain(domain: Domain): domain is SelectionDomain {\n return domain && domain['selection'];\n}\n\nexport interface Scale {\n /**\n * The type of scale. Vega-Lite supports the following categories of scale types:\n *\n * 1) [**Continuous Scales**](https://vega.github.io/vega-lite/docs/scale.html#continuous) -- mapping continuous domains to continuous output ranges ([`\"linear\"`](https://vega.github.io/vega-lite/docs/scale.html#linear), [`\"pow\"`](https://vega.github.io/vega-lite/docs/scale.html#pow), [`\"sqrt\"`](https://vega.github.io/vega-lite/docs/scale.html#sqrt), [`\"log\"`](https://vega.github.io/vega-lite/docs/scale.html#log), [`\"time\"`](https://vega.github.io/vega-lite/docs/scale.html#time), [`\"utc\"`](https://vega.github.io/vega-lite/docs/scale.html#utc), [`\"sequential\"`](https://vega.github.io/vega-lite/docs/scale.html#sequential)).\n *\n * 2) [**Discrete Scales**](https://vega.github.io/vega-lite/docs/scale.html#discrete) -- mapping discrete domains to discrete ([`\"ordinal\"`](https://vega.github.io/vega-lite/docs/scale.html#ordinal)) or continuous ([`\"band\"`](https://vega.github.io/vega-lite/docs/scale.html#band) and [`\"point\"`](https://vega.github.io/vega-lite/docs/scale.html#point)) output ranges.\n *\n * 3) [**Discretizing Scales**](https://vega.github.io/vega-lite/docs/scale.html#discretizing) -- mapping continuous domains to discrete output ranges ([`\"bin-linear\"`](https://vega.github.io/vega-lite/docs/scale.html#bin-linear) and [`\"bin-ordinal\"`](https://vega.github.io/vega-lite/docs/scale.html#bin-ordinal)).\n *\n * __Default value:__ please see the [scale type table](https://vega.github.io/vega-lite/docs/scale.html#type).\n */\n type?: ScaleType;\n\n /**\n * Customized domain values.\n *\n * For _quantitative_ fields, `domain` can take the form of a two-element array with minimum and maximum values. [Piecewise scales](https://vega.github.io/vega-lite/docs/scale.html#piecewise) can be created by providing a `domain` with more than two entries.\n * If the input field is aggregated, `domain` can also be a string value `\"unaggregated\"`, indicating that the domain should include the raw data values prior to the aggregation.\n *\n * For _temporal_ fields, `domain` can be a two-element array minimum and maximum values, in the form of either timestamps or the [DateTime definition objects](https://vega.github.io/vega-lite/docs/types.html#datetime).\n *\n * For _ordinal_ and _nominal_ fields, `domain` can be an array that lists valid input values.\n *\n * The `selection` property can be used to [interactively determine](https://vega.github.io/vega-lite/docs/selection.html#scale-domains) the scale domain.\n */\n domain?: number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain;\n\n\n // Hide because we might not really need this.\n /**\n * If true, reverses the order of the scale range.\n * __Default value:__ `false`.\n *\n * @hide\n */\n reverse?: boolean;\n\n /**\n * The range of the scale. One of:\n *\n * - A string indicating a [pre-defined named scale range](https://vega.github.io/vega-lite/docs/scale.html#range-config) (e.g., example, `\"symbol\"`, or `\"diverging\"`).\n *\n * - For [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous), two-element array indicating minimum and maximum values, or an array with more than two entries for specifying a [piecewise scale](https://vega.github.io/vega-lite/docs/scale.html#piecewise).\n *\n * - For [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) and [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales, an array of desired output values.\n *\n * __Notes:__\n *\n * 1) For [sequential](https://vega.github.io/vega-lite/docs/scale.html#sequential), [ordinal](https://vega.github.io/vega-lite/docs/scale.html#ordinal), and discretizing color scales, you can also specify a color [`scheme`](https://vega.github.io/vega-lite/docs/scale.html#scheme) instead of `range`.\n *\n * 2) Any directly specified `range` for `x` and `y` channels will be ignored. Range can be customized via the view's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` and `height`) or via [range steps and paddings properties](#range-step) for [band](#band) and [point](#point) scales.\n */\n range?: number[] | string[] | string;\n\n // ordinal\n /**\n * The distance between the starts of adjacent bands or points in [band](https://vega.github.io/vega-lite/docs/scale.html#band) and [point](https://vega.github.io/vega-lite/docs/scale.html#point) scales.\n *\n * If `rangeStep` is `null` or if the view contains the scale's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` for `x` scales and `height` for `y` scales), `rangeStep` will be automatically determined to fit the size of the view.\n *\n * __Default value:__ derived the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `textXRangeStep` (`90` by default) for x-scales of `text` marks and `rangeStep` (`21` by default) for x-scales of other marks and y-scales.\n *\n * __Warning__: If `rangeStep` is `null` and the cardinality of the scale's domain is higher than `width` or `height`, the rangeStep might become less than one pixel and the mark might not appear correctly.\n *\n * @minimum 0\n */\n rangeStep?: number | null;\n\n /**\n * A string indicating a color [scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme) name (e.g., `\"category10\"` or `\"viridis\"`) or a [scheme parameter object](https://vega.github.io/vega-lite/docs/scale.html#scheme-params).\n *\n * Discrete color schemes may be used with [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) or [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales. Continuous color schemes are intended for use with [sequential](https://vega.github.io/vega-lite/docs/scales.html#sequential) scales.\n *\n * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference.\n */\n scheme?: string | SchemeParams;\n\n /**\n * If `true`, rounds numeric output values to integers. This can be helpful for snapping to the pixel grid.\n *\n * __Default value:__ `false`.\n */\n round?: boolean;\n\n /**\n * For _[continuous](https://vega.github.io/vega-lite/docs/scale.html#continuous)_ scales, expands the scale domain to accommodate the specified number of pixels on each of the scale range. The scale range must represent pixels for this parameter to function as intended. Padding adjustment is performed prior to all other adjustments, including the effects of the zero, nice, domainMin, and domainMax properties.\n *\n * For _[band](https://vega.github.io/vega-lite/docs/scale.html#band)_ scales, shortcut for setting `paddingInner` and `paddingOuter` to the same value.\n *\n * For _[point](https://vega.github.io/vega-lite/docs/scale.html#point)_ scales, alias for `paddingOuter`.\n *\n * __Default value:__ For _continuous_ scales, derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `continuousPadding`.\n * For _band and point_ scales, see `paddingInner` and `paddingOuter`.\n *\n * @minimum 0\n */\n padding?: number;\n\n /**\n * The inner padding (spacing) within each band step of band scales, as a fraction of the step size. This value must lie in the range [0,1].\n *\n * For point scale, this property is invalid as point scales do not have internal band widths (only step sizes between bands).\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingInner`.\n *\n * @minimum 0\n * @maximum 1\n */\n paddingInner?: number;\n\n /**\n * The outer padding (spacing) at the ends of the range of band and point scales,\n * as a fraction of the step size. This value must lie in the range [0,1].\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingOuter` for band scales and `pointPadding` for point scales.\n *\n * @minimum 0\n * @maximum 1\n */\n paddingOuter?: number;\n\n // typical\n /**\n * If `true`, values that exceed the data domain are clamped to either the minimum or maximum range value\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `clamp` (`true` by default).\n */\n clamp?: boolean;\n\n /**\n * Extending the domain so that it starts and ends on nice round values. This method typically modifies the scale’s domain, and may only extend the bounds to the nearest round value. Nicing is useful if the domain is computed from data and may be irregular. For example, for a domain of _[0.201479…, 0.996679…]_, a nice domain might be _[0.2, 1.0]_.\n *\n * For quantitative scales such as linear, `nice` can be either a boolean flag or a number. If `nice` is a number, it will represent a desired tick count. This allows greater control over the step size used to extend the bounds, guaranteeing that the returned ticks will exactly cover the domain.\n *\n * For temporal fields with time and utc scales, the `nice` value can be a string indicating the desired time interval. Legal values are `\"millisecond\"`, `\"second\"`, `\"minute\"`, `\"hour\"`, `\"day\"`, `\"week\"`, `\"month\"`, and `\"year\"`. Alternatively, `time` and `utc` scales can accept an object-valued interval specifier of the form `{\"interval\": \"month\", \"step\": 3}`, which includes a desired number of interval steps. Here, the domain would snap to quarter (Jan, Apr, Jul, Oct) boundaries.\n *\n * __Default value:__ `true` for unbinned _quantitative_ fields; `false` otherwise.\n *\n */\n nice?: boolean | number | NiceTime | {interval: string, step: number};\n\n /**\n * The logarithm base of the `log` scale (default `10`).\n */\n base?: number;\n\n /**\n * The exponent of the `pow` scale.\n */\n exponent?: number;\n\n /**\n * If `true`, ensures that a zero baseline value is included in the scale domain.\n *\n * __Default value:__ `true` for x and y channels if the quantitative field is not binned and no custom `domain` is provided; `false` otherwise.\n *\n * __Note:__ Log, time, and utc scales do not support `zero`.\n */\n zero?: boolean;\n\n /**\n * The interpolation method for range values. By default, a general interpolator for numbers, dates, strings and colors (in RGB space) is used. For color ranges, this property allows interpolation in alternative color spaces. Legal values include `rgb`, `hsl`, `hsl-long`, `lab`, `hcl`, `hcl-long`, `cubehelix` and `cubehelix-long` ('-long' variants use longer paths in polar coordinate spaces). If object-valued, this property accepts an object with a string-valued _type_ property and an optional numeric _gamma_ property applicable to rgb and cubehelix interpolators. For more, see the [d3-interpolate documentation](https://github.com/d3/d3-interpolate).\n *\n * __Note:__ Sequential scales do not support `interpolate` as they have a fixed interpolator. Since Vega-Lite uses sequential scales for quantitative fields by default, you have to set the scale `type` to other quantitative scale type such as `\"linear\"` to customize `interpolate`.\n */\n interpolate?: ScaleInterpolate | ScaleInterpolateParams;\n}\n\nconst SCALE_PROPERTY_INDEX: Flag = {\n type: 1,\n domain: 1,\n range: 1,\n rangeStep: 1,\n scheme: 1,\n // Other properties\n reverse: 1,\n round: 1,\n // quantitative / time\n clamp: 1,\n nice: 1,\n // quantitative\n base: 1,\n exponent: 1,\n interpolate: 1,\n zero: 1, // zero depends on domain\n // band/point\n padding: 1,\n paddingInner: 1,\n paddingOuter: 1\n};\n\nexport const SCALE_PROPERTIES = flagKeys(SCALE_PROPERTY_INDEX);\n\nconst {type, domain, range, rangeStep, scheme, ...NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX} = SCALE_PROPERTY_INDEX;\n\nexport const NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES = flagKeys(NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX);\n\nexport const SCALE_TYPE_INDEX = generateScaleTypeIndex();\n\nexport function scaleTypeSupportProperty(scaleType: ScaleType, propName: keyof Scale) {\n switch (propName) {\n case 'type':\n case 'domain':\n case 'reverse':\n case 'range':\n return true;\n case 'scheme':\n return contains(['sequential', 'ordinal', 'bin-ordinal', 'quantile', 'quantize'], scaleType);\n case 'interpolate':\n // FIXME(https://github.com/vega/vega-lite/issues/2902) how about ordinal?\n return contains(['linear', 'bin-linear', 'pow', 'log', 'sqrt', 'utc', 'time'], scaleType);\n case 'round':\n return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point';\n case 'padding':\n return isContinuousToContinuous(scaleType) || contains(['point', 'band'], scaleType);\n case 'paddingOuter':\n case 'rangeStep':\n return contains(['point', 'band'], scaleType);\n case 'paddingInner':\n return scaleType === 'band';\n case 'clamp':\n return isContinuousToContinuous(scaleType) || scaleType === 'sequential';\n case 'nice':\n return isContinuousToContinuous(scaleType) || scaleType === 'sequential' || scaleType as any === 'quantize';\n case 'exponent':\n return scaleType === 'pow';\n case 'base':\n return scaleType === 'log';\n case 'zero':\n return hasContinuousDomain(scaleType) && !contains([\n 'log', // log scale cannot have zero value\n 'time', 'utc', // zero is not meaningful for time\n 'bin-linear', // binning should not automatically add zero\n 'threshold', // threshold requires custom domain so zero does not matter\n 'quantile' // quantile depends on distribution so zero does not matter\n ], scaleType);\n }\n /* istanbul ignore next: should never reach here*/\n throw new Error(`Invalid scale property ${propName}.`);\n}\n\n/**\n * Returns undefined if the input channel supports the input scale property name\n */\nexport function channelScalePropertyIncompatability(channel: Channel, propName: keyof Scale): string {\n switch (propName) {\n case 'interpolate':\n case 'scheme':\n if (!isColorChannel(channel)) {\n return log.message.cannotUseScalePropertyWithNonColor(channel);\n }\n return undefined;\n case 'type':\n case 'domain':\n case 'range':\n case 'base':\n case 'exponent':\n case 'nice':\n case 'padding':\n case 'paddingInner':\n case 'paddingOuter':\n case 'rangeStep':\n case 'reverse':\n case 'round':\n case 'clamp':\n case 'zero':\n return undefined; // GOOD!\n }\n /* istanbul ignore next: it should never reach here */\n throw new Error(`Invalid scale property \"${propName}\".`);\n}\n\nexport function scaleTypeSupportDataType(specifiedType: ScaleType, fieldDefType: Type, bin: boolean|BinParams):boolean {\n if (contains([Type.ORDINAL, Type.NOMINAL], fieldDefType)) {\n return specifiedType === undefined || hasDiscreteDomain(specifiedType);\n } else if (fieldDefType === Type.TEMPORAL) {\n return contains([ScaleType.TIME, ScaleType.UTC, ScaleType.SEQUENTIAL, undefined], specifiedType);\n } else if (fieldDefType === Type.QUANTITATIVE) {\n if (bin) {\n return contains([ScaleType.BIN_LINEAR, ScaleType.BIN_ORDINAL, ScaleType.LINEAR], specifiedType);\n }\n return contains([ScaleType.LOG, ScaleType.POW, ScaleType.SQRT, ScaleType.QUANTILE, ScaleType.QUANTIZE, ScaleType.LINEAR, ScaleType.SEQUENTIAL, undefined], specifiedType);\n }\n\n return true;\n}\n\nexport function channelSupportScaleType(channel: Channel, scaleType: ScaleType): boolean {\n switch (channel) {\n case Channel.X:\n case Channel.Y:\n case Channel.SIZE: // TODO: size and opacity can support ordinal with more modification\n case Channel.OPACITY:\n // Although it generally doesn't make sense to use band with size and opacity,\n // it can also work since we use band: 0.5 to get midpoint.\n return isContinuousToContinuous(scaleType) || contains(['band', 'point'], scaleType);\n\n case Channel.COLOR:\n case Channel.FILL:\n case Channel.STROKE:\n return scaleType !== 'band'; // band does not make sense with color\n\n case Channel.SHAPE:\n return scaleType === 'ordinal'; // shape = lookup only\n }\n /* istanbul ignore next: it should never reach here */\n return false;\n}\n\nexport function getSupportedScaleType(channel: Channel, fieldDefType: Type, bin?: boolean) {\n return SCALE_TYPE_INDEX[generateScaleTypeIndexKey(channel, fieldDefType, bin)];\n}\n\nexport interface ScaleTypeIndex {\n [channel: string]: ScaleType[];\n}\n\n// generates ScaleTypeIndex where keys are encoding channels and values are list of valid ScaleTypes\nfunction generateScaleTypeIndex() {\n const index: ScaleTypeIndex = {};\n for (const channel of CHANNELS) {\n for (const fieldDefType of keys(TYPE_INDEX)) {\n for (const scaleType of SCALE_TYPES) {\n for (const bin of [false, true]) {\n const key = generateScaleTypeIndexKey(channel, fieldDefType, bin);\n if (channelSupportScaleType(channel, scaleType) && scaleTypeSupportDataType(scaleType, fieldDefType, bin)) {\n index[key] = index[key] || [];\n index[key].push(scaleType);\n }\n }\n }\n }\n }\n return index;\n}\n\nfunction generateScaleTypeIndexKey(channel: Channel, fieldDefType: Type, bin: boolean) {\n const key = channel + '_' + fieldDefType;\n return bin ? key + '_bin' : key;\n}\n","import {SingleDefChannel} from './channel';\nimport {VgBinding, VgEventStream} from './vega.schema';\n\nexport const SELECTION_ID = '_vgsid_';\nexport type SelectionType = 'single' | 'multi' | 'interval';\nexport type SelectionResolution = 'global' | 'union' | 'intersect';\n\nexport interface BaseSelectionDef {\n /**\n * A [Vega event stream](https://vega.github.io/vega/docs/event-streams/) (object or selector) that triggers the selection.\n * For interval selections, the event stream must specify a [start and end](https://vega.github.io/vega/docs/event-streams/#between-filters).\n */\n on?: VgEventStream;\n /**\n * With layered and multi-view displays, a strategy that determines how\n * selections' data queries are resolved when applied in a filter transform,\n * conditional encoding rule, or scale domain.\n *\n */\n resolve?: SelectionResolution;\n\n // TODO(https://github.com/vega/vega-lite/issues/2596).\n // predicate?: string;\n // domain?: SelectionDomain;\n\n // Transforms\n\n /**\n * An array of encoding channels. The corresponding data field values\n * must match for a data tuple to fall within the selection.\n */\n encodings?: SingleDefChannel[];\n\n /**\n * An array of field names whose values must match for a data tuple to\n * fall within the selection.\n */\n fields?: string[];\n\n /**\n * By default, all data values are considered to lie within an empty selection.\n * When set to `none`, empty selections contain no data values.\n */\n empty?: 'all' | 'none';\n}\n\nexport interface SingleSelectionConfig extends BaseSelectionDef {\n /**\n * Establish a two-way binding between a single selection and input elements\n * (also known as dynamic query widgets). A binding takes the form of\n * Vega's [input element binding definition](https://vega.github.io/vega/docs/signals/#bind)\n * or can be a mapping between projected field/encodings and binding definitions.\n *\n * See the [bind transform](https://vega.github.io/vega-lite/docs/bind.html) documentation for more information.\n */\n bind?: VgBinding | {[key: string]: VgBinding};\n\n /**\n * When true, an invisible voronoi diagram is computed to accelerate discrete\n * selection. The data value _nearest_ the mouse cursor is added to the selection.\n *\n * See the [nearest transform](https://vega.github.io/vega-lite/docs/nearest.html) documentation for more information.\n */\n nearest?: boolean;\n}\n\nexport interface MultiSelectionConfig extends BaseSelectionDef {\n /**\n * Controls whether data values should be toggled or only ever inserted into\n * multi selections. Can be `true`, `false` (for insertion only), or a\n * [Vega expression](https://vega.github.io/vega/docs/expressions/).\n *\n * __Default value:__ `true`, which corresponds to `event.shiftKey` (i.e.,\n * data values are toggled when a user interacts with the shift-key pressed).\n *\n * See the [toggle transform](https://vega.github.io/vega-lite/docs/toggle.html) documentation for more information.\n */\n toggle?: string | boolean;\n\n /**\n * When true, an invisible voronoi diagram is computed to accelerate discrete\n * selection. The data value _nearest_ the mouse cursor is added to the selection.\n *\n * See the [nearest transform](https://vega.github.io/vega-lite/docs/nearest.html) documentation for more information.\n */\n nearest?: boolean;\n}\n\nexport interface BrushConfig {\n /**\n * The fill color of the interval mark.\n *\n * __Default value:__ `#333333`\n *\n */\n fill?: string;\n /**\n * The fill opacity of the interval mark (a value between 0 and 1).\n *\n * __Default value:__ `0.125`\n */\n fillOpacity?: number;\n /**\n * The stroke color of the interval mark.\n *\n * __Default value:__ `#ffffff`\n */\n stroke?: string;\n /**\n * The stroke opacity of the interval mark (a value between 0 and 1).\n */\n strokeOpacity?: number;\n /**\n * The stroke width of the interval mark.\n */\n strokeWidth?: number;\n /**\n * An array of alternating stroke and space lengths,\n * for creating dashed or dotted lines.\n */\n strokeDash?: number[];\n /**\n * The offset (in pixels) with which to begin drawing the stroke dash array.\n */\n strokeDashOffset?: number;\n}\n\nexport interface IntervalSelectionConfig extends BaseSelectionDef {\n /**\n * When truthy, allows a user to interactively move an interval selection\n * back-and-forth. Can be `true`, `false` (to disable panning), or a\n * [Vega event stream definition](https://vega.github.io/vega/docs/event-streams/)\n * which must include a start and end event to trigger continuous panning.\n *\n * __Default value:__ `true`, which corresponds to\n * `[mousedown, window:mouseup] > window:mousemove!` which corresponds to\n * clicks and dragging within an interval selection to reposition it.\n */\n translate?: string | boolean;\n\n /**\n * When truthy, allows a user to interactively resize an interval selection.\n * Can be `true`, `false` (to disable zooming), or a [Vega event stream\n * definition](https://vega.github.io/vega/docs/event-streams/). Currently,\n * only `wheel` events are supported.\n *\n *\n * __Default value:__ `true`, which corresponds to `wheel!`.\n */\n zoom?: string | boolean;\n\n /**\n * Establishes a two-way binding between the interval selection and the scales\n * used within the same view. This allows a user to interactively pan and\n * zoom the view.\n */\n bind?: 'scales';\n\n /**\n * An interval selection also adds a rectangle mark to depict the\n * extents of the interval. The `mark` property can be used to customize the\n * appearance of the mark.\n */\n mark?: BrushConfig;\n}\n\nexport interface SingleSelection extends SingleSelectionConfig {\n type: 'single';\n}\n\nexport interface MultiSelection extends MultiSelectionConfig {\n type: 'multi';\n}\n\nexport interface IntervalSelection extends IntervalSelectionConfig {\n type: 'interval';\n}\n\nexport type SelectionDef = SingleSelection | MultiSelection | IntervalSelection;\n\nexport interface SelectionConfig {\n /**\n * The default definition for a [`single`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations\n * for a single selection definition (except `type`) may be specified here.\n *\n * For instance, setting `single` to `{\"on\": \"dblclick\"}` populates single selections on double-click by default.\n */\n single?: SingleSelectionConfig;\n /**\n * The default definition for a [`multi`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations\n * for a multi selection definition (except `type`) may be specified here.\n *\n * For instance, setting `multi` to `{\"toggle\": \"event.altKey\"}` adds additional values to\n * multi selections when clicking with the alt-key pressed by default.\n */\n multi?: MultiSelectionConfig;\n /**\n * The default definition for an [`interval`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations\n * for an interval selection definition (except `type`) may be specified here.\n *\n * For instance, setting `interval` to `{\"translate\": false}` disables the ability to move\n * interval selections by default.\n */\n interval?: IntervalSelectionConfig;\n}\n\nexport const defaultConfig:SelectionConfig = {\n single: {\n on: 'click',\n fields: [SELECTION_ID],\n resolve: 'global',\n empty: 'all'\n },\n multi: {\n on: 'click',\n fields: [SELECTION_ID],\n toggle: 'event.shiftKey',\n resolve: 'global',\n empty: 'all'\n },\n interval: {\n on: '[mousedown, window:mouseup] > window:mousemove!',\n encodings: ['x', 'y'],\n translate: '[mousedown, window:mouseup] > window:mousemove!',\n zoom: 'wheel!',\n mark: {fill: '#333', fillOpacity: 0.125, stroke: 'white'},\n resolve: 'global'\n }\n};\n","import {Anchor, TitleOrient, VgMarkConfig, VgTitleConfig} from './vega.schema';\n\nexport interface TitleBase {\n /**\n * The orientation of the title relative to the chart. One of `\"top\"` (the default), `\"bottom\"`, `\"left\"`, or `\"right\"`.\n */\n orient?: TitleOrient;\n\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"`, or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n *\n * __Default value:__ `\"middle\"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views.\n * `\"start\"` for other composite views.\n *\n * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `\"start\"`.\n */\n anchor?: Anchor;\n\n /**\n * The orthogonal offset in pixels by which to displace the title from its position along the edge of the chart.\n */\n offset?: number;\n\n /**\n * A [mark style property](https://vega.github.io/vega-lite/docs/config.html#style) to apply to the title text mark.\n *\n * __Default value:__ `\"group-title\"`.\n */\n style?: string | string[];\n\n // TODO: name, encode, interactive, zindex\n}\n\nexport interface TitleParams extends TitleBase {\n /**\n * The title text.\n */\n text: string;\n}\n\nexport function extractTitleConfig(titleConfig: VgTitleConfig): {\n mark: VgMarkConfig,\n nonMark: TitleBase\n} {\n const {\n // These are non-mark title config that need to be hardcoded\n anchor, offset, orient,\n // color needs to be redirect to fill\n color,\n // The rest are mark config.\n ...titleMarkConfig\n } = titleConfig;\n\n const mark: VgMarkConfig = {\n ...titleMarkConfig,\n ...color ? {fill: color} : {}\n };\n\n const nonMark: TitleBase = {\n ...anchor ? {anchor} : {},\n ...offset ? {offset} : {},\n ...orient ? {orient} : {}\n };\n\n return {mark, nonMark};\n}\n","import {isObject} from 'vega-util';\nimport {AxisConfigMixins} from './axis';\nimport {COMPOSITE_MARK_STYLES} from './compositemark';\nimport {CompositeMarkConfigMixins, CompositeMarkStyle, VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX} from './compositemark/index';\nimport {VL_ONLY_GUIDE_CONFIG} from './guide';\nimport {HeaderConfig} from './header';\nimport {defaultLegendConfig, LegendConfig} from './legend';\nimport * as mark from './mark';\nimport {Mark, MarkConfigMixins, PRIMITIVE_MARKS, VL_ONLY_MARK_CONFIG_PROPERTIES, VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX} from './mark';\nimport {ProjectionConfig} from './projection';\nimport {defaultScaleConfig, ScaleConfig} from './scale';\nimport {defaultConfig as defaultSelectionConfig, SelectionConfig} from './selection';\nimport {StackOffset} from './stack';\nimport {extractTitleConfig} from './title';\nimport {TopLevelProperties} from './toplevelprops';\nimport {duplicate, keys, mergeDeep} from './util';\nimport {StrokeJoin, VgMarkConfig, VgScheme, VgTitleConfig} from './vega.schema';\n\n\nexport interface ViewConfig {\n /**\n * The default width of the single plot or each plot in a trellis plot when the visualization has a continuous (non-ordinal) x-scale or ordinal x-scale with `rangeStep` = `null`.\n *\n * __Default value:__ `200`\n *\n */\n width?: number;\n\n /**\n * The default height of the single plot or each plot in a trellis plot when the visualization has a continuous (non-ordinal) y-scale with `rangeStep` = `null`.\n *\n * __Default value:__ `200`\n *\n */\n height?: number;\n\n /**\n * Whether the view should be clipped.\n */\n clip?: boolean;\n\n // FILL_STROKE_CONFIG\n /**\n * The fill color.\n *\n * __Default value:__ (none)\n *\n */\n fill?: string;\n\n /**\n * The fill opacity (value between [0,1]).\n *\n * __Default value:__ (none)\n *\n */\n fillOpacity?: number;\n\n /**\n * The stroke color.\n *\n * __Default value:__ (none)\n *\n */\n stroke?: string;\n\n /**\n * The stroke opacity (value between [0,1]).\n *\n * __Default value:__ (none)\n *\n */\n strokeOpacity?: number;\n\n /**\n * The stroke width, in pixels.\n *\n * __Default value:__ (none)\n *\n */\n strokeWidth?: number;\n\n /**\n * An array of alternating stroke, space lengths for creating dashed or dotted lines.\n *\n * __Default value:__ (none)\n *\n */\n strokeDash?: number[];\n\n /**\n * The offset (in pixels) into which to begin drawing with the stroke dash array.\n *\n * __Default value:__ (none)\n *\n */\n strokeDashOffset?: number;\n\n /**\n * The stroke line join method. One of miter (default), round or bevel.\n *\n * __Default value:__ 'miter'\n *\n */\n strokeJoin?: StrokeJoin;\n\n /**\n * The stroke line join method. One of miter (default), round or bevel.\n *\n * __Default value:__ 'miter'\n *\n */\n strokeMiterLimit?: number;\n}\n\nexport const defaultViewConfig: ViewConfig = {\n width: 200,\n height: 200\n};\n\nexport type RangeConfigValue = (number|string)[] | VgScheme | {step: number};\n\nexport type RangeConfig = RangeConfigProps & {[name: string]: RangeConfigValue};\n\nexport interface RangeConfigProps {\n /**\n * Default range for _nominal_ (categorical) fields.\n */\n category?: string[] | VgScheme;\n\n /**\n * Default range for diverging _quantitative_ fields.\n */\n diverging?: string[] | VgScheme;\n\n /**\n * Default range for _quantitative_ heatmaps.\n */\n heatmap?: string[] | VgScheme;\n\n /**\n * Default range for _ordinal_ fields.\n */\n ordinal?: string[] | VgScheme;\n\n /**\n * Default range for _quantitative_ and _temporal_ fields.\n */\n ramp?: string[] | VgScheme;\n\n /**\n * Default range palette for the `shape` channel.\n */\n symbol?: string[];\n}\n\nexport interface VLOnlyConfig {\n /**\n * Default axis and legend title for count fields.\n *\n * __Default value:__ `'Number of Records'`.\n *\n * @type {string}\n */\n countTitle?: string;\n\n /**\n * Defines how Vega-Lite should handle invalid values (`null` and `NaN`).\n * - If set to `\"filter\"` (default), all data items with null values will be skipped (for line, trail, and area marks) or filtered (for other marks).\n * - If `null`, all data items are included. In this case, invalid values will be interpreted as zeroes.\n */\n invalidValues?: 'filter' | null;\n\n /**\n * Defines how Vega-Lite generates title for fields. There are three possible styles:\n * - `\"verbal\"` (Default) - displays function in a verbal style (e.g., \"Sum of field\", \"Year-month of date\", \"field (binned)\").\n * - `\"function\"` - displays function using parentheses and capitalized texts (e.g., \"SUM(field)\", \"YEARMONTH(date)\", \"BIN(field)\").\n * - `\"plain\"` - displays only the field name without functions (e.g., \"field\", \"date\", \"field\").\n */\n fieldTitle?: 'verbal' | 'functional' | 'plain';\n\n /**\n * D3 Number format for axis labels and text tables. For example \"s\" for SI units. Use [D3's number format pattern](https://github.com/d3/d3-format#locale_format).\n */\n numberFormat?: string;\n\n /**\n * Default datetime format for axis and legend labels. The format can be set directly on each axis and legend. Use [D3's time format pattern](https://github.com/d3/d3-time-format#locale_format).\n *\n * __Default value:__ `''` (The format will be automatically determined).\n *\n */\n timeFormat?: string;\n\n\n /** Default properties for [single view plots](https://vega.github.io/vega-lite/docs/spec.html#single). */\n view?: ViewConfig;\n\n /**\n * Scale configuration determines default properties for all [scales](https://vega.github.io/vega-lite/docs/scale.html). For a full list of scale configuration options, please see the [corresponding section of the scale documentation](https://vega.github.io/vega-lite/docs/scale.html#config).\n */\n scale?: ScaleConfig;\n\n /** An object hash for defining default properties for each type of selections. */\n selection?: SelectionConfig;\n\n /** Default stack offset for stackable mark. */\n stack?: StackOffset;\n}\n\nexport interface StyleConfigIndex {\n [style: string]: VgMarkConfig;\n}\n\n\nexport interface Config extends TopLevelProperties, VLOnlyConfig, MarkConfigMixins, CompositeMarkConfigMixins, AxisConfigMixins {\n\n /**\n * An object hash that defines default range arrays or schemes for using with scales.\n * For a full list of scale range configuration options, please see the [corresponding section of the scale documentation](https://vega.github.io/vega-lite/docs/scale.html#config).\n */\n range?: RangeConfig;\n\n /**\n * Legend configuration, which determines default properties for all [legends](https://vega.github.io/vega-lite/docs/legend.html). For a full list of legend configuration options, please see the [corresponding section of in the legend documentation](https://vega.github.io/vega-lite/docs/legend.html#config).\n */\n legend?: LegendConfig;\n\n /**\n * Header configuration, which determines default properties for all [header](https://vega.github.io/vega-lite/docs/header.html). For a full list of header configuration options, please see the [corresponding section of in the header documentation](https://vega.github.io/vega-lite/docs/header.html#config).\n */\n header?: HeaderConfig;\n\n /**\n * Title configuration, which determines default properties for all [titles](https://vega.github.io/vega-lite/docs/title.html). For a full list of title configuration options, please see the [corresponding section of the title documentation](https://vega.github.io/vega-lite/docs/title.html#config).\n */\n title?: VgTitleConfig;\n\n /**\n * Projection configuration, which determines default properties for all [projections](https://vega.github.io/vega-lite/docs/projection.html). For a full list of projection configuration options, please see the [corresponding section of the projection documentation](https://vega.github.io/vega-lite/docs/projection.html#config).\n */\n projection?: ProjectionConfig;\n\n /** An object hash that defines key-value mappings to determine default properties for marks with a given [style](https://vega.github.io/vega-lite/docs/mark.html#mark-def). The keys represent styles names; the values have to be valid [mark configuration objects](https://vega.github.io/vega-lite/docs/mark.html#config). */\n style?: StyleConfigIndex;\n}\n\nexport const defaultConfig: Config = {\n padding: 5,\n timeFormat: '',\n countTitle: 'Number of Records',\n\n invalidValues: 'filter',\n\n view: defaultViewConfig,\n\n mark: mark.defaultMarkConfig,\n area: {},\n bar: mark.defaultBarConfig,\n circle: {},\n geoshape: {},\n line: {},\n point: {},\n rect: {},\n rule: {color: 'black'}, // Need this to override default color in mark config\n square: {},\n text: {color: 'black'}, // Need this to override default color in mark config\n tick: mark.defaultTickConfig,\n trail: {},\n\n box: {size: 14, extent: 1.5},\n boxWhisker: {},\n boxMid: {color: 'white'},\n\n scale: defaultScaleConfig,\n projection: {},\n axis: {},\n axisX: {},\n axisY: {minExtent: 30},\n axisLeft: {},\n axisRight: {},\n axisTop: {},\n axisBottom: {},\n axisBand: {},\n legend: defaultLegendConfig,\n\n selection: defaultSelectionConfig,\n style: {},\n\n title: {},\n};\n\nexport function initConfig(config: Config) {\n return mergeDeep(duplicate(defaultConfig), config);\n}\n\nconst MARK_STYLES = ['view'].concat(PRIMITIVE_MARKS, COMPOSITE_MARK_STYLES) as ('view' | Mark | CompositeMarkStyle)[];\n\n\nconst VL_ONLY_CONFIG_PROPERTIES: (keyof Config)[] = [\n 'padding', 'numberFormat', 'timeFormat', 'countTitle',\n 'stack', 'scale', 'selection', 'invalidValues',\n 'overlay' as keyof Config // FIXME: Redesign and unhide this\n];\n\nconst VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = {\n view: ['width', 'height'],\n ...VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX,\n ...VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX\n};\n\nexport function stripAndRedirectConfig(config: Config) {\n config = duplicate(config);\n\n for (const prop of VL_ONLY_CONFIG_PROPERTIES) {\n delete config[prop];\n }\n\n // Remove Vega-Lite only axis/legend config\n if (config.axis) {\n for (const prop of VL_ONLY_GUIDE_CONFIG) {\n delete config.axis[prop];\n }\n }\n if (config.legend) {\n for (const prop of VL_ONLY_GUIDE_CONFIG) {\n delete config.legend[prop];\n }\n }\n\n // Remove Vega-Lite only generic mark config\n if (config.mark) {\n for (const prop of VL_ONLY_MARK_CONFIG_PROPERTIES) {\n delete config.mark[prop];\n }\n }\n\n for (const markType of MARK_STYLES) {\n // Remove Vega-Lite-only mark config\n for (const prop of VL_ONLY_MARK_CONFIG_PROPERTIES) {\n delete config[markType][prop];\n }\n\n // Remove Vega-Lite only mark-specific config\n const vlOnlyMarkSpecificConfigs = VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX[markType];\n if (vlOnlyMarkSpecificConfigs) {\n for (const prop of vlOnlyMarkSpecificConfigs) {\n delete config[markType][prop];\n }\n }\n\n // Redirect mark config to config.style so that mark config only affect its own mark type\n // without affecting other marks that share the same underlying Vega marks.\n // For example, config.rect should not affect bar marks.\n redirectConfig(config, markType);\n }\n\n // Redirect config.title -- so that title config do not\n // affect header labels, which also uses `title` directive to implement.\n redirectConfig(config, 'title', 'group-title');\n\n // Remove empty config objects\n for (const prop in config) {\n if (isObject(config[prop]) && keys(config[prop]).length === 0) {\n delete config[prop];\n }\n }\n\n return keys(config).length > 0 ? config : undefined;\n}\n\nfunction redirectConfig(config: Config, prop: Mark | CompositeMarkStyle | 'title' | 'view', toProp?: string) {\n const propConfig: VgMarkConfig = prop === 'title' ? extractTitleConfig(config.title).mark : config[prop];\n\n if (prop === 'view') {\n toProp = 'cell'; // View's default style is \"cell\"\n }\n\n const style: VgMarkConfig = {\n ...propConfig,\n ...config.style[prop]\n };\n // set config.style if it is not an empty object\n if (keys(style).length > 0) {\n config.style[toProp || prop] = style;\n }\n delete config[prop];\n}\n","import {isArray} from 'vega-util';\nimport {SUM_OPS} from './aggregate';\nimport {NONPOSITION_CHANNELS, NonPositionChannel, X, X2, Y2} from './channel';\nimport {channelHasField, Encoding} from './encoding';\nimport {Field, FieldDef, getFieldDef, isFieldDef, isStringFieldDef, PositionFieldDef, vgField} from './fielddef';\nimport * as log from './log';\nimport {AREA, BAR, CIRCLE, isMarkDef, isPathMark, LINE, Mark, MarkDef, POINT, RULE, SQUARE, TEXT, TICK} from './mark';\nimport {ScaleType} from './scale';\nimport {contains, Flag} from './util';\n\n\nexport type StackOffset = 'zero' | 'center' | 'normalize';\n\nconst STACK_OFFSET_INDEX: Flag = {\n zero: 1,\n center: 1,\n normalize: 1\n};\n\nexport function isStackOffset(s: string): s is StackOffset {\n return !!STACK_OFFSET_INDEX[s];\n}\n\nexport interface StackProperties {\n /** Dimension axis of the stack. */\n groupbyChannel: 'x' | 'y';\n\n /** Measure axis of the stack. */\n fieldChannel: 'x' | 'y';\n\n /** Stack-by fields e.g., color, detail */\n stackBy: {\n fieldDef: FieldDef,\n channel: NonPositionChannel\n }[];\n\n /**\n * See `\"stack\"` property of Position Field Def.\n */\n offset: StackOffset;\n\n /**\n * Whether this stack will produce impute transform\n */\n impute: boolean;\n}\n\nexport const STACKABLE_MARKS = [BAR, AREA, RULE, POINT, CIRCLE, SQUARE, LINE, TEXT, TICK];\nexport const STACK_BY_DEFAULT_MARKS = [BAR, AREA];\n\n\nfunction potentialStackedChannel(encoding: Encoding): 'x' | 'y' | undefined {\n const xDef = encoding.x;\n const yDef = encoding.y;\n\n if (isFieldDef(xDef) && isFieldDef(yDef)) {\n if (xDef.type === 'quantitative' && yDef.type === 'quantitative') {\n if (xDef.stack) {\n return 'x';\n } else if (yDef.stack) {\n return 'y';\n }\n // if there is no explicit stacking, only apply stack if there is only one aggregate for x or y\n if ((!!xDef.aggregate) !== (!!yDef.aggregate)) {\n return xDef.aggregate ? 'x' : 'y';\n }\n } else if (xDef.type === 'quantitative') {\n return 'x';\n } else if (yDef.type === 'quantitative') {\n return 'y';\n }\n } else if (isFieldDef(xDef) && xDef.type === 'quantitative') {\n return 'x';\n } else if (isFieldDef(yDef) && yDef.type === 'quantitative') {\n return 'y';\n }\n return undefined;\n}\n\n// Note: CompassQL uses this method and only pass in required properties of each argument object.\n// If required properties change, make sure to update CompassQL.\nexport function stack(m: Mark | MarkDef, encoding: Encoding, stackConfig: StackOffset): StackProperties {\n const mark = isMarkDef(m) ? m.type : m;\n // Should have stackable mark\n if (!contains(STACKABLE_MARKS, mark)) {\n return null;\n }\n\n const fieldChannel = potentialStackedChannel(encoding);\n if (!fieldChannel) {\n return null;\n }\n\n const stackedFieldDef = encoding[fieldChannel] as PositionFieldDef;\n const stackedField = isStringFieldDef(stackedFieldDef) ? vgField(stackedFieldDef, {}) : undefined;\n\n const dimensionChannel = fieldChannel === 'x' ? 'y' : 'x';\n const dimensionDef = encoding[dimensionChannel];\n const dimensionField = isStringFieldDef(dimensionDef) ? vgField(dimensionDef, {}) : undefined;\n\n // Should have grouping level of detail that is different from the dimension field\n const stackBy = NONPOSITION_CHANNELS.reduce((sc, channel) => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((cDef) => {\n const fieldDef = getFieldDef(cDef);\n if (fieldDef.aggregate) {\n return;\n }\n\n // Check whether the channel's field is identical to x/y's field or if the channel is a repeat\n const f = isStringFieldDef(fieldDef) ? vgField(fieldDef, {}) : undefined;\n if (\n // if fielddef is a repeat, just include it in the stack by\n !f ||\n // otherwise, the field must be different from x and y fields.\n (f !== dimensionField && f !== stackedField)\n ) {\n sc.push({channel, fieldDef});\n }\n });\n }\n return sc;\n }, []);\n\n if (stackBy.length === 0) {\n return null;\n }\n\n // Automatically determine offset\n let offset: StackOffset = undefined;\n if (stackedFieldDef.stack !== undefined) {\n offset = stackedFieldDef.stack;\n } else if (contains(STACK_BY_DEFAULT_MARKS, mark)) {\n // Bar and Area with sum ops are automatically stacked by default\n offset = stackConfig === undefined ? 'zero' : stackConfig;\n } else {\n offset = stackConfig;\n }\n\n if (!offset || !isStackOffset(offset)) {\n return null;\n }\n\n // warn when stacking non-linear\n if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== ScaleType.LINEAR) {\n log.warn(log.message.cannotStackNonLinearScale(stackedFieldDef.scale.type));\n }\n\n // Check if it is a ranged mark\n if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) {\n if (stackedFieldDef.stack !== undefined) {\n log.warn(log.message.cannotStackRangedMark(fieldChannel));\n }\n return null;\n }\n\n // Warn if stacking summative aggregate\n if (stackedFieldDef.aggregate && !contains(SUM_OPS, stackedFieldDef.aggregate)) {\n log.warn(log.message.stackNonSummativeAggregate(stackedFieldDef.aggregate));\n }\n\n return {\n groupbyChannel: dimensionDef ? dimensionChannel : undefined,\n fieldChannel,\n impute: isPathMark(mark),\n stackBy,\n offset\n };\n}\n","import {isObject} from 'vega-util';\nimport {COLUMN, ROW, X, X2, Y, Y2} from './channel';\nimport * as compositeMark from './compositemark';\nimport {Config} from './config';\nimport {Data} from './data';\nimport * as vlEncoding from './encoding';\nimport {channelHasField, Encoding, EncodingWithFacet, isRanged} from './encoding';\nimport {FacetMapping} from './facet';\nimport {Field, FieldDef, RepeatRef} from './fielddef';\nimport * as log from './log';\nimport {AnyMark, AreaConfig, isMarkDef, isPathMark, isPrimitiveMark, LineConfig, Mark, MarkConfig, MarkDef} from './mark';\nimport {Projection} from './projection';\nimport {Repeat} from './repeat';\nimport {Resolve} from './resolve';\nimport {SelectionDef} from './selection';\nimport {stack} from './stack';\nimport {TitleParams} from './title';\nimport {ConcatLayout, GenericCompositionLayout, TopLevelProperties} from './toplevelprops';\nimport {Transform} from './transform';\nimport {Dict, duplicate, hash, keys, omit, pick, vals} from './util';\n\n\nexport type TopLevel = S & TopLevelProperties & {\n /**\n * URL to [JSON schema](http://json-schema.org/) for a Vega-Lite specification. Unless you have a reason to change this, use `https://vega.github.io/schema/vega-lite/v2.json`. Setting the `$schema` property allows automatic validation and autocomplete in editors that support JSON schema.\n * @format uri\n */\n $schema?: string;\n\n /**\n * Vega-Lite configuration object. This property can only be defined at the top-level of a specification.\n */\n config?: Config;\n};\n\nexport type BaseSpec = Partial & {\n /**\n * Title for the plot.\n */\n title?: string | TitleParams;\n\n /**\n * Name of the visualization for later reference.\n */\n name?: string;\n\n /**\n * Description of this mark for commenting purpose.\n */\n description?: string;\n\n /**\n * An object describing the data source\n */\n data?: Data;\n\n /**\n * An array of data transformations such as filter and new field calculation.\n */\n transform?: Transform[];\n};\n\nexport type DataMixins = {\n /**\n * An object describing the data source\n */\n data: Data;\n};\n\n\n// TODO(https://github.com/vega/vega-lite/issues/2503): Make this generic so we can support some form of top-down sizing.\nexport interface LayoutSizeMixins {\n /**\n * The width of a visualization.\n *\n * __Default value:__ This will be determined by the following rules:\n *\n * - If a view's [`autosize`](https://vega.github.io/vega-lite/docs/size.html#autosize) type is `\"fit\"` or its x-channel has a [continuous scale](https://vega.github.io/vega-lite/docs/scale.html#continuous), the width will be the value of [`config.view.width`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - For x-axis with a band or point scale: if [`rangeStep`](https://vega.github.io/vega-lite/docs/scale.html#band) is a numeric value or unspecified, the width is [determined by the range step, paddings, and the cardinality of the field mapped to x-channel](https://vega.github.io/vega-lite/docs/scale.html#band). Otherwise, if the `rangeStep` is `null`, the width will be the value of [`config.view.width`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - If no field is mapped to `x` channel, the `width` will be the value of [`config.scale.textXRangeStep`](https://vega.github.io/vega-lite/docs/size.html#default-width-and-height) for `text` mark and the value of `rangeStep` for other marks.\n *\n * __Note:__ For plots with [`row` and `column` channels](https://vega.github.io/vega-lite/docs/encoding.html#facet), this represents the width of a single view.\n *\n * __See also:__ The documentation for [width and height](https://vega.github.io/vega-lite/docs/size.html) contains more examples.\n */\n width?: number;\n\n /**\n * The height of a visualization.\n *\n * __Default value:__\n * - If a view's [`autosize`](https://vega.github.io/vega-lite/docs/size.html#autosize) type is `\"fit\"` or its y-channel has a [continuous scale](https://vega.github.io/vega-lite/docs/scale.html#continuous), the height will be the value of [`config.view.height`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - For y-axis with a band or point scale: if [`rangeStep`](https://vega.github.io/vega-lite/docs/scale.html#band) is a numeric value or unspecified, the height is [determined by the range step, paddings, and the cardinality of the field mapped to y-channel](https://vega.github.io/vega-lite/docs/scale.html#band). Otherwise, if the `rangeStep` is `null`, the height will be the value of [`config.view.height`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - If no field is mapped to `y` channel, the `height` will be the value of `rangeStep`.\n *\n * __Note__: For plots with [`row` and `column` channels](https://vega.github.io/vega-lite/docs/encoding.html#facet), this represents the height of a single view.\n *\n * __See also:__ The documentation for [width and height](https://vega.github.io/vega-lite/docs/size.html) contains more examples.\n */\n height?: number;\n}\n\nexport interface GenericUnitSpec, M> extends BaseSpec, LayoutSizeMixins {\n\n /**\n * A string describing the mark type (one of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"rule\"`, `\"geoshape\"`, and `\"text\"`) or a [mark definition object](https://vega.github.io/vega-lite/docs/mark.html#mark-def).\n */\n mark: M;\n\n /**\n * A key-value mapping between encoding channels and definition of fields.\n */\n encoding?: E;\n\n\n /**\n * An object defining properties of geographic projection, which will be applied to `shape` path for `\"geoshape\"` marks\n * and to `latitude` and `\"longitude\"` channels for other marks.\n */\n projection?: Projection;\n\n /**\n * A key-value mapping between selection names and definitions.\n */\n selection?: {[name: string]: SelectionDef};\n}\n\nexport type NormalizedUnitSpec = GenericUnitSpec, Mark | MarkDef>;\n\n/**\n * Unit spec that can have a composite mark.\n */\nexport type CompositeUnitSpec = GenericUnitSpec, AnyMark>;\n\n/**\n * Unit spec that can have a composite mark and row or column channels.\n */\nexport type FacetedCompositeUnitSpec = GenericUnitSpec, AnyMark>;\n\nexport interface GenericLayerSpec> extends BaseSpec, LayoutSizeMixins {\n /**\n * Layer or single view specifications to be layered.\n *\n * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as layering facet specifications is not allowed.\n */\n layer: (GenericLayerSpec | U)[];\n\n /**\n * Scale, axis, and legend resolutions for layers.\n */\n resolve?: Resolve;\n}\n\n/**\n * Layer Spec with encoding and projection\n */\nexport interface ExtendedLayerSpec extends GenericLayerSpec {\n /**\n * A shared key-value mapping between encoding channels and definition of fields in the underlying layers.\n */\n encoding?: Encoding;\n\n\n /**\n * An object defining properties of the geographic projection shared by underlying layers.\n */\n projection?: Projection;\n}\n\nexport type NormalizedLayerSpec = GenericLayerSpec;\n\n\nexport interface GenericFacetSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n > extends BaseSpec, GenericCompositionLayout {\n /**\n * An object that describes mappings between `row` and `column` channels and their field definitions.\n */\n facet: FacetMapping;\n\n /**\n * A specification of the view that gets faceted.\n */\n spec: L | U;\n // TODO: replace this with GenericSpec once we support all cases;\n\n /**\n * Scale, axis, and legend resolutions for facets.\n */\n resolve?: Resolve;\n}\n\nexport type NormalizedFacetSpec = GenericFacetSpec;\n\nexport interface GenericRepeatSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> extends BaseSpec, GenericCompositionLayout {\n /**\n * An object that describes what fields should be repeated into views that are laid out as a `row` or `column`.\n */\n repeat: Repeat;\n\n spec: GenericSpec;\n\n /**\n * Scale and legend resolutions for repeated charts.\n */\n resolve?: Resolve;\n}\n\nexport type NormalizedRepeatSpec = GenericRepeatSpec;\n\nexport interface GenericVConcatSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> extends BaseSpec, ConcatLayout {\n /**\n * A list of views that should be concatenated and put into a column.\n */\n vconcat: (GenericSpec)[];\n\n /**\n * Scale, axis, and legend resolutions for vertically concatenated charts.\n */\n resolve?: Resolve;\n}\n\nexport interface GenericHConcatSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> extends BaseSpec, ConcatLayout {\n /**\n * A list of views that should be concatenated and put into a row.\n */\n hconcat: (GenericSpec)[];\n\n /**\n * Scale, axis, and legend resolutions for horizontally concatenated charts.\n */\n resolve?: Resolve;\n}\n\nexport type NormalizedConcatSpec =\n GenericVConcatSpec | GenericHConcatSpec;\n\nexport type GenericSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> = U | L | GenericFacetSpec | GenericRepeatSpec |\n GenericVConcatSpec |GenericHConcatSpec;\n\nexport type NormalizedSpec = GenericSpec;\n\nexport type TopLevelFacetedUnitSpec = TopLevel & DataMixins;\nexport type TopLevelFacetSpec = TopLevel> & DataMixins;\n\nexport type TopLevelSpec = TopLevelFacetedUnitSpec | TopLevelFacetSpec | TopLevel |\nTopLevel> | TopLevel> | TopLevel>;\n\n/* Custom type guards */\n\n\nexport function isFacetSpec(spec: BaseSpec): spec is GenericFacetSpec {\n return spec['facet'] !== undefined;\n}\n\nexport function isUnitSpec(spec: BaseSpec): spec is FacetedCompositeUnitSpec | NormalizedUnitSpec {\n return !!spec['mark'];\n}\n\nexport function isLayerSpec(spec: BaseSpec): spec is GenericLayerSpec {\n return spec['layer'] !== undefined;\n}\n\nexport function isRepeatSpec(spec: BaseSpec): spec is GenericRepeatSpec {\n return spec['repeat'] !== undefined;\n}\n\nexport function isConcatSpec(spec: BaseSpec):\n spec is GenericVConcatSpec |\n GenericHConcatSpec {\n return isVConcatSpec(spec) || isHConcatSpec(spec);\n}\n\nexport function isVConcatSpec(spec: BaseSpec): spec is GenericVConcatSpec {\n return spec['vconcat'] !== undefined;\n}\n\nexport function isHConcatSpec(spec: BaseSpec): spec is GenericHConcatSpec {\n return spec['hconcat'] !== undefined;\n}\n\n/**\n * Decompose extended unit specs into composition of pure unit specs.\n */\n// TODO: consider moving this to another file. Maybe vl.spec.normalize or vl.normalize\nexport function normalize(spec: TopLevelSpec | GenericSpec | FacetedCompositeUnitSpec, config: Config): NormalizedSpec {\n if (isFacetSpec(spec)) {\n return normalizeFacet(spec, config);\n }\n if (isLayerSpec(spec)) {\n return normalizeLayer(spec, config);\n }\n if (isRepeatSpec(spec)) {\n return normalizeRepeat(spec, config);\n }\n if (isVConcatSpec(spec)) {\n return normalizeVConcat(spec, config);\n }\n if (isHConcatSpec(spec)) {\n return normalizeHConcat(spec, config);\n }\n if (isUnitSpec(spec)) {\n const hasRow = channelHasField(spec.encoding, ROW);\n const hasColumn = channelHasField(spec.encoding, COLUMN);\n\n if (hasRow || hasColumn) {\n return normalizeFacetedUnit(spec, config);\n }\n return normalizeNonFacetUnit(spec, config);\n }\n throw new Error(log.message.INVALID_SPEC);\n}\n\nfunction normalizeFacet(spec: GenericFacetSpec, config: Config): NormalizedFacetSpec {\n const {spec: subspec, ...rest} = spec;\n return {\n ...rest,\n // TODO: remove \"any\" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760\n spec: normalize(subspec, config) as any\n };\n}\n\nfunction mergeEncoding(opt: {parentEncoding: Encoding, encoding: Encoding}): Encoding {\n const {parentEncoding, encoding} = opt;\n if (parentEncoding && encoding) {\n const overriden = keys(parentEncoding).reduce((o, key) => {\n if (encoding[key]) {\n o.push(key);\n }\n return o;\n }, []);\n\n if (overriden.length > 0) {\n log.warn(log.message.encodingOverridden(overriden));\n }\n }\n\n const merged = {\n ...(parentEncoding || {}),\n ...(encoding || {})\n };\n return keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeProjection(opt: {parentProjection: Projection, projection: Projection}) {\n const {parentProjection, projection} = opt;\n if (parentProjection && projection) {\n log.warn(log.message.projectionOverridden({parentProjection, projection}));\n }\n return projection || parentProjection;\n}\n\nfunction normalizeLayer(\n spec: ExtendedLayerSpec,\n config: Config,\n parentEncoding?: Encoding,\n parentProjection?: Projection\n): NormalizedLayerSpec {\n const {layer, encoding, projection, ...rest} = spec;\n const mergedEncoding = mergeEncoding({parentEncoding, encoding});\n const mergedProjection = mergeProjection({parentProjection, projection});\n return {\n ...rest,\n layer: layer.map((subspec) => {\n if (isLayerSpec(subspec)) {\n return normalizeLayer(subspec, config, mergedEncoding, mergedProjection);\n }\n return normalizeNonFacetUnit(subspec, config, mergedEncoding, mergedProjection);\n })\n };\n}\n\nfunction normalizeRepeat(spec: GenericRepeatSpec, config: Config): NormalizedRepeatSpec {\n const {spec: subspec, ...rest} = spec;\n return {\n ...rest,\n spec: normalize(subspec, config)\n };\n}\n\nfunction normalizeVConcat(spec: GenericVConcatSpec, config: Config): NormalizedConcatSpec {\n const {vconcat: vconcat, ...rest} = spec;\n return {\n ...rest,\n vconcat: vconcat.map((subspec) => normalize(subspec, config))\n };\n}\n\nfunction normalizeHConcat(spec: GenericHConcatSpec, config: Config): NormalizedConcatSpec {\n const {hconcat: hconcat, ...rest} = spec;\n return {\n ...rest,\n hconcat: hconcat.map((subspec) => normalize(subspec, config))\n };\n}\n\nfunction normalizeFacetedUnit(spec: FacetedCompositeUnitSpec, config: Config): NormalizedFacetSpec {\n // New encoding in the inside spec should not contain row / column\n // as row/column should be moved to facet\n const {row: row, column: column, ...encoding} = spec.encoding;\n\n // Mark and encoding should be moved into the inner spec\n const {mark, width, projection, height, selection, encoding: _, ...outerSpec} = spec;\n\n return {\n ...outerSpec,\n facet: {\n ...(row ? {row} : {}),\n ...(column ? {column}: {}),\n },\n spec: normalizeNonFacetUnit({\n ...(projection ? {projection} : {}),\n mark,\n ...(width ? {width} : {}),\n ...(height ? {height} : {}),\n encoding,\n ...(selection ? {selection} : {})\n }, config)\n };\n}\n\nfunction isNonFacetUnitSpecWithPrimitiveMark(spec: GenericUnitSpec, AnyMark>):\n spec is GenericUnitSpec, Mark> {\n return isPrimitiveMark(spec.mark);\n}\n\nfunction getPointOverlay(markDef: MarkDef, markConfig: LineConfig, encoding: Encoding): MarkConfig {\n if (markDef.point === 'transparent') {\n return {opacity: 0};\n } else if (markDef.point) { // truthy : true or object\n return isObject(markDef.point) ? markDef.point : {};\n } else if (markDef.point !== undefined) { // false or null\n return null;\n } else { // undefined (not disabled)\n if (markConfig.point || encoding.shape) {\n // enable point overlay if config[mark].point is truthy or if encoding.shape is provided\n return isObject(markConfig.point) ? markConfig.point : {};\n }\n // markDef.point is defined as falsy\n return null;\n }\n}\n\nfunction getLineOverlay(markDef: MarkDef, markConfig: AreaConfig): MarkConfig {\n if (markDef.line) { // true or object\n return markDef.line === true ? {} : markDef.line;\n } else if (markDef.line !== undefined) { // false or null\n return null;\n } else { // undefined (not disabled)\n if (markConfig.line) {\n // enable line overlay if config[mark].line is truthy\n return markConfig.line === true ? {} : markConfig.line;\n }\n // markDef.point is defined as falsy\n return null;\n }\n}\n\nfunction normalizeNonFacetUnit(\n spec: GenericUnitSpec, AnyMark>, config: Config,\n parentEncoding?: Encoding, parentProjection?: Projection\n): NormalizedUnitSpec | NormalizedLayerSpec {\n const {encoding, projection} = spec;\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n\n\n // merge parent encoding / projection first\n if (parentEncoding || parentProjection) {\n const mergedProjection = mergeProjection({parentProjection, projection});\n const mergedEncoding = mergeEncoding({parentEncoding, encoding});\n return normalizeNonFacetUnit({\n ...spec,\n ...(mergedProjection ? {projection: mergedProjection} : {}),\n ...(mergedEncoding ? {encoding: mergedEncoding} : {}),\n }, config);\n }\n\n if (isNonFacetUnitSpecWithPrimitiveMark(spec)) {\n // TODO: thoroughly test\n if (isRanged(encoding)) {\n return normalizeRangedUnit(spec);\n }\n\n if (mark === 'line' && (encoding.x2 || encoding.y2)) {\n log.warn(log.message.lineWithRange(!!encoding.x2, !!encoding.y2));\n\n return normalizeNonFacetUnit({\n mark: 'rule',\n ...spec\n }, config, parentEncoding, parentProjection);\n }\n\n if (isPathMark(mark)) {\n return normalizePathOverlay(spec, config);\n }\n\n return spec; // Nothing to normalize\n } else {\n return compositeMark.normalize(spec, config);\n }\n}\n\nfunction normalizeRangedUnit(spec: NormalizedUnitSpec) {\n const hasX = channelHasField(spec.encoding, X);\n const hasY = channelHasField(spec.encoding, Y);\n const hasX2 = channelHasField(spec.encoding, X2);\n const hasY2 = channelHasField(spec.encoding, Y2);\n if ((hasX2 && !hasX) || (hasY2 && !hasY)) {\n const normalizedSpec = duplicate(spec);\n if (hasX2 && !hasX) {\n normalizedSpec.encoding.x = normalizedSpec.encoding.x2;\n delete normalizedSpec.encoding.x2;\n }\n if (hasY2 && !hasY) {\n normalizedSpec.encoding.y = normalizedSpec.encoding.y2;\n delete normalizedSpec.encoding.y2;\n }\n\n return normalizedSpec;\n }\n return spec;\n}\n\nfunction dropLineAndPoint(markDef: MarkDef): MarkDef | Mark {\n const {point: _point, line: _line, ...mark} = markDef;\n\n return keys(mark).length > 1 ? mark : mark.type;\n}\n\nfunction normalizePathOverlay(spec: NormalizedUnitSpec, config: Config = {}): NormalizedLayerSpec | NormalizedUnitSpec {\n\n // _ is used to denote a dropped property of the unit spec\n // which should not be carried over to the layer spec\n const {selection, projection, encoding, mark, ...outerSpec} = spec;\n const markDef = isMarkDef(mark) ? mark : {type: mark};\n\n const pointOverlay = getPointOverlay(markDef, config[markDef.type], encoding);\n const lineOverlay = markDef.type === 'area' && getLineOverlay(markDef, config[markDef.type]);\n\n if (!pointOverlay && !lineOverlay) {\n return {\n ...spec,\n // Do not include point / line overlay in the normalize spec\n mark: dropLineAndPoint(markDef)\n };\n }\n\n const layer: NormalizedUnitSpec[] = [{\n ...(selection ? {selection} : {}),\n // Do not include point / line overlay in the normalize spec\n mark: dropLineAndPoint({\n ...markDef,\n // make area mark translucent by default\n // TODO: extract this 0.7 to be shared with default opacity for point/tick/...\n ...(markDef.type === 'area' ? {opacity: 0.7} : {}),\n }),\n // drop shape from encoding as this might be used to trigger point overlay\n encoding: omit(encoding, ['shape'])\n }];\n\n // FIXME: determine rules for applying selections.\n\n // Need to copy stack config to overlayed layer\n const stackProps = stack(markDef, encoding, config ? config.stack : undefined);\n\n let overlayEncoding = encoding;\n if (stackProps) {\n const {fieldChannel: stackFieldChannel, offset} = stackProps;\n overlayEncoding = {\n ...encoding,\n [stackFieldChannel]: {\n ...encoding[stackFieldChannel],\n ...(offset ? {stack: offset} : {})\n }\n };\n }\n\n if (lineOverlay) {\n layer.push({\n ...(projection ? {projection} : {}),\n mark: {\n type: 'line',\n ...pick(markDef, ['clip', 'interpolate']),\n ...lineOverlay\n },\n encoding: overlayEncoding\n });\n }\n if (pointOverlay) {\n layer.push({\n ...(projection ? {projection} : {}),\n mark: {\n type: 'point',\n opacity: 1,\n filled: true,\n ...pick(markDef, ['clip']),\n ...pointOverlay\n },\n encoding: overlayEncoding\n });\n }\n\n return {\n ...outerSpec,\n layer\n };\n}\n\n// TODO: add vl.spec.validate & move stuff from vl.validate to here\n\n/* Accumulate non-duplicate fieldDefs in a dictionary */\nfunction accumulate(dict: any, defs: FieldDef[]): any {\n defs.forEach(function(fieldDef) {\n // Consider only pure fieldDef properties (ignoring scale, axis, legend)\n const pureFieldDef = ['field', 'type', 'value', 'timeUnit', 'bin', 'aggregate'].reduce((f, key) => {\n if (fieldDef[key] !== undefined) {\n f[key] = fieldDef[key];\n }\n return f;\n }, {});\n const key = hash(pureFieldDef);\n dict[key] = dict[key] || fieldDef;\n });\n return dict;\n}\n\n/* Recursively get fieldDefs from a spec, returns a dictionary of fieldDefs */\nfunction fieldDefIndex(spec: GenericSpec, dict: Dict> = {}): Dict> {\n // FIXME(https://github.com/vega/vega-lite/issues/2207): Support fieldDefIndex for repeat\n if (isLayerSpec(spec)) {\n spec.layer.forEach(layer => {\n if (isUnitSpec(layer)) {\n accumulate(dict, vlEncoding.fieldDefs(layer.encoding));\n } else {\n fieldDefIndex(layer, dict);\n }\n });\n } else if (isFacetSpec(spec)) {\n accumulate(dict, vlEncoding.fieldDefs(spec.facet));\n fieldDefIndex(spec.spec, dict);\n } else if (isRepeatSpec(spec)) {\n fieldDefIndex(spec.spec, dict);\n } else if (isConcatSpec(spec)) {\n const childSpec = isVConcatSpec(spec) ? spec.vconcat : spec.hconcat;\n childSpec.forEach(child => fieldDefIndex(child, dict));\n } else { // Unit Spec\n accumulate(dict, vlEncoding.fieldDefs(spec.encoding));\n }\n return dict;\n}\n\n/* Returns all non-duplicate fieldDefs in a spec in a flat array */\nexport function fieldDefs(spec: GenericSpec): FieldDef[] {\n return vals(fieldDefIndex(spec));\n}\n\nexport function isStacked(spec: TopLevel, config?: Config): boolean {\n config = config || spec.config;\n if (isPrimitiveMark(spec.mark)) {\n return stack(spec.mark, spec.encoding,\n config ? config.stack : undefined\n ) !== null;\n }\n return false;\n}\n","import {isString} from 'vega-util';\n\nimport {InlineDataset} from './data';\nimport * as log from './log';\nimport {Dict} from './util';\nimport {RowCol, VgLayoutAlign} from './vega.schema';\n\n/**\n * @minimum 0\n */\nexport type Padding = number | {top?: number, bottom?: number, left?: number, right?: number};\n\nexport type Datasets = Dict;\n\nexport interface TopLevelProperties {\n /**\n * CSS color property to use as the background of visualization.\n *\n * __Default value:__ none (transparent)\n */\n background?: string;\n\n /**\n * The default visualization padding, in pixels, from the edge of the visualization canvas to the data rectangle. If a number, specifies padding for all sides.\n * If an object, the value should have the format `{\"left\": 5, \"top\": 5, \"right\": 5, \"bottom\": 5}` to specify padding for each side of the visualization.\n *\n * __Default value__: `5`\n */\n padding?: Padding;\n\n /**\n * Sets how the visualization size should be determined. If a string, should be one of `\"pad\"`, `\"fit\"` or `\"none\"`.\n * Object values can additionally specify parameters for content sizing and automatic resizing.\n * `\"fit\"` is only supported for single and layered views that don't use `rangeStep`.\n *\n * __Default value__: `pad`\n */\n autosize?: AutosizeType | AutoSizeParams;\n\n /**\n * A global data store for named datasets. This is a mapping from names to inline datasets.\n * This can be an array of objects or primitive values or a string. Arrays of primitive values are ingested as objects with a `data` property.\n */\n datasets?: Datasets;\n}\n\nexport interface BoundsMixins {\n /**\n * The bounds calculation method to use for determining the extent of a sub-plot. One of `full` (the default) or `flush`.\n *\n * - If set to `full`, the entire calculated bounds (including axes, title, and legend) will be used.\n * - If set to `flush`, only the specified width and height values for the sub-view will be used. The `flush` setting can be useful when attempting to place sub-plots without axes or legends into a uniform grid structure.\n *\n * __Default value:__ `\"full\"`\n */\n\n bounds?: 'full' | 'flush';\n}\n\n/**\n * Base layout mixins for V/HConcatSpec.\n * Concat layout should not have RowCol generic fo its property.\n */\nexport interface ConcatLayout extends BoundsMixins {\n /**\n * Boolean flag indicating if subviews should be centered relative to their respective rows or columns.\n *\n * __Default value:__ `false`\n */\n center?: boolean;\n\n /**\n * The spacing in pixels between sub-views of the concat operator.\n *\n * __Default value__: `10`\n */\n spacing?: number;\n}\n\n/**\n * Base layout for FacetSpec and RepeatSpec.\n * This is named \"GenericComposition\" layout as ConcatLayout is a GenericCompositionLayout too\n * (but _not_ vice versa).\n */\nexport interface GenericCompositionLayout extends BoundsMixins {\n /**\n * The alignment to apply to grid rows and columns.\n * The supported string values are `\"all\"`, `\"each\"`, and `\"none\"`.\n *\n * - For `\"none\"`, a flow layout will be used, in which adjacent subviews are simply placed one after the other.\n * - For `\"each\"`, subviews will be aligned into a clean grid structure, but each row or column may be of variable size.\n * - For `\"all\"`, subviews will be aligned and each row or column will be sized identically based on the maximum observed size. String values for this property will be applied to both grid rows and columns.\n *\n * Alternatively, an object value of the form `{\"row\": string, \"column\": string}` can be used to supply different alignments for rows and columns.\n *\n * __Default value:__ `\"all\"`.\n */\n align?: VgLayoutAlign | RowCol;\n\n /**\n * Boolean flag indicating if subviews should be centered relative to their respective rows or columns.\n *\n * An object value of the form `{\"row\": boolean, \"column\": boolean}` can be used to supply different centering values for rows and columns.\n *\n * __Default value:__ `false`\n */\n center?: boolean | RowCol;\n\n /**\n * The spacing in pixels between sub-views of the composition operator.\n * An object of the form `{\"row\": number, \"column\": number}` can be used to set\n * different spacing values for rows and columns.\n *\n * __Default value__: `10`\n */\n spacing?: number | RowCol;\n}\n\nexport function extractCompositionLayout(layout: GenericCompositionLayout): GenericCompositionLayout {\n const {align = undefined, center = undefined, bounds = undefined, spacing = undefined} = layout || {};\n return {align, bounds, center, spacing};\n}\n\nexport type AutosizeType = 'pad' | 'fit' | 'none';\n\nexport interface AutoSizeParams {\n /**\n * The sizing format type. One of `\"pad\"`, `\"fit\"` or `\"none\"`. See the [autosize type](https://vega.github.io/vega-lite/docs/size.html#autosize) documentation for descriptions of each.\n *\n * __Default value__: `\"pad\"`\n */\n type?: AutosizeType;\n\n /**\n * A boolean flag indicating if autosize layout should be re-calculated on every view update.\n *\n * __Default value__: `false`\n */\n resize?: boolean;\n\n /**\n * Determines how size calculation should be performed, one of `\"content\"` or `\"padding\"`. The default setting (`\"content\"`) interprets the width and height settings as the data rectangle (plotting) dimensions, to which padding is then added. In contrast, the `\"padding\"` setting includes the padding within the view size calculations, such that the width and height settings indicate the **total** intended size of the view.\n *\n * __Default value__: `\"content\"`\n */\n contains?: 'content' | 'padding';\n}\n\nfunction _normalizeAutoSize(autosize: AutosizeType | AutoSizeParams) {\n return isString(autosize) ? {type: autosize} : autosize || {};\n}\n\nexport function normalizeAutoSize(topLevelAutosize: AutosizeType | AutoSizeParams, configAutosize: AutosizeType | AutoSizeParams, isUnitOrLayer: boolean = true): AutoSizeParams {\n const autosize: AutoSizeParams = {\n type: 'pad',\n ..._normalizeAutoSize(configAutosize),\n ..._normalizeAutoSize(topLevelAutosize)\n };\n\n if (autosize.type === 'fit') {\n if (!isUnitOrLayer) {\n log.warn(log.message.FIT_NON_SINGLE);\n autosize.type = 'pad';\n }\n }\n\n return autosize;\n}\n\nconst TOP_LEVEL_PROPERTIES: (keyof TopLevelProperties)[] = [\n 'background', 'padding', 'datasets'\n // We do not include \"autosize\" here as it is supported by only unit and layer specs and thus need to be normalized\n];\n\nexport function extractTopLevelProperties(t: T) {\n return TOP_LEVEL_PROPERTIES.reduce((o, p) => {\n if (t && t[p] !== undefined) {\n o[p] = t[p];\n }\n return o;\n }, {});\n}\n","/*\n * Constants and utilities for data.\n */\nimport {VgData} from './vega.schema';\n\nexport interface Parse {\n [field: string]: null | string | 'string' | 'boolean' | 'date' | 'number';\n}\n\nexport interface DataFormatBase {\n /**\n * If set to `\"auto\"` (the default), perform automatic type inference to determine the desired data types.\n * If set to `null`, disable type inference based on the spec and only use type inference based on the data.\n * Alternatively, a parsing directive object can be provided for explicit data types. Each property of the object corresponds to a field name, and the value to the desired data type (one of `\"number\"`, `\"boolean\"`, `\"date\"`, or null (do not parse the field)).\n * For example, `\"parse\": {\"modified_on\": \"date\"}` parses the `modified_on` field in each input record a Date value.\n *\n * For `\"date\"`, we parse data based using Javascript's [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).\n * For Specific date formats can be provided (e.g., `{foo: 'date:\"%m%d%Y\"'}`), using the [d3-time-format syntax](https://github.com/d3/d3-time-format#locale_format). UTC date format parsing is supported similarly (e.g., `{foo: 'utc:\"%m%d%Y\"'}`). See more about [UTC time](https://vega.github.io/vega-lite/docs/timeunit.html#utc)\n */\n parse?: 'auto' | Parse | null;\n}\n\nexport interface CsvDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'csv' | 'tsv';\n}\n\nexport interface DsvDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'dsv';\n\n /**\n * The delimiter between records. The delimiter must be a single character (i.e., a single 16-bit code unit); so, ASCII delimiters are fine, but emoji delimiters are not.\n *\n * @minLength 1\n * @maxLength 1\n */\n delimiter: string;\n}\n\nexport interface JsonDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'json';\n /**\n * The JSON property containing the desired data.\n * This parameter can be used when the loaded JSON file may have surrounding structure or meta-data.\n * For example `\"property\": \"values.features\"` is equivalent to retrieving `json.values.features`\n * from the loaded JSON object.\n */\n property?: string;\n}\n\nexport interface TopoDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'topojson';\n /**\n * The name of the TopoJSON object set to convert to a GeoJSON feature collection.\n * For example, in a map of the world, there may be an object set named `\"countries\"`.\n * Using the feature property, we can extract this set and generate a GeoJSON feature object for each country.\n */\n feature?: string;\n /**\n * The name of the TopoJSON object set to convert to mesh.\n * Similar to the `feature` option, `mesh` extracts a named TopoJSON object set.\n * Unlike the `feature` option, the corresponding geo data is returned as a single, unified mesh instance, not as individual GeoJSON features.\n * Extracting a mesh is useful for more efficiently drawing borders or other geographic elements that you do not need to associate with specific regions such as individual countries, states or counties.\n */\n mesh?: string;\n}\n\nexport type DataFormat = CsvDataFormat | DsvDataFormat | JsonDataFormat | TopoDataFormat;\n\nexport type DataFormatType = 'json' | 'csv' | 'tsv' | 'dsv' | 'topojson';\n\nexport type Data = UrlData | InlineData | NamedData;\n\nexport type InlineDataset = number[] | string[] | boolean[] | object[] | string | object;\n\nexport interface DataBase {\n /**\n * An object that specifies the format for parsing the data.\n */\n format?: DataFormat;\n /**\n * Provide a placeholder name and bind data at runtime.\n */\n name?: string;\n}\n\nexport interface UrlData extends DataBase {\n /**\n * An URL from which to load the data set. Use the `format.type` property\n * to ensure the loaded data is correctly parsed.\n */\n url: string;\n}\n\nexport interface InlineData extends DataBase {\n /**\n * The full data set, included inline. This can be an array of objects or primitive values, an object, or a string.\n * Arrays of primitive values are ingested as objects with a `data` property. Strings are parsed according to the specified format type.\n */\n values: InlineDataset;\n}\n\nexport interface NamedData extends DataBase {\n /**\n * Provide a placeholder name and bind data at runtime.\n */\n name: string;\n}\n\nexport function isUrlData(data: Partial | Partial): data is UrlData {\n return !!data['url'];\n}\n\nexport function isInlineData(data: Partial | Partial): data is InlineData {\n return !!data['values'];\n}\n\nexport function isNamedData(data: Partial): data is NamedData {\n return !!data['name'] && !isUrlData(data) && !isInlineData(data);\n}\n\nexport type DataSourceType = 'raw' | 'main' | 'row' | 'column' | 'lookup';\n\nexport const MAIN: 'main' = 'main';\nexport const RAW: 'raw' = 'raw';\n","/**\n * Parse an event selector string.\n * Returns an array of event stream definitions.\n */\nexport default function(selector, source, marks) {\n DEFAULT_SOURCE = source || VIEW;\n MARKS = marks || DEFAULT_MARKS;\n return parseMerge(selector.trim()).map(parseSelector);\n}\n\nvar VIEW = 'view',\n LBRACK = '[',\n RBRACK = ']',\n LBRACE = '{',\n RBRACE = '}',\n COLON = ':',\n COMMA = ',',\n NAME = '@',\n GT = '>',\n ILLEGAL = /[[\\]{}]/,\n DEFAULT_SOURCE,\n MARKS,\n DEFAULT_MARKS = {\n '*': 1,\n arc: 1,\n area: 1,\n group: 1,\n image: 1,\n line: 1,\n path: 1,\n rect: 1,\n rule: 1,\n shape: 1,\n symbol: 1,\n text: 1,\n trail: 1\n };\n\nfunction isMarkType(type) {\n return MARKS.hasOwnProperty(type);\n}\n\nfunction find(s, i, endChar, pushChar, popChar) {\n var count = 0,\n n = s.length,\n c;\n for (; i= 0) --count;\n else if (pushChar && pushChar.indexOf(c) >= 0) ++count;\n }\n return i;\n}\n\nfunction parseMerge(s) {\n var output = [],\n start = 0,\n n = s.length,\n i = 0;\n\n while (i < n) {\n i = find(s, i, COMMA, LBRACK + LBRACE, RBRACK + RBRACE);\n output.push(s.substring(start, i).trim());\n start = ++i;\n }\n\n if (output.length === 0) {\n throw 'Empty event selector: ' + s;\n }\n return output;\n}\n\nfunction parseSelector(s) {\n return s[0] === '['\n ? parseBetween(s)\n : parseStream(s);\n}\n\nfunction parseBetween(s) {\n var n = s.length,\n i = 1,\n b, stream;\n\n i = find(s, i, RBRACK, LBRACK, RBRACK);\n if (i === n) {\n throw 'Empty between selector: ' + s;\n }\n\n b = parseMerge(s.substring(1, i));\n if (b.length !== 2) {\n throw 'Between selector must have two elements: ' + s;\n }\n\n s = s.slice(i + 1).trim();\n if (s[0] !== GT) {\n throw 'Expected \\'>\\' after between selector: ' + s;\n }\n\n b = b.map(parseSelector);\n\n stream = parseSelector(s.slice(1).trim());\n if (stream.between) {\n return {\n between: b,\n stream: stream\n };\n } else {\n stream.between = b;\n }\n\n return stream;\n}\n\nfunction parseStream(s) {\n var stream = {source: DEFAULT_SOURCE},\n source = [],\n throttle = [0, 0],\n markname = 0,\n start = 0,\n n = s.length,\n i = 0, j,\n filter;\n\n // extract throttle from end\n if (s[n-1] === RBRACE) {\n i = s.lastIndexOf(LBRACE);\n if (i >= 0) {\n try {\n throttle = parseThrottle(s.substring(i+1, n-1));\n } catch (e) {\n throw 'Invalid throttle specification: ' + s;\n }\n s = s.slice(0, i).trim();\n n = s.length;\n } else throw 'Unmatched right brace: ' + s;\n i = 0;\n }\n\n if (!n) throw s;\n\n // set name flag based on first char\n if (s[0] === NAME) markname = ++i;\n\n // extract first part of multi-part stream selector\n j = find(s, i, COLON);\n if (j < n) {\n source.push(s.substring(start, j).trim());\n start = i = ++j;\n }\n\n // extract remaining part of stream selector\n i = find(s, i, LBRACK);\n if (i === n) {\n source.push(s.substring(start, n).trim());\n } else {\n source.push(s.substring(start, i).trim());\n filter = [];\n start = ++i;\n if (start === n) throw 'Unmatched left bracket: ' + s;\n }\n\n // extract filters\n while (i < n) {\n i = find(s, i, RBRACK);\n if (i === n) throw 'Unmatched left bracket: ' + s;\n filter.push(s.substring(start, i).trim());\n if (i < n-1 && s[++i] !== LBRACK) throw 'Expected left bracket: ' + s;\n start = ++i;\n }\n\n // marshall event stream specification\n if (!(n = source.length) || ILLEGAL.test(source[n-1])) {\n throw 'Invalid event selector: ' + s;\n }\n\n if (n > 1) {\n stream.type = source[1];\n if (markname) {\n stream.markname = source[0].slice(1);\n } else if (isMarkType(source[0])) {\n stream.marktype = source[0];\n } else {\n stream.source = source[0];\n }\n } else {\n stream.type = source[0];\n }\n if (stream.type.slice(-1) === '!') {\n stream.consume = true;\n stream.type = stream.type.slice(0, -1)\n }\n if (filter != null) stream.filter = filter;\n if (throttle[0]) stream.throttle = throttle[0];\n if (throttle[1]) stream.debounce = throttle[1];\n\n return stream;\n}\n\nfunction parseThrottle(s) {\n var a = s.split(COMMA);\n if (!s.length || a.length > 2) throw s;\n return a.map(function(_) {\n var x = +_;\n if (x !== x) throw s;\n return x;\n });\n}\n","import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {BaseBin} from './bin';\nimport {NiceTime, ScaleType} from './scale';\nimport {SortOrder} from './sort';\nimport {StackOffset} from './stack';\nimport {WindowOnlyOp} from './transform';\nimport {Flag, flagKeys} from './util';\n\nexport interface VgData {\n name: string;\n source?: string;\n values?: any;\n format?: {\n type?: string;\n parse?: string | object;\n property?: string;\n feature?: string;\n mesh?: string;\n };\n url?: string;\n transform?: VgTransform[];\n}\n\n\nexport interface VgParentRef {\n parent: string;\n}\n\nexport type VgFieldRef = string | VgParentRef | VgParentRef[];\n\nexport type VgSortField = true | {\n field?: VgFieldRef,\n op: AggregateOp,\n order?: SortOrder\n};\n\n/**\n * Unioned domains can only be sorted by count aggregate.\n */\nexport type VgUnionSortField = true | {\n op: 'count'\n order?: SortOrder\n};\n\nexport interface VgDataRef {\n data: string;\n field: VgFieldRef;\n sort?: VgSortField;\n}\n\nexport interface VgSignalRef {\n signal: string;\n}\n\nexport function isVgSignalRef(o: any): o is VgSignalRef {\n return !!o['signal'];\n}\n\nexport type VgEventStream = any;\n\n// TODO: add type of value (Make it VgValueRef {value?:T ...})\nexport interface VgValueRef {\n value?: number | string | boolean;\n field?: string | {\n datum?: string,\n group?: string,\n parent?: string\n };\n signal?: string;\n scale?: string; // TODO: object\n mult?: number;\n offset?: number | VgValueRef;\n band?: boolean | number | VgValueRef;\n}\n\n// TODO: add vg prefix\nexport interface DataRefUnionDomain {\n fields: (any[] | VgDataRef | VgSignalRef)[];\n sort?: VgUnionSortField;\n}\n\nexport interface VgFieldRefUnionDomain {\n data: string;\n fields: VgFieldRef[];\n sort?: VgUnionSortField;\n}\n\nexport type VgScheme = {scheme: string, extent?: number[], count?: number};\nexport type VgRange = string | VgDataRef | (number|string|VgDataRef|VgSignalRef)[] | VgScheme | VgRangeStep;\n\nexport type VgRangeStep = {step: number | VgSignalRef};\nexport function isVgRangeStep(range: VgRange): range is VgRangeStep {\n return !!range['step'];\n}\n\n// Domains that are not a union of domains\nexport type VgNonUnionDomain = any[] | VgDataRef | VgSignalRef;\nexport type VgDomain = VgNonUnionDomain | DataRefUnionDomain | VgFieldRefUnionDomain;\n\nexport type VgMarkGroup = any;\n\nexport type VgProjectionType = 'albers' | 'albersUsa' | 'azimuthalEqualArea' | 'azimuthalEquidistant' | 'conicConformal' | 'conicEqualArea' | 'conicEquidistant' | 'equirectangular' | 'gnomonic' | 'mercator' | 'orthographic' | 'stereographic' | 'transverseMercator';\n\n\nexport type VgProjection = {\n /*\n * The name of the projection.\n */\n name: string;\n /*\n * The type of the projection.\n */\n type?: VgProjectionType;\n /*\n * The clip angle of the projection.\n */\n clipAngle?: number;\n /*\n * Sets the projection’s viewport clip extent to the specified bounds in pixels\n */\n clipExtent?: number[][];\n /*\n * Sets the projection’s scale factor to the specified value\n */\n scale?: number;\n /*\n * The translation of the projection.\n */\n translate?: number[];\n /*\n * The center of the projection.\n */\n center?: number[];\n /**\n * The rotation of the projection.\n */\n rotate?: number[];\n /*\n * The desired precision of the projection.\n */\n precision?: String;\n /*\n * GeoJSON data to which the projection should attempt to automatically fit the translate and scale parameters..\n */\n fit?: VgSignalRef | Object | any[];\n /*\n * Used in conjunction with fit, provides the pixel area to which the projection should be automatically fit.\n */\n extent?: VgSignalRef | number[][];\n /*\n * Used in conjunction with fit, provides the width and height in pixels of the area to which the projection should be automatically fit.\n */\n size?: VgSignalRef | (number | VgSignalRef)[];\n\n /* The following properties are all supported for specific types of projections. Consult the d3-geo-projection library for more information: https://github.com/d3/d3-geo-projection */\n coefficient?: number;\n distance?: number;\n fraction?: number;\n lobes?: number;\n parallel?: number;\n radius?: number;\n ratio?: number;\n spacing?: number;\n tilt?: number;\n};\n\nexport interface VgScale {\n name: string;\n type: ScaleType;\n domain: VgDomain;\n domainRaw?: VgSignalRef;\n range: VgRange;\n\n clamp?: boolean;\n base?: number;\n exponent?: number;\n interpolate?: ScaleInterpolate | ScaleInterpolateParams;\n nice?: boolean | number | NiceTime | {interval: string, step: number};\n padding?: number;\n paddingInner?: number;\n paddingOuter?: number;\n reverse?: boolean;\n round?: boolean;\n zero?: boolean;\n}\n\nexport type ScaleInterpolate = 'rgb'| 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long';\n\nexport interface ScaleInterpolateParams {\n type: 'rgb' | 'cubehelix' | 'cubehelix-long';\n gamma?: number;\n}\n\nexport type VgLayoutAlign = 'none' | 'each' | 'all';\n\nexport type RowCol = {\n row?: T,\n column?: T\n};\n\nexport interface VgLayout {\n center?: boolean | RowCol;\n padding?: number | RowCol;\n headerBand?: number | RowCol;\n footerBand?: number | RowCol;\n offset?: number | {\n rowHeader?: number,\n rowFooter?: number,\n rowTitle?: number,\n columnHeader?: number,\n columnFooter?: number,\n columnTitle?: number\n };\n bounds?: 'full' | 'flush';\n columns?: number | {signal: string};\n align?: VgLayoutAlign | RowCol;\n}\n\nexport function isDataRefUnionedDomain(domain: VgDomain): domain is DataRefUnionDomain {\n if (!isArray(domain)) {\n return 'fields' in domain && !('data' in domain);\n }\n return false;\n}\n\nexport function isFieldRefUnionDomain(domain: VgDomain): domain is VgFieldRefUnionDomain {\n if (!isArray(domain)) {\n return 'fields' in domain && 'data' in domain;\n }\n return false;\n}\n\nexport function isDataRefDomain(domain: VgDomain): domain is VgDataRef {\n if (!isArray(domain)) {\n return 'field' in domain && 'data' in domain;\n }\n return false;\n}\n\nexport function isSignalRefDomain(domain: VgDomain): domain is VgSignalRef {\n if (!isArray(domain)) {\n return 'signal' in domain;\n }\n return false;\n}\n\nexport interface VgEventHandler {\n events: string[] | VgSignalRef;\n update?: string;\n encode?: string;\n force?: boolean;\n between?: any[];\n}\n\nexport interface VgSignal {\n name: string;\n bind?: string;\n description?: string;\n on?: VgEventHandler[];\n update?: string;\n react?: boolean;\n value?: string | number | boolean | {} | VgSignalRef;\n // only for nested signals\n push?: string;\n}\n\nexport type VgEncodeChannel = 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height'|'opacity'|'fill'|'fillOpacity'|'stroke'|'strokeWidth'|'strokeCap'|'strokeOpacity'|'strokeDash'|'strokeDashOffset'|'strokeMiterLimit'|'strokeJoin'|'cursor'|'clip'|'size'|'shape'|'path'|'innerRadius'|'outerRadius'|'startAngle'|'endAngle'|'interpolate'|'tension'|'orient'|'url'|'align'|'baseline'|'text'|'dir'|'ellipsis'|'limit'|'dx'|'dy'|'radius'|'theta'|'angle'|'font'|'fontSize'|'fontWeight'|'fontStyle'|'tooltip'|'href'|'cursor'|'defined'|'cornerRadius';\nexport type VgEncodeEntry = {\n [k in VgEncodeChannel]?: VgValueRef | (VgValueRef & {test?: string})[];\n};\n\n\n// TODO: make export interface VgEncodeEntry {\n// x?: VgValueRef\n// y?: VgValueRef\n// ...\n// color?: VgValueRef\n// ...\n// }\n\nexport type AxisOrient = 'top' | 'right' | 'left' | 'bottom';\n\nexport interface VgAxis {\n scale: string;\n domain?: boolean;\n format?: string;\n grid?: boolean;\n gridScale?: string;\n\n labels?: boolean;\n\n labelBound?: boolean | number;\n labelFlush?: boolean | number;\n labelPadding?: number;\n labelOverlap?: boolean | 'parity' | 'greedy';\n maxExtent?: number;\n minExtent?: number;\n offset?: number;\n orient?: AxisOrient;\n position?: number;\n\n ticks?: boolean;\n tickCount?: number;\n tickSize?: number;\n\n title?: string;\n titlePadding?: number;\n\n values?: any[] | VgSignalRef;\n zindex?: number;\n\n encode?: VgAxisEncode;\n}\n\nexport type LegendType = 'symbol' | 'gradient';\n\nexport interface VgLegend {\n fill?: string;\n stroke?: string;\n size?: string;\n shape?: string;\n opacity?: string;\n\n entryPadding?: number;\n format?: string;\n\n offset?: number;\n orient?: LegendOrient;\n padding?: number;\n\n tickCount?: number;\n title?: string;\n type?: LegendType;\n values?: any[] | VgSignalRef;\n zindex?: number;\n\n encode?: VgLegendEncode;\n}\n\nexport interface VgBinTransform extends BaseBin {\n type: 'bin';\n extent?: number[] | {signal: string};\n field: string;\n as: string[];\n signal?: string;\n}\n\nexport interface VgExtentTransform {\n type: 'extent';\n field: string;\n signal: string;\n}\n\nexport interface VgFormulaTransform {\n type: 'formula';\n as: string;\n expr: string;\n}\n\nexport interface VgFilterTransform {\n type: 'filter';\n expr: string;\n}\n\nexport interface VgAggregateTransform {\n type: 'aggregate';\n groupby?: VgFieldRef[];\n fields?: VgFieldRef[];\n ops?: AggregateOp[];\n as?: string[];\n cross?: boolean;\n drop?: boolean;\n}\n\nexport interface VgCollectTransform {\n type: 'collect';\n sort: VgSort;\n}\n\nexport interface VgLookupTransform {\n type: 'lookup';\n from: string;\n key: string;\n fields: string[];\n values?: string[];\n as?: string[];\n default?: string;\n}\n\nexport interface VgStackTransform {\n type: 'stack';\n offset?: StackOffset;\n groupby: string[];\n field: string;\n sort: VgSort;\n as: string[];\n}\n\nexport interface VgIdentifierTransform {\n type: 'identifier';\n as: string;\n}\n\nexport type VgTransform = VgBinTransform | VgExtentTransform | VgFormulaTransform | VgAggregateTransform | VgFilterTransform | VgImputeTransform | VgStackTransform | VgCollectTransform | VgLookupTransform | VgIdentifierTransform | VgGeoPointTransform | VgGeoJSONTransform | VgGeoJSONTransform | VgWindowTransform;\n\nexport interface VgGeoPointTransform {\n type: 'geopoint';\n projection: string; // projection name\n fields: VgFieldRef[];\n as?: string[];\n}\n\nexport interface VgGeoShapeTransform {\n type: 'geoshape';\n projection: string; // projection name\n field?: VgFieldRef;\n as?: string;\n}\n\nexport interface VgGeoJSONTransform {\n type: 'geojson';\n fields?: VgFieldRef[];\n geojson?: VgFieldRef;\n signal: string;\n}\n\nexport type VgPostEncodingTransform = VgGeoShapeTransform;\n\nexport interface VgAxisEncode {\n ticks?: VgGuideEncode;\n labels?: VgGuideEncode;\n title?: VgGuideEncode;\n grid?: VgGuideEncode;\n domain?: VgGuideEncode;\n}\n\nexport interface VgLegendEncode {\n title?: VgGuideEncode;\n labels?: VgGuideEncode;\n legend?: VgGuideEncode;\n symbols?: VgGuideEncode;\n gradient?: VgGuideEncode;\n}\n\nexport type VgGuideEncode = any; // TODO: replace this (See guideEncode in Vega Schema)\n\nexport type VgSort = {\n field: string;\n order?: VgComparatorOrder;\n} | {\n field: string[];\n order?: (VgComparatorOrder)[];\n};\n\nexport interface VgImputeTransform {\n type: 'impute';\n groupby?: string[];\n field: string;\n key: string;\n keyvals?: string[];\n method?: 'value' | 'median' | 'max' | 'min' | 'mean';\n value?: any;\n}\n\nexport type VgCheckboxBinding = {\n input: 'checkbox';\n element?: string;\n};\n\nexport type VgRadioBinding = {\n input: 'radio';\n options: string[];\n element?: string;\n};\n\nexport type VgSelectBinding = {\n input: 'select';\n options: string[];\n element?: string;\n};\n\nexport type VgRangeBinding = {\n input: 'range';\n min?: number;\n max?: number;\n step?: number;\n element?: string;\n};\n\nexport type VgGenericBinding = {\n input: string;\n element?: string;\n};\n\nexport type VgBinding = VgCheckboxBinding | VgRadioBinding |\n VgSelectBinding | VgRangeBinding | VgGenericBinding;\n\n\n/**\n * Base object for Vega's Axis and Axis Config.\n * All of these properties are both properties of Vega's Axis and Axis Config.\n */\nexport interface VgAxisBase {\n /**\n * A boolean flag indicating if the domain (the axis baseline) should be included as part of the axis.\n *\n * __Default value:__ `true`\n */\n domain?: boolean;\n\n /**\n * A boolean flag indicating if grid lines should be included as part of the axis\n *\n * __Default value:__ `true` for [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous) that are not binned; otherwise, `false`.\n */\n grid?: boolean;\n\n /**\n * A boolean flag indicating if labels should be included as part of the axis.\n *\n * __Default value:__ `true`.\n */\n labels?: boolean;\n\n /**\n * Indicates if labels should be hidden if they exceed the axis range. If `false `(the default) no bounds overlap analysis is performed. If `true`, labels will be hidden if they exceed the axis range by more than 1 pixel. If this property is a number, it specifies the pixel tolerance: the maximum amount by which a label bounding box may exceed the axis range.\n *\n * __Default value:__ `false`.\n */\n labelBound?: boolean | number;\n\n /**\n * Indicates if the first and last axis labels should be aligned flush with the scale range. Flush alignment for a horizontal axis will left-align the first label and right-align the last label. For vertical axes, bottom and top text baselines are applied instead. If this property is a number, it also indicates the number of pixels by which to offset the first and last labels; for example, a value of 2 will flush-align the first and last labels and also push them 2 pixels outward from the center of the axis. The additional adjustment can sometimes help the labels better visually group with corresponding axis ticks.\n *\n * __Default value:__ `true` for axis of a continuous x-scale. Otherwise, `false`.\n */\n labelFlush?: boolean | number;\n\n /**\n * The strategy to use for resolving overlap of axis labels. If `false` (the default), no overlap reduction is attempted. If set to `true` or `\"parity\"`, a strategy of removing every other label is used (this works well for standard linear axes). If set to `\"greedy\"`, a linear scan of the labels is performed, removing any labels that overlaps with the last visible label (this often works better for log-scaled axes).\n *\n * __Default value:__ `true` for non-nominal fields with non-log scales; `\"greedy\"` for log scales; otherwise `false`.\n */\n labelOverlap?: boolean | 'parity' | 'greedy';\n\n /**\n * The padding, in pixels, between axis and text labels.\n */\n labelPadding?: number;\n\n /**\n * Boolean value that determines whether the axis should include ticks.\n */\n ticks?: boolean;\n\n /**\n * The size in pixels of axis ticks.\n *\n * @minimum 0\n */\n tickSize?: number;\n\n /**\n * Max length for axis title if the title is automatically generated from the field's description.\n *\n * @minimum 0\n * __Default value:__ `undefined`.\n */\n titleMaxLength?: number;\n\n /**\n * The padding, in pixels, between title and axis.\n */\n titlePadding?: number;\n\n /**\n * The minimum extent in pixels that axis ticks and labels should use. This determines a minimum offset value for axis titles.\n *\n * __Default value:__ `30` for y-axis; `undefined` for x-axis.\n */\n minExtent?: number;\n\n /**\n * The maximum extent in pixels that axis ticks and labels should use. This determines a maximum offset value for axis titles.\n *\n * __Default value:__ `undefined`.\n */\n maxExtent?: number;\n}\n\nexport interface VgAxisConfig extends VgAxisBase {\n /**\n * An interpolation fraction indicating where, for `band` scales, axis ticks should be positioned. A value of `0` places ticks at the left edge of their bands. A value of `0.5` places ticks in the middle of their bands.\n */\n bandPosition?: number;\n /**\n * Stroke width of axis domain line\n *\n * __Default value:__ (none, using Vega default).\n */\n domainWidth?: number;\n\n /**\n * Color of axis domain line.\n *\n * __Default value:__ (none, using Vega default).\n */\n domainColor?: string;\n\n // ---------- Grid ----------\n /**\n * Color of gridlines.\n */\n gridColor?: string;\n\n /**\n * The offset (in pixels) into which to begin drawing with the grid dash array.\n */\n gridDash?: number[];\n\n /**\n * The stroke opacity of grid (value between [0,1])\n *\n * __Default value:__ (`1` by default)\n * @minimum 0\n * @maximum 1\n */\n gridOpacity?: number;\n\n /**\n * The grid width, in pixels.\n * @minimum 0\n */\n gridWidth?: number;\n\n // ---------- Ticks ----------\n /**\n * The color of the axis's tick.\n */\n tickColor?: string;\n\n\n /**\n * The rotation angle of the axis labels.\n *\n * __Default value:__ `-90` for nominal and ordinal fields; `0` otherwise.\n *\n * @minimum -360\n * @maximum 360\n */\n labelAngle?: number;\n\n /**\n * The color of the tick label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the tick label.\n */\n labelFont?: string;\n\n /**\n * The font size of the label, in pixels.\n *\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * Maximum allowed pixel width of axis tick labels.\n */\n labelLimit?: number;\n\n /**\n * Boolean flag indicating if pixel position values should be rounded to the nearest integer.\n */\n tickRound?: boolean;\n\n /**\n * The width, in pixels, of ticks.\n *\n * @minimum 0\n */\n tickWidth?: number;\n\n // ---------- Title ----------\n\n /**\n * Horizontal text alignment of axis titles.\n */\n titleAlign?: string;\n\n /**\n * Angle in degrees of axis titles.\n */\n titleAngle?: number;\n /**\n * Vertical text baseline for axis titles.\n */\n titleBaseline?: string;\n /**\n * Color of the title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * Font of the title. (e.g., `\"Helvetica Neue\"`).\n */\n titleFont?: string;\n\n /**\n * Font size of the title.\n *\n * @minimum 0\n */\n titleFontSize?: number;\n\n /**\n * Font weight of the title.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n titleFontWeight?: FontWeight;\n\n /**\n * Maximum allowed pixel width of axis titles.\n */\n titleLimit?: number;\n\n /**\n * X-coordinate of the axis title relative to the axis group.\n */\n titleX?: number;\n\n /**\n * Y-coordinate of the axis title relative to the axis group.\n */\n titleY?: number;\n}\n\nexport type LegendOrient = 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'none';\n\nexport interface VgLegendBase {\n /**\n * Padding (in pixels) between legend entries in a symbol legend.\n */\n entryPadding?: number;\n\n\n /**\n * The orientation of the legend, which determines how the legend is positioned within the scene. One of \"left\", \"right\", \"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\", \"none\".\n *\n * __Default value:__ `\"right\"`\n */\n orient?: LegendOrient;\n\n /**\n * The offset, in pixels, by which to displace the legend from the edge of the enclosing group or data rectangle.\n *\n * __Default value:__ `0`\n */\n offset?: number;\n\n /**\n * The padding, in pixels, between the legend and axis.\n */\n padding?: number;\n}\n\nexport interface VgLegendConfig extends VgLegendBase {\n\n /**\n * Corner radius for the full legend.\n */\n cornerRadius?: number;\n\n /**\n * Background fill color for the full legend.\n */\n fillColor?: string;\n\n /**\n * Border stroke color for the full legend.\n */\n strokeColor?: string;\n\n /**\n * Border stroke dash pattern for the full legend.\n */\n strokeDash?: number[];\n\n /**\n * Border stroke width for the full legend.\n */\n strokeWidth?: number;\n // ---------- Gradient ----------\n /**\n * The color of the gradient stroke, can be in hex color code or regular color name.\n */\n gradientStrokeColor?: string;\n\n /**\n * The width of the gradient stroke, in pixels.\n * @minimum 0\n */\n gradientStrokeWidth?: number;\n\n /**\n * The height of the gradient, in pixels.\n * @minimum 0\n */\n gradientHeight?: number;\n\n /**\n * Text baseline for color ramp gradient labels.\n */\n gradientLabelBaseline?: string;\n\n /**\n * The maximum allowed length in pixels of color ramp gradient labels.\n */\n gradientLabelLimit?: number;\n\n /**\n * Vertical offset in pixels for color ramp gradient labels.\n */\n gradientLabelOffset?: number;\n\n /**\n * The width of the gradient, in pixels.\n * @minimum 0\n */\n gradientWidth?: number;\n\n // ---------- Label ----------\n /**\n * The alignment of the legend label, can be left, middle or right.\n */\n labelAlign?: string;\n\n /**\n * The position of the baseline of legend label, can be top, middle or bottom.\n */\n labelBaseline?: string;\n\n /**\n * The color of the legend label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the legend label.\n */\n labelFont?: string;\n\n /**\n * The font size of legend label.\n *\n * __Default value:__ `10`.\n *\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * Maximum allowed pixel width of axis tick labels.\n */\n labelLimit?: number;\n\n /**\n * The offset of the legend label.\n * @minimum 0\n */\n labelOffset?: number;\n\n // ---------- Symbols ----------\n /**\n * The color of the legend symbol,\n */\n symbolColor?: string;\n\n /**\n * Default shape type (such as \"circle\") for legend symbols.\n */\n symbolType?: string;\n\n /**\n * The size of the legend symbol, in pixels.\n * @minimum 0\n */\n symbolSize?: number;\n\n /**\n * The width of the symbol's stroke.\n * @minimum 0\n */\n symbolStrokeWidth?: number;\n\n // ---------- Title ----------\n /**\n * Horizontal text alignment for legend titles.\n */\n titleAlign?: string;\n\n /**\n * Vertical text baseline for legend titles.\n */\n titleBaseline?: string;\n /**\n * The color of the legend title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * The font of the legend title.\n */\n titleFont?: string;\n\n /**\n * The font size of the legend title.\n */\n titleFontSize?: number;\n\n /**\n * The font weight of the legend title.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n titleFontWeight?: FontWeight;\n\n /**\n * Maximum allowed pixel width of axis titles.\n */\n titleLimit?: number;\n\n /**\n * The padding, in pixels, between title and legend.\n */\n titlePadding?: number;\n}\n\nexport type FontStyle = 'normal' | 'italic';\n\nexport type FontWeightString = 'normal' | 'bold';\n/**\n * @TJS-type integer\n * @minimum 100\n * @maximum 900\n */\nexport type FontWeightNumber = number;\nexport type FontWeight = FontWeightString | FontWeightNumber;\nexport type HorizontalAlign = 'left' | 'right' | 'center';\nexport type Interpolate = 'linear' | 'linear-closed' |\n 'step' | 'step-before' | 'step-after' |\n 'basis' | 'basis-open' | 'basis-closed' |\n 'cardinal' | 'cardinal-open' | 'cardinal-closed' |\n 'bundle' | 'monotone';\nexport type Orient = 'horizontal' | 'vertical';\nexport type VerticalAlign = 'top' | 'middle' | 'bottom';\nexport type Cursor = 'auto' | 'default' | 'none' |\n 'context-menu' | 'help' | 'pointer' |\n 'progress' | 'wait' | 'cell' |\n 'crosshair' | 'text' | 'vertical-text' |\n 'alias' | 'copy' | 'move' |\n 'no-drop' | 'not-allowed' | 'e-resize' |\n 'n-resize' | 'ne-resize' | 'nw-resize' |\n 's-resize' | 'se-resize' | 'sw-resize' |\n 'w-resize' | 'ew-resize' | 'ns-resize' |\n 'nesw-resize' | 'nwse-resize' | 'col-resize' |\n 'row-resize' | 'all-scroll' | 'zoom-in' |\n 'zoom-out' | 'grab' | 'grabbing';\nexport type StrokeCap = 'butt' | 'round' | 'square';\nexport type StrokeJoin = 'miter' | 'round' | 'bevel';\nexport type Dir = 'ltr' | 'rtl';\n\nexport interface VgMarkConfig {\n\n /**\n * Default Fill Color. This has higher precedence than `config.color`\n *\n * __Default value:__ (None)\n *\n */\n fill?: string;\n\n /**\n * Default Stroke Color. This has higher precedence than `config.color`\n *\n * __Default value:__ (None)\n *\n */\n stroke?: string;\n\n // ---------- Opacity ----------\n /**\n * The overall opacity (value between [0,1]).\n *\n * __Default value:__ `0.7` for non-aggregate plots with `point`, `tick`, `circle`, or `square` marks or layered `bar` charts and `1` otherwise.\n *\n * @minimum 0\n * @maximum 1\n */\n opacity?: number;\n\n\n /**\n * The fill opacity (value between [0,1]).\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n * @maximum 1\n */\n fillOpacity?: number;\n\n /**\n * The stroke opacity (value between [0,1]).\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n * @maximum 1\n */\n strokeOpacity?: number;\n\n // ---------- Stroke Style ----------\n /**\n * The stroke width, in pixels.\n *\n * @minimum 0\n */\n strokeWidth?: number;\n\n /**\n * The stroke cap for line ending style. One of `\"butt\"`, `\"round\"`, or `\"square\"`.\n *\n * __Default value:__ `\"square\"`\n */\n strokeCap?: StrokeCap;\n\n /**\n * An array of alternating stroke, space lengths for creating dashed or dotted lines.\n */\n strokeDash?: number[];\n\n /**\n * The offset (in pixels) into which to begin drawing with the stroke dash array.\n */\n strokeDashOffset?: number;\n\n /**\n * The stroke line join method. One of `\"miter\"`, `\"round\"` or `\"bevel\"`.\n *\n * __Default value:__ `\"miter\"`\n */\n strokeJoin?: StrokeJoin;\n\n /**\n * The miter limit at which to bevel a line join.\n */\n strokeMiterLimit?: number;\n\n // ---------- Orientation: Bar, Tick, Line, Area ----------\n /**\n * The orientation of a non-stacked bar, tick, area, and line charts.\n * The value is either horizontal (default) or vertical.\n * - For bar, rule and tick, this determines whether the size of the bar and tick\n * should be applied to x or y dimension.\n * - For area, this property determines the orient property of the Vega output.\n * - For line and trail marks, this property determines the sort order of the points in the line\n * if `config.sortLineBy` is not specified.\n * For stacked charts, this is always determined by the orientation of the stack;\n * therefore explicitly specified value will be ignored.\n */\n orient?: Orient;\n\n // ---------- Interpolation: Line / area ----------\n /**\n * The line interpolation method to use for line and area marks. One of the following:\n * - `\"linear\"`: piecewise linear segments, as in a polyline.\n * - `\"linear-closed\"`: close the linear segments to form a polygon.\n * - `\"step\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"step-before\"`: alternate between vertical and horizontal segments, as in a step function.\n * - `\"step-after\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"basis\"`: a B-spline, with control point duplication on the ends.\n * - `\"basis-open\"`: an open B-spline; may not intersect the start or end.\n * - `\"basis-closed\"`: a closed B-spline, as in a loop.\n * - `\"cardinal\"`: a Cardinal spline, with control point duplication on the ends.\n * - `\"cardinal-open\"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points.\n * - `\"cardinal-closed\"`: a closed Cardinal spline, as in a loop.\n * - `\"bundle\"`: equivalent to basis, except the tension parameter is used to straighten the spline.\n * - `\"monotone\"`: cubic interpolation that preserves monotonicity in y.\n */\n interpolate?: Interpolate;\n /**\n * Depending on the interpolation type, sets the tension parameter (for line and area marks).\n * @minimum 0\n * @maximum 1\n */\n tension?: number;\n\n /**\n * The default symbol shape to use. One of: `\"circle\"` (default), `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, or `\"triangle-down\"`, or a custom SVG path.\n *\n * __Default value:__ `\"circle\"`\n *\n */\n shape?: string;\n\n /**\n * The pixel area each the point/circle/square.\n * For example: in the case of circles, the radius is determined in part by the square root of the size value.\n *\n * __Default value:__ `30`\n *\n * @minimum 0\n */\n size?: number;\n\n // Text / Label Mark Config\n\n /**\n * The horizontal alignment of the text. One of `\"left\"`, `\"right\"`, `\"center\"`.\n */\n align?: HorizontalAlign;\n\n /**\n * The rotation angle of the text, in degrees.\n * @minimum 0\n * @maximum 360\n */\n angle?: number;\n\n /**\n * The vertical alignment of the text. One of `\"top\"`, `\"middle\"`, `\"bottom\"`.\n *\n * __Default value:__ `\"middle\"`\n *\n */\n baseline?: VerticalAlign;\n\n /**\n * The direction of the text. One of `\"ltr\"` (left-to-right) or `\"rtl\"` (right-to-left). This property determines on which side is truncated in response to the limit parameter.\n *\n * __Default value:__ `\"ltr\"`\n */\n dir?: Dir;\n\n /**\n * The horizontal offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property.\n */\n dx?: number;\n\n /**\n * The vertical offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property.\n */\n dy?: number;\n\n /**\n * Polar coordinate radial offset, in pixels, of the text label from the origin determined by the `x` and `y` properties.\n * @minimum 0\n */\n radius?: number;\n\n /**\n * The maximum length of the text mark in pixels. The text value will be automatically truncated if the rendered size exceeds the limit.\n *\n * __Default value:__ `0`, indicating no limit\n */\n limit?: number;\n\n /**\n * The ellipsis string for text truncated in response to the limit parameter.\n *\n * __Default value:__ `\"…\"`\n */\n ellipsis?: string;\n\n /**\n * Polar coordinate angle, in radians, of the text label from the origin determined by the `x` and `y` properties. Values for `theta` follow the same convention of `arc` mark `startAngle` and `endAngle` properties: angles are measured in radians, with `0` indicating \"north\".\n */\n theta?: number;\n\n /**\n * The typeface to set the text in (e.g., `\"Helvetica Neue\"`).\n */\n font?: string;\n\n /**\n * The font size, in pixels.\n * @minimum 0\n */\n fontSize?: number;\n\n /**\n * The font style (e.g., `\"italic\"`).\n */\n fontStyle?: FontStyle;\n /**\n * The font weight.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n fontWeight?: FontWeight;\n\n /**\n * Placeholder text if the `text` channel is not specified\n */\n text?: string;\n\n /**\n * A URL to load upon mouse click. If defined, the mark acts as a hyperlink.\n *\n * @format uri\n */\n href?: string;\n\n /**\n * The mouse cursor used over the mark. Any valid [CSS cursor type](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Values) can be used.\n */\n cursor?: Cursor;\n\n /**\n * The tooltip text to show upon mouse hover.\n */\n tooltip?: any;\n\n // ---------- Corner Radius: Bar, Tick, Rect ----------\n\n /**\n * The radius in pixels of rounded rectangle corners.\n *\n * __Default value:__ `0`\n */\n cornerRadius?: number;\n}\n\nconst VG_MARK_CONFIG_INDEX: Flag = {\n opacity: 1,\n fill: 1,\n fillOpacity: 1,\n stroke: 1,\n strokeCap: 1,\n strokeWidth: 1,\n strokeOpacity: 1,\n strokeDash: 1,\n strokeDashOffset: 1,\n strokeJoin: 1,\n strokeMiterLimit: 1,\n size: 1,\n shape: 1,\n interpolate: 1,\n tension: 1,\n orient: 1,\n align: 1,\n baseline: 1,\n text: 1,\n dir: 1,\n dx: 1,\n dy: 1,\n ellipsis: 1,\n limit: 1,\n radius: 1,\n theta: 1,\n angle: 1,\n font: 1,\n fontSize: 1,\n fontWeight: 1,\n fontStyle: 1,\n cursor: 1,\n href: 1,\n tooltip: 1,\n cornerRadius: 1,\n // commented below are vg channel that do not have mark config.\n // 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height'\n // clip: 1,\n // endAngle: 1,\n // innerRadius: 1,\n // outerRadius: 1,\n // path: 1,\n // startAngle: 1,\n // url: 1,\n};\n\nexport const VG_MARK_CONFIGS = flagKeys(VG_MARK_CONFIG_INDEX);\n\nexport type Anchor = 'start' | 'middle' | 'end';\n\nexport interface VgTitle {\n /**\n * The title text.\n */\n text: string;\n\n /**\n * The orientation of the title relative to the chart. One of `\"top\"` (the default), `\"bottom\"`, `\"left\"`, or `\"right\"`.\n */\n orient?: TitleOrient;\n\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"` (the default), or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n */\n anchor?: Anchor;\n\n /**\n * The orthogonal offset in pixels by which to displace the title from its position along the edge of the chart.\n */\n offset?: number;\n\n style?: string | string[];\n\n // TODO: name, encode, interactive, zindex\n}\n\nexport type TitleOrient = 'top' | 'bottom' | 'left' | 'right';\n\nexport interface VgTitleConfig {\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"`, or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n *\n * __Default value:__ `\"middle\"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views.\n * `\"start\"` for other composite views.\n *\n * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `\"start\"`.\n */\n anchor?: Anchor;\n /**\n * Angle in degrees of title text.\n */\n angle?:\tnumber;\n /**\n * Vertical text baseline for title text.\n */\n baseline?: VerticalAlign;\n /**\n * Text color for title text.\n */\n color?:\tstring;\n /**\n * Font name for title text.\n */\n font?:\tstring;\n /**\n * Font size in pixels for title text.\n *\n * __Default value:__ `10`.\n *\n * @minimum 0\n */\n fontSize?:\tnumber;\n /**\n * Font weight for title text.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n fontWeight?: FontWeight;\n /**\n * The maximum allowed length in pixels of legend labels.\n *\n * @minimum 0\n */\n limit?:\tnumber;\n /**\n * Offset in pixels of the title from the chart body and axes.\n */\n offset?:\tnumber;\n /**\n * Default title orientation (\"top\", \"bottom\", \"left\", or \"right\")\n */\n orient?: TitleOrient;\n}\n\nexport type VgComparatorOrder = 'ascending' | 'descending';\n\nexport interface VgComparator {\n field?: string | string[];\n order?: VgComparatorOrder | VgComparatorOrder[];\n}\n\nexport interface VgWindowTransform {\n type: 'window';\n params?: Number[];\n as?: string[];\n ops?: (AggregateOp | WindowOnlyOp)[];\n fields?: string[];\n frame?: Number[];\n ignorePeers?: Boolean;\n groupby?: string[];\n sort?: VgComparator;\n}\n","import {isArray} from 'vega-util';\n\nimport {AXIS_PARTS, AXIS_PROPERTY_TYPE} from '../../axis';\nimport {Config} from '../../config';\nimport {FieldDefBase, title as fieldDefTitle} from '../../fielddef';\nimport {keys} from '../../util';\nimport {VgAxis} from '../../vega.schema';\nimport {AxisComponent, AxisComponentIndex} from './component';\n\nfunction assembleTitle(title: string | FieldDefBase[], config: Config) {\n if (isArray(title)) {\n return title.map(fieldDef => fieldDefTitle(fieldDef, config)).join(', ');\n }\n return title;\n}\n\nexport function assembleAxis(\n axisCmpt: AxisComponent,\n kind: 'main' | 'grid',\n config: Config,\n opt: {\n header: boolean // whether this is called via a header\n } = {header: false}\n): VgAxis {\n const {orient, scale, title, zindex, ...axis} = axisCmpt.combine();\n\n // Remove properties that are not valid for this kind of axis\n keys(axis).forEach((key) => {\n const propType = AXIS_PROPERTY_TYPE[key];\n if (propType && propType !== kind && propType !== 'both') {\n delete axis[key];\n }\n });\n\n if (kind === 'grid') {\n if (!axis.grid) {\n return undefined;\n }\n\n // Remove unnecessary encode block\n if (axis.encode) {\n // Only need to keep encode block for grid\n const {grid} = axis.encode;\n axis.encode = {\n ...(grid ? {grid} : {})\n };\n\n if (keys(axis.encode).length === 0) {\n delete axis.encode;\n }\n }\n\n return {\n scale,\n orient,\n ...axis,\n domain: false,\n labels: false,\n\n // Always set min/maxExtent to 0 to ensure that `config.axis*.minExtent` and `config.axis*.maxExtent`\n // would not affect gridAxis\n maxExtent: 0,\n minExtent: 0,\n ticks: false,\n zindex: zindex !== undefined ? zindex : 0 // put grid behind marks by default\n };\n } else { // kind === 'main'\n\n if (!opt.header && axisCmpt.mainExtracted) {\n // if mainExtracted has been extracted to a separate facet\n return undefined;\n }\n\n // Remove unnecessary encode block\n if (axis.encode) {\n for (const part of AXIS_PARTS) {\n if (\n !axisCmpt.hasAxisPart(part)\n ) {\n delete axis.encode[part];\n }\n }\n if (keys(axis.encode).length === 0) {\n delete axis.encode;\n }\n }\n\n const titleString = assembleTitle(title, config);\n\n return {\n scale,\n orient,\n grid: false,\n ...(titleString ? {title: titleString} : {}),\n ...axis,\n zindex: zindex !== undefined ? zindex : 1 // put axis line above marks by default\n };\n }\n}\n\nexport function assembleAxes(axisComponents: AxisComponentIndex, config: Config): VgAxis[] {\n const {x=[], y=[]} = axisComponents;\n return [\n ...x.map(a => assembleAxis(a, 'main', config)),\n ...x.map(a => assembleAxis(a, 'grid', config)),\n ...y.map(a => assembleAxis(a, 'main', config)),\n ...y.map(a => assembleAxis(a, 'grid', config))\n ].filter(a => a); // filter undefined\n}\n","import {TextBaseline} from 'vega';\nimport {Guide} from './guide';\nimport {FontWeight, VgTitleConfig} from './vega.schema';\n\nexport const HEADER_TITLE_PROPERTIES_MAP: {\n [k in keyof HeaderConfig]: keyof VgTitleConfig\n} = {\n titleAnchor: 'anchor',\n titleAngle: 'angle',\n titleBaseline: 'baseline',\n titleColor: 'color',\n titleFont: 'font',\n titleFontSize: 'fontSize',\n titleFontWeight: 'fontWeight',\n titleLimit: 'limit'\n};\n\nexport const HEADER_LABEL_PROPERTIES_MAP: {\n [k in keyof HeaderConfig]: keyof VgTitleConfig\n} = {\n labelAngle: 'angle',\n labelColor: 'color',\n labelFont: 'font',\n labelFontSize: 'fontSize',\n labelLimit: 'limit',\n};\n\nexport const HEADER_TITLE_PROPERTIES = Object.keys(HEADER_TITLE_PROPERTIES_MAP);\n\nexport const HEADER_LABEL_PROPERTIES = Object.keys(HEADER_LABEL_PROPERTIES_MAP);\n\nexport interface HeaderConfig {\n // ---------- Title ----------\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"`, or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n *\n * __Default value:__ `\"middle\"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views.\n * `\"start\"` for other composite views.\n *\n * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `\"start\"`.\n */\n titleAnchor?: string;\n\n /**\n * The rotation angle of the header title.\n *\n * __Default value:__ `0`.\n *\n * @minimum -360\n * @maximum 360\n */\n titleAngle?: number;\n /**\n * Vertical text baseline for the header title. One of `\"top\"`, `\"bottom\"`, `\"middle\"`.\n *\n * __Default value:__ `\"middle\"`\n */\n titleBaseline?: TextBaseline;\n /**\n * Color of the header title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * Font of the header title. (e.g., `\"Helvetica Neue\"`).\n */\n titleFont?: string;\n\n /**\n * Font size of the header title.\n *\n * @minimum 0\n */\n titleFontSize?: number;\n\n /**\n * Font weight of the header title.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n titleFontWeight?: FontWeight;\n\n /**\n * The maximum length of the header title in pixels. The text value will be automatically truncated if the rendered size exceeds the limit.\n *\n * __Default value:__ `0`, indicating no limit\n */\n titleLimit?: number;\n\n // ---------- Label ----------\n /**\n * The rotation angle of the header labels.\n *\n * __Default value:__ `0`.\n *\n * @minimum -360\n * @maximum 360\n */\n labelAngle?: number;\n\n /**\n * The color of the header label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the header label.\n */\n labelFont?: string;\n\n /**\n * The font size of the header label, in pixels.\n *\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * The maximum length of the header label in pixels. The text value will be automatically truncated if the rendered size exceeds the limit.\n *\n * __Default value:__ `0`, indicating no limit\n */\n labelLimit?: number;\n}\n\n/**\n * Headers of row / column channels for faceted plots.\n */\nexport interface Header extends HeaderConfig, Guide {}\n","import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {DateTime} from './datetime';\nimport {VgComparatorOrder} from './vega.schema';\n\nexport type SortOrder = VgComparatorOrder | null;\n\n\n/**\n * A sort definition for transform\n */\nexport interface SortField {\n /**\n * The name of the field to sort.\n */\n field: string;\n\n /**\n * Whether to sort the field in ascending or descending order.\n */\n order?: VgComparatorOrder;\n}\n\n\n/**\n * A sort definition for sorting a discrete scale in an encoding field definition.\n */\n\nexport interface EncodingSortField {\n /**\n * The data [field](https://vega.github.io/vega-lite/docs/field.html) to sort by.\n *\n * __Default value:__ If unspecified, defaults to the field specified in the outer data reference.\n */\n field?: F;\n /**\n * An [aggregate operation](https://vega.github.io/vega-lite/docs/aggregate.html#ops) to perform on the field prior to sorting (e.g., `\"count\"`, `\"mean\"` and `\"median\"`).\n * This property is required in cases where the sort field and the data reference field do not match.\n * The input data objects will be aggregated, grouped by the encoded data field.\n *\n * For a full list of operations, please see the documentation for [aggregate](https://vega.github.io/vega-lite/docs/aggregate.html#ops).\n */\n op: AggregateOp;\n\n /**\n * The sort order. One of `\"ascending\"` (default), `\"descending\"`, or `null` (no not sort).\n */\n order?: SortOrder;\n}\n\nexport type Sort = number[] | string[] | boolean[] | DateTime[] | SortOrder | EncodingSortField | null;\n\nexport function isSortField(sort: Sort): sort is EncodingSortField {\n return !!sort && (sort['op'] === 'count' || !!sort['field']) && !!sort['op'];\n}\n\nexport function isSortArray(sort: Sort): sort is number[] | string[] | boolean[] | DateTime[] {\n return !!sort && isArray(sort);\n}\n","/**\n * Utility files for producing Vega ValueRef for marks\n */\nimport {isArray, isFunction, isString} from 'vega-util';\n\nimport {Channel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {\n ChannelDef,\n ChannelDefWithCondition,\n FieldDef,\n FieldRefOption,\n isFieldDef,\n isValueDef,\n TextFieldDef,\n vgField,\n} from '../../fielddef';\nimport * as log from '../../log';\nimport {Mark, MarkDef} from '../../mark';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {StackProperties} from '../../stack';\nimport {QUANTITATIVE} from '../../type';\nimport {contains, some} from '../../util';\nimport {VgSignalRef, VgValueRef} from '../../vega.schema';\nimport {binRequiresRange, formatSignalRef} from '../common';\nimport {ScaleComponent} from '../scale/component';\n\n\n// TODO: we need to find a way to refactor these so that scaleName is a part of scale\n// but that's complicated. For now, this is a huge step moving forward.\n\n/**\n * @return Vega ValueRef for normal x- or y-position without projection\n */\nexport function position(channel: 'x' | 'y', channelDef: ChannelDef, scaleName: string, scale: ScaleComponent,\n stack: StackProperties, defaultRef: VgValueRef | (() => VgValueRef)): VgValueRef {\n if (isFieldDef(channelDef) && stack && channel === stack.fieldChannel) {\n // x or y use stack_end so that stacked line's point mark use stack_end too.\n return fieldRef(channelDef, scaleName, {suffix: 'end'});\n }\n return midPoint(channel, channelDef, scaleName, scale, stack, defaultRef);\n}\n\n/**\n * @return Vega ValueRef for normal x2- or y2-position without projection\n */\nexport function position2(channel: 'x2' | 'y2', aFieldDef: ChannelDef, a2fieldDef: ChannelDef, scaleName: string, scale: ScaleComponent,\n stack: StackProperties, defaultRef: VgValueRef | (() => VgValueRef)): VgValueRef {\n if (isFieldDef(aFieldDef) && stack &&\n // If fieldChannel is X and channel is X2 (or Y and Y2)\n channel.charAt(0) === stack.fieldChannel.charAt(0)\n ) {\n return fieldRef(aFieldDef, scaleName, {suffix: 'start'});\n }\n return midPoint(channel, a2fieldDef, scaleName, scale, stack, defaultRef);\n}\n\n\n\nexport function getOffset(channel: 'x' | 'y' | 'x2' | 'y2', markDef: MarkDef) {\n const offsetChannel = channel + 'Offset';\n // TODO: in the future read from encoding channel too\n\n const markDefOffsetValue = markDef[offsetChannel];\n if (markDefOffsetValue) {\n return markDefOffsetValue;\n }\n\n return undefined;\n}\n\n/**\n * Value Ref for binned fields\n */\nexport function bin(fieldDef: FieldDef, scaleName: string, side: 'start' | 'end', offset?: number) {\n const binSuffix = side === 'start' ? undefined : 'end';\n return fieldRef(fieldDef, scaleName, {binSuffix}, offset ? {offset} : {});\n}\n\nexport function fieldRef(\n fieldDef: FieldDef, scaleName: string, opt: FieldRefOption,\n mixins?: {offset?: number | VgValueRef, band?: number|boolean}\n ): VgValueRef {\n\n const ref: VgValueRef = {\n ...(scaleName ? {scale: scaleName} : {}),\n field: vgField(fieldDef, opt),\n };\n\n if (mixins) {\n return {\n ...ref,\n ...mixins\n };\n }\n return ref;\n}\n\nexport function bandRef(scaleName: string, band: number|boolean = true): VgValueRef {\n return {\n scale: scaleName,\n band: band\n };\n}\n\n/**\n * Signal that returns the middle of a bin. Should only be used with x and y.\n */\nfunction binMidSignal(fieldDef: FieldDef, scaleName: string) {\n return {\n signal: `(` +\n `scale(\"${scaleName}\", ${vgField(fieldDef, {expr: 'datum'})})` +\n ` + ` +\n `scale(\"${scaleName}\", ${vgField(fieldDef, {binSuffix: 'end', expr: 'datum'})})`+\n `)/2`\n };\n}\n\n/**\n * @returns {VgValueRef} Value Ref for xc / yc or mid point for other channels.\n */\nexport function midPoint(\n channel: Channel,\n channelDef: ChannelDef,\n scaleName: string,\n scale: ScaleComponent,\n stack: StackProperties,\n defaultRef: VgValueRef | (() => VgValueRef)\n): VgValueRef {\n // TODO: datum support\n\n if (channelDef) {\n /* istanbul ignore else */\n\n if (isFieldDef(channelDef)) {\n if (channelDef.bin) {\n // Use middle only for x an y to place marks in the center between start and end of the bin range.\n // We do not use the mid point for other channels (e.g. size) so that properties of legends and marks match.\n if (contains([X, Y], channel) && channelDef.type === QUANTITATIVE) {\n if (stack && stack.impute) {\n // For stack, we computed bin_mid so we can impute.\n return fieldRef(channelDef, scaleName, {binSuffix: 'mid'});\n }\n // For non-stack, we can just calculate bin mid on the fly using signal.\n return binMidSignal(channelDef, scaleName);\n }\n return fieldRef(channelDef, scaleName, binRequiresRange(channelDef, channel) ? {binSuffix: 'range'} : {});\n }\n\n if (scale) {\n const scaleType = scale.get('type');\n if (hasDiscreteDomain(scaleType)) {\n if (scaleType === 'band') {\n // For band, to get mid point, need to offset by half of the band\n return fieldRef(channelDef, scaleName, {binSuffix: 'range'}, {band: 0.5});\n }\n return fieldRef(channelDef, scaleName, {binSuffix: 'range'});\n }\n }\n return fieldRef(channelDef, scaleName, {}); // no need for bin suffix\n } else if (isValueDef(channelDef)) {\n const value = channelDef.value;\n\n if (contains(['x', 'x2'], channel) && value === 'width') {\n return {field: {group: 'width'}};\n } else if (contains(['y', 'y2'], channel) && value === 'height') {\n return {field: {group: 'height'}};\n }\n\n return {value};\n }\n\n // If channelDef is neither field def or value def, it's a condition-only def.\n // In such case, we will use default ref.\n }\n\n return isFunction(defaultRef) ? defaultRef() : defaultRef;\n}\n\nexport function text(textDef: ChannelDefWithCondition>, config: Config): VgValueRef {\n // text\n if (textDef) {\n if (isFieldDef(textDef)) {\n return formatSignalRef(textDef, textDef.format, 'datum', config);\n } else if (isValueDef(textDef)) {\n return {value: textDef.value};\n }\n }\n return undefined;\n}\n\nexport function mid(sizeRef: VgSignalRef): VgValueRef {\n return {...sizeRef, mult: 0.5};\n}\n\n/**\n * Whether the scale definitely includes zero in the domain\n */\nfunction domainDefinitelyIncludeZero(scale: ScaleComponent) {\n if (scale.get('zero') !== false) {\n return true;\n }\n const domains = scale.domains;\n if (isArray(domains)) {\n return some(domains, (d) => isArray(d) && d.length === 2 && d[0] <=0 && d[1] >= 0);\n }\n return false;\n}\n\nexport function getDefaultRef(\n defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax',\n channel: 'x' | 'y', scaleName: string, scale: ScaleComponent, mark: Mark\n) {\n return () => {\n if (isString(defaultRef)) {\n if (scaleName) {\n const scaleType = scale.get('type');\n if (contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scaleType)) {\n // Log scales cannot have zero.\n // Zero in time scale is arbitrary, and does not affect ratio.\n // (Time is an interval level of measurement, not ratio).\n // See https://en.wikipedia.org/wiki/Level_of_measurement for more info.\n if (mark === 'bar' || mark === 'area') {\n log.warn(log.message.nonZeroScaleUsedWithLengthMark(mark, channel, {scaleType}));\n }\n } else {\n if (domainDefinitelyIncludeZero(scale)) {\n return {\n scale: scaleName,\n value: 0\n };\n }\n if (mark === 'bar' || mark === 'area') {\n log.warn(log.message.nonZeroScaleUsedWithLengthMark(\n mark, channel, {zeroFalse: scale.explicit.zero === false}\n ));\n }\n }\n }\n\n if (defaultRef === 'zeroOrMin') {\n return channel === 'x' ? {value: 0} : {field: {group: 'height'}};\n } else { // zeroOrMax\n return channel === 'x' ? {field: {group: 'width'}} : {value: 0};\n }\n }\n return defaultRef;\n };\n}\n\n","import {isArray} from 'vega-util';\n\nimport {NONPOSITION_SCALE_CHANNELS, PositionScaleChannel} from '../../channel';\nimport {\n ChannelDef,\n FieldDef,\n FieldDefWithCondition,\n getFieldDef,\n isConditionalSelection,\n isValueDef,\n TextFieldDef,\n ValueDefWithCondition,\n vgField,\n} from '../../fielddef';\nimport * as log from '../../log';\nimport {MarkDef} from '../../mark';\nimport {expression} from '../../predicate';\nimport {hasContinuousDomain} from '../../scale';\nimport {contains} from '../../util';\nimport {VG_MARK_CONFIGS, VgEncodeEntry, VgValueRef} from '../../vega.schema';\nimport {getMarkConfig} from '../common';\nimport {selectionPredicate} from '../selection/selection';\nimport {UnitModel} from '../unit';\nimport * as ref from './valueref';\n\nexport function color(model: UnitModel, opt: {valueOnly: boolean} = {valueOnly: false}): VgEncodeEntry {\n const {markDef, encoding, config} = model;\n const {filled, type: markType} = markDef;\n\n const configValue = {\n fill: getMarkConfig('fill', markDef, config),\n stroke: getMarkConfig('stroke', markDef, config),\n color: getMarkConfig('color', markDef, config)\n };\n\n const transparentIfNeeded = contains(['bar', 'point', 'circle', 'square', 'geoshape'], markType) ? 'transparent' : undefined;\n\n const defaultValue = {\n fill: markDef.fill || configValue.fill ||\n // If there is no fill, always fill symbols, bar, geoshape\n // with transparent fills https://github.com/vega/vega-lite/issues/1316\n transparentIfNeeded,\n stroke: markDef.stroke || configValue.stroke\n };\n\n const colorVgChannel = filled ? 'fill' : 'stroke';\n\n const fillStrokeMarkDefAndConfig: VgEncodeEntry = {\n ...(defaultValue.fill ? {\n fill: {value: defaultValue.fill}\n } : {}),\n ...(defaultValue.stroke ? {\n stroke: {value: defaultValue.stroke}\n } : {}),\n };\n\n if (encoding.fill || encoding.stroke) {\n // ignore encoding.color, markDef.color, config.color\n if (markDef.color) {\n // warn for markDef.color (no need to warn encoding.color as it will be dropped in normalized already)\n log.warn(log.message.droppingColor('property', {fill: 'fill' in encoding, stroke: 'stroke' in encoding}));\n }\n\n return {\n ...nonPosition('fill', model, {defaultValue: defaultValue.fill || transparentIfNeeded}),\n ...nonPosition('stroke', model, {defaultValue: defaultValue.stroke})\n };\n } else if (encoding.color) {\n\n return {\n ...fillStrokeMarkDefAndConfig,\n // override them with encoded color field\n ...nonPosition('color', model, {\n vgChannel: colorVgChannel,\n // apply default fill/stroke first, then color config, then transparent if needed.\n defaultValue: markDef[colorVgChannel] || markDef.color || configValue[colorVgChannel] || configValue.color || (filled ? transparentIfNeeded : undefined)\n })\n };\n } else if (markDef.fill || markDef.stroke) {\n // Ignore markDef.color, config.color\n if (markDef.color) {\n log.warn(log.message.droppingColor('property', {fill: 'fill' in markDef, stroke: 'stroke' in markDef}));\n }\n return fillStrokeMarkDefAndConfig;\n } else if (markDef.color) {\n return {\n ...fillStrokeMarkDefAndConfig, // in this case, fillStrokeMarkDefAndConfig only include config\n\n // override config with markDef.color\n [colorVgChannel]: {value: markDef.color}\n };\n } else if (configValue.fill || configValue.stroke) {\n // ignore config.color\n return fillStrokeMarkDefAndConfig;\n } else if (configValue.color) {\n return {\n ...(transparentIfNeeded ? {fill: {value: 'transparent'}} : {}),\n [colorVgChannel]: {value: configValue.color}\n };\n }\n return {};\n}\n\nexport type Ignore = Record<'size' | 'orient', 'ignore' | 'include'>;\n\nexport function baseEncodeEntry(model: UnitModel, ignore: Ignore) {\n return {\n ...markDefProperties(model.markDef, ignore),\n ...color(model),\n ...nonPosition('opacity', model),\n ...tooltip(model),\n ...text(model, 'href')\n };\n}\n\nfunction markDefProperties(mark: MarkDef, ignore: Ignore) {\n return VG_MARK_CONFIGS.reduce((m, prop) => {\n if (mark[prop] !== undefined && ignore[prop] !== 'ignore') {\n m[prop] = {value: mark[prop]};\n }\n return m;\n }, {});\n}\n\nexport function valueIfDefined(prop: string, value: string | number | boolean): VgEncodeEntry {\n if (value !== undefined) {\n return {[prop]: {value: value}};\n }\n return undefined;\n}\n\nfunction validPredicate(vgRef: string) {\n return `${vgRef} !== null && !isNaN(${vgRef})`;\n}\n\nexport function defined(model: UnitModel): VgEncodeEntry {\n if (model.config.invalidValues === 'filter') {\n const fields = ['x', 'y'].map((channel: PositionScaleChannel) => {\n const scaleComponent = model.getScaleComponent(channel);\n if (scaleComponent) {\n const scaleType = scaleComponent.get('type');\n\n // Discrete domain scales can handle invalid values, but continuous scales can't.\n if (hasContinuousDomain(scaleType)) {\n return model.vgField(channel, {expr: 'datum'});\n }\n }\n return undefined;\n })\n .filter(field => !!field)\n .map(validPredicate);\n\n if (fields.length > 0) {\n return {\n defined: {signal: fields.join(' && ')}\n };\n }\n }\n\n return {};\n}\n\n/**\n * Return mixins for non-positional channels with scales. (Text doesn't have scale.)\n */\nexport function nonPosition(channel: typeof NONPOSITION_SCALE_CHANNELS[0], model: UnitModel, opt: {defaultValue?: number | string | boolean, vgChannel?: string, defaultRef?: VgValueRef} = {}): VgEncodeEntry {\n const {defaultValue, vgChannel} = opt;\n const defaultRef = opt.defaultRef || (defaultValue !== undefined ? {value: defaultValue} : undefined);\n\n const channelDef = model.encoding[channel];\n\n return wrapCondition(model, channelDef, vgChannel || channel, (cDef) => {\n return ref.midPoint(\n channel, cDef, model.scaleName(channel),\n model.getScaleComponent(channel),\n null, // No need to provide stack for non-position as it does not affect mid point\n defaultRef\n );\n });\n}\n\n/**\n * Return a mixin that include a Vega production rule for a Vega-Lite conditional channel definition.\n * or a simple mixin if channel def has no condition.\n */\nexport function wrapCondition(\n model: UnitModel, channelDef: ChannelDef, vgChannel: string,\n refFn: (cDef: ChannelDef) => VgValueRef\n ): VgEncodeEntry {\n const condition = channelDef && channelDef.condition;\n const valueRef = refFn(channelDef);\n if (condition) {\n const conditions = isArray(condition) ? condition : [condition];\n const vgConditions = conditions.map((c) => {\n const conditionValueRef = refFn(c);\n const test = isConditionalSelection(c) ? selectionPredicate(model, c.selection) : expression(model, c.test);\n return {\n test,\n ...conditionValueRef\n };\n });\n return {\n [vgChannel]: [\n ...vgConditions,\n ...(valueRef !== undefined ? [valueRef] : [])\n ]\n };\n } else {\n return valueRef !== undefined ? {[vgChannel]: valueRef} : {};\n }\n}\n\nexport function tooltip(model: UnitModel) {\n const channel = 'tooltip';\n const channelDef = model.encoding[channel];\n if (isArray(channelDef)) {\n const keyValues = channelDef.map((fieldDef) => {\n const key = fieldDef.title !== undefined ? fieldDef.title : vgField(fieldDef, {binSuffix: 'range'});\n const value = ref.text(fieldDef, model.config).signal;\n return `\"${key}\": ${value}`;\n });\n return {tooltip: {signal: `{${keyValues.join(', ')}}`}};\n } else {\n // if not an array, behave just like text\n return textCommon(model, channel, channelDef);\n }\n}\n\nexport function text(model: UnitModel, channel: 'text' | 'href' = 'text') {\n const channelDef = model.encoding[channel];\n return textCommon(model, channel, channelDef);\n}\n\nfunction textCommon(model: UnitModel, channel: 'text' | 'href' | 'tooltip', channelDef: FieldDefWithCondition> | ValueDefWithCondition>) {\n return wrapCondition(model, channelDef, channel, (cDef) => ref.text(cDef, model.config));\n}\n\nexport function bandPosition(fieldDef: FieldDef, channel: 'x'|'y', model: UnitModel) {\n const scaleName = model.scaleName(channel);\n const sizeChannel = channel === 'x' ? 'width' : 'height';\n\n if (model.encoding.size || model.markDef.size !== undefined) {\n const orient = model.markDef.orient;\n if (orient) {\n const centeredBandPositionMixins = {\n // Use xc/yc and place the mark at the middle of the band\n // This way we never have to deal with size's condition for x/y position.\n [channel+'c']: ref.fieldRef(fieldDef, scaleName, {}, {band: 0.5})\n };\n\n if (getFieldDef(model.encoding.size)) {\n return {\n ...centeredBandPositionMixins,\n ...nonPosition('size', model, {vgChannel: sizeChannel})\n };\n } else if (isValueDef(model.encoding.size)) {\n return {\n ...centeredBandPositionMixins,\n ...nonPosition('size', model, {vgChannel: sizeChannel})\n };\n } else if (model.markDef.size !== undefined) {\n return {\n ...centeredBandPositionMixins,\n [sizeChannel]: {value: model.markDef.size}\n };\n }\n } else {\n log.warn(log.message.cannotApplySizeToNonOrientedMark(model.markDef.type));\n }\n }\n return {\n [channel]: ref.fieldRef(fieldDef, scaleName, {binSuffix: 'range'}),\n [sizeChannel]: ref.bandRef(scaleName)\n };\n}\n\nexport function centeredBandPosition(channel: 'x' | 'y', model: UnitModel, defaultPosRef: VgValueRef, defaultSizeRef: VgValueRef) {\n const centerChannel: 'xc' | 'yc' = channel === 'x' ? 'xc' : 'yc';\n const sizeChannel = channel === 'x' ? 'width' : 'height';\n return {\n ...pointPosition(channel, model, defaultPosRef, centerChannel),\n ...nonPosition('size', model, {defaultRef: defaultSizeRef, vgChannel: sizeChannel})\n };\n}\n\nexport function binnedPosition(fieldDef: FieldDef, channel: 'x'|'y', scaleName: string, spacing: number, reverse: boolean) {\n if (channel === 'x') {\n return {\n x2: ref.bin(fieldDef, scaleName, 'start', reverse ? 0 : spacing),\n x: ref.bin(fieldDef, scaleName, 'end', reverse ? spacing : 0)\n };\n } else {\n return {\n y2: ref.bin(fieldDef, scaleName, 'start', reverse ? spacing : 0),\n y: ref.bin(fieldDef, scaleName, 'end', reverse ? 0 : spacing)\n };\n }\n}\n\n\n/**\n * Return mixins for point (non-band) position channels.\n */\nexport function pointPosition(channel: 'x'|'y', model: UnitModel, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax', vgChannel?: 'x'|'y'|'xc'|'yc') {\n // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613\n\n const {encoding, mark, stack} = model;\n\n const channelDef = encoding[channel];\n const scaleName = model.scaleName(channel);\n const scale = model.getScaleComponent(channel);\n\n\n const offset = ref.getOffset(channel, model.markDef);\n\n\n const valueRef = !channelDef && (encoding.latitude || encoding.longitude) ?\n // use geopoint output if there are lat/long and there is no point position overriding lat/long.\n {field: model.getName(channel)} :\n {\n ...ref.position(channel, encoding[channel], scaleName, scale, stack,\n ref.getDefaultRef(defaultRef, channel, scaleName, scale, mark)\n ),\n ...(offset ? {offset}: {})\n };\n\n return {\n [vgChannel || channel]: valueRef\n };\n}\n\n/**\n * Return mixins for x2, y2.\n * If channel is not specified, return one channel based on orientation.\n */\nexport function pointPosition2(model: UnitModel, defaultRef: 'zeroOrMin' | 'zeroOrMax', channel: 'x2' | 'y2') {\n const {encoding, mark, stack} = model;\n\n const baseChannel = channel === 'x2' ? 'x' : 'y';\n const channelDef = encoding[baseChannel];\n const scaleName = model.scaleName(baseChannel);\n const scale = model.getScaleComponent(baseChannel);\n\n const offset = ref.getOffset(channel, model.markDef);\n\n const valueRef = !channelDef && (encoding.latitude || encoding.longitude) ?\n // use geopoint output if there are lat2/long2 and there is no point position2 overriding lat2/long2.\n {field: model.getName(channel)}:\n {\n ...ref.position2(channel, channelDef, encoding[channel], scaleName, scale, stack,\n ref.getDefaultRef(defaultRef, baseChannel, scaleName, scale, mark)\n ),\n ...(offset ? {offset} : {})\n };\n\n return {[channel]: valueRef};\n}\n","import {isArray} from 'vega-util';\nimport {Channel, isScaleChannel} from '../channel';\nimport {Config, ViewConfig} from '../config';\nimport {FieldDef, FieldDefBase, FieldRefOption, isScaleFieldDef, isTimeFieldDef, OrderFieldDef, ValueDef, vgField} from '../fielddef';\nimport {GuideEncodingEntry} from '../guide';\nimport {MarkConfig, MarkDef, TextConfig} from '../mark';\nimport {ScaleType} from '../scale';\nimport {formatExpression, TimeUnit} from '../timeunit';\nimport {QUANTITATIVE} from '../type';\nimport {contains, keys, stringify} from '../util';\nimport {VgEncodeChannel, VgEncodeEntry, VgMarkConfig, VgSort} from '../vega.schema';\nimport {AxisComponentProps} from './axis/component';\nimport {wrapCondition} from './mark/mixins';\nimport {Explicit} from './split';\nimport {UnitModel} from './unit';\n\n\nexport function applyConfig(e: VgEncodeEntry,\n config: ViewConfig | MarkConfig | TextConfig, // TODO(#1842): consolidate MarkConfig | TextConfig?\n propsList: string[]) {\n for (const property of propsList) {\n const value = config[property];\n if (value !== undefined) {\n e[property] = {value: value};\n }\n }\n return e;\n}\n\nexport function applyMarkConfig(e: VgEncodeEntry, model: UnitModel, propsList: (keyof MarkConfig)[]) {\n for (const property of propsList) {\n const value = getMarkConfig(property, model.markDef, model.config);\n if (value !== undefined) {\n e[property] = {value: value};\n }\n }\n return e;\n}\n\nexport function getStyles(mark: MarkDef): string[] {\n return [].concat(mark.type, mark.style || []);\n}\n\n/**\n * Return property value from style or mark specific config property if exists.\n * Otherwise, return general mark specific config.\n */\nexport function getMarkConfig

(prop: P, mark: MarkDef, config: Config): MarkConfig[P] {\n // By default, read from mark config first!\n let value = config.mark[prop];\n\n // Then read mark specific config, which has higher precedence\n const markSpecificConfig = config[mark.type];\n if (markSpecificConfig[prop] !== undefined) {\n value = markSpecificConfig[prop];\n }\n\n // Then read style config, which has even higher precedence.\n const styles = getStyles(mark);\n for (const style of styles) {\n const styleConfig = config.style[style];\n\n // MarkConfig extends VgMarkConfig so a prop may not be a valid property for style\n // However here we also check if it is defined, so it is okay to cast here\n const p = prop as keyof VgMarkConfig;\n if (styleConfig && styleConfig[p] !== undefined) {\n value = styleConfig[p];\n }\n }\n\n return value;\n}\n\nexport function formatSignalRef(fieldDef: FieldDef, specifiedFormat: string, expr: 'datum' | 'parent', config: Config) {\n const format = numberFormat(fieldDef, specifiedFormat, config);\n if (fieldDef.bin) {\n const startField = vgField(fieldDef, {expr});\n const endField = vgField(fieldDef, {expr, binSuffix: 'end'});\n return {\n signal: binFormatExpression(startField, endField, format, config)\n };\n } else if (fieldDef.type === 'quantitative') {\n return {\n signal: `${formatExpr(vgField(fieldDef, {expr, binSuffix: 'range'}), format)}`\n };\n } else if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = isScaleFieldDef(fieldDef) && fieldDef['scale'] && fieldDef['scale'].type === ScaleType.UTC;\n return {\n signal: timeFormatExpression(vgField(fieldDef, {expr}), fieldDef.timeUnit, specifiedFormat, config.text.shortTimeLabels, config.timeFormat, isUTCScale, true)\n };\n } else {\n return {\n signal: `''+${vgField(fieldDef, {expr})}`\n };\n }\n}\n\nexport function getSpecifiedOrDefaultValue(specifiedValue: T, defaultValue: T | {signal: string}) {\n if (specifiedValue !== undefined) {\n return specifiedValue;\n }\n return defaultValue;\n}\n\n/**\n * Returns number format for a fieldDef\n *\n * @param format explicitly specified format\n */\nexport function numberFormat(fieldDef: FieldDef, specifiedFormat: string, config: Config) {\n if (fieldDef.type === QUANTITATIVE) {\n // add number format for quantitative type only\n\n // Specified format in axis/legend has higher precedence than fieldDef.format\n if (specifiedFormat) {\n return specifiedFormat;\n }\n\n // TODO: need to make this work correctly for numeric ordinal / nominal type\n return config.numberFormat;\n }\n return undefined;\n}\n\nfunction formatExpr(field: string, format: string) {\n return `format(${field}, \"${format || ''}\")`;\n}\n\nexport function numberFormatExpr(field: string, specifiedFormat: string, config: Config) {\n return formatExpr(field, specifiedFormat || config.numberFormat);\n}\n\n\nexport function binFormatExpression(startField: string, endField: string, format: string, config: Config) {\n return `${startField} === null || isNaN(${startField}) ? \"null\" : ${numberFormatExpr(startField, format, config)} + \" - \" + ${numberFormatExpr(endField, format, config)}`;\n}\n\n\n/**\n * Returns the time expression used for axis/legend labels or text mark for a temporal field\n */\nexport function timeFormatExpression(field: string, timeUnit: TimeUnit, format: string, shortTimeLabels: boolean, timeFormatConfig: string, isUTCScale: boolean, alwaysReturn: boolean = false): string {\n if (!timeUnit || format) {\n // If there is not time unit, or if user explicitly specify format for axis/legend/text.\n format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit.\n\n if (format || alwaysReturn) {\n return `${isUTCScale ? 'utc' : 'time'}Format(${field}, '${format}')`;\n } else {\n return undefined;\n }\n } else {\n return formatExpression(timeUnit, field, shortTimeLabels, isUTCScale);\n }\n}\n\n/**\n * Return Vega sort parameters (tuple of field and order).\n */\nexport function sortParams(orderDef: OrderFieldDef | OrderFieldDef[], fieldRefOption?: FieldRefOption): VgSort {\n return (isArray(orderDef) ? orderDef : [orderDef]).reduce((s, orderChannelDef) => {\n s.field.push(vgField(orderChannelDef, fieldRefOption));\n s.order.push(orderChannelDef.sort || 'ascending');\n return s;\n }, {field:[], order: []});\n}\n\nexport type AxisTitleComponent = AxisComponentProps['title'];\n\nexport function mergeTitleFieldDefs(f1: FieldDefBase[], f2: FieldDefBase[]) {\n const merged = [...f1];\n\n f2.forEach((fdToMerge) => {\n for (const fieldDef1 of merged) {\n // If already exists, no need to append to merged array\n if (stringify(fieldDef1) === stringify(fdToMerge)) {\n return;\n }\n }\n merged.push(fdToMerge);\n });\n return merged;\n}\n\nexport function mergeTitle(title1: string, title2: string) {\n return title1 === title2 ?\n title1 : // if title is the same just use one of them\n title1 + ', ' + title2; // join title with comma if different\n}\n\nexport function mergeTitleComponent(\n v1: Explicit, v2: Explicit\n) {\n if (isArray(v1.value) && isArray(v2.value)) {\n return {\n explicit: v1.explicit,\n value: mergeTitleFieldDefs(v1.value, v2.value)\n };\n } else if (!isArray(v1.value) && !isArray(v2.value)) {\n return {\n explicit: v1.explicit, // keep the old explicit\n value: mergeTitle(v1.value, v2.value)\n };\n }\n /* istanbul ignore next: Condition should not happen -- only for warning in development. */\n throw new Error('It should never reach here');\n}\n\n/**\n * Checks whether a fieldDef for a particular channel requires a computed bin range.\n */\nexport function binRequiresRange(fieldDef: FieldDef, channel: Channel) {\n if (!fieldDef.bin) {\n console.warn('Only use this method with binned field defs');\n return false;\n }\n\n // We need the range only when the user explicitly forces a binned field to be use discrete scale. In this case, bin range is used in axis and legend labels.\n // We could check whether the axis or legend exists (not disabled) but that seems overkill.\n return isScaleChannel(channel) && contains(['ordinal', 'nominal'], fieldDef.type);\n}\n\nexport function guideEncodeEntry(encoding: GuideEncodingEntry, model: UnitModel) {\n return keys(encoding).reduce((encode, channel: VgEncodeChannel) => {\n const valueDef = encoding[channel];\n return {\n ...encode,\n ...wrapCondition(model, valueDef, channel, (x: ValueDef) => ({value: x.value}))\n };\n }, {});\n}\n","\nimport {DataSourceType} from '../../data';\nimport {Dict, StringSet} from '../../util';\n\n\n/**\n * A node in the dataflow tree.\n */\nexport class DataFlowNode {\n private _children: DataFlowNode[] = [];\n\n private _parent: DataFlowNode = null;\n\n constructor(parent: DataFlowNode, public readonly debugName?: string) {\n if (parent) {\n this.parent = parent;\n }\n }\n\n /**\n * Clone this node with a deep copy but don't clone links to children or parents.\n */\n public clone(): DataFlowNode {\n throw new Error('Cannot clone node');\n }\n\n /**\n * Set of fields that are being created by this node.\n */\n public producedFields(): StringSet {\n return {};\n }\n\n public dependentFields(): StringSet {\n return {};\n }\n\n get parent() {\n return this._parent;\n }\n\n /**\n * Set the parent of the node and also add this not to the parent's children.\n */\n set parent(parent: DataFlowNode) {\n this._parent = parent;\n parent.addChild(this);\n }\n\n get children() {\n return this._children;\n }\n\n public numChildren() {\n return this._children.length;\n }\n\n public addChild(child: DataFlowNode) {\n this._children.push(child);\n }\n\n public removeChild(oldChild: DataFlowNode) {\n this._children.splice(this._children.indexOf(oldChild), 1);\n }\n\n /**\n * Remove node from the dataflow.\n */\n public remove() {\n for (const child of this._children) {\n child.parent = this._parent;\n }\n this._parent.removeChild(this);\n }\n\n /**\n * Insert another node as a parent of this node.\n */\n public insertAsParentOf(other: DataFlowNode) {\n const parent = other.parent;\n parent.removeChild(this);\n this.parent = parent;\n other.parent = this;\n }\n\n public swapWithParent() {\n const parent = this._parent;\n const newParent = parent.parent;\n\n // reconnect the children\n for (const child of this._children) {\n child.parent = parent;\n }\n\n // remove old links\n this._children = []; // equivalent to removing every child link one by one\n parent.removeChild(this);\n parent.parent.removeChild(parent);\n\n\n // swap two nodes\n this.parent = newParent;\n parent.parent = this;\n }\n}\n\nexport class OutputNode extends DataFlowNode {\n private _source: string;\n\n private _name: string;\n\n public clone(): this {\n const cloneObj = new (this.constructor);\n cloneObj.debugName = 'clone_' + this.debugName;\n cloneObj._source = this._source;\n cloneObj._name = 'clone_' + this._name;\n cloneObj.type = this.type;\n cloneObj.refCounts = this.refCounts;\n cloneObj.refCounts[cloneObj._name] = 0;\n return cloneObj;\n }\n\n /**\n * @param source The name of the source. Will change in assemble.\n * @param type The type of the output node.\n * @param refCounts A global ref counter map.\n */\n constructor(parent: DataFlowNode, source: string, public readonly type: DataSourceType, private readonly refCounts: Dict) {\n super(parent, source);\n\n this._source = this._name = source;\n\n if (this.refCounts && !(this._name in this.refCounts)) {\n this.refCounts[this._name] = 0;\n }\n }\n\n /**\n * Request the datasource name and increase the ref counter.\n *\n * During the parsing phase, this will return the simple name such as 'main' or 'raw'.\n * It is crucial to request the name from an output node to mark it as a required node.\n * If nobody ever requests the name, this datasource will not be instantiated in the assemble phase.\n *\n * In the assemble phase, this will return the correct name.\n */\n public getSource() {\n this.refCounts[this._name]++;\n return this._source;\n }\n\n public isRequired(): boolean {\n return !!this.refCounts[this._name];\n }\n\n public setSource(source: string) {\n this._source = source;\n }\n}\n","import {DateTime} from '../../datetime';\nimport {FieldDef, isScaleFieldDef, vgField} from '../../fielddef';\nimport {fieldFilterExpression} from '../../predicate';\nimport {isSortArray} from '../../sort';\nimport {duplicate} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\nimport {ModelWithField} from '../model';\nimport {SingleDefChannel} from './../../channel';\nimport {CalculateTransform} from './../../transform';\nimport {DataFlowNode} from './dataflow';\n\n/**\n * We don't know what a calculate node depends on so we should never move it beyond anything that produces fields.\n */\nexport class CalculateNode extends DataFlowNode {\n public clone() {\n return new CalculateNode(null, duplicate(this.transform));\n }\n\n constructor(parent: DataFlowNode, private transform: CalculateTransform) {\n super(parent);\n }\n\n public static parseAllForSortIndex(parent: DataFlowNode, model: ModelWithField) {\n // get all the encoding with sort fields from model\n model.forEachFieldDef((fieldDef: FieldDef, channel: SingleDefChannel) => {\n if (!isScaleFieldDef(fieldDef)) {\n return;\n }\n if (isSortArray(fieldDef.sort)) {\n const {field, timeUnit} = fieldDef;\n const sort: (number | string | boolean | DateTime)[] = fieldDef.sort;\n // generate `datum[\"a\"] === val0 ? 0 : datum[\"a\"] === val1 ? 1 : ... : n` via FieldEqualPredicate\n const calculate = sort.map((sortValue, i) => {\n return `${fieldFilterExpression({field, timeUnit, equal: sortValue})} ? ${i} : `;\n }).join('') + sort.length;\n\n parent = new CalculateNode(parent, {\n calculate,\n as: sortArrayIndexField(fieldDef, channel)\n });\n }\n });\n return parent;\n }\n\n public producedFields() {\n const out = {};\n out[this.transform.as] = true;\n return out;\n }\n\n public assemble(): VgFormulaTransform {\n return {\n type: 'formula',\n expr: this.transform.calculate,\n as: this.transform.as\n };\n }\n}\n\nexport function sortArrayIndexField(fieldDef: FieldDef, channel: SingleDefChannel, expr?: 'datum') {\n return vgField(fieldDef, {prefix: channel, suffix: 'sort_index', expr});\n}\n","/**\n * Utility for generating row / column headers\n */\nimport {isArray} from 'vega-util';\nimport {Config} from '../../config';\nimport {FacetFieldDef} from '../../facet';\nimport {vgField} from '../../fielddef';\nimport {HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP, HeaderConfig} from '../../header';\nimport {isSortField} from '../../sort';\nimport {keys} from '../../util';\nimport {AxisOrient, VgAxis, VgComparator, VgMarkGroup, VgTitleConfig} from '../../vega.schema';\nimport {formatSignalRef} from '../common';\nimport {sortArrayIndexField} from '../data/calculate';\nimport {Model} from '../model';\n\n\nexport type HeaderChannel = 'row' | 'column';\nexport const HEADER_CHANNELS: HeaderChannel[] = ['row', 'column'];\n\nexport type HeaderType = 'header' | 'footer';\nexport const HEADER_TYPES: HeaderType[] = ['header', 'footer'];\n\n/**\n * A component that represents all header, footers and title of a Vega group with layout directive.\n */\nexport interface LayoutHeaderComponent {\n title?: string;\n\n // TODO: repeat and concat can have multiple header / footer.\n // Need to redesign this part a bit.\n\n facetFieldDef?: FacetFieldDef;\n\n /**\n * An array of header components for headers.\n * For facet, there should be only one header component, which is data-driven.\n * For repeat and concat, there can be multiple header components that explicitly list different axes.\n */\n header?: HeaderComponent[];\n\n /**\n * An array of header components for footers.\n * For facet, there should be only one header component, which is data-driven.\n * For repeat and concat, there can be multiple header components that explicitly list different axes.\n */\n footer?: HeaderComponent[];\n}\n\n/**\n * A component that represents one group of row/column-header/footer.\n */\nexport interface HeaderComponent {\n\n labels: boolean;\n\n sizeSignal: {signal: string};\n\n axes: VgAxis[];\n}\n\nexport function getHeaderType(orient: AxisOrient) {\n if (orient === 'top' || orient === 'left') {\n return 'header';\n }\n return 'footer';\n}\n\nexport function getTitleGroup(model: Model, channel: HeaderChannel) {\n const title = model.component.layoutHeaders[channel].title;\n const textOrient = channel === 'row' ? 'left' : undefined;\n const config = model.config? model.config : undefined;\n const facetFieldDef = model.component.layoutHeaders[channel].facetFieldDef? model.component.layoutHeaders[channel].facetFieldDef : undefined;\n\n return {\n name: `${channel}-title`,\n type: 'group',\n role: `${channel}-title`,\n title: {\n text: title,\n offset: 10,\n orient: textOrient,\n style: 'guide-title',\n ...getHeaderProperties(config, facetFieldDef, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP)\n }\n };\n}\n\nexport function getHeaderGroups(model: Model, channel: HeaderChannel): VgMarkGroup[] {\n const layoutHeader = model.component.layoutHeaders[channel];\n const groups = [];\n for (const headerType of HEADER_TYPES) {\n if (layoutHeader[headerType]) {\n for (const headerCmpt of layoutHeader[headerType]) {\n groups.push(getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt));\n }\n }\n }\n return groups;\n}\n\n// 0, (0,90), 90, (90, 180), 180, (180, 270), 270, (270, 0)\n\nexport function labelAlign(angle: number) {\n // to keep angle in [0, 360)\n angle = ((angle % 360) + 360) % 360;\n if ((angle + 90) % 180 === 0) { // for 90 and 270\n return {}; // default center\n } else if (angle < 90 || 270 < angle) {\n return {align: {value: 'right'}};\n } else if (135 <= angle && angle < 225) {\n return {align: {value: 'left'}};\n }\n return {};\n}\n\nexport function labelBaseline(angle: number) {\n // to keep angle in [0, 360)\n angle = ((angle % 360) + 360) % 360;\n if (45 <= angle && angle <= 135) {\n return {baseline: 'top'};\n }\n return {baseline: 'middle'};\n}\n\nfunction getSort(facetFieldDef: FacetFieldDef, channel: 'row' | 'column'): VgComparator {\n const {sort} = facetFieldDef;\n if (isSortField(sort)) {\n return {\n field: vgField(sort, {expr: 'datum'}),\n order: sort.order || 'ascending'\n };\n } else if (isArray(sort)) {\n return {\n field: sortArrayIndexField(facetFieldDef, channel, 'datum'),\n order: 'ascending'\n };\n } else {\n return {\n field: vgField(facetFieldDef, {expr: 'datum'}),\n order: sort || 'ascending'\n };\n }\n}\n\nexport function getHeaderGroup(model: Model, channel: HeaderChannel, headerType: HeaderType, layoutHeader: LayoutHeaderComponent, headerCmpt: HeaderComponent) {\n if (headerCmpt) {\n let title = null;\n const {facetFieldDef} = layoutHeader;\n if (facetFieldDef && headerCmpt.labels) {\n const {header = {}} = facetFieldDef;\n const {format, labelAngle} = header;\n const config = model.config? model.config : undefined;\n\n const update = {\n ...labelAlign(labelAngle)\n };\n\n title = {\n text: formatSignalRef(facetFieldDef, format, 'parent', model.config),\n offset: 10,\n orient: channel === 'row' ? 'left' : 'top',\n style: 'guide-label',\n ...getHeaderProperties(config, facetFieldDef, HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP),\n ...(keys(update).length > 0 ? {encode: {update}} : {})\n };\n }\n\n const axes = headerCmpt.axes;\n\n const hasAxes = axes && axes.length > 0;\n if (title || hasAxes) {\n const sizeChannel = channel === 'row' ? 'height' : 'width';\n\n\n\n return {\n name: model.getName(`${channel}_${headerType}`),\n type: 'group',\n role: `${channel}-${headerType}`,\n ...(layoutHeader.facetFieldDef ? {\n from: {data: model.getName(channel + '_domain')},\n sort: getSort(facetFieldDef, channel)\n } : {}),\n ...(title ? {title} : {}),\n ...(headerCmpt.sizeSignal ? {\n encode: {\n update: {\n [sizeChannel]: headerCmpt.sizeSignal\n }\n }\n }: {}),\n ...(hasAxes ? {axes} : {})\n };\n }\n }\n return null;\n}\n\nexport function getHeaderProperties(config: Config, facetFieldDef: FacetFieldDef, properties: string[], propertiesMap: {[k in keyof HeaderConfig]: keyof VgTitleConfig}) {\n const props = {};\n for (const prop of properties) {\n if (config && config.header) {\n if (config.header[prop]) {\n props[propertiesMap[prop]] = config.header[prop];\n }\n }\n if (facetFieldDef && facetFieldDef.header) {\n if (facetFieldDef.header[prop]) {\n props[propertiesMap[prop]] = facetFieldDef.header[prop];\n }\n }\n }\n return props;\n}\n","\nimport {hasDiscreteDomain} from '../../scale';\nimport {isVgRangeStep, VgRangeStep, VgSignal} from '../../vega.schema';\nimport {isFacetModel, Model} from '../model';\nimport {ScaleComponent} from '../scale/component';\n\nexport function assembleLayoutSignals(model: Model): VgSignal[] {\n return [].concat(\n sizeSignals(model, 'width'),\n sizeSignals(model, 'height')\n );\n}\n\nexport function sizeSignals(model: Model, sizeType: 'width' | 'height'): VgSignal[] {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const size = model.component.layoutSize.get(sizeType);\n if (!size || size === 'merged') {\n return [];\n }\n\n // Read size signal name from name map, just in case it is the top-level size signal that got renamed.\n const name = model.getSizeSignalRef(sizeType).signal;\n\n if (size === 'range-step') {\n const scaleComponent = model.getScaleComponent(channel);\n\n if (scaleComponent) {\n const type = scaleComponent.get('type');\n const range = scaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const scaleName = model.scaleName(channel);\n\n if (isFacetModel(model.parent)) {\n // If parent is facet and this is an independent scale, return only signal signal\n // as the width/height will be calculated using the cardinality from\n // facet's aggregate rather than reading from scale domain\n const parentResolve = model.parent.component.resolve;\n if (parentResolve.scale[channel] === 'independent') {\n return [stepSignal(scaleName, range)];\n }\n }\n\n return [\n stepSignal(scaleName, range),\n {\n name,\n update: sizeExpr(scaleName, scaleComponent, `domain('${scaleName}').length`)\n }\n ];\n }\n }\n /* istanbul ignore next: Condition should not happen -- only for warning in development. */\n throw new Error('layout size is range step although there is no rangeStep.');\n } else {\n return [{\n name,\n value: size\n }];\n }\n}\n\nfunction stepSignal(scaleName: string, range: VgRangeStep): VgSignal {\n return {\n name: scaleName + '_step',\n value: range.step,\n };\n}\n\nexport function sizeExpr(scaleName: string, scaleComponent: ScaleComponent, cardinality: string) {\n const type = scaleComponent.get('type');\n const padding = scaleComponent.get('padding');\n let paddingOuter = scaleComponent.get('paddingOuter');\n paddingOuter = paddingOuter !== undefined ? paddingOuter : padding;\n\n let paddingInner = scaleComponent.get('paddingInner');\n paddingInner = type === 'band' ?\n // only band has real paddingInner\n (paddingInner !== undefined ? paddingInner : padding) :\n // For point, as calculated in https://github.com/vega/vega-scale/blob/master/src/band.js#L128,\n // it's equivalent to have paddingInner = 1 since there is only n-1 steps between n points.\n 1;\n return `bandspace(${cardinality}, ${paddingInner}, ${paddingOuter}) * ${scaleName}_step`;\n}\n\n\n","import {POSITION_SCALE_CHANNELS, ScaleChannel} from '../channel';\nimport * as log from '../log';\nimport {Resolve, ResolveMode} from '../resolve';\nimport {contains} from '../util';\nimport {isConcatModel, isFacetModel, isLayerModel, isRepeatModel, Model} from './model';\n\nexport function defaultScaleResolve(channel: ScaleChannel, model: Model): ResolveMode {\n if (isLayerModel(model) || isFacetModel(model)) {\n return 'shared';\n } else if (isConcatModel(model) || isRepeatModel(model)) {\n return contains(POSITION_SCALE_CHANNELS, channel) ? 'independent' : 'shared';\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('invalid model type for resolve');\n}\n\nexport function parseGuideResolve(resolve: Resolve, channel: ScaleChannel): ResolveMode {\n const channelScaleResolve = resolve.scale[channel];\n const guide = contains(POSITION_SCALE_CHANNELS, channel) ? 'axis' : 'legend';\n\n if (channelScaleResolve === 'independent') {\n if (resolve[guide][channel] === 'shared') {\n log.warn(log.message.independentScaleMeansIndependentGuide(channel));\n }\n return 'independent';\n }\n\n return resolve[guide][channel] || 'shared';\n}\n","import * as log from '../log';\nimport {duplicate, keys, stringify} from '../util';\n\n\n/**\n * Generic class for storing properties that are explicitly specified\n * and implicitly determined by the compiler.\n * This is important for scale/axis/legend merging as\n * we want to prioritize properties that users explicitly specified.\n */\nexport class Split {\n constructor(\n public readonly explicit: Partial = {},\n public readonly implicit: Partial = {}\n ) {}\n\n public clone() {\n return new Split(duplicate(this.explicit), duplicate(this.implicit));\n }\n\n public combine(): Partial {\n // FIXME remove \"as any\".\n // Add \"as any\" to avoid an error \"Spread types may only be created from object types\".\n return {\n ...this.explicit as any, // Explicit properties comes first\n ...this.implicit as any\n };\n }\n\n public get(key: K): T[K] {\n // Explicit has higher precedence\n return this.explicit[key] !== undefined ? this.explicit[key] : this.implicit[key];\n }\n\n public getWithExplicit(key: K): Explicit {\n // Explicit has higher precedence\n if (this.explicit[key] !== undefined) {\n return {explicit: true, value: this.explicit[key]};\n } else if (this.implicit[key] !== undefined) {\n return {explicit: false, value: this.implicit[key]};\n }\n return {explicit: false, value: undefined};\n }\n\n public setWithExplicit(key: K, value: Explicit) {\n if (value.value !== undefined) {\n this.set(key, value.value, value.explicit);\n }\n }\n\n public set(key: K, value: T[K], explicit: boolean) {\n delete this[explicit ? 'implicit' : 'explicit'][key];\n this[explicit ? 'explicit' : 'implicit'][key] = value;\n return this;\n }\n\n public copyKeyFromSplit(key: keyof T, s: Split) {\n // Explicit has higher precedence\n if (s.explicit[key] !== undefined) {\n this.set(key, s.explicit[key], true);\n } else if (s.implicit[key] !== undefined) {\n this.set(key, s.implicit[key], false);\n }\n }\n public copyKeyFromObject>(key: keyof T, s: S) {\n // Explicit has higher precedence\n if (s[key] !== undefined) {\n this.set(key, s[key], true);\n }\n }\n\n /**\n * Merge split object into this split object. Properties from the other split\n * overwrite properties from this split.\n */\n public copyAll(other: Split) {\n for (const key of keys(other.combine())) {\n const val = other.getWithExplicit(key);\n this.setWithExplicit(key, val);\n }\n }\n}\n\nexport interface Explicit {\n explicit: boolean;\n value: T;\n}\n\n\nexport function makeExplicit(value: T): Explicit {\n return {\n explicit: true,\n value\n };\n}\n\nexport function makeImplicit(value: T): Explicit {\n return {\n explicit: false,\n value\n };\n}\n\nexport function tieBreakByComparing(compare: (v1: T, v2: T) => number) {\n return (v1: Explicit, v2: Explicit, property: keyof S | never, propertyOf: string | number | symbol): Explicit => {\n const diff = compare(v1.value, v2.value);\n if (diff > 0) {\n return v1;\n } else if (diff < 0) {\n return v2;\n }\n return defaultTieBreaker(v1, v2, property, propertyOf);\n };\n}\n\nexport function defaultTieBreaker(v1: Explicit, v2: Explicit, property: keyof S, propertyOf: string | number | symbol) {\n if (v1.explicit && v2.explicit) {\n log.warn(log.message.mergeConflictingProperty(property, propertyOf, v1.value, v2.value));\n }\n // If equal score, prefer v1.\n return v1;\n}\n\nexport function mergeValuesWithExplicit(\n v1: Explicit, v2: Explicit,\n property: keyof S,\n propertyOf: 'scale' | 'axis' | 'legend' | '',\n tieBreaker: (v1: Explicit, v2: Explicit, property: keyof S, propertyOf: string) => Explicit = defaultTieBreaker\n ) {\n if (v1 === undefined || v1.value === undefined) {\n // For first run\n return v2;\n }\n\n if (v1.explicit && !v2.explicit) {\n return v1;\n } else if (v2.explicit && !v1.explicit) {\n return v2;\n } else if (stringify(v1.value) === stringify(v2.value)) {\n return v1;\n } else {\n return tieBreaker(v1, v2, property, propertyOf);\n }\n}\n","import {Legend} from '../..//legend';\nimport {NonPositionScaleChannel} from '../../channel';\nimport {VgLegend} from '../../vega.schema';\nimport {Split} from '../split';\n\n\nexport class LegendComponent extends Split {}\n\n// Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\nexport type LegendComponentIndex = {[P in NonPositionScaleChannel]?: LegendComponent};\n\nexport type LegendIndex = {[P in NonPositionScaleChannel]?: Legend};\n","import {isArray} from 'vega-util';\n\nimport {Channel, COLOR, NonPositionScaleChannel, OPACITY, SHAPE} from '../../channel';\nimport {\n Conditional,\n FieldDef,\n FieldDefWithCondition,\n hasConditionalValueDef,\n isTimeFieldDef,\n isValueDef,\n MarkPropFieldDef,\n ValueDef,\n ValueDefWithCondition,\n} from '../../fielddef';\nimport {AREA, BAR, CIRCLE, FILL_STROKE_CONFIG, GEOSHAPE, LINE, POINT, SQUARE, TEXT, TICK} from '../../mark';\nimport {ScaleType} from '../../scale';\nimport {keys} from '../../util';\nimport {LegendType, VgEncodeEntry} from '../../vega.schema';\nimport {applyMarkConfig, timeFormatExpression} from '../common';\nimport * as mixins from '../mark/mixins';\nimport {UnitModel} from '../unit';\n\nexport function symbols(fieldDef: FieldDef, symbolsSpec: any, model: UnitModel, channel: Channel, type: LegendType): VgEncodeEntry {\n if (type === 'gradient') {\n return undefined;\n }\n\n let out = {\n ...applyMarkConfig({}, model, FILL_STROKE_CONFIG),\n ...mixins.color(model)\n };\n\n switch (model.mark) {\n case BAR:\n case TICK:\n case TEXT:\n out.shape = {value: 'square'};\n break;\n case CIRCLE:\n case SQUARE:\n out.shape = {value: model.mark};\n break;\n case POINT:\n case LINE:\n case GEOSHAPE:\n case AREA:\n // use default circle\n break;\n }\n\n const {markDef, encoding} = model;\n const filled = markDef.filled;\n\n if (out.fill) {\n // for fill legend, we don't want any fill in symbol\n if (channel === 'fill' || (filled && channel === COLOR)) {\n delete out.fill;\n } else {\n if (out.fill['field']) {\n // For others, remove fill field\n delete out.fill;\n } else if (isArray(out.fill)) {\n const fill = getFirstConditionValue(encoding.fill || encoding.color) || markDef.fill || (filled && markDef.color);\n if (fill) {\n out.fill = {value: fill};\n }\n }\n }\n }\n\n if (out.stroke) {\n if (channel === 'stroke' || (!filled && channel === COLOR)) {\n delete out.stroke;\n } else {\n if (out.stroke['field']) {\n // For others, remove stroke field\n delete out.stroke;\n } else if (isArray(out.stroke)) {\n const stroke = getFirstConditionValue(encoding.stroke || encoding.color) || markDef.stroke || (!filled && markDef.color);\n if (stroke) {\n out.stroke = {value: stroke};\n }\n }\n }\n }\n\n if (out.fill && out.fill['value'] !== 'transparent' && !out.stroke) {\n // for non color channel's legend, we need to override symbol stroke config from Vega config\n out.stroke = {value: 'transparent'};\n }\n\n if (channel !== SHAPE) {\n const shape = getFirstConditionValue(encoding.shape) || markDef.shape;\n if (shape) {\n out.shape = {value: shape};\n }\n }\n\n if (channel !== OPACITY) {\n const opacity = getMaxValue(encoding.opacity) || markDef.opacity;\n if (opacity) { // only apply opacity if it is neither zero or undefined\n out.opacity = {value: opacity};\n }\n }\n\n out = {...out, ...symbolsSpec};\n\n return keys(out).length > 0 ? out : undefined;\n}\n\nexport function gradient(fieldDef: FieldDef, gradientSpec: any, model: UnitModel, channel: Channel, type: LegendType) {\n let out: any = {};\n\n if (type === 'gradient') {\n const opacity = getMaxValue(model.encoding.opacity) || model.markDef.opacity;\n if (opacity) { // only apply opacity if it is neither zero or undefined\n out.opacity = {value: opacity};\n }\n }\n\n out = {...out, ...gradientSpec};\n return keys(out).length > 0 ? out : undefined;\n}\n\nexport function labels(fieldDef: FieldDef, labelsSpec: any, model: UnitModel, channel: NonPositionScaleChannel, type: LegendType) {\n const legend = model.legend(channel);\n const config = model.config;\n\n let out: any = {};\n\n if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC;\n const expr = timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat, isUTCScale);\n labelsSpec = {\n ...(expr ? {text: {signal: expr}} : {}),\n ...labelsSpec,\n };\n }\n\n out = {...out, ...labelsSpec};\n\n return keys(out).length > 0 ? out : undefined;\n}\n\nfunction getMaxValue(channelDef: FieldDefWithCondition> | ValueDefWithCondition>) {\n return getConditionValue(channelDef,\n (v: number, conditionalDef) => Math.max(v, conditionalDef.value as any)\n );\n}\n\nfunction getFirstConditionValue(channelDef: FieldDefWithCondition> | ValueDefWithCondition>) {\n return getConditionValue(channelDef,\n (v: number, conditionalDef) => v !== undefined ? v : conditionalDef.value\n );\n}\n\nfunction getConditionValue(\n channelDef: FieldDefWithCondition> | ValueDefWithCondition>,\n reducer: (val: T, conditionalDef: Conditional) => T\n): T {\n\n if (hasConditionalValueDef(channelDef)) {\n return (isArray(channelDef.condition) ? channelDef.condition : [channelDef.condition])\n .reduce(reducer, channelDef.value as any);\n } else if (isValueDef(channelDef)) {\n return channelDef.value as any;\n }\n return undefined;\n}\n","import {Channel, isColorChannel} from '../../channel';\nimport {FieldDef, valueArray} from '../../fielddef';\nimport {Legend} from '../../legend';\nimport {isBinScale, ScaleType} from '../../scale';\nimport {Type} from '../../type';\nimport {contains} from '../../util';\n\nexport function values(legend: Legend, fieldDef: FieldDef) {\n const vals = legend.values;\n\n if (vals) {\n return valueArray(fieldDef, vals);\n }\n return undefined;\n}\n\nexport function type(t: Type, channel: Channel, scaleType: ScaleType): 'gradient' {\n if (\n isColorChannel(channel) && (\n (t === 'quantitative' && !isBinScale(scaleType)) ||\n (t === 'temporal' && contains(['time', 'utc'], scaleType))\n )\n ) {\n return 'gradient';\n }\n return undefined;\n}\n","import {COLOR, FILL, NonPositionScaleChannel, OPACITY, SHAPE, SIZE, STROKE} from '../../channel';\nimport {isFieldDef, title as fieldDefTitle} from '../../fielddef';\nimport {Legend, LEGEND_PROPERTIES, VG_LEGEND_PROPERTIES} from '../../legend';\nimport {GEOJSON} from '../../type';\nimport {deleteNestedProperty, keys} from '../../util';\nimport {VgLegend, VgLegendEncode} from '../../vega.schema';\nimport {getSpecifiedOrDefaultValue, guideEncodeEntry, mergeTitleComponent, numberFormat} from '../common';\nimport {isUnitModel, Model} from '../model';\nimport {parseGuideResolve} from '../resolve';\nimport {defaultTieBreaker, Explicit, makeImplicit, mergeValuesWithExplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {LegendComponent, LegendComponentIndex} from './component';\nimport * as encode from './encode';\nimport * as properties from './properties';\n\n\nexport function parseLegend(model: Model) {\n if (isUnitModel(model)) {\n model.component.legends = parseUnitLegend(model);\n } else {\n model.component.legends = parseNonUnitLegend(model);\n }\n}\n\nfunction parseUnitLegend(model: UnitModel): LegendComponentIndex {\n const {encoding} = model;\n return [COLOR, FILL, STROKE, SIZE, SHAPE, OPACITY].reduce(function (legendComponent, channel) {\n const def = encoding[channel];\n if (model.legend(channel) && model.getScaleComponent(channel) && !(isFieldDef(def) && (channel === SHAPE && def.type === GEOJSON))) {\n legendComponent[channel] = parseLegendForChannel(model, channel);\n }\n return legendComponent;\n }, {});\n}\n\nfunction getLegendDefWithScale(model: UnitModel, channel: NonPositionScaleChannel): VgLegend {\n // For binned field with continuous scale, use a special scale so we can overrride the mark props and labels\n switch (channel) {\n case COLOR:\n const scale = model.scaleName(COLOR);\n return model.markDef.filled ? {fill: scale} : {stroke: scale};\n case FILL:\n case STROKE:\n case SIZE:\n case SHAPE:\n case OPACITY:\n return {[channel]: model.scaleName(channel)};\n }\n}\n\nexport function parseLegendForChannel(model: UnitModel, channel: NonPositionScaleChannel): LegendComponent {\n const fieldDef = model.fieldDef(channel);\n const legend = model.legend(channel);\n\n const legendCmpt = new LegendComponent({}, getLegendDefWithScale(model, channel));\n\n LEGEND_PROPERTIES.forEach(function(property) {\n const value = getProperty(property, legend, channel, model);\n if (value !== undefined) {\n const explicit =\n // specified legend.values is already respected, but may get transformed.\n property === 'values' ? !!legend.values :\n // title can be explicit if fieldDef.title is set\n property === 'title' && value === model.fieldDef(channel).title ? true :\n // Otherwise, things are explicit if the returned value matches the specified property\n value === legend[property];\n if (explicit || model.config.legend[property] === undefined) {\n legendCmpt.set(property, value, explicit);\n }\n }\n });\n\n // 2) Add mark property definition groups\n const legendEncoding = legend.encoding || {};\n const legendEncode = ['labels', 'legend', 'title', 'symbols', 'gradient'].reduce((e: VgLegendEncode, part) => {\n const legendEncodingPart = guideEncodeEntry(legendEncoding[part] || {}, model);\n const value = encode[part] ?\n // TODO: replace legendCmpt with type is sufficient\n encode[part](fieldDef, legendEncodingPart, model, channel, legendCmpt.get('type')) : // apply rule\n legendEncodingPart; // no rule -- just default values\n if (value !== undefined && keys(value).length > 0) {\n e[part] = {update: value};\n }\n return e;\n }, {} as VgLegendEncode);\n\n if (keys(legendEncode).length > 0) {\n legendCmpt.set('encode', legendEncode, !!legend.encoding);\n }\n\n return legendCmpt;\n}\n\nfunction getProperty(property: keyof (Legend | VgLegend), specifiedLegend: Legend, channel: NonPositionScaleChannel, model: UnitModel) {\n const fieldDef = model.fieldDef(channel);\n\n switch (property) {\n case 'format':\n // We don't include temporal field here as we apply format in encode block\n return numberFormat(fieldDef, specifiedLegend.format, model.config);\n case 'title':\n // For falsy value, keep undefined so we use default,\n // but use null for '', null, and false to hide the title\n const specifiedTitle = fieldDef.title !== undefined ? fieldDef.title :\n specifiedLegend.title || (specifiedLegend.title === undefined ? undefined : null);\n\n return getSpecifiedOrDefaultValue(\n specifiedTitle,\n fieldDefTitle(fieldDef, model.config)\n ) || undefined; // make falsy value undefined so output Vega spec is shorter\n case 'values':\n return properties.values(specifiedLegend, fieldDef);\n case 'type':\n return getSpecifiedOrDefaultValue(specifiedLegend.type, properties.type(fieldDef.type, channel, model.getScaleComponent(channel).get('type')));\n }\n\n // Otherwise, return specified property.\n return specifiedLegend[property];\n}\n\nfunction parseNonUnitLegend(model: Model) {\n const {legends, resolve} = model.component;\n\n for (const child of model.children) {\n parseLegend(child);\n\n keys(child.component.legends).forEach((channel: NonPositionScaleChannel) => {\n resolve.legend[channel] = parseGuideResolve(model.component.resolve, channel);\n\n if (resolve.legend[channel] === 'shared') {\n // If the resolve says shared (and has not been overridden)\n // We will try to merge and see if there is a conflict\n\n legends[channel] = mergeLegendComponent(legends[channel], child.component.legends[channel]);\n\n if (!legends[channel]) {\n // If merge returns nothing, there is a conflict so we cannot make the legend shared.\n // Thus, mark legend as independent and remove the legend component.\n resolve.legend[channel] = 'independent';\n delete legends[channel];\n }\n }\n });\n }\n\n keys(legends).forEach((channel: NonPositionScaleChannel) => {\n for (const child of model.children) {\n if (!child.component.legends[channel]) {\n // skip if the child does not have a particular legend\n continue;\n }\n\n if (resolve.legend[channel] === 'shared') {\n // After merging shared legend, make sure to remove legend from child\n delete child.component.legends[channel];\n }\n }\n });\n return legends;\n}\n\nexport function mergeLegendComponent(mergedLegend: LegendComponent, childLegend: LegendComponent): LegendComponent {\n if (!mergedLegend) {\n return childLegend.clone();\n }\n const mergedOrient = mergedLegend.getWithExplicit('orient');\n const childOrient = childLegend.getWithExplicit('orient');\n\n\n if (mergedOrient.explicit && childOrient.explicit && mergedOrient.value !== childOrient.value) {\n // TODO: throw warning if resolve is explicit (We don't have info about explicit/implicit resolve yet.)\n // Cannot merge due to inconsistent orient\n return undefined;\n }\n let typeMerged = false;\n // Otherwise, let's merge\n for (const prop of VG_LEGEND_PROPERTIES) {\n const mergedValueWithExplicit = mergeValuesWithExplicit(\n mergedLegend.getWithExplicit(prop),\n childLegend.getWithExplicit(prop),\n prop, 'legend',\n\n // Tie breaker function\n (v1: Explicit, v2: Explicit): any => {\n switch (prop) {\n case 'title':\n return mergeTitleComponent(v1, v2);\n case 'type':\n // There are only two types. If we have different types, then prefer symbol over gradient.\n typeMerged = true;\n return makeImplicit('symbol');\n }\n return defaultTieBreaker(v1, v2, prop, 'legend');\n }\n );\n mergedLegend.setWithExplicit(prop, mergedValueWithExplicit);\n }\n if (typeMerged) {\n if(((mergedLegend.implicit || {}).encode || {}).gradient) {\n deleteNestedProperty(mergedLegend.implicit, ['encode', 'gradient']);\n }\n if (((mergedLegend.explicit || {}).encode || {}).gradient) {\n deleteNestedProperty(mergedLegend.explicit, ['encode', 'gradient']);\n }\n }\n\n\n return mergedLegend;\n}\n\n","import {flatten, keys, stringify, vals} from '../../util';\nimport {VgLegend} from '../../vega.schema';\nimport {Model} from '../model';\nimport {LegendComponent} from './component';\nimport {mergeLegendComponent} from './parse';\n\nexport function assembleLegends(model: Model): VgLegend[] {\n const legendComponentIndex = model.component.legends;\n const legendByDomain: {[domainHash: string]: LegendComponent[]} = {};\n\n for (const channel of keys(legendComponentIndex)) {\n const scaleComponent = model.getScaleComponent(channel);\n const domainHash = stringify(scaleComponent.domains);\n if (legendByDomain[domainHash]) {\n for (const mergedLegendComponent of legendByDomain[domainHash]) {\n const merged = mergeLegendComponent(mergedLegendComponent, legendComponentIndex[channel]);\n if (!merged) {\n // If cannot merge, need to add this legend separately\n legendByDomain[domainHash].push(legendComponentIndex[channel]);\n }\n }\n\n } else {\n legendByDomain[domainHash] = [legendComponentIndex[channel].clone()];\n }\n }\n\n return flatten(vals(legendByDomain)).map((legendCmpt: LegendComponent) => legendCmpt.combine());\n}\n","import {contains} from '../../util';\nimport {isVgSignalRef, VgProjection, VgSignalRef} from '../../vega.schema';\nimport {isConcatModel, isLayerModel, isRepeatModel, Model} from '../model';\n\nexport function assembleProjections(model: Model): VgProjection[] {\n if (isLayerModel(model) || isConcatModel(model) || isRepeatModel(model)) {\n return assembleProjectionsForModelAndChildren(model);\n } else {\n return assembleProjectionForModel(model);\n }\n}\n\nexport function assembleProjectionsForModelAndChildren(model: Model): VgProjection[] {\n return model.children.reduce((projections, child) => {\n return projections.concat(child.assembleProjections());\n }, assembleProjectionForModel(model));\n}\n\nexport function assembleProjectionForModel(model: Model): VgProjection[] {\n const component = model.component.projection;\n if (!component || component.merged) {\n return [];\n }\n\n const projection = component.combine();\n const {name, ...rest} = projection; // we need to extract name so that it is always present in the output and pass TS type validation\n\n const size: VgSignalRef = {\n signal: `[${component.size.map((ref) => ref.signal).join(', ')}]`\n };\n\n const fit: string[] = component.data.reduce((sources, data) => {\n const source: string = isVgSignalRef(data) ? data.signal : `data('${model.lookupDataSource(data)}')`;\n if (!contains(sources, source)) {\n // build a unique list of sources\n sources.push(source);\n }\n return sources;\n }, []);\n\n if (fit.length <= 0) {\n throw new Error(\"Projection's fit didn't find any data sources\");\n }\n\n return [{\n name,\n size,\n fit: {\n signal: fit.length > 1 ? `[${fit.join(', ')}]` : fit[0]\n },\n ...rest\n }];\n}\n","\nimport {VgProjectionType} from './vega.schema';\n\nexport type ProjectionType = VgProjectionType;\n\nexport interface Projection {\n /**\n * The cartographic projection to use. This value is case-insensitive, for example `\"albers\"` and `\"Albers\"` indicate the same projection type. You can find all valid projection types [in the documentation](https://vega.github.io/vega-lite/docs/projection.html#projection-types).\n *\n * __Default value:__ `mercator`\n */\n type?: ProjectionType;\n\n /**\n * Sets the projection’s clipping circle radius to the specified angle in degrees. If `null`, switches to [antimeridian](http://bl.ocks.org/mbostock/3788999) cutting rather than small-circle clipping.\n */\n clipAngle?: number;\n\n /**\n * Sets the projection’s viewport clip extent to the specified bounds in pixels. The extent bounds are specified as an array `[[x0, y0], [x1, y1]]`, where `x0` is the left-side of the viewport, `y0` is the top, `x1` is the right and `y1` is the bottom. If `null`, no viewport clipping is performed.\n */\n clipExtent?: number[][];\n\n /**\n * Sets the projection’s center to the specified center, a two-element array of longitude and latitude in degrees.\n *\n * __Default value:__ `[0, 0]`\n */\n center?: number[];\n\n /**\n * Sets the projection’s three-axis rotation to the specified angles, which must be a two- or three-element array of numbers [`lambda`, `phi`, `gamma`] specifying the rotation angles in degrees about each spherical axis. (These correspond to yaw, pitch and roll.)\n *\n * __Default value:__ `[0, 0, 0]`\n */\n rotate?: number[];\n\n /**\n * Sets the threshold for the projection’s [adaptive resampling](http://bl.ocks.org/mbostock/3795544) to the specified value in pixels. This value corresponds to the [Douglas–Peucker distance](http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm). If precision is not specified, returns the projection’s current resampling precision which defaults to `√0.5 ≅ 0.70710…`.\n */\n precision?: String;\n\n /* The following properties are all supported for specific types of projections. Consult the d3-geo-projection library for more information: https://github.com/d3/d3-geo-projection */\n coefficient?: number;\n distance?: number;\n fraction?: number;\n lobes?: number;\n parallel?: number;\n radius?: number;\n ratio?: number;\n spacing?: number;\n tilt?: number;\n}\n\n/**\n * Any property of Projection can be in config\n */\nexport interface ProjectionConfig extends Projection { }\n\nexport const PROJECTION_PROPERTIES: (keyof Projection)[] = [\n 'type',\n 'clipAngle',\n 'clipExtent',\n 'center',\n 'rotate',\n 'precision',\n 'coefficient',\n 'distance',\n 'fraction',\n 'lobes',\n 'parallel',\n 'radius',\n 'ratio',\n 'spacing',\n 'tilt'\n];\n","import {Projection} from '../../projection';\nimport {VgProjection, VgSignalRef} from '../../vega.schema';\nimport {Split} from '../split';\n\nexport class ProjectionComponent extends Split {\n public merged = false;\n\n constructor(name: string, public specifiedProjection: Projection, public size: VgSignalRef[], public data: (string | VgSignalRef)[]) {\n super(\n {...specifiedProjection}, // all explicit properties of projection\n {name} // name as initial implicit property\n );\n }\n}\n","import {LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2, SHAPE} from '../../channel';\nimport {MAIN} from '../../data';\nimport {PROJECTION_PROPERTIES} from '../../projection';\nimport {GEOJSON} from '../../type';\nimport {duplicate, every, stringify} from '../../util';\nimport {VgSignalRef} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {UnitModel} from '../unit';\nimport {ProjectionComponent} from './component';\n\nexport function parseProjection(model: Model) {\n if (isUnitModel(model)) {\n model.component.projection = parseUnitProjection(model);\n } else {\n // because parse happens from leaves up (unit specs before layer spec),\n // we can be sure that the above if statement has already occurred\n // and therefore we have access to child.component.projection\n // for each of model's children\n model.component.projection = parseNonUnitProjections(model);\n }\n}\n\nfunction parseUnitProjection(model: UnitModel): ProjectionComponent {\n const {specifiedProjection, config, hasProjection} = model;\n\n if (hasProjection) {\n const data: (VgSignalRef | string)[] = [];\n\n [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach((posssiblePair) => {\n if (model.channelHasField(posssiblePair[0]) || model.channelHasField(posssiblePair[1])) {\n data.push({\n signal: model.getName(`geojson_${data.length}`)\n });\n }\n });\n\n if (model.channelHasField(SHAPE) && model.fieldDef(SHAPE).type === GEOJSON) {\n data.push({\n signal: model.getName(`geojson_${data.length}`)\n });\n }\n\n if (data.length === 0) {\n // main source is geojson, so we can just use that\n data.push(model.requestDataName(MAIN));\n }\n\n return new ProjectionComponent(model.projectionName(true), {\n ...(config.projection || {}),\n ...(specifiedProjection || {}),\n }, [model.getSizeSignalRef('width'), model.getSizeSignalRef('height')], data);\n }\n\n return undefined;\n}\n\n\nfunction mergeIfNoConflict(first: ProjectionComponent, second: ProjectionComponent): ProjectionComponent {\n const allPropertiesShared = every(PROJECTION_PROPERTIES, (prop) => {\n // neither has the poperty\n if (!first.explicit.hasOwnProperty(prop) &&\n !second.explicit.hasOwnProperty(prop)) {\n return true;\n }\n // both have property and an equal value for property\n if (first.explicit.hasOwnProperty(prop) &&\n second.explicit.hasOwnProperty(prop) &&\n // some properties might be signals or objects and require hashing for comparison\n stringify(first.get(prop)) === stringify(second.get(prop))) {\n return true;\n }\n return false;\n });\n\n const size = stringify(first.size) === stringify(second.size);\n if (size) {\n if (allPropertiesShared) {\n return first;\n } else if (stringify(first.explicit) === stringify({})) {\n return second;\n } else if (stringify(second.explicit) === stringify({})) {\n return first;\n }\n }\n\n // if all properties don't match, let each unit spec have its own projection\n return null;\n}\n\nfunction parseNonUnitProjections(model: Model): ProjectionComponent {\n if (model.children.length === 0) {\n return undefined;\n }\n\n let nonUnitProjection: ProjectionComponent;\n const mergable = every(model.children, (child) => {\n parseProjection(child);\n const projection = child.component.projection;\n if (!projection) {\n // child layer does not use a projection\n return true;\n } else if (!nonUnitProjection) {\n // cached 'projection' is null, cache this one\n nonUnitProjection = projection;\n return true;\n } else {\n const merge = mergeIfNoConflict(nonUnitProjection, projection);\n if (merge) {\n nonUnitProjection = merge;\n }\n return !!merge;\n }\n });\n\n // it cached one and all other children share the same projection,\n if (nonUnitProjection && mergable) {\n // so we can elevate it to the layer level\n const name = model.projectionName(true);\n const modelProjection = new ProjectionComponent(\n name,\n nonUnitProjection.specifiedProjection,\n nonUnitProjection.size,\n duplicate(nonUnitProjection.data)\n );\n\n // rename and assign all others as merged\n model.children.forEach((child) => {\n if (child.component.projection) {\n modelProjection.data = modelProjection.data.concat(child.component.projection.data);\n child.renameProjection(child.component.projection.get('name'), name);\n child.component.projection.merged = true;\n }\n });\n\n return modelProjection;\n }\n\n return undefined;\n}\n","import {AggregateOp} from 'vega';\n\nimport {Channel, isScaleChannel} from '../../channel';\nimport {FieldDef, vgField} from '../../fielddef';\nimport * as log from '../../log';\nimport {AggregateTransform} from '../../transform';\nimport {Dict, differ, duplicate, keys, StringSet} from '../../util';\nimport {VgAggregateTransform} from '../../vega.schema';\nimport {binRequiresRange} from '../common';\nimport {UnitModel} from './../unit';\nimport {DataFlowNode} from './dataflow';\n\nfunction addDimension(dims: {[field: string]: boolean}, channel: Channel, fieldDef: FieldDef) {\n if (fieldDef.bin) {\n dims[vgField(fieldDef, {})] = true;\n dims[vgField(fieldDef, {binSuffix: 'end'})] = true;\n\n if (binRequiresRange(fieldDef, channel)) {\n dims[vgField(fieldDef, {binSuffix: 'range'})] = true;\n }\n } else {\n dims[vgField(fieldDef)] = true;\n }\n return dims;\n}\n\nfunction mergeMeasures(parentMeasures: Dict>, childMeasures: Dict>) {\n for (const f in childMeasures) {\n if (childMeasures.hasOwnProperty(f)) {\n // when we merge a measure, we either have to add an aggregation operator or even a new field\n const ops = childMeasures[f];\n for (const op in ops) {\n if (ops.hasOwnProperty(op)) {\n if (f in parentMeasures) {\n // add operator to existing measure field\n parentMeasures[f][op] = ops[op];\n } else {\n parentMeasures[f] = {op: ops[op]};\n }\n }\n }\n }\n }\n}\n\nexport class AggregateNode extends DataFlowNode {\n public clone() {\n return new AggregateNode(null, {...this.dimensions}, duplicate(this.measures));\n }\n\n /**\n * @param dimensions string set for dimensions\n * @param measures dictionary mapping field name => dict of aggregation functions and names to use\n */\n constructor(parent: DataFlowNode, private dimensions: StringSet, private measures: Dict<{[key in AggregateOp]?: string}>) {\n super(parent);\n }\n\n public static makeFromEncoding(parent: DataFlowNode, model: UnitModel): AggregateNode {\n let isAggregate = false;\n model.forEachFieldDef(fd => {\n if (fd.aggregate) {\n isAggregate = true;\n }\n });\n\n const meas = {};\n const dims = {};\n\n if (!isAggregate) {\n // no need to create this node if the model has no aggregation\n return null;\n }\n\n model.forEachFieldDef((fieldDef, channel) => {\n const {aggregate, field} = fieldDef;\n if (aggregate) {\n if (aggregate === 'count') {\n meas['*'] = meas['*'] || {};\n meas['*']['count'] = vgField(fieldDef);\n } else {\n meas[field] = meas[field] || {};\n meas[field][aggregate] = vgField(fieldDef);\n\n // For scale channel with domain === 'unaggregated', add min/max so we can use their union as unaggregated domain\n if (isScaleChannel(channel) && model.scaleDomain(channel) === 'unaggregated') {\n meas[field]['min'] = vgField({field, aggregate: 'min'});\n meas[field]['max'] = vgField({field, aggregate: 'max'});\n }\n }\n } else {\n addDimension(dims, channel, fieldDef);\n }\n });\n\n if ((keys(dims).length + keys(meas).length) === 0) {\n return null;\n }\n\n return new AggregateNode(parent, dims, meas);\n }\n\n public static makeFromTransform(parent: DataFlowNode, t: AggregateTransform): AggregateNode {\n const dims = {};\n const meas = {};\n\n for (const s of t.aggregate) {\n const {op, field, as} = s;\n if (op) {\n if (op === 'count') {\n meas['*'] = meas['*'] || {};\n meas['*']['count'] = as || vgField(s);\n } else {\n meas[field] = meas[field] || {};\n meas[field][op] = as || vgField(s);\n }\n }\n }\n\n for (const s of t.groupby || []) {\n dims[s] = true;\n }\n\n if ((keys(dims).length + keys(meas).length) === 0) {\n return null;\n }\n\n return new AggregateNode(parent, dims, meas);\n }\n\n public merge(other: AggregateNode) {\n if (!differ(this.dimensions, other.dimensions)) {\n mergeMeasures(this.measures, other.measures);\n other.remove();\n } else {\n log.debug('different dimensions, cannot merge');\n }\n }\n\n public addDimensions(fields: string[]) {\n fields.forEach(f => this.dimensions[f] = true);\n }\n\n public dependentFields() {\n const out = {};\n\n keys(this.dimensions).forEach(f => out[f] = true);\n keys(this.measures).forEach(m => out[m] = true);\n\n return out;\n }\n\n public producedFields() {\n const out = {};\n\n keys(this.measures).forEach(field => {\n keys(this.measures[field]).forEach(op => {\n out[`${op}_${field}`] = true;\n });\n });\n\n return out;\n }\n\n public assemble(): VgAggregateTransform {\n const ops: AggregateOp[] = [];\n const fields: string[] = [];\n const as: string[] = [];\n\n for (const field of keys(this.measures)) {\n for (const op of keys(this.measures[field])) {\n as.push(this.measures[field][op]);\n ops.push(op);\n fields.push(field);\n }\n }\n\n const result: VgAggregateTransform = {\n type: 'aggregate',\n groupby: keys(this.dimensions),\n ops,\n fields,\n as\n };\n\n return result;\n }\n}\n","import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {COLUMN, ROW, ScaleChannel} from '../../channel';\nimport {vgField} from '../../fielddef';\nimport * as log from '../../log';\nimport {hasDiscreteDomain} from '../../scale';\nimport {EncodingSortField, isSortField} from '../../sort';\nimport {isVgRangeStep, VgData} from '../../vega.schema';\nimport {FacetModel} from '../facet';\nimport {Model} from '../model';\nimport {assembleDomain, getFieldFromDomain} from '../scale/domain';\nimport {sortArrayIndexField} from './calculate';\nimport {DataFlowNode} from './dataflow';\n\ntype ChildIndependentFieldsWithStep = {\n x?: string,\n y?: string\n};\n\ninterface FacetChannelInfo {\n name: string;\n fields: string[];\n sortField?: EncodingSortField;\n\n sortIndexField?: string;\n}\n\n/**\n * A node that helps us track what fields we are faceting by.\n */\nexport class FacetNode extends DataFlowNode {\n private readonly column: FacetChannelInfo;\n\n private readonly row: FacetChannelInfo;\n\n private readonly childModel: Model;\n\n /**\n * @param model The facet model.\n * @param name The name that this facet source will have.\n * @param data The source data for this facet data.\n */\n public constructor(parent: DataFlowNode, public readonly model: FacetModel, public readonly name: string, public data: string) {\n super(parent);\n\n for (const channel of [COLUMN, ROW]) {\n const fieldDef = model.facet[channel];\n if (fieldDef) {\n const {bin, sort} = fieldDef;\n this[channel] = {\n name: model.getName(`${channel}_domain`),\n fields: [\n vgField(fieldDef),\n ...(bin ? [vgField(fieldDef, {binSuffix: 'end'})] : [])\n ],\n ...(\n isSortField(sort) ? {sortField: sort} :\n isArray(sort) ? {sortIndexField: sortArrayIndexField(fieldDef, channel)} :\n {}\n )\n };\n }\n }\n this.childModel = model.child;\n }\n\n get fields() {\n return [\n ...(this.column && this.column.fields) || [],\n ...(this.row && this.row.fields) || []\n ];\n }\n\n /**\n * The name to reference this source is its name.\n */\n public getSource() {\n return this.name;\n }\n\n private getChildIndependentFieldsWithStep() {\n const childIndependentFieldsWithStep: ChildIndependentFieldsWithStep = {};\n\n for (const channel of ['x', 'y'] as ScaleChannel[]) {\n const childScaleComponent = this.childModel.component.scales[channel];\n if (childScaleComponent && !childScaleComponent.merged) {\n const type = childScaleComponent.get('type');\n const range = childScaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const domain = assembleDomain(this.childModel, channel);\n const field = getFieldFromDomain(domain);\n if (field) {\n childIndependentFieldsWithStep[channel] = field;\n } else {\n log.warn('Unknown field for ${channel}. Cannot calculate view size.');\n }\n }\n }\n }\n\n return childIndependentFieldsWithStep;\n }\n\n private assembleRowColumnData(channel: 'row' | 'column', crossedDataName: string, childIndependentFieldsWithStep: ChildIndependentFieldsWithStep): VgData {\n const childChannel = channel === 'row' ? 'y' : 'x';\n\n const fields: string[] = [];\n const ops: AggregateOp[] = [];\n const as: string[] = [];\n\n if (childIndependentFieldsWithStep[childChannel]) {\n if (crossedDataName) {\n // If there is a crossed data, calculate max\n fields.push(`distinct_${childIndependentFieldsWithStep[childChannel]}`);\n\n ops.push('max');\n } else {\n // If there is no crossed data, just calculate distinct\n fields.push(childIndependentFieldsWithStep[childChannel]);\n ops.push('distinct');\n }\n // Although it is technically a max, just name it distinct so it's easier to refer to it\n as.push(`distinct_${childIndependentFieldsWithStep[childChannel]}`);\n }\n\n const {sortField, sortIndexField} = this[channel];\n if (sortField) {\n const {op, field} = sortField;\n fields.push(field);\n ops.push(op);\n as.push(vgField(sortField));\n } else if (sortIndexField) {\n fields.push(sortIndexField);\n ops.push('max');\n as.push(sortIndexField);\n }\n\n return {\n name: this[channel].name,\n // Use data from the crossed one if it exist\n source: crossedDataName || this.data,\n transform: [{\n type: 'aggregate',\n groupby: this[channel].fields,\n ...(fields.length ? {\n fields, ops, as\n } : {})\n }]\n };\n }\n\n public assemble() {\n const data: VgData[] = [];\n let crossedDataName = null;\n const childIndependentFieldsWithStep = this.getChildIndependentFieldsWithStep();\n\n if (this.column && this.row && (childIndependentFieldsWithStep.x || childIndependentFieldsWithStep.y)) {\n // Need to create a cross dataset to correctly calculate cardinality\n crossedDataName = `cross_${this.column.name}_${this.row.name}`;\n\n const fields = [].concat(\n childIndependentFieldsWithStep.x ? [childIndependentFieldsWithStep.x] : [],\n childIndependentFieldsWithStep.y ? [childIndependentFieldsWithStep.y] : [],\n );\n const ops = fields.map((): AggregateOp => 'distinct');\n\n data.push({\n name: crossedDataName,\n source: this.data,\n transform: [{\n type: 'aggregate',\n groupby: [...this.column.fields, ...this.row.fields],\n fields,\n ops\n }]\n });\n }\n\n for (const channel of [COLUMN, ROW]) {\n if (this[channel]) {\n data.push(this.assembleRowColumnData(channel, crossedDataName, childIndependentFieldsWithStep));\n }\n }\n\n return data;\n }\n}\n","import {isScaleChannel} from '../../channel';\nimport {FieldDef, vgField as fieldRef} from '../../fielddef';\nimport {isPathMark} from '../../mark';\nimport {hasContinuousDomain, ScaleType} from '../../scale';\nimport {Dict, keys} from '../../util';\nimport {VgFilterTransform} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {DataFlowNode} from './dataflow';\n\nexport class FilterInvalidNode extends DataFlowNode {\n public clone() {\n return new FilterInvalidNode(null, {...this.fieldDefs});\n }\n\n constructor(parent: DataFlowNode, private fieldDefs: Dict>) {\n super(parent);\n }\n\n public static make(parent: DataFlowNode, model: UnitModel): FilterInvalidNode {\n const {config, mark} = model;\n if (config.invalidValues !== 'filter' ) {\n return null;\n }\n\n const filter = model.reduceFieldDef((aggregator: Dict>, fieldDef, channel) => {\n const scaleComponent = isScaleChannel(channel) && model.getScaleComponent(channel);\n if (scaleComponent) {\n const scaleType = scaleComponent.get('type');\n\n\n // While discrete domain scales can handle invalid values, continuous scales can't.\n // Thus, for non-path marks, we have to filter null for scales with continuous domains.\n // (For path marks, we will use \"defined\" property and skip these values instead.)\n if (hasContinuousDomain(scaleType) && !fieldDef.aggregate && !isPathMark(mark)) {\n aggregator[fieldDef.field] = fieldDef;\n }\n }\n return aggregator;\n }, {} as Dict>);\n\n if (!keys(filter).length) {\n return null;\n }\n\n return new FilterInvalidNode(parent, filter);\n }\n\n get filter() {\n return this.fieldDefs;\n }\n\n // create the VgTransforms for each of the filtered fields\n public assemble(): VgFilterTransform {\n const filters = keys(this.filter).reduce((vegaFilters, field) => {\n const fieldDef = this.fieldDefs[field];\n const ref = fieldRef(fieldDef, {expr: 'datum'});\n\n if (fieldDef !== null) {\n vegaFilters.push(`${ref} !== null`);\n vegaFilters.push(`!isNaN(${ref})`);\n }\n return vegaFilters;\n }, []);\n\n return filters.length > 0 ?\n {\n type: 'filter',\n expr: filters.join(' && ')\n } : null;\n }\n}\n","import {isNumber, isString, toSet} from 'vega-util';\nimport {AncestorParse} from '.';\nimport {isCountingAggregateOp} from '../../aggregate';\nimport {DateTime, isDateTime} from '../../datetime';\nimport {isNumberFieldDef, isScaleFieldDef, isTimeFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {forEachLeaf} from '../../logical';\nimport {isFieldEqualPredicate, isFieldOneOfPredicate, isFieldPredicate, isFieldRangePredicate} from '../../predicate';\nimport {isSortField} from '../../sort';\nimport {FilterTransform} from '../../transform';\nimport {accessPathDepth, accessPathWithDatum, Dict, duplicate, keys, removePathFromField, StringSet} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\nimport {isFacetModel, isUnitModel, Model} from '../model';\nimport {Split} from '../split';\nimport {DataFlowNode} from './dataflow';\n\n\n/**\n * @param field The field.\n * @param parse What to parse the field as.\n */\nfunction parseExpression(field: string, parse: string): string {\n const f = accessPathWithDatum(field);\n if (parse === 'number') {\n return `toNumber(${f})`;\n } else if (parse === 'boolean') {\n return `toBoolean(${f})`;\n } else if (parse === 'string') {\n return `toString(${f})`;\n } else if (parse === 'date') {\n return `toDate(${f})`;\n } else if (parse === 'flatten') {\n return f;\n } else if (parse.indexOf('date:') === 0) {\n const specifier = parse.slice(5, parse.length);\n return `timeParse(${f},${specifier})`;\n } else if (parse.indexOf('utc:') === 0) {\n const specifier = parse.slice(4, parse.length);\n return `utcParse(${f},${specifier})`;\n } else {\n log.warn(log.message.unrecognizedParse(parse));\n return null;\n }\n}\n\nexport class ParseNode extends DataFlowNode {\n private _parse: Dict;\n\n public clone() {\n return new ParseNode(null, duplicate(this._parse));\n }\n\n constructor(parent: DataFlowNode, parse: Dict) {\n super(parent);\n\n this._parse = parse;\n }\n\n /**\n * Creates a parse node from a data.format.parse and updates ancestorParse.\n */\n public static makeExplicit(parent: DataFlowNode, model: Model, ancestorParse: AncestorParse) {\n // Custom parse\n let explicit = {};\n const data = model.data;\n if (data && data.format && data.format.parse) {\n explicit = data.format.parse;\n }\n\n return this.makeWithAncestors(parent, explicit, {}, ancestorParse);\n }\n\n public static makeImplicitFromFilterTransform(parent: DataFlowNode, transform: FilterTransform, ancestorParse: AncestorParse) {\n const parse = {};\n forEachLeaf(transform.filter, filter => {\n if (isFieldPredicate(filter)) {\n // Automatically add a parse node for filters with filter objects\n let val: string | number | boolean | DateTime = null;\n\n // For EqualFilter, just use the equal property.\n // For RangeFilter and OneOfFilter, all array members should have\n // the same type, so we only use the first one.\n if (isFieldEqualPredicate(filter)) {\n val = filter.equal;\n } else if (isFieldRangePredicate(filter)) {\n val = filter.range[0];\n } else if (isFieldOneOfPredicate(filter)) {\n val = (filter.oneOf || filter['in'])[0];\n } // else -- for filter expression, we can't infer anything\n if (val) {\n if (isDateTime(val)) {\n parse[filter.field] = 'date';\n } else if (isNumber(val)) {\n parse[filter.field] = 'number';\n } else if (isString(val)) {\n parse[filter.field] = 'string';\n }\n }\n\n if (filter.timeUnit) {\n parse[filter.field] = 'date';\n }\n }\n });\n\n if (keys(parse).length === 0) {\n return null;\n }\n\n return this.makeWithAncestors(parent, {}, parse, ancestorParse);\n }\n\n /**\n * Creates a parse node for implicit parsing from a model and updates ancestorParse.\n */\n public static makeImplicitFromEncoding(parent: DataFlowNode, model: Model, ancestorParse: AncestorParse) {\n const implicit = {};\n\n if (isUnitModel(model) || isFacetModel(model)) {\n // Parse encoded fields\n model.forEachFieldDef(fieldDef => {\n if (isTimeFieldDef(fieldDef)) {\n implicit[fieldDef.field] = 'date';\n } else if (isNumberFieldDef(fieldDef)) {\n if (!isCountingAggregateOp(fieldDef.aggregate)) {\n implicit[fieldDef.field] = 'number';\n }\n } else if (accessPathDepth(fieldDef.field) > 1) {\n // For non-date/non-number (strings and booleans), derive a flattened field for a referenced nested field.\n // (Parsing numbers / dates already flattens numeric and temporal fields.)\n if (!(fieldDef.field in implicit)) {\n implicit[fieldDef.field] = 'flatten';\n }\n } else if (isScaleFieldDef(fieldDef) && isSortField(fieldDef.sort) && accessPathDepth(fieldDef.sort.field) > 1) {\n // Flatten fields that we sort by but that are not otherwise flattened.\n if (!(fieldDef.sort.field in implicit)) {\n implicit[fieldDef.sort.field] = 'flatten';\n }\n }\n });\n }\n\n return this.makeWithAncestors(parent, {}, implicit, ancestorParse);\n }\n\n /**\n * Creates a parse node from \"explicit\" parse and \"implicit\" parse and updates ancestorParse.\n */\n private static makeWithAncestors(parent: DataFlowNode, explicit: Dict, implicit: Dict, ancestorParse: AncestorParse) {\n // We should not parse what has already been parsed in a parent (explicitly or implicitly) or what has been derived (maked as \"derived\"). We also don't need to flatten a field that has already been parsed.\n for (const field of keys(implicit)) {\n const parsedAs = ancestorParse.getWithExplicit(field);\n if (parsedAs.value !== undefined) {\n // We always ignore derived fields even if they are implicitly defined because we expect users to create the right types.\n if (parsedAs.explicit || parsedAs.value === implicit[field] || parsedAs.value === 'derived' || implicit[field] === 'flatten') {\n delete implicit[field];\n } else {\n log.warn(log.message.differentParse(field, implicit[field], parsedAs.value));\n }\n }\n }\n\n for (const field of keys(explicit)) {\n const parsedAs = ancestorParse.get(field);\n if (parsedAs !== undefined) {\n // Don't parse a field again if it has been parsed with the same type already.\n if (parsedAs === explicit[field]) {\n delete explicit[field];\n } else {\n log.warn(log.message.differentParse(field, explicit[field], parsedAs));\n }\n }\n }\n\n const parse = new Split(explicit, implicit);\n\n // add the format parse from this model so that children don't parse the same field again\n ancestorParse.copyAll(parse);\n\n // copy only non-null parses\n const p = {};\n for (const key of keys(parse.combine())) {\n const val = parse.get(key);\n if (val !== null) {\n p[key] = val;\n }\n }\n\n if (keys(p).length === 0 || ancestorParse.parseNothing) {\n return null;\n }\n\n return new ParseNode(parent, p);\n }\n\n public get parse() {\n return this._parse;\n }\n\n public merge(other: ParseNode) {\n this._parse = {...this._parse, ...other.parse};\n other.remove();\n }\n\n /**\n * Assemble an object for Vega's format.parse property.\n */\n public assembleFormatParse() {\n const formatParse = {};\n for (const field of keys(this._parse)) {\n const p = this._parse[field];\n if (accessPathDepth(field) === 1) {\n formatParse[field] = p;\n }\n }\n return formatParse;\n }\n\n // format parse depends and produces all fields in its parse\n public producedFields(): StringSet {\n return toSet(keys(this._parse));\n }\n\n public dependentFields(): StringSet {\n return toSet(keys(this._parse));\n }\n\n public assembleTransforms(onlyNested = false): VgFormulaTransform[] {\n return keys(this._parse)\n .filter(field => onlyNested ? accessPathDepth(field) > 1 : true)\n .map(field => {\n const expr = parseExpression(field, this._parse[field]);\n if (!expr) {\n return null;\n }\n\n const formula: VgFormulaTransform = {\n type: 'formula',\n expr,\n as: removePathFromField(field) // Vega output is always flattened\n };\n return formula;\n }).filter(t => t !== null);\n }\n}\n","import {Data, DataFormatType, isInlineData, isNamedData, isUrlData} from '../../data';\nimport {contains, hash} from '../../util';\nimport {VgData} from '../../vega.schema';\nimport {DataFlowNode} from './dataflow';\n\nexport class SourceNode extends DataFlowNode {\n private _data: Partial;\n\n private _name: string;\n\n private _hash: string | number;\n\n constructor(data: Data) {\n super(null); // source cannot have parent\n\n data = data || {name: 'source'};\n\n if (isInlineData(data)) {\n this._data = {values: data.values};\n } else if (isUrlData(data)) {\n this._data = {url: data.url};\n\n if (!data.format) {\n data.format = {};\n }\n\n if (!data.format || !data.format.type) {\n // Extract extension from URL using snippet from\n // http://stackoverflow.com/questions/680929/how-to-extract-extension-from-filename-string-in-javascript\n let defaultExtension = /(?:\\.([^.]+))?$/.exec(data.url)[1];\n if (!contains(['json', 'csv', 'tsv', 'dsv', 'topojson'], defaultExtension)) {\n defaultExtension = 'json';\n }\n\n // defaultExtension has type string but we ensure that it is DataFormatType above\n data.format.type = defaultExtension as DataFormatType;\n }\n } else if (isNamedData(data)) {\n this._data = {};\n }\n\n // any dataset can be named\n if (data.name) {\n this._name = data.name;\n }\n\n if (data.format) {\n const {parse = null, ...format} = data.format;\n this._data.format = format;\n }\n }\n\n get data() {\n return this._data;\n }\n\n public hasName(): boolean {\n return !!this._name;\n }\n\n get dataName() {\n return this._name;\n }\n\n set dataName(name: string) {\n this._name = name;\n }\n\n set parent(parent: DataFlowNode) {\n throw new Error('Source nodes have to be roots.');\n }\n\n public remove() {\n throw new Error('Source nodes are roots and cannot be removed.');\n }\n\n /**\n * Return a unique identifier for this data source.\n */\n public hash() {\n if (isInlineData(this._data)) {\n if (!this._hash) {\n // Hashing can be expensive for large inline datasets.\n this._hash = hash(this._data);\n }\n return this._hash;\n } else if (isUrlData(this._data)) {\n return hash([this._data.url, this._data.format]);\n } else {\n return this._name;\n }\n }\n\n public assemble(): VgData {\n return {\n name: this._name,\n ...this._data,\n transform: []\n };\n }\n}\n","import {vgField} from '../../fielddef';\nimport {fieldExpr, TimeUnit} from '../../timeunit';\nimport {TimeUnitTransform} from '../../transform';\nimport {Dict, duplicate, keys, vals} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\nimport {ModelWithField} from '../model';\nimport {DataFlowNode} from './dataflow';\n\n\nexport interface TimeUnitComponent {\n as: string;\n timeUnit: TimeUnit;\n field: string;\n}\n\nexport class TimeUnitNode extends DataFlowNode {\n public clone() {\n return new TimeUnitNode(null, duplicate(this.formula));\n }\n\n constructor(parent: DataFlowNode, private formula: Dict) {\n super(parent);\n }\n\n public static makeFromEncoding(parent: DataFlowNode, model: ModelWithField) {\n const formula = model.reduceFieldDef((timeUnitComponent: TimeUnitComponent, fieldDef) => {\n if (fieldDef.timeUnit) {\n const f = vgField(fieldDef);\n timeUnitComponent[f] = {\n as: f,\n timeUnit: fieldDef.timeUnit,\n field: fieldDef.field\n };\n }\n return timeUnitComponent;\n }, {} as Dict);\n\n if (keys(formula).length === 0) {\n return null;\n }\n\n return new TimeUnitNode(parent, formula);\n }\n\n public static makeFromTransform(parent: DataFlowNode, t: TimeUnitTransform) {\n return new TimeUnitNode(parent, {\n [t.field]: {\n as: t.as,\n timeUnit: t.timeUnit,\n field: t.field\n }\n });\n }\n\n public merge(other: TimeUnitNode) {\n this.formula = {...this.formula, ...other.formula};\n other.remove();\n }\n\n public producedFields() {\n const out = {};\n\n vals(this.formula).forEach(f => {\n out[f.as] = true;\n });\n\n return out;\n }\n\n public dependentFields() {\n const out = {};\n\n vals(this.formula).forEach(f => {\n out[f.field] = true;\n });\n\n return out;\n }\n\n public assemble() {\n return vals(this.formula).map(c => {\n return {\n type: 'formula',\n as: c.as,\n expr: fieldExpr(c.timeUnit, c.field)\n } as VgFormulaTransform;\n });\n }\n}\n","import {hasIntersection, keys} from '../../util';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {ParseNode} from './formatparse';\nimport {SourceNode} from './source';\nimport {TimeUnitNode} from './timeunit';\n\n\n/**\n * Start optimization path at the leaves. Useful for merging up or removing things.\n *\n * If the callback returns true, the recursion continues.\n */\nexport function iterateFromLeaves(f: (node: DataFlowNode) => boolean) {\n function optimizeNextFromLeaves(node: DataFlowNode) {\n if (node instanceof SourceNode) {\n return;\n }\n\n const next = node.parent;\n if (f(node)) {\n optimizeNextFromLeaves(next);\n }\n }\n\n return optimizeNextFromLeaves;\n}\n\n/**\n * Move parse nodes up to forks.\n */\nexport function moveParseUp(node: DataFlowNode) {\n const parent = node.parent;\n\n // move parse up by merging or swapping\n if (node instanceof ParseNode) {\n if (parent instanceof SourceNode) {\n return false;\n }\n\n if (parent.numChildren() > 1) {\n // don't move parse further up but continue with parent.\n return true;\n }\n\n if (parent instanceof ParseNode) {\n parent.merge(node);\n } else {\n // don't swap with nodes that produce something that the parse node depends on (e.g. lookup)\n if (hasIntersection(parent.producedFields(), node.dependentFields())) {\n return true;\n }\n\n node.swapWithParent();\n }\n }\n\n return true;\n}\n\n/**\n * Repeatedly remove leaf nodes that are not output or facet nodes.\n * The reason is that we don't need subtrees that don't have any output nodes.\n * Facet nodes are needed for the row or column domains.\n */\nexport function removeUnusedSubtrees(node: DataFlowNode) {\n if (node instanceof OutputNode || node.numChildren() > 0 || node instanceof FacetNode) {\n // no need to continue with parent because it is output node or will have children (there was a fork)\n return false;\n } else {\n node.remove();\n }\n return true;\n}\n\n/**\n * Removes duplicate time unit nodes (as determined by the name of the\n * output field) that may be generated due to selections projected over\n * time units.\n */\nexport function removeDuplicateTimeUnits(leaf: DataFlowNode) {\n let fields = {};\n return iterateFromLeaves((node: DataFlowNode) => {\n if (node instanceof TimeUnitNode) {\n const pfields = node.producedFields();\n const dupe = keys(pfields).every((k) => !!fields[k]);\n\n if (dupe) {\n node.remove();\n } else {\n fields = {...fields, ...pfields};\n }\n }\n\n return true;\n })(leaf);\n}\n","import {isArray, isString} from 'vega-util';\nimport {FieldDef, isFieldDef, vgField} from '../../fielddef';\nimport {StackOffset} from '../../stack';\nimport {StackTransform} from '../../transform';\nimport {duplicate} from '../../util';\nimport {VgComparatorOrder, VgSort, VgTransform} from '../../vega.schema';\nimport {sortParams} from '../common';\nimport {UnitModel} from './../unit';\nimport {DataFlowNode} from './dataflow';\n\nfunction getStackByFields(model: UnitModel): string[] {\n return model.stack.stackBy.reduce((fields, by) => {\n const fieldDef = by.fieldDef;\n\n const _field = vgField(fieldDef);\n if (_field) {\n fields.push(_field);\n }\n return fields;\n }, [] as string[]);\n}\n\nexport interface StackComponent {\n\n /**\n * Faceted field.\n */\n facetby: string[];\n\n dimensionFieldDef?: FieldDef;\n\n /**\n * Stack measure's field. Used in makeFromEncoding.\n */\n stackField: string;\n\n /**\n * Level of detail fields for each level in the stacked charts such as color or detail.\n * Used in makeFromEncoding.\n */\n stackby?: string[];\n\n /**\n * Field that determines order of levels in the stacked charts.\n * Used in both but optional in transform.\n */\n sort: VgSort;\n\n /** Mode for stacking marks.\n */\n offset: StackOffset;\n\n /**\n * Whether to impute the data before stacking. Used only in makeFromEncoding.\n */\n impute?: boolean;\n\n /**\n * The data fields to group by.\n */\n groupby?: string[];\n /**\n * Output field names of each stack field.\n */\n as: string[];\n\n}\n\nfunction isValidAsArray(as: string[] | string): as is string[] {\n return isArray(as) && as.every(s => isString(s)) && as.length >1;\n}\n\nexport class StackNode extends DataFlowNode {\n private _stack: StackComponent;\n\n public clone() {\n return new StackNode(null, duplicate(this._stack));\n }\n\n constructor(parent: DataFlowNode, stack: StackComponent) {\n super(parent);\n\n this._stack = stack;\n }\n\n public static makeFromTransform(parent: DataFlowNode, stackTransform: StackTransform) {\n\n const {stack, groupby, as, offset='zero'} = stackTransform;\n\n const sortFields: string[] = [];\n const sortOrder: VgComparatorOrder[] = [];\n if (stackTransform.sort !== undefined) {\n for (const sortField of stackTransform.sort) {\n sortFields.push(sortField.field);\n sortOrder.push(sortField.order === undefined ? 'ascending' : sortField.order as VgComparatorOrder);\n }\n }\n const sort: VgSort = {\n field: sortFields,\n order: sortOrder,\n };\n let normalizedAs: Array;\n if (isValidAsArray(as)) {\n normalizedAs = as;\n } else if(isString(as)) {\n normalizedAs = [as, as + '_end'];\n } else {\n normalizedAs = [stackTransform.stack + '_start', stackTransform.stack + '_end'];\n }\n\n return new StackNode (parent, {\n stackField: stack,\n groupby,\n offset,\n sort,\n facetby: [],\n as: normalizedAs\n });\n\n }\n public static makeFromEncoding(parent: DataFlowNode, model: UnitModel) {\n\n const stackProperties = model.stack;\n\n if (!stackProperties) {\n return null;\n }\n\n let dimensionFieldDef: FieldDef;\n if (stackProperties.groupbyChannel) {\n dimensionFieldDef = model.fieldDef(stackProperties.groupbyChannel);\n }\n\n const stackby = getStackByFields(model);\n const orderDef = model.encoding.order;\n\n let sort: VgSort;\n if (isArray(orderDef) || isFieldDef(orderDef)) {\n sort = sortParams(orderDef);\n } else {\n // default = descending by stackFields\n // FIXME is the default here correct for binned fields?\n sort = stackby.reduce((s, field) => {\n s.field.push(field);\n s.order.push('descending');\n return s;\n }, {field:[], order: []});\n }\n // Refactored to add \"as\" in the make phase so that we can get producedFields\n // from the as property\n const field = model.vgField(stackProperties.fieldChannel);\n\n return new StackNode(parent, {\n dimensionFieldDef,\n stackField:field,\n facetby: [],\n stackby,\n sort,\n offset: stackProperties.offset,\n impute: stackProperties.impute,\n as: [field + '_start', field + '_end']\n });\n }\n\n get stack(): StackComponent {\n return this._stack;\n }\n\n public addDimensions(fields: string[]) {\n this._stack.facetby = this._stack.facetby.concat(fields);\n }\n\n public dependentFields() {\n const out = {};\n\n out[this._stack.stackField] = true;\n\n this.getGroupbyFields().forEach(f => out[f] = true);\n this._stack.facetby.forEach(f => out[f] = true);\n const field = this._stack.sort.field;\n isArray(field) ? field.forEach(f => out[f] = true) : out[field] = true;\n\n return out;\n }\n\n public producedFields() {\n return this._stack.as.reduce((result, item) => {\n result[item] = true;\n return result;\n }, {});\n }\n\n private getGroupbyFields() {\n const {dimensionFieldDef, impute, groupby} = this._stack;\n if (dimensionFieldDef) {\n if (dimensionFieldDef.bin) {\n if (impute) {\n // For binned group by field with impute, we calculate bin_mid\n // as we cannot impute two fields simultaneously\n return [vgField(dimensionFieldDef, {binSuffix: 'mid'})];\n }\n return [\n // For binned group by field without impute, we need both bin (start) and bin_end\n vgField(dimensionFieldDef, {}),\n vgField(dimensionFieldDef, {binSuffix: 'end'})\n ];\n }\n return [vgField(dimensionFieldDef)];\n }\n return groupby || [];\n }\n\n public assemble(): VgTransform[] {\n const transform: VgTransform[] = [];\n const {facetby, dimensionFieldDef, stackField: field, stackby, sort, offset, impute, as} = this._stack;\n\n // Impute\n if (impute && dimensionFieldDef) {\n const dimensionField = dimensionFieldDef ? vgField(dimensionFieldDef, {binSuffix: 'mid'}): undefined;\n\n if (dimensionFieldDef.bin) {\n // As we can only impute one field at a time, we need to calculate\n // mid point for a binned field\n transform.push({\n type: 'formula',\n expr: '(' +\n vgField(dimensionFieldDef, {expr: 'datum'}) +\n '+' +\n vgField(dimensionFieldDef, {expr: 'datum', binSuffix: 'end'}) +\n ')/2',\n as: dimensionField\n });\n }\n\n transform.push({\n type: 'impute',\n field,\n groupby: stackby,\n key: dimensionField,\n method: 'value',\n value: 0\n });\n }\n\n // Stack\n transform.push({\n type: 'stack',\n groupby: this.getGroupbyFields().concat(facetby),\n field,\n sort,\n as,\n offset\n });\n\n return transform;\n }\n}\n","import {MAIN} from '../../data';\nimport {every, flatten, keys, vals} from '../../util';\nimport {AggregateNode} from './aggregate';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {FilterInvalidNode} from './filterinvalid';\nimport {DataComponent} from './index';\nimport * as optimizers from './optimizers';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\n\nexport const FACET_SCALE_PREFIX = 'scale_';\n\n/**\n * Clones the subtree and ignores output nodes except for the leafs, which are renamed.\n */\nfunction cloneSubtree(facet: FacetNode) {\n function clone(node: DataFlowNode): DataFlowNode[] {\n if (!(node instanceof FacetNode)) {\n const copy = node.clone();\n\n if (copy instanceof OutputNode) {\n const newName = FACET_SCALE_PREFIX + copy.getSource();\n copy.setSource(newName);\n\n facet.model.component.data.outputNodes[newName] = copy;\n } else if (copy instanceof AggregateNode || copy instanceof StackNode) {\n copy.addDimensions(facet.fields);\n }\n flatten(node.children.map(clone)).forEach((n: DataFlowNode) => n.parent = copy);\n\n return [copy];\n }\n\n return flatten(node.children.map(clone));\n }\n return clone;\n}\n\n/**\n * Move facet nodes down to the next fork or output node. Also pull the main output with the facet node.\n * After moving down the facet node, make a copy of the subtree and make it a child of the main output.\n */\nfunction moveFacetDown(node: DataFlowNode) {\n if (node instanceof FacetNode) {\n if (node.numChildren() === 1 && !(node.children[0] instanceof OutputNode)) {\n // move down until we hit a fork or output node\n\n const child = node.children[0];\n\n if (child instanceof AggregateNode || child instanceof StackNode) {\n child.addDimensions(node.fields);\n }\n\n child.swapWithParent();\n moveFacetDown(node);\n } else {\n // move main to facet\n moveMainDownToFacet(node.model.component.data.main);\n\n // replicate the subtree and place it before the facet's main node\n const copy: DataFlowNode[] = flatten(node.children.map(cloneSubtree(node)));\n copy.forEach(c => c.parent = node.model.component.data.main);\n }\n } else {\n node.children.forEach(moveFacetDown);\n }\n}\n\nfunction moveMainDownToFacet(node: DataFlowNode) {\n if (node instanceof OutputNode && node.type === MAIN) {\n if (node.numChildren() === 1) {\n const child = node.children[0];\n\n if (!(child instanceof FacetNode)) {\n child.swapWithParent();\n moveMainDownToFacet(node);\n }\n }\n }\n}\n\n/**\n * Remove nodes that are not required starting from a root.\n */\nfunction removeUnnecessaryNodes(node: DataFlowNode) {\n\n // remove empty null filter nodes\n if (node instanceof FilterInvalidNode && every(vals(node.filter), f => f === null)) {\n node.remove();\n }\n\n // remove output nodes that are not required\n if (node instanceof OutputNode && !node.isRequired()) {\n node.remove();\n }\n\n node.children.forEach(removeUnnecessaryNodes);\n}\n\n/**\n * Return all leaf nodes.\n */\nfunction getLeaves(roots: DataFlowNode[]) {\n const leaves: DataFlowNode[] = [];\n function append(node: DataFlowNode) {\n if (node.numChildren() === 0) {\n leaves.push(node);\n } else {\n node.children.forEach(append);\n }\n }\n\n roots.forEach(append);\n return leaves;\n}\n\n/**\n * Optimizes the dataflow of the passed in data component.\n */\nexport function optimizeDataflow(dataComponent: DataComponent) {\n let roots: SourceNode[] = vals(dataComponent.sources);\n\n roots.forEach(removeUnnecessaryNodes);\n\n // remove source nodes that don't have any children because they also don't have output nodes\n roots = roots.filter(r => r.numChildren() > 0);\n getLeaves(roots).forEach(optimizers.iterateFromLeaves(optimizers.removeUnusedSubtrees));\n roots = roots.filter(r => r.numChildren() > 0);\n\n getLeaves(roots).forEach(optimizers.iterateFromLeaves(optimizers.moveParseUp));\n getLeaves(roots).forEach(optimizers.removeDuplicateTimeUnits);\n\n roots.forEach(moveFacetDown);\n\n keys(dataComponent.sources).forEach(s => {\n if (dataComponent.sources[s].numChildren() === 0) {\n delete dataComponent.sources[s];\n }\n });\n}\n","import {isString} from 'vega-util';\nimport {SHARED_DOMAIN_OP_INDEX} from '../../aggregate';\nimport {binToString, isBinParams} from '../../bin';\nimport {isScaleChannel, ScaleChannel} from '../../channel';\nimport {MAIN, RAW} from '../../data';\nimport {DateTime} from '../../datetime';\nimport {FieldDef, ScaleFieldDef, valueExpr, vgField} from '../../fielddef';\nimport * as log from '../../log';\nimport {Domain, hasDiscreteDomain, isBinScale, isSelectionDomain, ScaleConfig, ScaleType} from '../../scale';\nimport {EncodingSortField, isSortArray, isSortField} from '../../sort';\nimport {TimeUnit} from '../../timeunit';\nimport {Type} from '../../type';\nimport * as util from '../../util';\nimport {isDataRefDomain, isDataRefUnionedDomain, isFieldRefUnionDomain, VgDataRef, VgDomain, VgFieldRefUnionDomain, VgNonUnionDomain, VgSortField, VgUnionSortField} from '../../vega.schema';\nimport {binRequiresRange} from '../common';\nimport {sortArrayIndexField} from '../data/calculate';\nimport {FACET_SCALE_PREFIX} from '../data/optimize';\nimport {isFacetModel, isUnitModel, Model} from '../model';\nimport {SELECTION_DOMAIN} from '../selection/selection';\nimport {UnitModel} from '../unit';\nimport {ScaleComponentIndex} from './component';\n\n\nexport function parseScaleDomain(model: Model) {\n if (isUnitModel(model)) {\n parseUnitScaleDomain(model);\n } else {\n parseNonUnitScaleDomain(model);\n }\n}\n\nfunction parseUnitScaleDomain(model: UnitModel) {\n const scales = model.specifiedScales;\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n util.keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n const specifiedScale = scales[channel];\n const specifiedDomain = specifiedScale ? specifiedScale.domain : undefined;\n\n const domains = parseDomainForChannel(model, channel);\n const localScaleCmpt = localScaleComponents[channel];\n localScaleCmpt.domains = domains;\n\n if (isSelectionDomain(specifiedDomain)) {\n // As scale parsing occurs before selection parsing, we use a temporary\n // signal here and append the scale.domain definition. This is replaced\n // with the correct domainRaw signal during scale assembly.\n // For more information, see isRawSelectionDomain in selection.ts.\n\n // FIXME: replace this with a special property in the scaleComponent\n localScaleCmpt.set('domainRaw', {\n signal: SELECTION_DOMAIN + util.hash(specifiedDomain)\n }, true);\n }\n\n if (model.component.data.isFaceted) {\n // get resolve from closest facet parent as this decides whether we need to refer to cloned subtree or not\n let facetParent: Model = model;\n while (!isFacetModel(facetParent) && facetParent.parent) {\n facetParent = facetParent.parent;\n }\n\n const resolve = facetParent.component.resolve.scale[channel];\n\n if (resolve === 'shared') {\n for (const domain of domains) {\n // Replace the scale domain with data output from a cloned subtree after the facet.\n if (isDataRefDomain(domain)) {\n // use data from cloned subtree (which is the same as data but with a prefix added once)\n domain.data = FACET_SCALE_PREFIX + domain.data.replace(FACET_SCALE_PREFIX, '');\n }\n }\n }\n }\n });\n}\n\nfunction parseNonUnitScaleDomain(model: Model) {\n for (const child of model.children) {\n parseScaleDomain(child);\n }\n\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n util.keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n let domains: VgNonUnionDomain[];\n let domainRaw = null;\n\n for (const child of model.children) {\n const childComponent = child.component.scales[channel];\n if (childComponent) {\n if (domains === undefined) {\n domains = childComponent.domains;\n } else {\n domains = domains.concat(childComponent.domains);\n }\n\n const dr = childComponent.get('domainRaw');\n if (domainRaw && dr && domainRaw.signal !== dr.signal) {\n log.warn('The same selection must be used to override scale domains in a layered view.');\n }\n domainRaw = dr;\n }\n }\n\n localScaleComponents[channel].domains = domains;\n\n if (domainRaw) {\n localScaleComponents[channel].set('domainRaw', domainRaw, true);\n }\n });\n}\n\n\n/**\n * Remove unaggregated domain if it is not applicable\n * Add unaggregated domain if domain is not specified and config.scale.useUnaggregatedDomain is true.\n */\nfunction normalizeUnaggregatedDomain(domain: Domain, fieldDef: FieldDef, scaleType: ScaleType, scaleConfig: ScaleConfig) {\n if (domain === 'unaggregated') {\n const {valid, reason} = canUseUnaggregatedDomain(fieldDef, scaleType);\n if(!valid) {\n log.warn(reason);\n return undefined;\n }\n } else if (domain === undefined && scaleConfig.useUnaggregatedDomain) {\n // Apply config if domain is not specified.\n const {valid} = canUseUnaggregatedDomain(fieldDef, scaleType);\n if (valid) {\n return 'unaggregated';\n }\n }\n\n return domain;\n}\n\nexport function parseDomainForChannel(model: UnitModel, channel: ScaleChannel): VgNonUnionDomain[] {\n const scaleType = model.getScaleComponent(channel).get('type');\n\n const domain = normalizeUnaggregatedDomain(model.scaleDomain(channel), model.fieldDef(channel), scaleType, model.config.scale);\n if (domain !== model.scaleDomain(channel)) {\n model.specifiedScales[channel] = {\n ...model.specifiedScales[channel],\n domain\n };\n }\n\n // If channel is either X or Y then union them with X2 & Y2 if they exist\n if (channel === 'x' && model.channelHasField('x2')) {\n if (model.channelHasField('x')) {\n return parseSingleChannelDomain(scaleType, domain, model, 'x').concat(parseSingleChannelDomain(scaleType, domain, model, 'x2'));\n } else {\n return parseSingleChannelDomain(scaleType, domain, model, 'x2');\n }\n } else if (channel === 'y' && model.channelHasField('y2')) {\n if (model.channelHasField('y')) {\n return parseSingleChannelDomain(scaleType, domain, model, 'y').concat(parseSingleChannelDomain(scaleType, domain, model, 'y2'));\n } else {\n return parseSingleChannelDomain(scaleType, domain, model, 'y2');\n }\n }\n return parseSingleChannelDomain(scaleType, domain, model, channel);\n}\n\nfunction mapDomainToDataSignal(domain: T[], type: Type, timeUnit: TimeUnit) {\n return domain.map(v => {\n const data = valueExpr(v, {timeUnit, type});\n return {signal: `{data: ${data}}`};\n });\n}\n\nfunction parseSingleChannelDomain(scaleType: ScaleType, domain: Domain, model: UnitModel, channel: ScaleChannel | 'x2' | 'y2'): VgNonUnionDomain[] {\n const fieldDef = model.fieldDef(channel);\n\n if (domain && domain !== 'unaggregated' && !isSelectionDomain(domain)) { // explicit value\n const {type, timeUnit} = fieldDef;\n if (type === 'temporal' || timeUnit) {\n return mapDomainToDataSignal(domain, type, timeUnit);\n }\n\n return [domain];\n }\n\n const stack = model.stack;\n if (stack && channel === stack.fieldChannel) {\n if(stack.offset === 'normalize') {\n return [[0, 1]];\n }\n\n const data = model.requestDataName(MAIN);\n return [{\n data,\n field: model.vgField(channel, {suffix: 'start'})\n }, {\n data,\n field: model.vgField(channel, {suffix: 'end'})\n }];\n }\n\n const sort = isScaleChannel(channel) ? domainSort(model, channel, scaleType) : undefined;\n\n if (domain === 'unaggregated') {\n const data = model.requestDataName(MAIN);\n const {field} = fieldDef;\n return [{\n data,\n field: vgField({field, aggregate: 'min'})\n }, {\n data,\n field: vgField({field, aggregate: 'max'})\n }];\n } else if (fieldDef.bin) { // bin\n if (isBinScale(scaleType)) {\n const signal = model.getName(`${binToString(fieldDef.bin)}_${fieldDef.field}_bins`);\n return [{signal: `sequence(${signal}.start, ${signal}.stop + ${signal}.step, ${signal}.step)`}];\n }\n\n if (hasDiscreteDomain(scaleType)) {\n // ordinal bin scale takes domain from bin_range, ordered by bin start\n // This is useful for both axis-based scale (x/y) and legend-based scale (other channels).\n return [{\n // If sort by aggregation of a specified sort field, we need to use RAW table,\n // so we can aggregate values for the scale independently from the main aggregation.\n data: util.isBoolean(sort) ? model.requestDataName(MAIN) : model.requestDataName(RAW),\n // Use range if we added it and the scale does not support computing a range as a signal.\n field: model.vgField(channel, binRequiresRange(fieldDef, channel) ? {binSuffix: 'range'} : {}),\n // we have to use a sort object if sort = true to make the sort correct by bin start\n sort: sort === true || !isSortField(sort) ? {\n field: model.vgField(channel, {}),\n op: 'min' // min or max doesn't matter since we sort by the start of the bin range\n } : sort\n }];\n } else { // continuous scales\n if (channel === 'x' || channel === 'y') {\n if (isBinParams(fieldDef.bin) && fieldDef.bin.extent) {\n return [fieldDef.bin.extent];\n }\n // X/Y position have to include start and end for non-ordinal scale\n const data = model.requestDataName(MAIN);\n return [{\n data,\n field: model.vgField(channel, {})\n }, {\n data,\n field: model.vgField(channel, {binSuffix: 'end'})\n }];\n } else {\n // TODO: use bin_mid\n return [{\n data: model.requestDataName(MAIN),\n field: model.vgField(channel, {})\n }];\n }\n }\n } else if (sort) {\n return [{\n // If sort by aggregation of a specified sort field, we need to use RAW table,\n // so we can aggregate values for the scale independently from the main aggregation.\n data: util.isBoolean(sort) ? model.requestDataName(MAIN) : model.requestDataName(RAW),\n field: model.vgField(channel),\n sort: sort\n }];\n } else {\n return [{\n data: model.requestDataName(MAIN),\n field: model.vgField(channel)\n }];\n }\n}\n\n\nexport function domainSort(model: UnitModel, channel: ScaleChannel, scaleType: ScaleType): true | EncodingSortField {\n if (!hasDiscreteDomain(scaleType)) {\n return undefined;\n }\n\n const fieldDef: ScaleFieldDef = model.fieldDef(channel);\n const sort = fieldDef.sort;\n\n // if the sort is specified with array, use the derived sort index field\n if (isSortArray(sort)) {\n return {\n op: 'min',\n field: sortArrayIndexField(fieldDef, channel),\n order: 'ascending'\n };\n }\n\n // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale)\n if (isSortField(sort)) {\n // flatten nested fields\n return {\n ...sort,\n ...(sort.field ? {field: util.replacePathInField(sort.field)} : {})\n };\n }\n\n if (sort === 'descending') {\n return {\n op: 'min',\n field: model.vgField(channel),\n order: 'descending'\n };\n }\n\n if (util.contains(['ascending', undefined /* default =ascending*/], sort)) {\n return true;\n }\n\n // sort == null\n return undefined;\n}\n\n\n\n/**\n * Determine if a scale can use unaggregated domain.\n * @return {Boolean} Returns true if all of the following conditons applies:\n * 1. `scale.domain` is `unaggregated`\n * 2. Aggregation function is not `count` or `sum`\n * 3. The scale is quantitative or time scale.\n */\nexport function canUseUnaggregatedDomain(fieldDef: FieldDef, scaleType: ScaleType): {valid: boolean, reason?: string} {\n if (!fieldDef.aggregate) {\n return {\n valid: false,\n reason: log.message.unaggregateDomainHasNoEffectForRawField(fieldDef)\n };\n }\n\n if (!SHARED_DOMAIN_OP_INDEX[fieldDef.aggregate]) {\n return {\n valid: false,\n reason: log.message.unaggregateDomainWithNonSharedDomainOp(fieldDef.aggregate)\n };\n }\n\n if (fieldDef.type === 'quantitative') {\n if (scaleType === 'log') {\n return {\n valid: false,\n reason: log.message.unaggregatedDomainWithLogScale(fieldDef)\n };\n }\n }\n\n return {valid: true};\n}\n\n/**\n * Converts an array of domains to a single Vega scale domain.\n */\nexport function mergeDomains(domains: VgNonUnionDomain[]): VgDomain {\n const uniqueDomains = util.unique(domains.map(domain => {\n // ignore sort property when computing the unique domains\n if (isDataRefDomain(domain)) {\n const {sort: _s, ...domainWithoutSort} = domain;\n return domainWithoutSort;\n }\n return domain;\n }), util.hash);\n\n const sorts: VgSortField[] = util.unique(domains.map(d => {\n if (isDataRefDomain(d)) {\n const s = d.sort;\n if (s !== undefined && !util.isBoolean(s)) {\n if (s.op === 'count') {\n // let's make sure that if op is count, we don't use a field\n delete s.field;\n }\n if (s.order === 'ascending') {\n // drop order: ascending as it is the default\n delete s.order;\n }\n }\n return s;\n }\n return undefined;\n }).filter(s => s !== undefined), util.hash);\n\n if (uniqueDomains.length === 1) {\n const domain = domains[0];\n if (isDataRefDomain(domain) && sorts.length > 0) {\n let sort = sorts[0];\n if (sorts.length > 1) {\n log.warn(log.message.MORE_THAN_ONE_SORT);\n sort = true;\n }\n return {\n ...domain,\n sort\n };\n }\n return domain;\n }\n\n // only keep simple sort properties that work with unioned domains\n const simpleSorts = util.unique(sorts.map(s => {\n if (s === true) {\n return s;\n }\n if (s.op === 'count') {\n return s;\n }\n log.warn(log.message.domainSortDropped(s));\n return true;\n }), util.hash) as VgUnionSortField[];\n\n let sort: VgUnionSortField = undefined;\n\n if (simpleSorts.length === 1) {\n sort = simpleSorts[0];\n } else if (simpleSorts.length > 1) {\n log.warn(log.message.MORE_THAN_ONE_SORT);\n sort = true;\n }\n\n const allData = util.unique(domains.map(d => {\n if (isDataRefDomain(d)) {\n return d.data;\n }\n return null;\n }), x => x);\n\n if (allData.length === 1 && allData[0] !== null) {\n // create a union domain of different fields with a single data source\n const domain: VgFieldRefUnionDomain = {\n data: allData[0],\n fields: uniqueDomains.map(d => (d as VgDataRef).field),\n ...(sort ? {sort} : {})\n };\n\n return domain;\n }\n\n return {fields: uniqueDomains, ...(sort ? {sort} : {})};\n}\n\n/**\n * Return a field if a scale single field.\n * Return `undefined` otherwise.\n *\n */\nexport function getFieldFromDomain(domain: VgDomain): string {\n if (isDataRefDomain(domain) && isString(domain.field)) {\n return domain.field;\n } else if (isDataRefUnionedDomain(domain)) {\n let field;\n for (const nonUnionDomain of domain.fields) {\n if (isDataRefDomain(nonUnionDomain) && isString(nonUnionDomain.field)) {\n if (!field) {\n field = nonUnionDomain.field;\n } else if (field !== nonUnionDomain.field) {\n log.warn('Detected faceted independent scales that union domain of multiple fields from different data sources. We will use the first field. The result view size may be incorrect.');\n return field;\n }\n }\n }\n log.warn('Detected faceted independent scales that union domain of identical fields from different source detected. We will assume that this is the same field from a different fork of the same data source. However, if this is not case, the result view size maybe incorrect.');\n return field;\n } else if (isFieldRefUnionDomain(domain)) {\n log.warn('Detected faceted independent scales that union domain of multiple fields from the same data source. We will use the first field. The result view size may be incorrect.');\n const field = domain.fields[0];\n return isString(field) ? field : undefined;\n }\n\n return undefined;\n}\n\nexport function assembleDomain(model: Model, channel: ScaleChannel) {\n const scaleComponent = model.component.scales[channel];\n const domains = scaleComponent.domains.map(domain => {\n // Correct references to data as the original domain's data was determined\n // in parseScale, which happens before parseData. Thus the original data\n // reference can be incorrect.\n\n if (isDataRefDomain(domain)) {\n domain.data = model.lookupDataSource(domain.data);\n }\n return domain;\n });\n\n // domains is an array that has to be merged into a single vega domain\n return mergeDomains(domains);\n}\n","import {isArray} from 'vega-util';\nimport {Channel, ScaleChannel} from '../../channel';\nimport {keys} from '../../util';\nimport {isVgRangeStep, isVgSignalRef, VgRange, VgScale} from '../../vega.schema';\nimport {isConcatModel, isLayerModel, isRepeatModel, Model} from '../model';\nimport {isRawSelectionDomain, selectionScaleDomain} from '../selection/selection';\nimport {assembleDomain} from './domain';\n\nexport function assembleScales(model: Model): VgScale[] {\n if (isLayerModel(model) || isConcatModel(model) || isRepeatModel(model)) {\n // For concat / layer / repeat, include scales of children too\n return model.children.reduce((scales, child) => {\n return scales.concat(assembleScales(child));\n }, assembleScalesForModel(model));\n } else {\n // For facet, child scales would not be included in the parent's scope.\n // For unit, there is no child.\n return assembleScalesForModel(model);\n }\n}\n\nexport function assembleScalesForModel(model: Model): VgScale[] {\n return keys(model.component.scales).reduce((scales: VgScale[], channel: ScaleChannel) => {\n const scaleComponent = model.component.scales[channel];\n if (scaleComponent.merged) {\n // Skipped merged scales\n return scales;\n }\n\n const scale = scaleComponent.combine();\n\n // need to separate const and non const object destruction\n let {domainRaw, range} = scale;\n const {name, type, domainRaw: _d, range: _r, ...otherScaleProps} = scale;\n\n range = assembleScaleRange(range, name, model, channel);\n\n // As scale parsing occurs before selection parsing, a temporary signal\n // is used for domainRaw. Here, we detect if this temporary signal\n // is set, and replace it with the correct domainRaw signal.\n // For more information, see isRawSelectionDomain in selection.ts.\n if (domainRaw && isRawSelectionDomain(domainRaw)) {\n domainRaw = selectionScaleDomain(model, domainRaw);\n }\n\n\n scales.push({\n name,\n type,\n domain: assembleDomain(model, channel),\n ...(domainRaw ? {domainRaw} : {}),\n range: range,\n ...otherScaleProps\n });\n\n return scales;\n }, [] as VgScale[]);\n}\n\nexport function assembleScaleRange(scaleRange: VgRange, scaleName: string, model: Model, channel: Channel) {\n // add signals to x/y range\n if (channel === 'x' || channel === 'y') {\n if (isVgRangeStep(scaleRange)) {\n // For x/y range step, use a signal created in layout assemble instead of a constant range step.\n return {\n step: {signal: scaleName + '_step'}\n };\n } else if (isArray(scaleRange) && scaleRange.length === 2) {\n const r0 = scaleRange[0];\n const r1 = scaleRange[1];\n if (r0 === 0 && isVgSignalRef(r1)) {\n // Replace width signal just in case it is renamed.\n return [0, {signal: model.getSizeName(r1.signal)}];\n } else if (isVgSignalRef(r0) && r1 === 0) {\n // Replace height signal just in case it is renamed.\n return [{signal: model.getSizeName(r0.signal)}, 0];\n }\n }\n }\n return scaleRange;\n}\n","import {ScaleChannel} from '../../channel';\nimport {Scale, ScaleType} from '../../scale';\nimport {Omit} from '../../util';\nimport {VgNonUnionDomain, VgScale} from '../../vega.schema';\nimport {Explicit, Split} from '../split';\n\n/**\n * All VgDomain property except domain.\n * (We exclude domain as we have a special \"domains\" array that allow us merge them all at once in assemble.)\n */\n// TODO: also exclude domainRaw and property implement the right scaleComponent for selection domain\nexport type ScaleComponentProps = Omit;\n\nexport class ScaleComponent extends Split {\n public merged = false;\n\n public domains: VgNonUnionDomain[] = [];\n\n constructor(name: string, typeWithExplicit: Explicit) {\n super(\n {}, // no initial explicit property\n {name} // name as initial implicit property\n );\n this.setWithExplicit('type', typeWithExplicit);\n }\n}\n\n// Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\nexport type ScaleComponentIndex = {[P in ScaleChannel]?: ScaleComponent};\n\nexport type ScaleIndex = {[P in ScaleChannel]?: Scale};\n","import {isNumber} from 'vega-util';\n\nimport {Channel, COLOR, FILL, OPACITY, SCALE_CHANNELS, ScaleChannel, SHAPE, SIZE, STROKE, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport * as log from '../../log';\nimport {Mark} from '../../mark';\nimport {\n channelScalePropertyIncompatability,\n isExtendedScheme,\n Range,\n Scale,\n ScaleConfig,\n ScaleType,\n scaleTypeSupportProperty,\n Scheme,\n} from '../../scale';\nimport {hasContinuousDomain} from '../../scale';\nimport {Type} from '../../type';\nimport * as util from '../../util';\nimport {isVgRangeStep, VgRange, VgScheme} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {Explicit, makeExplicit, makeImplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {ScaleComponentIndex} from './component';\nimport {parseNonUnitScaleProperty} from './properties';\n\n\nexport type RangeMixins = {range: Range} | {rangeStep: number} | {scheme: Scheme};\n\nexport const RANGE_PROPERTIES: (keyof Scale)[] = ['range', 'rangeStep', 'scheme'];\n\n\nexport function parseScaleRange(model: Model) {\n if (isUnitModel(model)) {\n parseUnitScaleRange(model);\n } else {\n parseNonUnitScaleProperty(model, 'range');\n }\n}\n\nfunction parseUnitScaleRange(model: UnitModel) {\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n // use SCALE_CHANNELS instead of scales[channel] to ensure that x, y come first!\n SCALE_CHANNELS.forEach((channel: ScaleChannel) => {\n const localScaleCmpt = localScaleComponents[channel];\n if (!localScaleCmpt) {\n return;\n }\n const mergedScaleCmpt = model.getScaleComponent(channel);\n\n\n const specifiedScale = model.specifiedScales[channel];\n const fieldDef = model.fieldDef(channel);\n\n // Read if there is a specified width/height\n const sizeType = channel === 'x' ? 'width' : channel === 'y' ? 'height' : undefined;\n let sizeSpecified = sizeType ? !!model.component.layoutSize.get(sizeType) : undefined;\n\n const scaleType = mergedScaleCmpt.get('type');\n\n // if autosize is fit, size cannot be data driven\n const rangeStep = util.contains(['point', 'band'], scaleType) || !!specifiedScale.rangeStep;\n if (sizeType && model.fit && !sizeSpecified && rangeStep) {\n log.warn(log.message.CANNOT_FIX_RANGE_STEP_WITH_FIT);\n sizeSpecified = true;\n }\n\n const xyRangeSteps = getXYRangeStep(model);\n\n const rangeWithExplicit = parseRangeForChannel(\n channel, scaleType, fieldDef.type, specifiedScale, model.config,\n localScaleCmpt.get('zero'), model.mark, sizeSpecified, model.getName(sizeType), xyRangeSteps\n );\n\n localScaleCmpt.setWithExplicit('range', rangeWithExplicit);\n });\n}\n\nfunction getXYRangeStep(model: UnitModel) {\n const xyRangeSteps: number[] = [];\n\n const xScale = model.getScaleComponent('x');\n const xRange = xScale && xScale.get('range');\n if (xRange && isVgRangeStep(xRange) && isNumber(xRange.step)) {\n xyRangeSteps.push(xRange.step);\n }\n\n const yScale = model.getScaleComponent('y');\n const yRange = yScale && yScale.get('range');\n if (yRange && isVgRangeStep(yRange) && isNumber(yRange.step)) {\n xyRangeSteps.push(yRange.step);\n }\n\n return xyRangeSteps;\n}\n\n/**\n * Return mixins that includes one of the range properties (range, rangeStep, scheme).\n */\nexport function parseRangeForChannel(\n channel: Channel, scaleType: ScaleType, type: Type, specifiedScale: Scale, config: Config,\n zero: boolean, mark: Mark, sizeSpecified: boolean, sizeSignal: string, xyRangeSteps: number[]\n ): Explicit {\n\n const noRangeStep = sizeSpecified || specifiedScale.rangeStep === null;\n\n // Check if any of the range properties is specified.\n // If so, check if it is compatible and make sure that we only output one of the properties\n for (const property of RANGE_PROPERTIES) {\n if (specifiedScale[property] !== undefined) {\n const supportedByScaleType = scaleTypeSupportProperty(scaleType, property);\n const channelIncompatability = channelScalePropertyIncompatability(channel, property);\n if (!supportedByScaleType) {\n log.warn(log.message.scalePropertyNotWorkWithScaleType(scaleType, property, channel));\n } else if (channelIncompatability) { // channel\n log.warn(channelIncompatability);\n } else {\n switch (property) {\n case 'range':\n return makeExplicit(specifiedScale[property]);\n case 'scheme':\n return makeExplicit(parseScheme(specifiedScale[property]));\n case 'rangeStep':\n const rangeStep = specifiedScale[property];\n if (rangeStep !== null) {\n if (!sizeSpecified) {\n return makeExplicit({step: rangeStep});\n } else {\n // If top-level size is specified, we ignore specified rangeStep.\n log.warn(log.message.rangeStepDropped(channel));\n }\n }\n }\n }\n }\n }\n return makeImplicit(\n defaultRange(\n channel, scaleType, type, config,\n zero, mark, sizeSignal, xyRangeSteps, noRangeStep\n )\n );\n}\n\nfunction parseScheme(scheme: Scheme) {\n if (isExtendedScheme(scheme)) {\n const r: VgScheme = {scheme: scheme.name};\n if (scheme.count) {\n r.count = scheme.count;\n }\n if (scheme.extent) {\n r.extent = scheme.extent;\n }\n return r;\n }\n return {scheme: scheme};\n}\n\nexport function defaultRange(\n channel: Channel, scaleType: ScaleType, type: Type, config: Config, zero: boolean, mark: Mark,\n sizeSignal: string, xyRangeSteps: number[], noRangeStep: boolean\n): VgRange {\n switch (channel) {\n case X:\n case Y:\n if (util.contains(['point', 'band'], scaleType) && !noRangeStep) {\n if (channel === X && mark === 'text') {\n if (config.scale.textXRangeStep) {\n return {step: config.scale.textXRangeStep};\n }\n } else {\n if (config.scale.rangeStep) {\n return {step: config.scale.rangeStep};\n }\n }\n }\n\n // If range step is null, use zero to width or height.\n // Note that these range signals are temporary\n // as they can be merged and renamed.\n // (We do not have the right size signal here since parseLayoutSize() happens after parseScale().)\n // We will later replace these temporary names with\n // the final name in assembleScaleRange()\n\n if (channel === Y && hasContinuousDomain(scaleType)) {\n // For y continuous scale, we have to start from the height as the bottom part has the max value.\n return [{signal: sizeSignal}, 0];\n } else {\n return [0, {signal: sizeSignal}];\n }\n case SIZE:\n // TODO: support custom rangeMin, rangeMax\n const rangeMin = sizeRangeMin(mark, zero, config);\n const rangeMax = sizeRangeMax(mark, xyRangeSteps, config);\n return [rangeMin, rangeMax];\n case SHAPE:\n return 'symbol';\n case COLOR:\n case FILL:\n case STROKE:\n if (scaleType === 'ordinal') {\n // Only nominal data uses ordinal scale by default\n return type === 'nominal' ? 'category' : 'ordinal';\n }\n return mark === 'rect' || mark === 'geoshape' ? 'heatmap' : 'ramp';\n case OPACITY:\n // TODO: support custom rangeMin, rangeMax\n return [config.scale.minOpacity, config.scale.maxOpacity];\n }\n /* istanbul ignore next: should never reach here */\n throw new Error(`Scale range undefined for channel ${channel}`);\n}\n\nfunction sizeRangeMin(mark: Mark, zero: boolean, config: Config) {\n if (zero) {\n return 0;\n }\n switch (mark) {\n case 'bar':\n case 'tick':\n return config.scale.minBandSize;\n case 'line':\n case 'trail':\n case 'rule':\n return config.scale.minStrokeWidth;\n case 'text':\n return config.scale.minFontSize;\n case 'point':\n case 'square':\n case 'circle':\n return config.scale.minSize;\n }\n /* istanbul ignore next: should never reach here */\n // sizeRangeMin not implemented for the mark\n throw new Error(log.message.incompatibleChannel('size', mark));\n}\n\nfunction sizeRangeMax(mark: Mark, xyRangeSteps: number[], config: Config) {\n const scaleConfig = config.scale;\n switch (mark) {\n case 'bar':\n case 'tick':\n if (config.scale.maxBandSize !== undefined) {\n return config.scale.maxBandSize;\n }\n return minXYRangeStep(xyRangeSteps, config.scale) - 1;\n case 'line':\n case 'trail':\n case 'rule':\n return config.scale.maxStrokeWidth;\n case 'text':\n return config.scale.maxFontSize;\n case 'point':\n case 'square':\n case 'circle':\n if (config.scale.maxSize) {\n return config.scale.maxSize;\n }\n\n // FIXME this case totally should be refactored\n const pointStep = minXYRangeStep(xyRangeSteps, scaleConfig);\n return (pointStep - 2) * (pointStep - 2);\n }\n /* istanbul ignore next: should never reach here */\n // sizeRangeMax not implemented for the mark\n throw new Error(log.message.incompatibleChannel('size', mark));\n}\n\n/**\n * @returns {number} Range step of x or y or minimum between the two if both are ordinal scale.\n */\nfunction minXYRangeStep(xyRangeSteps: number[], scaleConfig: ScaleConfig): number {\n if (xyRangeSteps.length > 0) {\n return Math.min.apply(null, xyRangeSteps);\n }\n if (scaleConfig.rangeStep) {\n return scaleConfig.rangeStep;\n }\n return 21; // FIXME: re-evaluate the default value here.\n}\n","import {Channel, ScaleChannel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {FieldDef, ScaleFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {BarConfig, MarkDef} from '../../mark';\nimport {channelScalePropertyIncompatability, Domain, hasContinuousDomain, isContinuousToContinuous, NiceTime, Scale, ScaleConfig, ScaleType, scaleTypeSupportProperty} from '../../scale';\nimport {Sort} from '../../sort';\nimport * as util from '../../util';\nimport {contains, keys} from '../../util';\nimport {VgScale} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {Explicit, mergeValuesWithExplicit, tieBreakByComparing} from '../split';\nimport {UnitModel} from '../unit';\nimport {ScaleComponentIndex, ScaleComponentProps} from './component';\nimport {parseScaleRange} from './range';\n\nexport function parseScaleProperty(model: Model, property: keyof (Scale | ScaleComponentProps)) {\n if (isUnitModel(model)) {\n parseUnitScaleProperty(model, property);\n } else {\n parseNonUnitScaleProperty(model, property);\n }\n}\n\nfunction parseUnitScaleProperty(model: UnitModel, property: keyof (Scale | ScaleComponentProps)) {\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n const specifiedScale = model.specifiedScales[channel];\n const localScaleCmpt = localScaleComponents[channel];\n const mergedScaleCmpt = model.getScaleComponent(channel);\n const fieldDef = model.fieldDef(channel);\n const config = model.config;\n\n const specifiedValue = specifiedScale[property];\n const sType = mergedScaleCmpt.get('type');\n\n const supportedByScaleType = scaleTypeSupportProperty(sType, property);\n const channelIncompatability = channelScalePropertyIncompatability(channel, property);\n\n if (specifiedValue !== undefined) {\n // If there is a specified value, check if it is compatible with scale type and channel\n if (!supportedByScaleType) {\n log.warn(log.message.scalePropertyNotWorkWithScaleType(sType, property, channel));\n } else if (channelIncompatability) { // channel\n log.warn(channelIncompatability);\n }\n }\n if (supportedByScaleType && channelIncompatability === undefined) {\n if (specifiedValue !== undefined) {\n // copyKeyFromObject ensure type safety\n localScaleCmpt.copyKeyFromObject(property, specifiedScale);\n } else {\n const value = getDefaultValue(\n property, channel, fieldDef,\n mergedScaleCmpt.get('type'),\n mergedScaleCmpt.get('padding'),\n mergedScaleCmpt.get('paddingInner'),\n specifiedScale.domain,\n model.markDef, config\n );\n if (value !== undefined) {\n localScaleCmpt.set(property, value, false);\n }\n }\n }\n });\n}\n\n// Note: This method is used in Voyager.\nexport function getDefaultValue(\n property: keyof Scale, channel: Channel, fieldDef: ScaleFieldDef,\n scaleType: ScaleType, scalePadding: number, scalePaddingInner: number,\n specifiedDomain: Scale['domain'], markDef: MarkDef, config: Config) {\n const scaleConfig = config.scale;\n\n // If we have default rule-base, determine default value first\n switch (property) {\n case 'nice':\n return nice(scaleType, channel, fieldDef);\n case 'padding':\n return padding(channel, scaleType, scaleConfig, fieldDef, markDef, config.bar);\n case 'paddingInner':\n return paddingInner(scalePadding, channel, scaleConfig);\n case 'paddingOuter':\n return paddingOuter(scalePadding, channel, scaleType, scalePaddingInner, scaleConfig);\n case 'reverse':\n return reverse(scaleType, fieldDef.sort);\n case 'zero':\n return zero(channel, fieldDef, specifiedDomain, markDef);\n }\n // Otherwise, use scale config\n return scaleConfig[property];\n}\n\nexport function parseNonUnitScaleProperty(model: Model, property: keyof (Scale | ScaleComponentProps)) {\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n for (const child of model.children) {\n if (property === 'range') {\n parseScaleRange(child);\n } else {\n parseScaleProperty(child, property);\n }\n }\n\n keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n let valueWithExplicit: Explicit;\n\n for (const child of model.children) {\n const childComponent = child.component.scales[channel];\n if (childComponent) {\n const childValueWithExplicit = childComponent.getWithExplicit(property);\n valueWithExplicit = mergeValuesWithExplicit(\n valueWithExplicit, childValueWithExplicit,\n property,\n 'scale',\n tieBreakByComparing((v1, v2) => {\n switch (property) {\n case 'range':\n // For range step, prefer larger step\n if (v1.step && v2.step) {\n return v1.step - v2.step;\n }\n return 0;\n // TODO: precedence rule for other properties\n }\n return 0;\n })\n );\n }\n }\n localScaleComponents[channel].setWithExplicit(property, valueWithExplicit);\n });\n}\n\nexport function nice(scaleType: ScaleType, channel: Channel, fieldDef: FieldDef): boolean | NiceTime {\n if (fieldDef.bin || util.contains([ScaleType.TIME, ScaleType.UTC], scaleType)) {\n return undefined;\n }\n return util.contains([X, Y], channel); // return true for quantitative X/Y unless binned\n}\n\nexport function padding(channel: Channel, scaleType: ScaleType, scaleConfig: ScaleConfig, fieldDef: FieldDef, markDef: MarkDef, barConfig: BarConfig) {\n if (util.contains([X, Y], channel)) {\n if (isContinuousToContinuous(scaleType)) {\n if (scaleConfig.continuousPadding !== undefined) {\n return scaleConfig.continuousPadding;\n }\n\n const {type, orient} = markDef;\n if (type === 'bar' && !fieldDef.bin) {\n if (\n (orient === 'vertical' && channel === 'x') ||\n (orient === 'horizontal' && channel === 'y')\n ) {\n return barConfig.continuousBandSize;\n }\n }\n }\n\n if (scaleType === ScaleType.POINT) {\n return scaleConfig.pointPadding;\n }\n }\n return undefined;\n}\n\nexport function paddingInner(paddingValue: number, channel: Channel, scaleConfig: ScaleConfig) {\n if (paddingValue !== undefined) {\n // If user has already manually specified \"padding\", no need to add default paddingInner.\n return undefined;\n }\n\n if (util.contains([X, Y], channel)) {\n // Padding is only set for X and Y by default.\n // Basically it doesn't make sense to add padding for color and size.\n\n // paddingOuter would only be called if it's a band scale, just return the default for bandScale.\n return scaleConfig.bandPaddingInner;\n }\n return undefined;\n}\n\nexport function paddingOuter(paddingValue: number, channel: Channel, scaleType: ScaleType, paddingInnerValue: number, scaleConfig: ScaleConfig) {\n if (paddingValue !== undefined) {\n // If user has already manually specified \"padding\", no need to add default paddingOuter.\n return undefined;\n }\n\n if (util.contains([X, Y], channel)) {\n // Padding is only set for X and Y by default.\n // Basically it doesn't make sense to add padding for color and size.\n if (scaleType === ScaleType.BAND) {\n if (scaleConfig.bandPaddingOuter !== undefined) {\n return scaleConfig.bandPaddingOuter;\n }\n /* By default, paddingOuter is paddingInner / 2. The reason is that\n size (width/height) = step * (cardinality - paddingInner + 2 * paddingOuter).\n and we want the width/height to be integer by default.\n Note that step (by default) and cardinality are integers.) */\n return paddingInnerValue / 2;\n }\n }\n return undefined;\n}\n\nexport function reverse(scaleType: ScaleType, sort: Sort) {\n if (hasContinuousDomain(scaleType) && sort === 'descending') {\n // For continuous domain scales, Vega does not support domain sort.\n // Thus, we reverse range instead if sort is descending\n return true;\n }\n return undefined;\n}\n\nexport function zero(channel: Channel, fieldDef: FieldDef, specifiedScale: Domain, markDef: MarkDef) {\n\n // If users explicitly provide a domain range, we should not augment zero as that will be unexpected.\n const hasCustomDomain = !!specifiedScale && specifiedScale !== 'unaggregated';\n if (hasCustomDomain) {\n return false;\n }\n\n // If there is no custom domain, return true only for the following cases:\n\n // 1) using quantitative field with size\n // While this can be either ratio or interval fields, our assumption is that\n // ratio are more common.\n if (channel === 'size' && fieldDef.type === 'quantitative') {\n return true;\n }\n\n // 2) non-binned, quantitative x-scale or y-scale\n // (For binning, we should not include zero by default because binning are calculated without zero.)\n if (!fieldDef.bin && util.contains([X, Y], channel)) {\n const {orient, type} = markDef;\n if (contains(['bar', 'area', 'line', 'trail'], type)) {\n if (\n (orient === 'horizontal' && channel === 'y') ||\n (orient === 'vertical' && channel === 'x')\n ) {\n return false;\n }\n }\n\n return true;\n }\n return false;\n}\n","import {Channel, isColorChannel, isScaleChannel, rangeType} from '../../channel';\nimport {FieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {Mark} from '../../mark';\nimport {channelSupportScaleType, ScaleConfig, ScaleType, scaleTypeSupportDataType} from '../../scale';\nimport * as util from '../../util';\n\nexport type RangeType = 'continuous' | 'discrete' | 'flexible' | undefined;\n\n/**\n * Determine if there is a specified scale type and if it is appropriate,\n * or determine default type if type is unspecified or inappropriate.\n */\n// NOTE: CompassQL uses this method.\nexport function scaleType(\n specifiedType: ScaleType, channel: Channel, fieldDef: FieldDef,\n mark: Mark, scaleConfig: ScaleConfig\n): ScaleType {\n\n const defaultScaleType = defaultType(channel, fieldDef, mark, scaleConfig);\n\n if (!isScaleChannel(channel)) {\n // There is no scale for these channels\n return null;\n }\n if (specifiedType !== undefined) {\n // Check if explicitly specified scale type is supported by the channel\n if (!channelSupportScaleType(channel, specifiedType)) {\n log.warn(log.message.scaleTypeNotWorkWithChannel(channel, specifiedType, defaultScaleType));\n return defaultScaleType;\n }\n\n // Check if explicitly specified scale type is supported by the data type\n if (!scaleTypeSupportDataType(specifiedType, fieldDef.type, fieldDef.bin)) {\n log.warn(log.message.scaleTypeNotWorkWithFieldDef(specifiedType, defaultScaleType));\n return defaultScaleType;\n }\n\n return specifiedType;\n }\n\n return defaultScaleType;\n}\n\n/**\n * Determine appropriate default scale type.\n */\n// NOTE: Voyager uses this method.\nfunction defaultType(\n channel: Channel, fieldDef: FieldDef, mark: Mark, scaleConfig: ScaleConfig\n): ScaleType {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n if (isColorChannel(channel)|| rangeType(channel) === 'discrete') {\n if (channel === 'shape' && fieldDef.type === 'ordinal') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'ordinal'));\n }\n return 'ordinal';\n }\n\n if (util.contains(['x', 'y'], channel)) {\n if (util.contains(['rect', 'bar', 'rule'], mark)) {\n // The rect/bar mark should fit into a band.\n // For rule, using band scale to make rule align with axis ticks better https://github.com/vega/vega-lite/issues/3429\n return 'band';\n }\n if (mark === 'bar') {\n return 'band';\n }\n }\n // Otherwise, use ordinal point scale so we can easily get center positions of the marks.\n return 'point';\n\n case 'temporal':\n if (isColorChannel(channel)) {\n return 'sequential';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'temporal'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n return 'time';\n\n case 'quantitative':\n if (isColorChannel(channel)) {\n if (fieldDef.bin) {\n return 'bin-ordinal';\n }\n // Use `sequential` as the default color scale for continuous data\n // since it supports both array range and scheme range.\n return 'sequential';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'quantitative'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n\n // x and y use a linear scale because selections don't work with bin scales.\n // Binned scales apply discretization but pan/zoom apply transformations to a [min, max] extent domain.\n if (fieldDef.bin && channel !== 'x' && channel !== 'y') {\n return 'bin-linear';\n }\n return 'linear';\n\n case 'latitude':\n case 'longitude':\n case 'geojson':\n return undefined;\n }\n\n /* istanbul ignore next: should never reach this */\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n","import {SCALE_CHANNELS, ScaleChannel, SHAPE, X, Y} from '../../channel';\nimport {FieldDef, getFieldDef, hasConditionalFieldDef, isFieldDef} from '../../fielddef';\nimport {GEOSHAPE} from '../../mark';\nimport {\n NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES,\n Scale,\n scaleCompatible,\n ScaleType,\n scaleTypePrecedence,\n} from '../../scale';\nimport {GEOJSON} from '../../type';\nimport {keys} from '../../util';\nimport {VgScale} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {defaultScaleResolve} from '../resolve';\nimport {Explicit, mergeValuesWithExplicit, tieBreakByComparing} from '../split';\nimport {UnitModel} from '../unit';\nimport {ScaleComponent, ScaleComponentIndex} from './component';\nimport {parseScaleDomain} from './domain';\nimport {parseScaleProperty} from './properties';\nimport {parseScaleRange} from './range';\nimport {scaleType} from './type';\n\nexport function parseScale(model: Model) {\n parseScaleCore(model);\n parseScaleDomain(model);\n for (const prop of NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES) {\n parseScaleProperty(model, prop);\n }\n // range depends on zero\n parseScaleRange(model);\n}\n\nexport function parseScaleCore(model: Model) {\n if (isUnitModel(model)) {\n model.component.scales = parseUnitScaleCore(model);\n } else {\n model.component.scales = parseNonUnitScaleCore(model);\n }\n}\n\n/**\n * Parse scales for all channels of a model.\n */\nfunction parseUnitScaleCore(model: UnitModel): ScaleComponentIndex {\n const {encoding, config, mark} = model;\n\n return SCALE_CHANNELS.reduce((scaleComponents: ScaleComponentIndex, channel: ScaleChannel) => {\n let fieldDef: FieldDef;\n let specifiedScale: Scale | null = undefined;\n\n const channelDef = encoding[channel];\n\n // Don't generate scale for shape of geoshape\n if (\n isFieldDef(channelDef) && mark === GEOSHAPE &&\n channel === SHAPE && channelDef.type === GEOJSON\n ) {\n return scaleComponents;\n }\n\n if (isFieldDef(channelDef)) {\n fieldDef = channelDef;\n specifiedScale = channelDef.scale;\n } else if (hasConditionalFieldDef(channelDef)) {\n fieldDef = channelDef.condition;\n specifiedScale = channelDef.condition['scale']; // We use ['scale'] since we know that channel here has scale for sure\n } else if (channel === X) {\n fieldDef = getFieldDef(encoding.x2);\n } else if (channel === Y) {\n fieldDef = getFieldDef(encoding.y2);\n }\n\n if (fieldDef && specifiedScale !== null && specifiedScale !== false) {\n specifiedScale = specifiedScale || {};\n const specifiedScaleType = specifiedScale.type;\n const sType = scaleType(specifiedScale.type, channel, fieldDef, mark, config.scale);\n scaleComponents[channel] = new ScaleComponent(\n model.scaleName(channel + '', true),\n {value: sType, explicit: specifiedScaleType === sType}\n );\n }\n return scaleComponents;\n }, {});\n}\n\nconst scaleTypeTieBreaker = tieBreakByComparing(\n (st1: ScaleType, st2: ScaleType) => (scaleTypePrecedence(st1) - scaleTypePrecedence(st2))\n);\n\n\nfunction parseNonUnitScaleCore(model: Model) {\n const scaleComponents: ScaleComponentIndex = model.component.scales = {};\n\n const scaleTypeWithExplicitIndex: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleChannel]?: Explicit\n } = {};\n const resolve = model.component.resolve;\n\n // Parse each child scale and determine if a particular channel can be merged.\n for (const child of model.children) {\n parseScaleCore(child);\n\n // Instead of always merging right away -- check if it is compatible to merge first!\n keys(child.component.scales).forEach((channel: ScaleChannel) => {\n // if resolve is undefined, set default first\n resolve.scale[channel] = resolve.scale[channel] || defaultScaleResolve(channel, model);\n\n if (resolve.scale[channel] === 'shared') {\n const explicitScaleType = scaleTypeWithExplicitIndex[channel];\n const childScaleType = child.component.scales[channel].getWithExplicit('type');\n\n if (explicitScaleType) {\n if (scaleCompatible(explicitScaleType.value, childScaleType.value)) {\n // merge scale component if type are compatible\n scaleTypeWithExplicitIndex[channel] = mergeValuesWithExplicit(\n explicitScaleType, childScaleType, 'type', 'scale', scaleTypeTieBreaker\n );\n } else {\n // Otherwise, update conflicting channel to be independent\n resolve.scale[channel] = 'independent';\n // Remove from the index so they don't get merged\n delete scaleTypeWithExplicitIndex[channel];\n }\n } else {\n scaleTypeWithExplicitIndex[channel] = childScaleType;\n }\n }\n });\n }\n\n // Merge each channel listed in the index\n keys(scaleTypeWithExplicitIndex).forEach((channel: ScaleChannel) => {\n // Create new merged scale component\n const name = model.scaleName(channel, true);\n const typeWithExplicit = scaleTypeWithExplicitIndex[channel];\n scaleComponents[channel] = new ScaleComponent(name, typeWithExplicit);\n\n // rename each child and mark them as merged\n for (const child of model.children) {\n const childScale = child.component.scales[channel];\n if (childScale) {\n child.renameScale(childScale.get('name'), name);\n childScale.merged = true;\n }\n }\n });\n\n return scaleComponents;\n}\n","import {isNumber, isString} from 'vega-util';\nimport {Channel, isChannel, isScaleChannel, ScaleChannel, SingleDefChannel} from '../channel';\nimport {Config} from '../config';\nimport {Data, DataSourceType} from '../data';\nimport {forEach, reduce} from '../encoding';\nimport {ChannelDef, FieldDef, FieldRefOption, getFieldDef, vgField} from '../fielddef';\nimport * as log from '../log';\nimport {Resolve} from '../resolve';\nimport {hasDiscreteDomain} from '../scale';\nimport {BaseSpec, isFacetSpec, isLayerSpec, isUnitSpec} from '../spec';\nimport {extractTitleConfig, TitleParams} from '../title';\nimport {extractCompositionLayout, GenericCompositionLayout} from '../toplevelprops';\nimport {normalizeTransform, Transform} from '../transform';\nimport {contains, Dict, keys, varName} from '../util';\nimport {isVgRangeStep, VgAxis, VgData, VgEncodeEntry, VgLayout, VgLegend, VgMarkGroup, VgProjection, VgSignal, VgSignalRef, VgTitle} from '../vega.schema';\nimport {assembleAxes} from './axis/assemble';\nimport {AxisComponentIndex} from './axis/component';\nimport {ConcatModel} from './concat';\nimport {DataComponent} from './data';\nimport {FacetModel} from './facet';\nimport {getHeaderGroups, getTitleGroup, HEADER_CHANNELS, LayoutHeaderComponent} from './header/index';\nimport {LayerModel} from './layer';\nimport {sizeExpr} from './layoutsize/assemble';\nimport {LayoutSizeComponent, LayoutSizeIndex} from './layoutsize/component';\nimport {assembleLegends} from './legend/assemble';\nimport {LegendComponentIndex} from './legend/component';\nimport {parseLegend} from './legend/parse';\nimport {assembleProjections} from './projection/assemble';\nimport {ProjectionComponent} from './projection/component';\nimport {parseProjection} from './projection/parse';\nimport {RepeatModel} from './repeat';\nimport {RepeaterValue} from './repeater';\nimport {assembleScales} from './scale/assemble';\nimport {ScaleComponent, ScaleComponentIndex} from './scale/component';\nimport {assembleDomain, getFieldFromDomain} from './scale/domain';\nimport {parseScale} from './scale/parse';\nimport {SelectionComponent} from './selection/selection';\nimport {Split} from './split';\nimport {UnitModel} from './unit';\n\n/**\n * Composable Components that are intermediate results of the parsing phase of the\n * compilations. The components represents parts of the specification in a form that\n * can be easily merged (during parsing for composite specs).\n * In addition, these components are easily transformed into Vega specifications\n * during the \"assemble\" phase, which is the last phase of the compilation step.\n */\nexport interface Component {\n data: DataComponent;\n\n layoutSize: LayoutSizeComponent;\n\n layoutHeaders: {\n row?: LayoutHeaderComponent,\n column?: LayoutHeaderComponent\n };\n\n mark: VgMarkGroup[];\n scales: ScaleComponentIndex;\n projection: ProjectionComponent;\n selection: Dict;\n\n /** Dictionary mapping channel to VgAxis definition */\n axes: AxisComponentIndex;\n\n /** Dictionary mapping channel to VgLegend definition */\n legends: LegendComponentIndex;\n\n resolve: Resolve;\n}\n\nexport interface NameMapInterface {\n rename(oldname: string, newName: string): void;\n has(name: string): boolean;\n get(name: string): string;\n}\n\nexport class NameMap implements NameMapInterface {\n private nameMap: Dict;\n\n constructor() {\n this.nameMap = {};\n }\n\n public rename(oldName: string, newName: string) {\n this.nameMap[oldName] = newName;\n }\n\n\n public has(name: string): boolean {\n return this.nameMap[name] !== undefined;\n }\n\n public get(name: string): string {\n // If the name appears in the _nameMap, we need to read its new name.\n // We have to loop over the dict just in case the new name also gets renamed.\n while (this.nameMap[name] && name !== this.nameMap[name]) {\n name = this.nameMap[name];\n }\n\n return name;\n }\n}\n\n/*\n We use type guards instead of `instanceof` as `instanceof` makes\n different parts of the compiler depend on the actual implementation of\n the model classes, which in turn depend on different parts of the compiler.\n Thus, `instanceof` leads to circular dependency problems.\n\n On the other hand, type guards only make different parts of the compiler\n depend on the type of the model classes, but not the actual implementation.\n*/\n\nexport function isUnitModel(model: Model): model is UnitModel {\n return model && model.type === 'unit';\n}\n\nexport function isFacetModel(model: Model): model is FacetModel {\n return model && model.type === 'facet';\n}\n\nexport function isRepeatModel(model: Model): model is RepeatModel {\n return model && model.type === 'repeat';\n}\n\nexport function isConcatModel(model: Model): model is ConcatModel {\n return model && model.type === 'concat';\n}\n\nexport function isLayerModel(model: Model): model is LayerModel {\n return model && model.type === 'layer';\n}\n\nexport abstract class Model {\n public abstract readonly type: 'unit' | 'facet' | 'layer' | 'concat' | 'repeat';\n public readonly parent: Model;\n public readonly name: string;\n\n public readonly title: TitleParams;\n public readonly description: string;\n\n public readonly data: Data;\n public readonly transforms: Transform[];\n public readonly layout: GenericCompositionLayout;\n\n /** Name map for scales, which can be renamed by a model's parent. */\n protected scaleNameMap: NameMapInterface;\n\n /** Name map for projections, which can be renamed by a model's parent. */\n protected projectionNameMap: NameMapInterface;\n\n /** Name map for size, which can be renamed by a model's parent. */\n protected layoutSizeNameMap: NameMapInterface;\n\n public readonly repeater: RepeaterValue;\n\n public readonly config: Config;\n\n public readonly component: Component;\n\n public abstract readonly children: Model[] = [];\n\n constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, repeater: RepeaterValue, resolve: Resolve) {\n this.parent = parent;\n this.config = config;\n this.repeater = repeater;\n\n // If name is not provided, always use parent's givenName to avoid name conflicts.\n this.name = spec.name || parentGivenName;\n this.title = isString(spec.title) ? {text: spec.title} : spec.title;\n\n // Shared name maps\n this.scaleNameMap = parent ? parent.scaleNameMap : new NameMap();\n this.projectionNameMap = parent ? parent.projectionNameMap : new NameMap();\n this.layoutSizeNameMap = parent ? parent.layoutSizeNameMap : new NameMap();\n\n this.data = spec.data;\n\n this.description = spec.description;\n this.transforms = normalizeTransform(spec.transform || []);\n this.layout = isUnitSpec(spec) || isLayerSpec(spec) ? undefined : extractCompositionLayout(spec);\n\n this.component = {\n data: {\n sources: parent ? parent.component.data.sources : {},\n outputNodes: parent ? parent.component.data.outputNodes : {},\n outputNodeRefCounts: parent ? parent.component.data.outputNodeRefCounts : {},\n // data is faceted if the spec is a facet spec or the parent has faceted data and no data is defined\n isFaceted: isFacetSpec(spec) || (parent && parent.component.data.isFaceted && !spec.data)\n },\n layoutSize: new Split(),\n layoutHeaders:{row: {}, column: {}},\n mark: null,\n resolve: {\n scale: {}, axis: {}, legend: {},\n ...(resolve || {})\n },\n selection: null,\n scales: null,\n projection: null,\n axes: {},\n legends: {},\n };\n }\n\n public get width(): VgSignalRef {\n return this.getSizeSignalRef('width');\n }\n\n\n public get height(): VgSignalRef {\n return this.getSizeSignalRef('height');\n }\n\n protected initSize(size: LayoutSizeIndex) {\n const {width, height} = size;\n if (width) {\n this.component.layoutSize.set('width', width, true);\n }\n\n if (height) {\n this.component.layoutSize.set('height', height, true);\n }\n }\n\n public parse() {\n this.parseScale();\n\n this.parseLayoutSize(); // depends on scale\n this.renameTopLevelLayoutSize();\n\n this.parseSelection();\n this.parseProjection();\n this.parseData(); // (pathorder) depends on markDef; selection filters depend on parsed selections; depends on projection because some transforms require the finalized projection name.\n this.parseAxisAndHeader(); // depends on scale and layout size\n this.parseLegend(); // depends on scale, markDef\n this.parseMarkGroup(); // depends on data name, scale, layout size, axisGroup, and children's scale, axis, legend and mark.\n }\n\n public abstract parseData(): void;\n\n public abstract parseSelection(): void;\n\n\n public parseScale() {\n parseScale(this);\n }\n\n public parseProjection() {\n parseProjection(this);\n }\n\n public abstract parseLayoutSize(): void;\n\n /**\n * Rename top-level spec's size to be just width / height, ignoring model name.\n * This essentially merges the top-level spec's width/height signals with the width/height signals\n * to help us reduce redundant signals declaration.\n */\n private renameTopLevelLayoutSize() {\n if (this.getName('width') !== 'width') {\n this.renameLayoutSize(this.getName('width'), 'width');\n }\n if (this.getName('height') !== 'height') {\n this.renameLayoutSize(this.getName('height'), 'height');\n }\n }\n\n public abstract parseMarkGroup(): void;\n\n public abstract parseAxisAndHeader(): void;\n\n public parseLegend() {\n parseLegend(this);\n }\n\n public abstract assembleSelectionTopLevelSignals(signals: any[]): any[];\n public abstract assembleSelectionSignals(): any[];\n\n public abstract assembleSelectionData(data: VgData[]): VgData[];\n\n public assembleGroupStyle(): string {\n if (this.type === 'unit' || this.type === 'layer') {\n return 'cell';\n }\n return undefined;\n }\n\n public assembleLayoutSize(): VgEncodeEntry {\n if (this.type === 'unit' || this.type === 'layer') {\n return {\n width: this.getSizeSignalRef('width'),\n height: this.getSizeSignalRef('height')\n };\n }\n return undefined;\n }\n\n public assembleLayout(): VgLayout {\n if (!this.layout) {\n return undefined;\n }\n\n const {align, bounds, center, spacing = {}} = this.layout;\n\n return {\n padding: isNumber(spacing) ? spacing : {\n row: spacing.row || 10,\n column: spacing.column || 10\n },\n ...this.assembleDefaultLayout(),\n ...(align ? {align} : {}),\n ...(bounds ? {bounds} : {}),\n ...(center ? {center} : {})\n };\n }\n\n protected assembleDefaultLayout(): VgLayout {\n return {};\n }\n\n public abstract assembleLayoutSignals(): VgSignal[];\n\n public assembleHeaderMarks(): VgMarkGroup[] {\n const {layoutHeaders} = this.component;\n let headerMarks = [];\n\n for (const channel of HEADER_CHANNELS) {\n if (layoutHeaders[channel].title) {\n headerMarks.push(getTitleGroup(this, channel));\n }\n }\n\n for (const channel of HEADER_CHANNELS) {\n headerMarks = headerMarks.concat(getHeaderGroups(this, channel));\n }\n return headerMarks;\n }\n\n public abstract assembleMarks(): VgMarkGroup[]; // TODO: VgMarkGroup[]\n\n public assembleAxes(): VgAxis[] {\n return assembleAxes(this.component.axes, this.config);\n }\n\n public assembleLegends(): VgLegend[] {\n return assembleLegends(this);\n }\n\n public assembleProjections(): VgProjection[] {\n return assembleProjections(this);\n }\n\n public assembleTitle(): VgTitle {\n const title: VgTitle = {\n ...extractTitleConfig(this.config.title).nonMark,\n ...this.title\n };\n\n if (title.text) {\n if (!contains(['unit', 'layer'], this.type)) {\n // As described in https://github.com/vega/vega-lite/issues/2875:\n // Due to vega/vega#960 (comment), we only support title's anchor for unit and layered spec for now.\n\n if (title.anchor && title.anchor !== 'start') {\n log.warn(log.message.cannotSetTitleAnchor(this.type));\n }\n title.anchor = 'start';\n }\n\n return keys(title).length > 0 ? title : undefined;\n }\n return undefined;\n }\n\n /**\n * Assemble the mark group for this model. We accept optional `signals` so that we can include concat top-level signals with the top-level model's local signals.\n */\n public assembleGroup(signals: VgSignal[] = []) {\n const group: VgMarkGroup = {};\n\n signals = signals.concat(this.assembleSelectionSignals());\n\n if (signals.length > 0) {\n group.signals = signals;\n }\n\n const layout = this.assembleLayout();\n if (layout) {\n group.layout = layout;\n }\n\n group.marks = [].concat(\n this.assembleHeaderMarks(),\n this.assembleMarks()\n );\n\n // Only include scales if this spec is top-level or if parent is facet.\n // (Otherwise, it will be merged with upper-level's scope.)\n const scales = (!this.parent || isFacetModel(this.parent)) ? assembleScales(this) : [];\n if (scales.length > 0) {\n group.scales = scales;\n }\n\n const axes = this.assembleAxes();\n if (axes.length > 0) {\n group.axes = axes;\n }\n\n const legends = this.assembleLegends();\n if (legends.length > 0) {\n group.legends = legends;\n }\n\n return group;\n }\n\n public hasDescendantWithFieldOnChannel(channel: Channel) {\n for (const child of this.children) {\n if (isUnitModel(child)) {\n if (child.channelHasField(channel)) {\n return true;\n }\n } else {\n if (child.hasDescendantWithFieldOnChannel(channel)) {\n return true;\n }\n }\n }\n return false;\n }\n\n public getName(text: string) {\n return varName((this.name ? this.name + '_' : '') + text);\n }\n\n /**\n * Request a data source name for the given data source type and mark that data source as required. This method should be called in parse, so that all used data source can be correctly instantiated in assembleData().\n */\n public requestDataName(name: DataSourceType) {\n const fullName = this.getName(name);\n\n // Increase ref count. This is critical because otherwise we won't create a data source.\n // We also increase the ref counts on OutputNode.getSource() calls.\n const refCounts = this.component.data.outputNodeRefCounts;\n refCounts[fullName] = (refCounts[fullName] || 0) + 1;\n\n return fullName;\n }\n\n public getSizeSignalRef(sizeType: 'width' | 'height'): VgSignalRef {\n if (isFacetModel(this.parent)) {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const scaleComponent = this.component.scales[channel];\n\n if (scaleComponent && !scaleComponent.merged) { // independent scale\n const type = scaleComponent.get('type');\n const range = scaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const scaleName = scaleComponent.get('name');\n const domain = assembleDomain(this, channel);\n const field = getFieldFromDomain(domain);\n if (field) {\n const fieldRef = vgField({aggregate: 'distinct', field}, {expr: 'datum'});\n return {\n signal: sizeExpr(scaleName, scaleComponent, fieldRef)\n };\n } else {\n log.warn('Unknown field for ${channel}. Cannot calculate view size.');\n return null;\n }\n\n }\n }\n }\n\n return {\n signal: this.layoutSizeNameMap.get(this.getName(sizeType))\n };\n }\n\n /**\n * Lookup the name of the datasource for an output node. You probably want to call this in assemble.\n */\n public lookupDataSource(name: string) {\n const node = this.component.data.outputNodes[name];\n\n if (!node) {\n // Name not found in map so let's just return what we got.\n // This can happen if we already have the correct name.\n return name;\n }\n\n return node.getSource();\n }\n\n public getSizeName(oldSizeName: string): string {\n return this.layoutSizeNameMap.get(oldSizeName);\n }\n\n public renameLayoutSize(oldName: string, newName: string) {\n this.layoutSizeNameMap.rename(oldName, newName);\n }\n\n public renameScale(oldName: string, newName: string) {\n this.scaleNameMap.rename(oldName, newName);\n }\n\n public renameProjection(oldName: string, newName: string) {\n this.projectionNameMap.rename(oldName, newName);\n }\n\n /**\n * @return scale name for a given channel after the scale has been parsed and named.\n */\n public scaleName(originalScaleName: Channel | string, parse?: boolean): string {\n if (parse) {\n // During the parse phase always return a value\n // No need to refer to rename map because a scale can't be renamed\n // before it has the original name.\n return this.getName(originalScaleName);\n }\n\n // If there is a scale for the channel, it should either\n // be in the scale component or exist in the name map\n if (\n // If there is a scale for the channel, there should be a local scale component for it\n (isChannel(originalScaleName) && isScaleChannel(originalScaleName) && this.component.scales[originalScaleName]) ||\n // in the scale name map (the scale get merged by its parent)\n this.scaleNameMap.has(this.getName(originalScaleName))\n ) {\n return this.scaleNameMap.get(this.getName(originalScaleName));\n }\n return undefined;\n }\n\n /**\n * @return projection name after the projection has been parsed and named.\n */\n public projectionName(parse?: boolean): string {\n if (parse) {\n // During the parse phase always return a value\n // No need to refer to rename map because a projection can't be renamed\n // before it has the original name.\n return this.getName('projection');\n }\n\n if ((this.component.projection && !this.component.projection.merged) || this.projectionNameMap.has(this.getName('projection'))) {\n return this.projectionNameMap.get(this.getName('projection'));\n }\n return undefined;\n }\n\n /**\n * Corrects the data references in marks after assemble.\n */\n public correctDataNames = (mark: VgMarkGroup) => {\n // TODO: make this correct\n\n // for normal data references\n if (mark.from && mark.from.data) {\n mark.from.data = this.lookupDataSource(mark.from.data);\n }\n\n // for access to facet data\n if (mark.from && mark.from.facet && mark.from.facet.data) {\n mark.from.facet.data = this.lookupDataSource(mark.from.facet.data);\n }\n\n return mark;\n }\n\n /**\n * Traverse a model's hierarchy to get the scale component for a particular channel.\n */\n public getScaleComponent(channel: ScaleChannel): ScaleComponent {\n /* istanbul ignore next: This is warning for debugging test */\n if (!this.component.scales) {\n throw new Error('getScaleComponent cannot be called before parseScale(). Make sure you have called parseScale or use parseUnitModelWithScale().');\n }\n\n const localScaleComponent = this.component.scales[channel];\n if (localScaleComponent && !localScaleComponent.merged) {\n return localScaleComponent;\n }\n return (this.parent ? this.parent.getScaleComponent(channel) : undefined);\n }\n\n /**\n * Traverse a model's hierarchy to get a particular selection component.\n */\n public getSelectionComponent(variableName: string, origName: string): SelectionComponent {\n let sel = this.component.selection[variableName];\n if (!sel && this.parent) {\n sel = this.parent.getSelectionComponent(variableName, origName);\n }\n if (!sel) {\n throw new Error(log.message.selectionNotFound(origName));\n }\n return sel;\n }\n}\n\n/** Abstract class for UnitModel and FacetModel. Both of which can contain fieldDefs as a part of its own specification. */\nexport abstract class ModelWithField extends Model {\n public abstract fieldDef(channel: SingleDefChannel): FieldDef;\n\n /** Get \"field\" reference for vega */\n public vgField(channel: SingleDefChannel, opt: FieldRefOption = {}) {\n const fieldDef = this.fieldDef(channel);\n\n if (!fieldDef) {\n return undefined;\n }\n\n return vgField(fieldDef, opt);\n }\n\n protected abstract getMapping(): {[key in Channel]?: any};\n\n public reduceFieldDef(f: (acc: U, fd: FieldDef, c: Channel) => U, init: T, t?: any) {\n return reduce(this.getMapping(), (acc:U , cd: ChannelDef, c: Channel) => {\n const fieldDef = getFieldDef(cd);\n if (fieldDef) {\n return f(acc, fieldDef, c);\n }\n return acc;\n }, init, t);\n }\n\n public forEachFieldDef(f: (fd: FieldDef, c: Channel) => void, t?: any) {\n forEach(this.getMapping(), (cd: ChannelDef, c: Channel) => {\n const fieldDef = getFieldDef(cd);\n if (fieldDef) {\n f(fieldDef, c);\n }\n }, t);\n }\n public abstract channelHasField(channel: Channel): boolean;\n}\n","import {stringValue} from 'vega-util';\nimport {Channel, X, Y} from '../../../channel';\nimport * as log from '../../../log';\nimport {hasContinuousDomain, isBinScale} from '../../../scale';\nimport {UnitModel} from '../../unit';\nimport {channelSignalName} from '../selection';\nimport {TransformCompiler} from './transforms';\n\n\nconst scaleBindings:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.resolve === 'global' &&\n selCmpt.bind && selCmpt.bind === 'scales';\n },\n\n parse: function(model, selDef, selCmpt) {\n const bound: Channel[] = selCmpt.scales = [];\n\n selCmpt.project.forEach(function(p) {\n const channel = p.channel;\n const scale = model.getScaleComponent(channel);\n const scaleType = scale ? scale.get('type') : undefined;\n\n if (!scale || !hasContinuousDomain(scaleType) || isBinScale(scaleType)) {\n log.warn(log.message.SCALE_BINDINGS_CONTINUOUS);\n return;\n }\n\n scale.set('domainRaw', {signal: channelSignalName(selCmpt, channel, 'data')}, true);\n bound.push(channel);\n\n // Bind both x/y for diag plot of repeated views.\n if (model.repeater && model.repeater.row === model.repeater.column) {\n const scale2 = model.getScaleComponent(channel === X ? Y : X);\n scale2.set('domainRaw', {signal: channelSignalName(selCmpt, channel, 'data')}, true);\n }\n });\n },\n\n topLevelSignals: function(model, selCmpt, signals) {\n // Top-level signals are only needed when coordinating composed views.\n if (!model.parent) {\n return signals;\n }\n\n const channels = selCmpt.scales.filter((channel) => {\n return !(signals.filter(s => s.name === channelSignalName(selCmpt, channel, 'data')).length);\n });\n\n return signals.concat(channels.map((channel) => {\n return {name: channelSignalName(selCmpt, channel, 'data')};\n }));\n },\n\n signals: function(model, selCmpt, signals) {\n // Nested signals need only push to top-level signals when within composed views.\n if (model.parent) {\n selCmpt.scales.forEach(channel => {\n const signal = signals.filter(s => s.name === channelSignalName(selCmpt, channel, 'data'))[0];\n\n signal.push = 'outer';\n delete signal.value;\n delete signal.update;\n });\n }\n\n return signals;\n }\n};\n\nexport default scaleBindings;\n\nexport function domain(model: UnitModel, channel: Channel) {\n const scale = stringValue(model.scaleName(channel));\n return `domain(${scale})`;\n}\n","import {stringValue} from 'vega-util';\nimport {X, Y} from '../../channel';\nimport {warn} from '../../log';\nimport {hasContinuousDomain, isBinScale} from '../../scale';\nimport {keys} from '../../util';\nimport {VgEventStream} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {\n channelSignalName,\n positionalProjections,\n SelectionCompiler,\n SelectionComponent,\n STORE,\n TUPLE,\n unitName,\n} from './selection';\nimport scales from './transforms/scales';\n\nexport const BRUSH = '_brush';\nexport const SCALE_TRIGGER = '_scale_trigger';\n\nconst interval:SelectionCompiler = {\n predicate: 'vlInterval',\n scaleDomain: 'vlIntervalDomain',\n\n signals: function(model, selCmpt) {\n const name = selCmpt.name;\n const hasScales = scales.has(selCmpt);\n const signals: any[] = [];\n const intervals: any[] = [];\n const tupleTriggers: string[] = [];\n const scaleTriggers: any[] = [];\n\n if (selCmpt.translate && !hasScales) {\n const filterExpr = `!event.item || event.item.mark.name !== ${stringValue(name + BRUSH)}`;\n events(selCmpt, function(_: any[], evt: VgEventStream) {\n const filters = evt.between[0].filter || (evt.between[0].filter = []);\n if (filters.indexOf(filterExpr) < 0) {\n filters.push(filterExpr);\n }\n });\n }\n\n selCmpt.project.forEach(function(p) {\n const channel = p.channel;\n if (channel !== X && channel !== Y) {\n warn('Interval selections only support x and y encoding channels.');\n return;\n }\n\n const cs = channelSignals(model, selCmpt, channel);\n const dname = channelSignalName(selCmpt, channel, 'data');\n const vname = channelSignalName(selCmpt, channel, 'visual');\n const scaleStr = stringValue(model.scaleName(channel));\n const scaleType = model.getScaleComponent(channel).get('type');\n const toNum = hasContinuousDomain(scaleType) ? '+' : '';\n\n signals.push.apply(signals, cs);\n tupleTriggers.push(dname);\n intervals.push(`{encoding: ${stringValue(channel)}, ` +\n `field: ${stringValue(p.field)}, extent: ${dname}}`);\n\n scaleTriggers.push({\n scaleName: model.scaleName(channel),\n expr: `(!isArray(${dname}) || ` +\n `(${toNum}invert(${scaleStr}, ${vname})[0] === ${toNum}${dname}[0] && ` +\n `${toNum}invert(${scaleStr}, ${vname})[1] === ${toNum}${dname}[1]))`\n });\n });\n\n // Proxy scale reactions to ensure that an infinite loop doesn't occur\n // when an interval selection filter touches the scale.\n if (!hasScales) {\n signals.push({\n name: name + SCALE_TRIGGER,\n update: scaleTriggers.map((t) => t.expr).join(' && ') +\n ` ? ${name + SCALE_TRIGGER} : {}`\n });\n }\n\n // Only add an interval to the store if it has valid data extents. Data extents\n // are set to null if pixel extents are equal to account for intervals over\n // ordinal/nominal domains which, when inverted, will still produce a valid datum.\n return signals.concat({\n name: name + TUPLE,\n on: [{\n events: tupleTriggers.map((t) => ({signal: t})),\n update: tupleTriggers.join(' && ') +\n ` ? {unit: ${unitName(model)}, intervals: [${intervals.join(', ')}]} : null`\n }]\n });\n },\n\n modifyExpr: function(model, selCmpt) {\n const tpl = selCmpt.name + TUPLE;\n return tpl + ', ' +\n (selCmpt.resolve === 'global' ? 'true' : `{unit: ${unitName(model)}}`);\n },\n\n marks: function(model, selCmpt, marks) {\n const name = selCmpt.name;\n const {xi, yi} = positionalProjections(selCmpt);\n const store = `data(${stringValue(selCmpt.name + STORE)})`;\n\n // Do not add a brush if we're binding to scales.\n if (scales.has(selCmpt)) {\n return marks;\n }\n\n const update: any = {\n x: xi !== null ? {signal: `${name}_x[0]`} : {value: 0},\n y: yi !== null ? {signal: `${name}_y[0]`} : {value: 0},\n x2: xi !== null ? {signal: `${name}_x[1]`} : {field: {group: 'width'}},\n y2: yi !== null ? {signal: `${name}_y[1]`} : {field: {group: 'height'}}\n };\n\n // If the selection is resolved to global, only a single interval is in\n // the store. Wrap brush mark's encodings with a production rule to test\n // this based on the `unit` property. Hide the brush mark if it corresponds\n // to a unit different from the one in the store.\n if (selCmpt.resolve === 'global') {\n for (const key of keys(update)) {\n update[key] = [{\n test: `${store}.length && ${store}[0].unit === ${unitName(model)}`,\n ...update[key]\n }, {value: 0}];\n }\n }\n\n // Two brush marks ensure that fill colors and other aesthetic choices do\n // not interefere with the core marks, but that the brushed region can still\n // be interacted with (e.g., dragging it around).\n const {fill, fillOpacity, ...stroke} = selCmpt.mark;\n const vgStroke = keys(stroke).reduce((def, k) => {\n def[k] = [{\n test: [\n xi !== null && `${name}_x[0] !== ${name}_x[1]`,\n yi != null && `${name}_y[0] !== ${name}_y[1]`,\n ].filter(x => x).join(' && '),\n value: stroke[k]\n }, {value: null}];\n return def;\n }, {});\n\n return [{\n name: name + BRUSH + '_bg',\n type: 'rect',\n clip: true,\n encode: {\n enter: {\n fill: {value: fill},\n fillOpacity: {value: fillOpacity}\n },\n update: update\n }\n } as any].concat(marks, {\n name: name + BRUSH,\n type: 'rect',\n clip: true,\n encode: {\n enter: {\n fill: {value: 'transparent'}\n },\n update: {...update, ...vgStroke}\n }\n });\n }\n};\nexport default interval;\n\n/**\n * Returns the visual and data signals for an interval selection.\n */\nfunction channelSignals(model: UnitModel, selCmpt: SelectionComponent, channel: 'x'|'y'): any {\n const vname = channelSignalName(selCmpt, channel, 'visual');\n const dname = channelSignalName(selCmpt, channel, 'data');\n const hasScales = scales.has(selCmpt);\n const scaleName = model.scaleName(channel);\n const scaleStr = stringValue(scaleName);\n const scale = model.getScaleComponent(channel);\n const scaleType = scale ? scale.get('type') : undefined;\n const size = model.getSizeSignalRef(channel === X ? 'width' : 'height').signal;\n const coord = `${channel}(unit)`;\n\n const on = events(selCmpt, function(def: any[], evt: VgEventStream) {\n return def.concat(\n {events: evt.between[0], update: `[${coord}, ${coord}]`}, // Brush Start\n {events: evt, update: `[${vname}[0], clamp(${coord}, 0, ${size})]`} // Brush End\n );\n });\n\n // React to pan/zooms of continuous scales. Non-continuous scales\n // (bin-linear, band, point) cannot be pan/zoomed and any other changes\n // to their domains (e.g., filtering) should clear the brushes.\n on.push({\n events: {signal: selCmpt.name + SCALE_TRIGGER},\n update: hasContinuousDomain(scaleType) && !isBinScale(scaleType) ?\n `[scale(${scaleStr}, ${dname}[0]), scale(${scaleStr}, ${dname}[1])]` : `[0, 0]`\n });\n\n return hasScales ? [{name: dname, on: []}] : [{\n name: vname, value: [], on: on\n }, {\n name: dname,\n on: [{events: {signal: vname}, update: `${vname}[0] === ${vname}[1] ? null : invert(${scaleStr}, ${vname})`}]\n }];\n}\n\nfunction events(selCmpt: SelectionComponent, cb: Function) {\n return selCmpt.events.reduce(function(on: any[], evt: VgEventStream) {\n if (!evt.between) {\n warn(`${evt} is not an ordered event stream for interval selections`);\n return on;\n }\n return cb(on, evt);\n }, []);\n}\n","import * as log from '../../../log';\nimport {isPathMark} from '../../../mark';\nimport {positionalProjections} from '../selection';\nimport {TransformCompiler} from './transforms';\n\nconst VORONOI = 'voronoi';\n\nconst nearest:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type !== 'interval' && selCmpt.nearest;\n },\n\n marks: function(model, selCmpt, marks) {\n const {x, y} = positionalProjections(selCmpt);\n const markType = model.mark;\n if (isPathMark(markType)) {\n log.warn(log.message.nearestNotSupportForContinuous(markType));\n return marks;\n }\n\n const cellDef = {\n name: model.getName(VORONOI),\n type: 'path',\n from: {data: model.getName('marks')},\n encode: {\n enter: {\n fill: {value: 'transparent'},\n strokeWidth: {value: 0.35},\n stroke: {value: 'transparent'},\n isVoronoi: {value: true}\n }\n },\n transform: [{\n type: 'voronoi',\n x: {expr: (x || (!x && !y)) ? 'datum.datum.x || 0' : '0'},\n y: {expr: (y || (!x && !y)) ? 'datum.datum.y || 0' : '0'},\n size: [model.getSizeSignalRef('width'), model.getSizeSignalRef('height')]\n }]\n };\n\n let index = 0;\n let exists = false;\n marks.forEach((mark, i) => {\n const name = mark.name || '';\n if (name === model.component.mark[0].name) {\n index = i;\n } else if (name.indexOf(VORONOI) >= 0) {\n exists = true;\n }\n });\n\n if (!exists) {\n marks.splice(index + 1, 0, cellDef);\n }\n\n return marks;\n }\n};\n\nexport default nearest;\n","import {stringValue} from 'vega-util';\n\nimport {accessPathWithDatum} from '../../util';\nimport {UnitModel} from '../unit';\nimport {SelectionCompiler, SelectionComponent, TUPLE, unitName} from './selection';\nimport nearest from './transforms/nearest';\n\nexport function signals(model: UnitModel, selCmpt: SelectionComponent) {\n const proj = selCmpt.project;\n const datum = nearest.has(selCmpt) ?\n '(item().isVoronoi ? datum.datum : datum)' : 'datum';\n const bins: string[] = [];\n const encodings = proj.map((p) => stringValue(p.channel)).filter((e) => e).join(', ');\n const fields = proj.map((p) => stringValue(p.field)).join(', ');\n const values = proj.map((p) => {\n const channel = p.channel;\n const fieldDef = model.fieldDef(channel);\n // Binned fields should capture extents, for a range test against the raw field.\n return (fieldDef && fieldDef.bin) ? (bins.push(p.field),\n `[${accessPathWithDatum(model.vgField(channel, {}), datum)}, ` +\n `${accessPathWithDatum(model.vgField(channel, {binSuffix: 'end'}), datum)}]`) :\n `${accessPathWithDatum(p.field, datum)}`;\n }).join(', ');\n\n // Only add a discrete selection to the store if a datum is present _and_\n // the interaction isn't occurring on a group mark. This guards against\n // polluting interactive state with invalid values in faceted displays\n // as the group marks are also data-driven. We force the update to account\n // for constant null states but varying toggles (e.g., shift-click in\n // whitespace followed by a click in whitespace; the store should only\n // be cleared on the second click).\n return [{\n name: selCmpt.name + TUPLE,\n value: {},\n on: [{\n events: selCmpt.events,\n update: `datum && item().mark.marktype !== 'group' ? ` +\n `{unit: ${unitName(model)}, encodings: [${encodings}], ` +\n `fields: [${fields}], values: [${values}]` +\n (bins.length ? ', ' + bins.map((b) => `${stringValue('bin_' + b)}: 1`).join(', ') : '') +\n '} : null',\n force: true\n }]\n }];\n}\n\nconst multi:SelectionCompiler = {\n predicate: 'vlMulti',\n scaleDomain: 'vlMultiDomain',\n\n signals: signals,\n\n modifyExpr: function(model, selCmpt) {\n const tpl = selCmpt.name + TUPLE;\n return tpl + ', ' +\n (selCmpt.resolve === 'global' ? 'null' : `{unit: ${unitName(model)}}`);\n }\n};\n\nexport default multi;\n","import {stringValue} from 'vega-util';\n\nimport {signals as multiSignals} from './multi';\nimport {SelectionCompiler, STORE, TUPLE, unitName} from './selection';\n\n\nconst single:SelectionCompiler = {\n predicate: 'vlSingle',\n scaleDomain: 'vlSingleDomain',\n\n signals: multiSignals,\n\n topLevelSignals: function(model, selCmpt, signals) {\n const hasSignal = signals.filter((s) => s.name === selCmpt.name);\n const data = `data(${stringValue(selCmpt.name + STORE)})`;\n const values = `${data}[0].values`;\n return hasSignal.length ? signals : signals.concat({\n name: selCmpt.name,\n update: `${data}.length && {` +\n selCmpt.project.map((p, i) => `${p.field}: ${values}[${i}]`).join(', ') + '}'\n });\n },\n\n modifyExpr: function(model, selCmpt) {\n const tpl = selCmpt.name + TUPLE;\n return tpl + ', ' +\n (selCmpt.resolve === 'global' ? 'true' : `{unit: ${unitName(model)}}`);\n }\n};\n\nexport default single;\n","import {stringValue} from 'vega-util';\nimport {accessPathWithDatum, varName} from '../../../util';\nimport {TUPLE} from '../selection';\nimport nearest from './nearest';\nimport {TransformCompiler} from './transforms';\n\n\nconst inputBindings:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'single' && selCmpt.resolve === 'global' &&\n selCmpt.bind && selCmpt.bind !== 'scales';\n },\n\n topLevelSignals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const proj = selCmpt.project;\n const bind = selCmpt.bind;\n const datum = nearest.has(selCmpt) ?\n '(item().isVoronoi ? datum.datum : datum)' : 'datum';\n\n proj.forEach(function(p) {\n const sgname = varName(`${name}_${p.field}`);\n const hasSignal = signals.filter((s) => s.name === sgname);\n if (!hasSignal.length) {\n signals.unshift({\n name: sgname,\n value: '',\n on: [{\n events: selCmpt.events,\n update: `datum && item().mark.marktype !== 'group' ? ${accessPathWithDatum(p.field, datum)} : null`\n }],\n bind: bind[p.field] || bind[p.channel] || bind\n });\n }\n });\n\n return signals;\n },\n\n signals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const proj = selCmpt.project;\n const signal = signals.filter((s) => s.name === name + TUPLE)[0];\n const fields = proj.map((p) => stringValue(p.field)).join(', ');\n const values = proj.map((p) => varName(`${name}_${p.field}`));\n\n if (values.length) {\n signal.update = `${values.join(' && ')} ? {fields: [${fields}], values: [${values.join(', ')}]} : null`;\n }\n\n delete signal.value;\n delete signal.on;\n\n return signals;\n }\n};\n\nexport default inputBindings;\n","import {SingleDefChannel} from '../../../channel';\nimport * as log from '../../../log';\nimport {SelectionDef} from '../../../selection';\nimport {keys} from '../../../util';\nimport {TimeUnitComponent, TimeUnitNode} from '../../data/timeunit';\nimport {SelectionComponent} from '../selection';\nimport {TransformCompiler} from './transforms';\n\nconst project: TransformCompiler = {\n has: function(selDef: SelectionComponent | SelectionDef) {\n const def = selDef as SelectionDef;\n return def.fields !== undefined || def.encodings !== undefined;\n },\n\n parse: function(model, selDef, selCmpt) {\n const channels = {};\n const timeUnits: {[key: string]: TimeUnitComponent} = {};\n\n // TODO: find a possible channel mapping for these fields.\n (selDef.fields || []).forEach((field) => channels[field] = null);\n\n (selDef.encodings || []).forEach((channel: SingleDefChannel) => {\n const fieldDef = model.fieldDef(channel);\n if (fieldDef) {\n if (fieldDef.timeUnit) {\n const tuField = model.vgField(channel);\n channels[tuField] = channel;\n\n // Construct TimeUnitComponents which will be combined into a\n // TimeUnitNode. This node may need to be inserted into the\n // dataflow if the selection is used across views that do not\n // have these time units defined.\n timeUnits[tuField] = {\n as: tuField,\n field: fieldDef.field,\n timeUnit: fieldDef.timeUnit\n };\n } else {\n channels[fieldDef.field] = channel;\n }\n } else {\n log.warn(log.message.cannotProjectOnChannelWithoutField(channel));\n }\n });\n\n const projection = selCmpt.project || (selCmpt.project = []);\n for (const field in channels) {\n if (channels.hasOwnProperty(field)) {\n projection.push({field: field, channel: channels[field]});\n }\n }\n\n const fields = selCmpt.fields || (selCmpt.fields = {});\n projection.filter((p) => p.channel).forEach((p) => fields[p.channel] = p.field);\n\n if (keys(timeUnits).length) {\n selCmpt.timeUnit = new TimeUnitNode(null, timeUnits);\n }\n }\n};\n\nexport default project;\n","\nimport {TUPLE, unitName} from '../selection';\nimport {TransformCompiler} from './transforms';\n\n\nconst TOGGLE = '_toggle';\n\nconst toggle:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'multi' && selCmpt.toggle;\n },\n\n signals: function(model, selCmpt, signals) {\n return signals.concat({\n name: selCmpt.name + TOGGLE,\n value: false,\n on: [{events: selCmpt.events, update: selCmpt.toggle}]\n });\n },\n\n modifyExpr: function(model, selCmpt, expr) {\n const tpl = selCmpt.name + TUPLE;\n const signal = selCmpt.name + TOGGLE;\n\n return `${signal} ? null : ${tpl}, ` +\n (selCmpt.resolve === 'global' ?\n `${signal} ? null : true, ` :\n `${signal} ? null : {unit: ${unitName(model)}}, `) +\n `${signal} ? ${tpl} : null`;\n }\n};\n\nexport default toggle;\n","import {selector as parseSelector} from 'vega-event-selector';\n\nimport {ScaleChannel, X, Y} from '../../../channel';\nimport {VgSignal} from '../../../vega.schema';\nimport {BRUSH as INTERVAL_BRUSH} from '../interval';\nimport {channelSignalName, positionalProjections, SelectionComponent} from '../selection';\nimport {UnitModel} from './../../unit';\nimport scalesCompiler, {domain} from './scales';\nimport {TransformCompiler} from './transforms';\n\n\nconst ANCHOR = '_translate_anchor';\nconst DELTA = '_translate_delta';\n\nconst translate:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.translate;\n },\n\n signals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const anchor = name + ANCHOR;\n const {x, y} = positionalProjections(selCmpt);\n let events = parseSelector(selCmpt.translate, 'scope');\n\n if (!hasScales) {\n events = events.map((e) => (e.between[0].markname = name + INTERVAL_BRUSH, e));\n }\n\n signals.push({\n name: anchor,\n value: {},\n on: [{\n events: events.map((e) => e.between[0]),\n update: '{x: x(unit), y: y(unit)' +\n (x !== null ? ', extent_x: ' + (hasScales ? domain(model, X) :\n `slice(${channelSignalName(selCmpt, 'x', 'visual')})`) : '') +\n\n (y !== null ? ', extent_y: ' + (hasScales ? domain(model, Y) :\n `slice(${channelSignalName(selCmpt, 'y', 'visual')})`) : '') + '}'\n }]\n }, {\n name: name + DELTA,\n value: {},\n on: [{\n events: events,\n update: `{x: ${anchor}.x - x(unit), y: ${anchor}.y - y(unit)}`\n }]\n });\n\n if (x !== null) {\n onDelta(model, selCmpt, X, 'width', signals);\n }\n\n if (y !== null) {\n onDelta(model, selCmpt, Y, 'height', signals);\n }\n\n return signals;\n }\n};\n\nexport default translate;\n\nfunction onDelta(model: UnitModel, selCmpt: SelectionComponent, channel: ScaleChannel, size: 'width' | 'height', signals: VgSignal[]) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const signal = signals.filter(s => {\n return s.name === channelSignalName(selCmpt, channel, hasScales ? 'data' : 'visual');\n })[0];\n const anchor = name + ANCHOR;\n const delta = name + DELTA;\n const sizeSg = model.getSizeSignalRef(size).signal;\n const scaleCmpt = model.getScaleComponent(channel);\n const scaleType = scaleCmpt.get('type');\n const sign = hasScales && channel === X ? '-' : ''; // Invert delta when panning x-scales.\n const extent = `${anchor}.extent_${channel}`;\n const offset = `${sign}${delta}.${channel} / ` + (hasScales ? `${sizeSg}` : `span(${extent})`);\n const panFn = !hasScales ? 'panLinear' :\n scaleType === 'log' ? 'panLog' :\n scaleType === 'pow' ? 'panPow' : 'panLinear';\n const update = `${panFn}(${extent}, ${offset}` +\n (hasScales && scaleType === 'pow' ? `, ${scaleCmpt.get('exponent') || 1}` : '') + ')';\n\n signal.on.push({\n events: {signal: delta},\n update: hasScales ? update : `clampRange(${update}, 0, ${sizeSg})`\n });\n}\n","import {selector as parseSelector} from 'vega-event-selector';\nimport {stringValue} from 'vega-util';\nimport {ScaleChannel, X, Y} from '../../../channel';\nimport {VgSignal} from '../../../vega.schema';\nimport {BRUSH as INTERVAL_BRUSH} from '../interval';\nimport {channelSignalName, positionalProjections, SelectionComponent} from '../selection';\nimport {UnitModel} from './../../unit';\nimport {default as scalesCompiler, domain} from './scales';\nimport {TransformCompiler} from './transforms';\n\n\nconst ANCHOR = '_zoom_anchor';\nconst DELTA = '_zoom_delta';\n\nconst zoom:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.zoom;\n },\n\n signals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const delta = name + DELTA;\n const {x, y} = positionalProjections(selCmpt);\n const sx = stringValue(model.scaleName(X));\n const sy = stringValue(model.scaleName(Y));\n let events = parseSelector(selCmpt.zoom, 'scope');\n\n if (!hasScales) {\n events = events.map((e) => (e.markname = name + INTERVAL_BRUSH, e));\n }\n\n signals.push({\n name: name + ANCHOR,\n on: [{\n events: events,\n update: !hasScales ? `{x: x(unit), y: y(unit)}` :\n '{' + [\n (sx ? `x: invert(${sx}, x(unit))` : ''),\n (sy ? `y: invert(${sy}, y(unit))` : '')\n ].filter((expr) => !!expr).join(', ') + '}'\n }]\n }, {\n name: delta,\n on: [{\n events: events,\n force: true,\n update: 'pow(1.001, event.deltaY * pow(16, event.deltaMode))'\n }]\n });\n\n if (x !== null) {\n onDelta(model, selCmpt, 'x', 'width', signals);\n }\n\n if (y !== null) {\n onDelta(model, selCmpt, 'y', 'height', signals);\n }\n\n return signals;\n }\n};\n\nexport default zoom;\n\nfunction onDelta(model: UnitModel, selCmpt: SelectionComponent, channel: ScaleChannel, size: 'width' | 'height', signals: VgSignal[]) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const signal = signals.filter(s => {\n return s.name === channelSignalName(selCmpt, channel, hasScales ? 'data' : 'visual');\n })[0];\n const sizeSg = model.getSizeSignalRef(size).signal;\n const scaleCmpt = model.getScaleComponent(channel);\n const scaleType = scaleCmpt.get('type');\n const base = hasScales ? domain(model, channel) : signal.name;\n const delta = name + DELTA;\n const anchor = `${name}${ANCHOR}.${channel}`;\n const zoomFn = !hasScales ? 'zoomLinear' :\n scaleType === 'log' ? 'zoomLog' :\n scaleType === 'pow' ? 'zoomPow' : 'zoomLinear';\n const update = `${zoomFn}(${base}, ${anchor}, ${delta}` +\n (hasScales && scaleType === 'pow' ? `, ${scaleCmpt.get('exponent') || 1}` : '') + ')';\n\n signal.on.push({\n events: {signal: delta},\n update: hasScales ? update : `clampRange(${update}, 0, ${sizeSg})`\n });\n}\n","import {SelectionDef} from '../../../selection';\nimport {Dict} from '../../../util';\nimport {VgSignal} from '../../../vega.schema';\nimport {Model} from '../../model';\nimport {UnitModel} from '../../unit';\nimport {SelectionComponent} from '../selection';\n\n\nexport interface TransformCompiler {\n has: (selCmpt: SelectionComponent | SelectionDef) => boolean;\n parse?: (model: UnitModel, def: SelectionDef, selCmpt: SelectionComponent) => void;\n signals?: (model: UnitModel, selCmpt: SelectionComponent, signals: VgSignal[]) => VgSignal[];\n topLevelSignals?: (model: Model, selCmpt: SelectionComponent, signals: VgSignal[]) => VgSignal[];\n modifyExpr?: (model: UnitModel, selCmpt: SelectionComponent, expr: string) => string;\n marks?: (model: UnitModel, selCmpt:SelectionComponent, marks: any[]) => any[];\n}\n\nimport inputs from './inputs';\nimport nearest from './nearest';\nimport project from './project';\nimport scales from './scales';\nimport toggle from './toggle';\nimport translate from './translate';\nimport zoom from './zoom';\nconst compilers: Dict = {project, toggle, scales,\n translate, zoom, inputs, nearest};\n\nexport function forEachTransform(selCmpt: SelectionComponent, cb: (tx: TransformCompiler) => void) {\n for (const t in compilers) {\n if (compilers[t].has(selCmpt)) {\n cb(compilers[t]);\n }\n }\n}\n","import {selector as parseSelector} from 'vega-event-selector';\nimport {isString, stringValue} from 'vega-util';\nimport {Channel, ScaleChannel, X, Y} from '../../channel';\nimport {warn} from '../../log';\nimport {LogicalOperand} from '../../logical';\nimport {BrushConfig, SELECTION_ID, SelectionDef, SelectionResolution, SelectionType} from '../../selection';\nimport {accessPathWithDatum, Dict, logicalExpr, varName} from '../../util';\nimport {VgBinding, VgData, VgEventStream, VgSignalRef} from '../../vega.schema';\nimport {DataFlowNode} from '../data/dataflow';\nimport {TimeUnitNode} from '../data/timeunit';\nimport {FacetModel} from '../facet';\nimport {LayerModel} from '../layer';\nimport {isFacetModel, isUnitModel, Model} from '../model';\nimport {UnitModel} from '../unit';\nimport intervalCompiler from './interval';\nimport multiCompiler from './multi';\nimport {SelectionComponent} from './selection';\nimport singleCompiler from './single';\nimport {forEachTransform} from './transforms/transforms';\n\n\nexport const STORE = '_store';\nexport const TUPLE = '_tuple';\nexport const MODIFY = '_modify';\nexport const SELECTION_DOMAIN = '_selection_domain_';\n\nexport interface SelectionComponent {\n name: string;\n type: SelectionType;\n events: VgEventStream;\n // predicate?: string;\n bind?: 'scales' | VgBinding | {[key: string]: VgBinding};\n resolve: SelectionResolution;\n empty: 'all' | 'none';\n mark?: BrushConfig;\n\n _signalNames: {};\n\n // Transforms\n project?: ProjectComponent[];\n fields?: any;\n timeUnit?: TimeUnitNode;\n scales?: Channel[];\n toggle?: any;\n translate?: any;\n zoom?: any;\n nearest?: any;\n}\n\nexport interface ProjectComponent {\n field?: string;\n channel?: ScaleChannel;\n}\n\nexport interface SelectionCompiler {\n signals: (model: UnitModel, selCmpt: SelectionComponent) => any[];\n topLevelSignals?: (model: Model, selCmpt: SelectionComponent, signals: any[]) => any[];\n modifyExpr: (model: UnitModel, selCmpt: SelectionComponent) => string;\n marks?: (model: UnitModel, selCmpt:SelectionComponent, marks: any[]) => any[];\n predicate: string; // Vega expr string to determine inclusion in selection.\n scaleDomain: string; // Vega expr string to materialize a scale domain.\n}\n\nexport function parseUnitSelection(model: UnitModel, selDefs: Dict) {\n const selCmpts: Dict = {};\n const selectionConfig = model.config.selection;\n\n for (let name in selDefs) {\n if (!selDefs.hasOwnProperty(name)) {\n continue;\n }\n\n const selDef = selDefs[name];\n const cfg = selectionConfig[selDef.type];\n\n // Set default values from config if a property hasn't been specified,\n // or if it is true. E.g., \"translate\": true should use the default\n // event handlers for translate. However, true may be a valid value for\n // a property (e.g., \"nearest\": true).\n for (const key in cfg) {\n // A selection should contain either `encodings` or `fields`, only use\n // default values for these two values if neither of them is specified.\n if ((key === 'encodings' && selDef.fields) || (key === 'fields' && selDef.encodings)) {\n continue;\n }\n\n if (key === 'mark') {\n selDef[key] = {...cfg[key], ...selDef[key]};\n }\n\n if (selDef[key] === undefined || selDef[key] === true) {\n selDef[key] = cfg[key] || selDef[key];\n }\n }\n\n name = varName(name);\n const selCmpt = selCmpts[name] = {\n ...selDef,\n name: name,\n events: isString(selDef.on) ? parseSelector(selDef.on, 'scope') : selDef.on,\n } as SelectionComponent;\n\n forEachTransform(selCmpt, txCompiler => {\n if (txCompiler.parse) {\n txCompiler.parse(model, selDef, selCmpt);\n }\n });\n }\n\n return selCmpts;\n}\n\nexport function assembleUnitSelectionSignals(model: UnitModel, signals: any[]) {\n forEachSelection(model, (selCmpt, selCompiler) => {\n const name = selCmpt.name;\n let modifyExpr = selCompiler.modifyExpr(model, selCmpt);\n\n signals.push.apply(signals, selCompiler.signals(model, selCmpt));\n\n forEachTransform(selCmpt, txCompiler => {\n if (txCompiler.signals) {\n signals = txCompiler.signals(model, selCmpt, signals);\n }\n if (txCompiler.modifyExpr) {\n modifyExpr = txCompiler.modifyExpr(model, selCmpt, modifyExpr);\n }\n });\n\n signals.push({\n name: name + MODIFY,\n on: [{\n events: {signal: name + TUPLE},\n update: `modify(${stringValue(selCmpt.name + STORE)}, ${modifyExpr})`\n }]\n });\n });\n\n const facetModel = getFacetModel(model);\n if (signals.length && facetModel) {\n const name = stringValue(facetModel.getName('cell'));\n signals.unshift({\n name: 'facet',\n value: {},\n on: [{\n events: parseSelector('mousemove', 'scope'),\n update: `isTuple(facet) ? facet : group(${name}).datum`\n }]\n });\n }\n\n return signals;\n}\n\nexport function assembleTopLevelSignals(model: UnitModel, signals: any[]) {\n let needsUnit = false;\n forEachSelection(model, (selCmpt, selCompiler) => {\n if (selCompiler.topLevelSignals) {\n signals = selCompiler.topLevelSignals(model, selCmpt, signals);\n }\n\n forEachTransform(selCmpt, txCompiler => {\n if (txCompiler.topLevelSignals) {\n signals = txCompiler.topLevelSignals(model, selCmpt, signals);\n }\n });\n\n needsUnit = true;\n });\n\n if (needsUnit) {\n const hasUnit = signals.filter((s) => s.name === 'unit');\n if (!(hasUnit.length)) {\n signals.unshift({\n name: 'unit',\n value: {},\n on: [{events: 'mousemove', update: 'isTuple(group()) ? group() : unit'}]\n });\n }\n }\n\n return signals;\n}\n\nexport function assembleUnitSelectionData(model: UnitModel, data: VgData[]): VgData[] {\n forEachSelection(model, selCmpt => {\n const contains = data.filter((d) => d.name === selCmpt.name + STORE);\n if (!contains.length) {\n data.push({name: selCmpt.name + STORE});\n }\n });\n\n return data;\n}\n\nexport function assembleUnitSelectionMarks(model: UnitModel, marks: any[]): any[] {\n forEachSelection(model, (selCmpt, selCompiler) => {\n marks = selCompiler.marks ? selCompiler.marks(model, selCmpt, marks) : marks;\n forEachTransform(selCmpt, (txCompiler) => {\n if (txCompiler.marks) {\n marks = txCompiler.marks(model, selCmpt, marks);\n }\n });\n });\n\n return marks;\n}\n\nexport function assembleLayerSelectionMarks(model: LayerModel, marks: any[]): any[] {\n model.children.forEach(child => {\n if (isUnitModel(child)) {\n marks = assembleUnitSelectionMarks(child, marks);\n }\n });\n\n return marks;\n}\n\nexport function selectionPredicate(model: Model, selections: LogicalOperand, dfnode?: DataFlowNode): string {\n const stores: string[] = [];\n function expr(name: string): string {\n const vname = varName(name);\n const selCmpt = model.getSelectionComponent(vname, name);\n const store = stringValue(vname + STORE);\n\n if (selCmpt.timeUnit) {\n const child = dfnode || model.component.data.raw;\n const tunode = selCmpt.timeUnit.clone();\n if (child.parent) {\n tunode.insertAsParentOf(child);\n } else {\n child.parent = tunode;\n }\n }\n\n if (selCmpt.empty !== 'none') {\n stores.push(store);\n }\n\n return compiler(selCmpt.type).predicate + `(${store}, datum` +\n (selCmpt.resolve === 'global' ? ')' : `, ${stringValue(selCmpt.resolve)})`);\n }\n\n const predicateStr = logicalExpr(selections, expr);\n return (stores.length\n ? '!(' + stores.map((s) => `length(data(${s}))`).join(' || ') + ') || '\n : ''\n ) + `(${predicateStr})`;\n}\n\n// Selections are parsed _after_ scales. If a scale domain is set to\n// use a selection, the SELECTION_DOMAIN constant is used as the\n// domainRaw.signal during scale.parse and then replaced with the necessary\n// selection expression function during scale.assemble. To not pollute the\n// type signatures to account for this setup, the selection domain definition\n// is coerced to a string and appended to SELECTION_DOMAIN.\nexport function isRawSelectionDomain(domainRaw: VgSignalRef) {\n return domainRaw.signal.indexOf(SELECTION_DOMAIN) >= 0;\n}\nexport function selectionScaleDomain(model: Model, domainRaw: VgSignalRef): VgSignalRef {\n const selDomain = JSON.parse(domainRaw.signal.replace(SELECTION_DOMAIN, ''));\n const name = varName(selDomain.selection);\n\n let selCmpt = model.component.selection && model.component.selection[name];\n if (selCmpt) {\n warn('Use \"bind\": \"scales\" to setup a binding for scales and selections within the same view.');\n } else {\n selCmpt = model.getSelectionComponent(name, selDomain.selection);\n if (!selDomain.encoding && !selDomain.field) {\n selDomain.field = selCmpt.project[0].field;\n if (selCmpt.project.length > 1) {\n warn('A \"field\" or \"encoding\" must be specified when using a selection as a scale domain. ' +\n `Using \"field\": ${stringValue(selDomain.field)}.`);\n }\n }\n return {\n signal: compiler(selCmpt.type).scaleDomain +\n `(${stringValue(name + STORE)}, ${stringValue(selDomain.encoding || null)}, ` +\n stringValue(selDomain.field || null) +\n (selCmpt.resolve === 'global' ? ')' : `, ${stringValue(selCmpt.resolve)})`)\n };\n }\n\n return {signal: 'null'};\n}\n\n// Utility functions\n\nfunction forEachSelection(model: Model, cb: (selCmpt: SelectionComponent, selCompiler: SelectionCompiler) => void) {\n const selections = model.component.selection;\n for (const name in selections) {\n if (selections.hasOwnProperty(name)) {\n const sel = selections[name];\n cb(sel, compiler(sel.type));\n }\n }\n}\n\nfunction compiler(type: SelectionType): SelectionCompiler {\n switch (type) {\n case 'single':\n return singleCompiler;\n case 'multi':\n return multiCompiler;\n case 'interval':\n return intervalCompiler;\n }\n return null;\n}\n\nfunction getFacetModel(model: Model): FacetModel {\n let parent = model.parent;\n while (parent) {\n if (isFacetModel(parent)) {\n break;\n }\n parent = parent.parent;\n }\n\n return parent as FacetModel;\n}\n\nexport function unitName(model: Model) {\n let name = stringValue(model.name);\n const facet = getFacetModel(model);\n if (facet) {\n name += (facet.facet.row ? ` + '_' + (${accessPathWithDatum(facet.vgField('row'), 'facet')})` : '')\n + (facet.facet.column ? ` + '_' + (${accessPathWithDatum(facet.vgField('column'), 'facet')})` : '');\n }\n return name;\n}\n\nexport function requiresSelectionId(model: Model) {\n let identifier = false;\n forEachSelection(model, (selCmpt) => {\n identifier = identifier || selCmpt.project.some((proj) => proj.field === SELECTION_ID);\n });\n return identifier;\n}\n\nexport function channelSignalName(selCmpt: SelectionComponent, channel: Channel, range: 'visual' | 'data') {\n const sgNames = selCmpt._signalNames || (selCmpt._signalNames = {});\n if (sgNames[channel] && sgNames[channel][range]) {\n return sgNames[channel][range];\n }\n\n sgNames[channel] = sgNames[channel] || {};\n const basename = varName(selCmpt.name + '_' + (range === 'visual' ? channel : selCmpt.fields[channel]));\n let name = basename;\n let counter = 1;\n while (sgNames[name]) {\n name = `${basename}_${counter++}`;\n }\n\n return (sgNames[name] = sgNames[channel][range] = name);\n}\n\nexport function positionalProjections(selCmpt: SelectionComponent) {\n let x:ProjectComponent = null;\n let xi:number = null;\n let y:ProjectComponent = null;\n let yi: number = null;\n\n selCmpt.project.forEach((p, i) => {\n if (p.channel === X) {\n x = p;\n xi = i;\n } else if (p.channel === Y) {\n y = p;\n yi = i;\n }\n });\n return {x, xi, y, yi};\n}\n","import {isArray, isString} from 'vega-util';\nimport {DataFlowNode} from './compile/data/dataflow';\nimport {Model} from './compile/model';\nimport {selectionPredicate} from './compile/selection/selection';\nimport {DateTime} from './datetime';\nimport {valueExpr, vgField} from './fielddef';\nimport {LogicalOperand} from './logical';\nimport {fieldExpr as timeUnitFieldExpr, normalizeTimeUnit, TimeUnit} from './timeunit';\nimport {logicalExpr} from './util';\n\nexport type Predicate =\n // a) FieldPredicate (but we don't type FieldFilter here so the schema has no nesting\n // and thus the documentation shows all of the types clearly)\n FieldEqualPredicate | FieldRangePredicate | FieldOneOfPredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate |\n // b) Selection Predicate\n SelectionPredicate |\n // c) Vega Expression string\n string;\n\n\n\nexport type FieldPredicate = FieldEqualPredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate |FieldRangePredicate | FieldOneOfPredicate;\n\nexport interface SelectionPredicate {\n /**\n * Filter using a selection name.\n */\n selection: LogicalOperand;\n}\n\nexport function isSelectionPredicate(predicate: LogicalOperand): predicate is SelectionPredicate {\n return predicate && predicate['selection'];\n}\n\nexport interface FieldPredicateBase {\n // TODO: support aggregate\n\n /**\n * Time unit for the field to be filtered.\n */\n timeUnit?: TimeUnit;\n\n /**\n * Field to be filtered.\n */\n field: string;\n}\n\nexport interface FieldEqualPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be equal to.\n */\n equal: string | number | boolean | DateTime;\n\n}\n\nexport function isFieldEqualPredicate(predicate: any): predicate is FieldEqualPredicate {\n return predicate && !!predicate.field && predicate.equal !== undefined;\n}\n\nexport interface FieldLTPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be less than.\n */\n lt: string | number | DateTime;\n\n}\n\nexport function isFieldLTPredicate(predicate: any): predicate is FieldLTPredicate {\n return predicate && !!predicate.field && predicate.lt !== undefined;\n}\n\n\nexport interface FieldLTEPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be less than or equals to.\n */\n lte: string | number | DateTime;\n\n}\n\nexport function isFieldLTEPredicate(predicate: any): predicate is FieldLTEPredicate {\n return predicate && !!predicate.field && predicate.lte !== undefined;\n}\n\n\nexport interface FieldGTPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be greater than.\n */\n gt: string | number | DateTime;\n\n}\n\nexport function isFieldGTPredicate(predicate: any): predicate is FieldGTPredicate {\n return predicate && !!predicate.field && predicate.gt !== undefined;\n}\n\nexport interface FieldGTEPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be greater than or equals to.\n */\n gte: string | number | DateTime;\n\n}\n\nexport function isFieldGTEPredicate(predicate: any): predicate is FieldGTEPredicate {\n return predicate && !!predicate.field && predicate.gte !== undefined;\n}\n\nexport interface FieldRangePredicate extends FieldPredicateBase {\n /**\n * An array of inclusive minimum and maximum values\n * for a field value of a data item to be included in the filtered data.\n * @maxItems 2\n * @minItems 2\n */\n range: (number|DateTime|null)[];\n}\n\nexport function isFieldRangePredicate(predicate: any): predicate is FieldRangePredicate {\n if (predicate && predicate.field) {\n if (isArray(predicate.range) && predicate.range.length === 2) {\n return true;\n }\n }\n return false;\n}\n\nexport interface FieldOneOfPredicate extends FieldPredicateBase {\n /**\n * A set of values that the `field`'s value should be a member of,\n * for a data item included in the filtered data.\n */\n oneOf: string[] | number[] | boolean[] | DateTime[];\n\n}\n\nexport function isFieldOneOfPredicate(predicate: any): predicate is FieldOneOfPredicate {\n return predicate && !!predicate.field && (\n isArray(predicate.oneOf) ||\n isArray(predicate.in) // backward compatibility\n );\n}\n\nexport function isFieldPredicate(predicate: Predicate): predicate is FieldOneOfPredicate | FieldEqualPredicate | FieldRangePredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate {\n return isFieldOneOfPredicate(predicate) || isFieldEqualPredicate(predicate) || isFieldRangePredicate(predicate) || isFieldLTPredicate(predicate) || isFieldGTPredicate(predicate) || isFieldLTEPredicate(predicate) || isFieldGTEPredicate(predicate);\n}\n\n/**\n * Converts a predicate into an expression.\n */\n// model is only used for selection filters.\nexport function expression(model: Model, filterOp: LogicalOperand, node?: DataFlowNode): string {\n return logicalExpr(filterOp, (predicate: Predicate) => {\n if (isString(predicate)) {\n return predicate;\n } else if (isSelectionPredicate(predicate)) {\n return selectionPredicate(model, predicate.selection, node);\n } else { // Filter Object\n return fieldFilterExpression(predicate);\n }\n });\n}\n\nfunction predicateValueExpr(v: number | string | boolean | DateTime, timeUnit: TimeUnit) {\n return valueExpr(v, {timeUnit, time: true});\n}\n\nfunction predicateValuesExpr(vals: (number|string | boolean | DateTime)[], timeUnit: TimeUnit) {\n return vals.map((v) => predicateValueExpr(v, timeUnit));\n}\n\n// This method is used by Voyager. Do not change its behavior without changing Voyager.\nexport function fieldFilterExpression(predicate: FieldPredicate, useInRange=true) {\n const {field, timeUnit} = predicate;\n const fieldExpr = timeUnit ?\n // For timeUnit, cast into integer with time() so we can use ===, inrange, indexOf to compare values directly.\n // TODO: We calculate timeUnit on the fly here. Consider if we would like to consolidate this with timeUnit pipeline\n // TODO: support utc\n ('time(' + timeUnitFieldExpr(timeUnit, field) + ')') :\n vgField(predicate, {expr: 'datum'});\n\n if (isFieldEqualPredicate(predicate)) {\n return fieldExpr + '===' + predicateValueExpr(predicate.equal, timeUnit);\n } else if (isFieldLTPredicate(predicate)) {\n const upper = predicate.lt;\n return `${fieldExpr}<${predicateValueExpr(upper, timeUnit)}`;\n } else if (isFieldGTPredicate(predicate)) {\n const lower = predicate.gt;\n return `${fieldExpr}>${predicateValueExpr(lower, timeUnit)}`;\n } else if (isFieldLTEPredicate(predicate)) {\n const upper = predicate.lte;\n return `${fieldExpr}<=${predicateValueExpr(upper, timeUnit)}`;\n } else if (isFieldGTEPredicate(predicate)) {\n const lower = predicate.gte;\n return `${fieldExpr}>=${predicateValueExpr(lower, timeUnit)}`;\n } else if (isFieldOneOfPredicate(predicate)) {\n // \"oneOf\" was formerly \"in\" -- so we need to add backward compatibility\n let oneOf = predicate.oneOf;\n oneOf = oneOf || predicate['in'];\n return 'indexof([' +\n predicateValuesExpr(oneOf, timeUnit).join(',') +\n '], ' + fieldExpr + ') !== -1';\n } else if (isFieldRangePredicate(predicate)) {\n const lower = predicate.range[0];\n const upper = predicate.range[1];\n\n if (lower !== null && upper !== null && useInRange) {\n return 'inrange(' + fieldExpr + ', [' +\n predicateValueExpr(lower, timeUnit) + ', ' +\n predicateValueExpr(upper, timeUnit) + '])';\n }\n\n const exprs = [];\n if (lower !== null) {\n exprs.push(`${fieldExpr} >= ${predicateValueExpr(lower, timeUnit)}`);\n }\n if (upper !== null) {\n exprs.push(`${fieldExpr} <= ${predicateValueExpr(upper, timeUnit)}`);\n }\n\n return exprs.length > 0 ? exprs.join(' && ') : 'true';\n }\n\n /* istanbul ignore next: it should never reach here */\n throw new Error(`Invalid field predicate: ${JSON.stringify(predicate)}`);\n}\n\nexport function normalizePredicate(f: Predicate): Predicate {\n if (isFieldPredicate(f) && f.timeUnit) {\n return {\n ...f,\n timeUnit: normalizeTimeUnit(f.timeUnit)\n };\n }\n return f;\n}\n","import {AggregateOp} from 'vega';\n\nimport {BinParams} from './bin';\nimport {Data} from './data';\nimport {LogicalOperand, normalizeLogicalOperand} from './logical';\nimport {normalizePredicate, Predicate} from './predicate';\nimport {SortField} from './sort';\nimport {TimeUnit} from './timeunit';\n\nexport interface FilterTransform {\n /**\n * The `filter` property must be one of the predicate definitions:\n *\n * 1) an [expression](https://vega.github.io/vega-lite/docs/types.html#expression) string,\n * where `datum` can be used to refer to the current data object\n *\n * 2) one of the field predicates: [`equal`](https://vega.github.io/vega-lite/docs/filter.html#equal-predicate),\n * [`lt`](https://vega.github.io/vega-lite/docs/filter.html#lt-predicate),\n * [`lte`](https://vega.github.io/vega-lite/docs/filter.html#lte-predicate),\n * [`gt`](https://vega.github.io/vega-lite/docs/filter.html#gt-predicate),\n * [`gte`](https://vega.github.io/vega-lite/docs/filter.html#gte-predicate),\n * [`range`](https://vega.github.io/vega-lite/docs/filter.html#range-predicate),\n * or [`oneOf`](https://vega.github.io/vega-lite/docs/filter.html#one-of-predicate).\n *\n * 3) a [selection predicate](https://vega.github.io/vega-lite/docs/filter.html#selection-predicate)\n *\n * 4) a logical operand that combines (1), (2), or (3).\n */\n // TODO: https://github.com/vega/vega-lite/issues/2901\n filter: LogicalOperand;\n}\n\nexport function isFilter(t: Transform): t is FilterTransform {\n return t['filter'] !== undefined;\n}\n\nexport interface CalculateTransform {\n /**\n * A [expression](https://vega.github.io/vega-lite/docs/types.html#expression) string. Use the variable `datum` to refer to the current data object.\n */\n calculate: string;\n\n /**\n * The field for storing the computed formula value.\n */\n as: string;\n}\n\nexport interface BinTransform {\n /**\n * An object indicating bin properties, or simply `true` for using default bin parameters.\n */\n bin: boolean | BinParams;\n\n /**\n * The data field to bin.\n */\n field: string;\n\n /**\n * The output fields at which to write the start and end bin values.\n */\n as: string | string[];\n}\n\nexport interface TimeUnitTransform {\n /**\n * The timeUnit.\n */\n timeUnit: TimeUnit;\n\n /**\n * The data field to apply time unit.\n */\n field: string;\n\n /**\n * The output field to write the timeUnit value.\n */\n as: string;\n}\n\nexport interface AggregateTransform {\n /**\n * Array of objects that define fields to aggregate.\n */\n aggregate: AggregatedFieldDef[];\n\n /**\n * The data fields to group by. If not specified, a single group containing all data objects will be used.\n */\n groupby?: string[];\n}\n\nexport interface AggregatedFieldDef {\n /**\n * The aggregation operations to apply to the fields, such as sum, average or count.\n * See the [full list of supported aggregation operations](https://vega.github.io/vega-lite/docs/aggregate.html#ops)\n * for more information.\n */\n op: AggregateOp;\n\n /**\n * The data field for which to compute aggregate function. This is required for all aggregation operations except `\"count\"`.\n */\n field?: string;\n\n /**\n * The output field names to use for each aggregated field.\n */\n as: string;\n}\n\n\n/**\n * @hide\n */\nexport interface StackTransform {\n /**\n * The field which is stacked.\n */\n stack: string;\n /**\n * The data fields to group by.\n */\n groupby: string[];\n /**\n * Mode for stacking marks.\n * __Default value:__ `\"zero\"`\n */\n offset?: 'zero' | 'center' | 'normalize';\n /**\n * Field that determines the order of leaves in the stacked charts.\n */\n sort?: SortField[];\n /**\n * Output field names. This can be either a string or an array of strings with\n * two elements denoting the name for the fields for stack start and stack end\n * respectively.\n * If a single string(eg.\"val\") is provided, the end field will be \"val_end\".\n */\n as: string | string[];\n\n}\n\n\nexport type WindowOnlyOp =\n 'row_number' |\n 'rank' |\n 'dense_rank' |\n 'percent_rank' |\n 'cume_dist' |\n 'ntile' |\n 'lag' |\n 'lead' |\n 'first_value' |\n 'last_value' |\n 'nth_value';\n\nexport interface WindowFieldDef {\n /**\n * The window or aggregation operations to apply within a window, including `rank`, `lead`, `sum`, `average` or `count`. See the list of all supported operations [here](https://vega.github.io/vega-lite/docs/window.html#ops).\n */\n op: AggregateOp | WindowOnlyOp;\n\n /**\n * Parameter values for the window functions. Parameter values can be omitted for operations that do not accept a parameter.\n *\n * See the list of all supported operations and their parameters [here](https://vega.github.io/vega-lite/docs/transforms/window.html).\n */\n param?: number;\n\n /**\n * The data field for which to compute the aggregate or window function. This can be omitted for window functions that do not operate over a field such as `count`, `rank`, `dense_rank`.\n */\n field?: string;\n\n /**\n * The output name for the window operation.\n */\n as: string;\n}\n\nexport interface WindowTransform {\n /**\n * The definition of the fields in the window, and what calculations to use.\n */\n window: WindowFieldDef[];\n\n /**\n * A frame specification as a two-element array indicating how the sliding window should proceed. The array entries should either be a number indicating the offset from the current data object, or null to indicate unbounded rows preceding or following the current data object. The default value is `[null, 0]`, indicating that the sliding window includes the current object and all preceding objects. The value `[-5, 5]` indicates that the window should include five objects preceding and five objects following the current object. Finally, `[null, null]` indicates that the window frame should always include all data objects. The only operators affected are the aggregation operations and the `first_value`, `last_value`, and `nth_value` window operations. The other window operations are not affected by this.\n *\n * __Default value:__: `[null, 0]` (includes the current object and all preceding objects)\n */\n frame?: (null | number)[];\n\n /**\n * Indicates if the sliding window frame should ignore peer values. (Peer values are those considered identical by the sort criteria). The default is false, causing the window frame to expand to include all peer values. If set to true, the window frame will be defined by offset values only. This setting only affects those operations that depend on the window frame, namely aggregation operations and the first_value, last_value, and nth_value window operations.\n *\n * __Default value:__ `false`\n */\n ignorePeers?: boolean;\n\n /**\n * The data fields for partitioning the data objects into separate windows. If unspecified, all data points will be in a single group.\n */\n groupby?: string[];\n\n /**\n * A sort field definition for sorting data objects within a window. If two data objects are considered equal by the comparator, they are considered “peer” values of equal rank. If sort is not specified, the order is undefined: data objects are processed in the order they are observed and none are considered peers (the ignorePeers parameter is ignored and treated as if set to `true`).\n */\n sort?: SortField[];\n}\n\nexport interface LookupData {\n /**\n * Secondary data source to lookup in.\n */\n data: Data;\n /**\n * Key in data to lookup.\n */\n key: string;\n /**\n * Fields in foreign data to lookup.\n * If not specified, the entire object is queried.\n */\n fields?: string[];\n}\n\nexport interface LookupTransform {\n /**\n * Key in primary data source.\n */\n lookup: string;\n\n /**\n * Secondary data reference.\n */\n from: LookupData;\n\n /**\n * The field or fields for storing the computed formula value.\n * If `from.fields` is specified, the transform will use the same names for `as`.\n * If `from.fields` is not specified, `as` has to be a string and we put the whole object into the data under the specified name.\n */\n as?: string | string[];\n\n /**\n * The default value to use if lookup fails.\n *\n * __Default value:__ `null`\n */\n default?: string;\n}\n\n\n\nexport function isLookup(t: Transform): t is LookupTransform {\n return t['lookup'] !== undefined;\n}\n\nexport function isWindow(t: Transform): t is WindowTransform {\n return t['window'] !== undefined;\n}\n\nexport function isCalculate(t: Transform): t is CalculateTransform {\n return t['calculate'] !== undefined;\n}\n\nexport function isBin(t: Transform): t is BinTransform {\n return !!t['bin'];\n}\n\nexport function isTimeUnit(t: Transform): t is TimeUnitTransform {\n return t['timeUnit'] !== undefined;\n}\n\nexport function isAggregate(t: Transform): t is AggregateTransform {\n return t['aggregate'] !== undefined;\n}\n\nexport function isStack(t: Transform): t is StackTransform {\n return t['stack'] !== undefined;\n}\n\nexport type Transform = FilterTransform | CalculateTransform | LookupTransform | BinTransform | TimeUnitTransform | AggregateTransform | WindowTransform | StackTransform;\n\nexport function normalizeTransform(transform: Transform[]) {\n return transform.map(t => {\n if (isFilter(t)) {\n return {\n filter: normalizeLogicalOperand(t.filter, normalizePredicate)\n };\n }\n return t;\n });\n}\n","import {isString} from 'vega-util';\nimport {BinParams, binToString} from '../../bin';\nimport {Channel} from '../../channel';\nimport {Config} from '../../config';\nimport {FieldDef, normalizeBin, vgField} from '../../fielddef';\nimport {BinTransform} from '../../transform';\nimport {Dict, duplicate, flatten, keys, vals} from '../../util';\nimport {VgBinTransform, VgTransform} from '../../vega.schema';\nimport {binFormatExpression, binRequiresRange} from '../common';\nimport {isUnitModel, Model, ModelWithField} from '../model';\nimport {DataFlowNode} from './dataflow';\n\nfunction rangeFormula(model: ModelWithField, fieldDef: FieldDef, channel: Channel, config: Config) {\n if (binRequiresRange(fieldDef, channel)) {\n // read format from axis or legend, if there is no format then use config.numberFormat\n\n const guide = isUnitModel(model) ? (model.axis(channel) || model.legend(channel) || {}) : {};\n\n const startField = vgField(fieldDef, {expr: 'datum',});\n const endField = vgField(fieldDef, {expr: 'datum', binSuffix: 'end'});\n\n return {\n formulaAs: vgField(fieldDef, {binSuffix: 'range'}),\n formula: binFormatExpression(startField, endField, guide.format, config)\n };\n }\n return {};\n}\n\nfunction binKey(bin: BinParams, field: string) {\n return `${binToString(bin)}_${field}`;\n}\n\nfunction getSignalsFromModel(model: Model, key: string) {\n return {\n signal: model.getName(`${key}_bins`),\n extentSignal: model.getName(`${key}_extent`)\n };\n}\n\nfunction isBinTransform(t: FieldDef | BinTransform): t is BinTransform {\n return 'as' in t;\n}\n\nfunction createBinComponent(t: FieldDef | BinTransform, model: Model) {\n let as: [string, string];\n\n if (isBinTransform(t)) {\n as = isString(t.as) ? [t.as, `${t.as}_end`] : [t.as[0],t.as[1]];\n } else {\n as = [vgField(t, {}), vgField(t, {binSuffix: 'end'})];\n }\n\n const bin = normalizeBin(t.bin, undefined) || {};\n const key = binKey(bin, t.field);\n const {signal, extentSignal} = getSignalsFromModel(model, key);\n\n const binComponent: BinComponent = {\n bin: bin,\n field: t.field,\n as: as,\n ...signal ? {signal} : {},\n ...extentSignal ? {extentSignal} : {}\n };\n\n return {key, binComponent};\n}\n\nexport interface BinComponent {\n bin: BinParams;\n field: string;\n extentSignal?: string;\n signal?: string;\n as: string[];\n\n // Range Formula\n\n formula?: string;\n formulaAs?: string;\n}\n\nexport class BinNode extends DataFlowNode {\n public clone() {\n return new BinNode(null, duplicate(this.bins));\n }\n\n constructor(parent: DataFlowNode, private bins: Dict) {\n super(parent);\n }\n\n public static makeFromEncoding(parent: DataFlowNode, model: ModelWithField) {\n const bins = model.reduceFieldDef((binComponentIndex: Dict, fieldDef, channel) => {\n if (fieldDef.bin) {\n const {key, binComponent} = createBinComponent(fieldDef, model);\n binComponentIndex[key] = {\n ...binComponent,\n ...binComponentIndex[key],\n ...rangeFormula(model, fieldDef, channel, model.config)\n };\n }\n return binComponentIndex;\n }, {});\n\n if (keys(bins).length === 0) {\n return null;\n }\n\n return new BinNode(parent, bins);\n }\n\n /**\n * Creates a bin node from BinTransform.\n * The optional parameter should provide\n */\n public static makeFromTransform(parent: DataFlowNode, t: BinTransform, model: Model) {\n const {key, binComponent} = createBinComponent(t, model);\n return new BinNode(parent, {\n [key]: binComponent\n });\n }\n\n public merge(other: BinNode) {\n this.bins = {...this.bins, ...other.bins};\n other.remove();\n }\n\n public producedFields() {\n const out = {};\n\n vals(this.bins).forEach(c => {\n c.as.forEach(f => out[f] = true);\n });\n\n return out;\n }\n\n public dependentFields() {\n const out = {};\n\n vals(this.bins).forEach(c => {\n out[c.field] = true;\n });\n\n return out;\n }\n\n public assemble(): VgTransform[] {\n return flatten(vals(this.bins).map(bin => {\n const transform: VgTransform[] = [];\n\n const binTrans: VgBinTransform = {\n type: 'bin',\n field: bin.field,\n as: bin.as,\n signal: bin.signal,\n ...bin.bin\n };\n\n if (!bin.bin.extent && bin.extentSignal) {\n transform.push({\n type: 'extent',\n field: bin.field,\n signal: bin.extentSignal\n });\n binTrans.extent = {signal: bin.extentSignal};\n }\n\n transform.push(binTrans);\n\n if (bin.formula) {\n transform.push({\n type: 'formula',\n expr: bin.formula,\n as: bin.formulaAs\n });\n }\n\n return transform;\n }));\n }\n}\n","import {LogicalOperand} from '../../logical';\nimport {expression, Predicate} from '../../predicate';\nimport {duplicate} from '../../util';\nimport {VgFilterTransform} from '../../vega.schema';\nimport {Model} from '../model';\nimport {DataFlowNode} from './dataflow';\n\nexport class FilterNode extends DataFlowNode {\n private expr: string;\n public clone() {\n return new FilterNode(null, this.model, duplicate(this.filter));\n }\n\n constructor(parent: DataFlowNode, private readonly model: Model, private filter: LogicalOperand) {\n super(parent);\n this.expr = expression(this.model, this.filter, this);\n }\n\n public assemble(): VgFilterTransform {\n return {\n type: 'filter',\n expr: this.expr\n };\n }\n}\n","import {GeoPositionChannel, LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2, SHAPE} from '../../channel';\nimport {GEOJSON} from '../../type';\nimport {duplicate} from '../../util';\nimport {VgGeoJSONTransform} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {DataFlowNode} from './dataflow';\n\nexport class GeoJSONNode extends DataFlowNode {\n public clone() {\n return new GeoJSONNode(null, duplicate(this.fields), this.geojson, this.signal);\n }\n\n public static parseAll(parent: DataFlowNode, model: UnitModel): DataFlowNode {\n let geoJsonCounter = 0;\n\n [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach((coordinates: GeoPositionChannel[]) => {\n const pair = coordinates.map(\n channel => model.channelHasField(channel) ? model.fieldDef(channel).field : undefined\n );\n\n if (pair[0] || pair[1]) {\n parent = new GeoJSONNode(parent, pair, null, model.getName(`geojson_${geoJsonCounter++}`));\n }\n });\n\n if (model.channelHasField(SHAPE)) {\n const fieldDef = model.fieldDef(SHAPE);\n if (fieldDef.type === GEOJSON) {\n parent = new GeoJSONNode(parent, null, fieldDef.field, model.getName(`geojson_${geoJsonCounter++}`));\n }\n }\n\n return parent;\n }\n\n constructor(parent: DataFlowNode, private fields?: string[], private geojson?: string, private signal?: string) {\n super(parent);\n }\n\n public assemble(): VgGeoJSONTransform {\n return {\n type: 'geojson',\n ...(this.fields ? {fields: this.fields} : {}),\n ...(this.geojson ? {geojson: this.geojson} : {}),\n signal: this.signal\n };\n }\n}\n","import {GeoPositionChannel, LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2} from '../../channel';\nimport {duplicate} from '../../util';\nimport {VgGeoPointTransform} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {DataFlowNode} from './dataflow';\n\n\nexport class GeoPointNode extends DataFlowNode {\n public clone() {\n return new GeoPointNode(null, this.projection, duplicate(this.fields), duplicate(this.as));\n }\n\n constructor(parent: DataFlowNode, private projection: string, private fields: string[], private as: string[]) {\n super(parent);\n }\n\n public static parseAll(parent: DataFlowNode, model: UnitModel): DataFlowNode {\n if (!model.projectionName()) {\n return parent;\n }\n\n [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach((coordinates: GeoPositionChannel[]) => {\n const pair = coordinates.map(\n channel => model.channelHasField(channel) ? model.fieldDef(channel).field : undefined\n );\n\n const suffix = coordinates[0] === LONGITUDE2 ? '2' : '';\n\n if (pair[0] || pair[1]) {\n parent = new GeoPointNode(\n parent,\n model.projectionName(),\n pair,\n [model.getName('x' + suffix), model.getName('y' + suffix)]\n );\n }\n });\n\n return parent;\n }\n\n public assemble(): VgGeoPointTransform {\n return {\n type: 'geopoint',\n projection: this.projection,\n fields: this.fields,\n as: this.as\n };\n }\n}\n","import {SELECTION_ID} from '../../selection';\nimport {StringSet} from '../../util';\nimport {VgIdentifierTransform} from '../../vega.schema';\nimport {DataFlowNode} from './dataflow';\n\nexport class IdentifierNode extends DataFlowNode {\n public clone() {\n return new IdentifierNode(null);\n }\n\n constructor(parent: DataFlowNode) {\n super(parent);\n }\n\n public producedFields(): StringSet {\n return {[SELECTION_ID]: true};\n }\n\n public assemble(): VgIdentifierTransform {\n return {type: 'identifier', as: SELECTION_ID};\n }\n}\n","import {Dict} from '../../util';\nimport {Split} from '../split';\nimport {OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {SourceNode} from './source';\n\nexport interface DataComponent {\n /**\n * A dictionary of sources indexed by a hash.\n */\n sources: Dict;\n\n /**\n * Registry of output nodes.\n */\n outputNodes: Dict;\n\n /**\n * How often is an output node used. If it is not used, we don't need to\n * instantiate it in the assemble step.\n */\n outputNodeRefCounts: Dict;\n\n /**\n * The output node before aggregation.\n */\n raw?: OutputNode;\n\n /**\n * The main output node.\n */\n main?: OutputNode;\n\n /**\n * For facets, we store the reference to the root node.\n */\n facetRoot?: FacetNode;\n\n /**\n * True if the data for this model is faceted.\n * A dataset is faceted if a parent model is a facet and no new dataset is\n * defined (which would make the data unfaceted again).\n */\n isFaceted: boolean;\n\n /**\n * Parse properties passed down from ancestors. Helps us to keep track of what has been parsed or is derived.\n */\n ancestorParse?: AncestorParse;\n}\n\n/**\n * Class to track interesting properties (see https://15721.courses.cs.cmu.edu/spring2016/papers/graefe-ieee1995.pdf)\n * about how fields have been parsed or whether they have been derived in a transforms. We use this to not parse the\n * same field again (or differently).\n */\nexport class AncestorParse extends Split> {\n constructor(\n public readonly explicit: Partial> = {},\n public readonly implicit: Partial> = {},\n public parseNothing = false\n ) {\n super(explicit, implicit);\n }\n\n public clone(): AncestorParse {\n const clone = super.clone() as AncestorParse;\n clone.parseNothing = this.parseNothing;\n return clone;\n }\n}\n","import {isString, toSet} from 'vega-util';\nimport * as log from '../../log';\nimport {LookupTransform} from '../../transform';\nimport {StringSet} from '../../util';\nimport {VgLookupTransform} from '../../vega.schema';\nimport {Model} from '../model';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {SourceNode} from './source';\n\nexport class LookupNode extends DataFlowNode {\n constructor(parent: DataFlowNode, public readonly transform: LookupTransform, public readonly secondary: string) {\n super(parent);\n }\n\n public static make(parent: DataFlowNode, model: Model, transform: LookupTransform, counter: number) {\n const sources = model.component.data.sources;\n const s = new SourceNode(transform.from.data);\n let fromSource = sources[s.hash()];\n if (!fromSource) {\n sources[s.hash()] = s;\n fromSource = s;\n }\n\n const fromOutputName = model.getName(`lookup_${counter}`);\n const fromOutputNode = new OutputNode(fromSource, fromOutputName, 'lookup', model.component.data.outputNodeRefCounts);\n\n model.component.data.outputNodes[fromOutputName] = fromOutputNode;\n\n return new LookupNode(parent, transform, fromOutputNode.getSource());\n }\n\n public producedFields(): StringSet {\n return toSet(this.transform.from.fields || ((this.transform.as instanceof Array) ? this.transform.as : [this.transform.as]));\n }\n\n public assemble(): VgLookupTransform {\n let foreign: Partial;\n\n if (this.transform.from.fields) {\n // lookup a few fields and add create a flat output\n foreign = {\n values: this.transform.from.fields,\n ... this.transform.as ? {as: ((this.transform.as instanceof Array) ? this.transform.as : [this.transform.as])} : {}\n };\n } else {\n // lookup full record and nest it\n let asName = this.transform.as;\n if (!isString(asName)) {\n log.warn(log.message.NO_FIELDS_NEEDS_AS);\n asName = '_lookup';\n }\n\n foreign = {\n as: [asName]\n };\n }\n\n return {\n type: 'lookup',\n from: this.secondary,\n key: this.transform.from.key,\n fields: [this.transform.lookup],\n ...foreign,\n ...(this.transform.default ? {default: this.transform.default} : {})\n };\n }\n}\n","import {InlineDataset, isUrlData} from '../../data';\nimport {Dict, vals} from '../../util';\nimport {VgData} from '../../vega.schema';\nimport {DataComponent} from './';\nimport {AggregateNode} from './aggregate';\nimport {BinNode} from './bin';\nimport {CalculateNode} from './calculate';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {FilterNode} from './filter';\nimport {FilterInvalidNode} from './filterinvalid';\nimport {ParseNode} from './formatparse';\nimport {GeoJSONNode} from './geojson';\nimport {GeoPointNode} from './geopoint';\nimport {IdentifierNode} from './identifier';\nimport {LookupNode} from './lookup';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\nimport {TimeUnitNode} from './timeunit';\nimport {WindowTransformNode} from './window';\n\n/**\n * Print debug information for dataflow tree.\n */\n// tslint:disable-next-line\nfunction debug(node: DataFlowNode) {\n console.log(`${(node.constructor as any).name}${node.debugName ? ` (${node.debugName})` : ''} -> ${\n (node.children.map(c => {\n return `${(c.constructor as any).name}${c.debugName ? ` (${c.debugName})` : ''}`;\n }))\n }`);\n console.log(node);\n node.children.forEach(debug);\n}\n\nfunction makeWalkTree(data: VgData[]) {\n // to name datasources\n let datasetIndex = 0;\n\n /**\n * Recursively walk down the tree.\n */\n function walkTree(node: DataFlowNode, dataSource: VgData) {\n if (node instanceof SourceNode) {\n // If the source is a named data source or a data source with values, we need\n // to put it in a different data source. Otherwise, Vega may override the data.\n if (!isUrlData(node.data)) {\n data.push(dataSource);\n const newData: VgData = {\n name: null,\n source: dataSource.name,\n transform: []\n };\n dataSource = newData;\n }\n }\n\n if (node instanceof ParseNode) {\n if (node.parent instanceof SourceNode && !dataSource.source) {\n // If node's parent is a root source and the data source does not refer to another data source, use normal format parse\n dataSource.format = {\n ...dataSource.format || {},\n parse: node.assembleFormatParse()\n };\n\n // add calculates for all nested fields\n dataSource.transform = dataSource.transform.concat(node.assembleTransforms(true));\n } else {\n // Otherwise use Vega expression to parse\n dataSource.transform = dataSource.transform.concat(node.assembleTransforms());\n }\n }\n\n if (node instanceof FacetNode) {\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n\n if (!dataSource.source || dataSource.transform.length > 0) {\n data.push(dataSource);\n node.data = dataSource.name;\n } else {\n node.data = dataSource.source;\n }\n\n node.assemble().forEach(d => data.push(d));\n\n // break here because the rest of the tree has to be taken care of by the facet.\n return;\n }\n\n if (node instanceof FilterNode ||\n node instanceof CalculateNode ||\n node instanceof GeoPointNode ||\n node instanceof GeoJSONNode ||\n node instanceof AggregateNode ||\n node instanceof LookupNode ||\n node instanceof WindowTransformNode ||\n node instanceof IdentifierNode) {\n dataSource.transform.push(node.assemble());\n }\n\n if (node instanceof FilterInvalidNode ||\n node instanceof BinNode ||\n node instanceof TimeUnitNode ||\n node instanceof StackNode) {\n dataSource.transform = dataSource.transform.concat(node.assemble());\n }\n\n if (node instanceof AggregateNode) {\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n }\n\n if (node instanceof OutputNode) {\n if (dataSource.source && dataSource.transform.length === 0) {\n node.setSource(dataSource.source);\n } else if (node.parent instanceof OutputNode) {\n // Note that an output node may be required but we still do not assemble a\n // separate data source for it.\n node.setSource(dataSource.name);\n } else {\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n\n // Here we set the name of the datasource we generated. From now on\n // other assemblers can use it.\n node.setSource(dataSource.name);\n\n // if this node has more than one child, we will add a datasource automatically\n if (node.numChildren() === 1) {\n data.push(dataSource);\n const newData: VgData = {\n name: null,\n source: dataSource.name,\n transform: []\n };\n dataSource = newData;\n }\n }\n }\n\n switch (node.numChildren()) {\n case 0:\n // done\n if (node instanceof OutputNode && (!dataSource.source || dataSource.transform.length > 0)) {\n // do not push empty datasources that are simply references\n data.push(dataSource);\n }\n break;\n case 1:\n walkTree(node.children[0], dataSource);\n break;\n default:\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n\n let source = dataSource.name;\n if (!dataSource.source || dataSource.transform.length > 0) {\n data.push(dataSource);\n } else {\n source = dataSource.source;\n }\n\n node.children.forEach(child => {\n const newData: VgData = {\n name: null,\n source: source,\n transform: []\n };\n walkTree(child, newData);\n });\n break;\n }\n }\n\n return walkTree;\n}\n\n/**\n * Assemble data sources that are derived from faceted data.\n */\nexport function assembleFacetData(root: FacetNode): VgData[] {\n const data: VgData[] = [];\n const walkTree = makeWalkTree(data);\n\n root.children.forEach(child => walkTree(child, {\n source: root.name,\n name: null,\n transform: []\n }));\n\n return data;\n}\n\n/**\n * Create Vega Data array from a given compiled model and append all of them to the given array\n *\n * @param model\n * @param data array\n * @return modified data array\n */\nexport function assembleRootData(dataComponent: DataComponent, datasets: Dict): VgData[] {\n const roots: SourceNode[] = vals(dataComponent.sources);\n const data: VgData[] = [];\n\n // roots.forEach(debug);\n\n const walkTree = makeWalkTree(data);\n\n let sourceIndex = 0;\n\n roots.forEach(root => {\n // assign a name if the source does not have a name yet\n if (!root.hasName()) {\n root.dataName = `source_${sourceIndex++}`;\n }\n\n const newData: VgData = root.assemble();\n\n walkTree(root, newData);\n });\n\n // remove empty transform arrays for cleaner output\n data.forEach(d => {\n if (d.transform.length === 0) {\n delete d.transform;\n }\n });\n\n // move sources without transforms (the ones that are potentially used in lookups) to the beginning\n let whereTo = 0;\n for (let i = 0; i < data.length; i++) {\n const d = data[i];\n if ((d.transform || []).length === 0 && !d.source) {\n data.splice(whereTo++, 0, data.splice(i, 1)[0]);\n }\n }\n\n // now fix the from references in lookup transforms\n for (const d of data) {\n for (const t of d.transform || []) {\n if (t.type === 'lookup') {\n t.from = dataComponent.outputNodes[t.from].getSource();\n }\n }\n }\n\n // inline values for datasets that are in the datastore\n for (const d of data) {\n if (d.name in datasets) {\n d.values = datasets[d.name];\n }\n }\n\n return data;\n}\n","import {defaultScaleConfig, hasDiscreteDomain} from '../../scale';\nimport {isVgRangeStep} from '../../vega.schema';\nimport {ConcatModel} from '../concat';\nimport {Model} from '../model';\nimport {Explicit, mergeValuesWithExplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {LayoutSize, LayoutSizeIndex} from './component';\n\nexport function parseLayerLayoutSize(model: Model) {\n parseChildrenLayoutSize(model);\n\n const layoutSizeCmpt = model.component.layoutSize;\n layoutSizeCmpt.setWithExplicit('width', parseNonUnitLayoutSizeForChannel(model, 'width'));\n layoutSizeCmpt.setWithExplicit('height', parseNonUnitLayoutSizeForChannel(model, 'height'));\n}\n\nexport const parseRepeatLayoutSize = parseLayerLayoutSize;\n\nexport function parseConcatLayoutSize(model: ConcatModel) {\n parseChildrenLayoutSize(model);\n const layoutSizeCmpt = model.component.layoutSize;\n\n const sizeTypeToMerge = model.isVConcat ? 'width' : 'height';\n layoutSizeCmpt.setWithExplicit(sizeTypeToMerge, parseNonUnitLayoutSizeForChannel(model, sizeTypeToMerge));\n}\n\nexport function parseChildrenLayoutSize(model: Model) {\n for (const child of model.children) {\n child.parseLayoutSize();\n }\n}\n\nfunction parseNonUnitLayoutSizeForChannel(model: Model, sizeType: 'width' | 'height'): Explicit {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const resolve = model.component.resolve;\n\n let mergedSize: Explicit;\n // Try to merge layout size\n for (const child of model.children) {\n const childSize = child.component.layoutSize.getWithExplicit(sizeType);\n const scaleResolve = resolve.scale[channel];\n if (scaleResolve === 'independent' && childSize.value === 'range-step') {\n // Do not merge independent scales with range-step as their size depends\n // on the scale domains, which can be different between scales.\n mergedSize = undefined;\n break;\n }\n\n if (mergedSize) {\n if (scaleResolve === 'independent' && mergedSize.value !== childSize.value) {\n // For independent scale, only merge if all the sizes are the same.\n // If the values are different, abandon the merge!\n mergedSize = undefined;\n break;\n }\n mergedSize = mergeValuesWithExplicit(\n mergedSize, childSize, sizeType, ''\n );\n } else {\n mergedSize = childSize;\n }\n }\n\n if (mergedSize) {\n // If merged, rename size and set size of all children.\n for (const child of model.children) {\n model.renameLayoutSize(child.getName(sizeType), model.getName(sizeType));\n child.component.layoutSize.set(sizeType, 'merged', false);\n }\n return mergedSize;\n } else {\n // Otherwise, there is no merged size.\n return {\n explicit: false,\n value: undefined\n };\n }\n}\n\nexport function parseUnitLayoutSize(model: UnitModel) {\n const layoutSizeComponent = model.component.layoutSize;\n if (!layoutSizeComponent.explicit.width) {\n const width = defaultUnitSize(model, 'width');\n layoutSizeComponent.set('width', width, false);\n }\n\n if (!layoutSizeComponent.explicit.height) {\n const height = defaultUnitSize(model, 'height');\n layoutSizeComponent.set('height', height, false);\n }\n}\n\nfunction defaultUnitSize(model: UnitModel, sizeType: 'width' | 'height'): LayoutSize {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const config = model.config;\n const scaleComponent = model.getScaleComponent(channel);\n\n if (scaleComponent) {\n const scaleType = scaleComponent.get('type');\n const range = scaleComponent.get('range');\n\n if (hasDiscreteDomain(scaleType) && isVgRangeStep(range)) {\n // For discrete domain with range.step, use dynamic width/height\n return 'range-step';\n } else {\n return config.view[sizeType];\n }\n } else if (model.hasProjection) {\n return config.view[sizeType];\n } else {\n // No scale - set default size\n if (sizeType === 'width' && model.mark === 'text') {\n // width for text mark without x-field is a bit wider than typical range step\n return config.scale.textXRangeStep;\n }\n\n // Set width/height equal to rangeStep config or if rangeStep is null, use value from default scale config.\n return config.scale.rangeStep || defaultScaleConfig.rangeStep;\n }\n\n}\n","import {isArray} from 'vega-util';\nimport {Encoding} from '../encoding';\nimport {FacetMapping} from '../facet';\nimport {Field, hasConditionalFieldDef, isConditionalDef, isFieldDef, isRepeatRef, ValueDef} from '../fielddef';\nimport {ChannelDef, ScaleFieldDef} from '../fielddef';\nimport * as log from '../log';\nimport {isSortField} from '../sort';\n\nexport type RepeaterValue = {\n row?: string,\n column?: string\n};\n\nexport function replaceRepeaterInFacet(facet: FacetMapping, repeater: RepeaterValue): FacetMapping {\n return replaceRepeater(facet, repeater) as FacetMapping;\n}\n\nexport function replaceRepeaterInEncoding(encoding: Encoding, repeater: RepeaterValue): Encoding {\n return replaceRepeater(encoding, repeater) as Encoding;\n}\n\n/**\n * Replaces repeated value and returns if the repeated value is valid.\n */\nfunction replaceRepeat(o: T, repeater: RepeaterValue): T {\n if (isRepeatRef(o.field)) {\n if (o.field.repeat in repeater) {\n // any needed to calm down ts compiler\n return {...o as any, field: repeater[o.field.repeat]};\n } else {\n log.warn(log.message.noSuchRepeatedValue(o.field.repeat));\n return undefined;\n }\n }\n return o;\n}\n\n/**\n * Replace repeater values in a field def with the concrete field name.\n */\nfunction replaceRepeaterInFieldDef(fieldDef: ScaleFieldDef, repeater: RepeaterValue): ScaleFieldDef {\n fieldDef = replaceRepeat(fieldDef, repeater);\n\n if (fieldDef === undefined) {\n // the field def should be ignored\n return undefined;\n }\n\n if (fieldDef.sort && isSortField(fieldDef.sort)) {\n const sort = replaceRepeat(fieldDef.sort, repeater);\n fieldDef = {\n ...fieldDef,\n ...(sort ? {sort} : {})\n };\n }\n\n return fieldDef as ScaleFieldDef;\n}\n\nfunction replaceRepeaterInChannelDef(channelDef: ChannelDef, repeater: RepeaterValue): ChannelDef {\n if (isFieldDef(channelDef)) {\n const fd = replaceRepeaterInFieldDef(channelDef, repeater);\n if (fd) {\n return fd;\n } else if (isConditionalDef(channelDef)) {\n return {condition: channelDef.condition};\n }\n } else {\n if (hasConditionalFieldDef(channelDef)) {\n const fd = replaceRepeaterInFieldDef(channelDef.condition, repeater);\n if (fd) {\n return {\n ...channelDef,\n condition: fd\n } as ChannelDef;\n } else {\n const {condition, ...channelDefWithoutCondition} = channelDef;\n return channelDefWithoutCondition as ChannelDef;\n }\n }\n return channelDef as ValueDef;\n }\n return undefined;\n}\n\ntype EncodingOrFacet = Encoding | FacetMapping;\n\nfunction replaceRepeater(mapping: EncodingOrFacet, repeater: RepeaterValue): EncodingOrFacet {\n const out: EncodingOrFacet = {};\n for (const channel in mapping) {\n if (mapping.hasOwnProperty(channel)) {\n const channelDef: ChannelDef | ChannelDef[] = mapping[channel];\n\n if (isArray(channelDef)) {\n // array cannot have condition\n out[channel] = channelDef.map(cd => replaceRepeaterInChannelDef(cd, repeater))\n .filter(cd => cd);\n } else {\n const cd = replaceRepeaterInChannelDef(channelDef, repeater);\n if (cd) {\n out[channel] = cd;\n }\n }\n }\n }\n return out;\n}\n","import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {Channel, COLUMN, ROW, ScaleChannel} from '../channel';\nimport {Config} from '../config';\nimport {reduce} from '../encoding';\nimport {FacetFieldDef, FacetMapping} from '../facet';\nimport {FieldDef, normalize, title as fieldDefTitle, vgField} from '../fielddef';\nimport * as log from '../log';\nimport {hasDiscreteDomain} from '../scale';\nimport {EncodingSortField, isSortField, SortOrder} from '../sort';\nimport {NormalizedFacetSpec} from '../spec';\nimport {contains} from '../util';\nimport {isVgRangeStep, VgData, VgLayout, VgMarkGroup, VgSignal} from '../vega.schema';\nimport {assembleAxis} from './axis/assemble';\nimport {buildModel} from './buildmodel';\nimport {assembleFacetData} from './data/assemble';\nimport {sortArrayIndexField} from './data/calculate';\nimport {parseData} from './data/parse';\nimport {getHeaderType, HeaderChannel, HeaderComponent} from './header/index';\nimport {parseChildrenLayoutSize} from './layoutsize/parse';\nimport {Model, ModelWithField} from './model';\nimport {RepeaterValue, replaceRepeaterInFacet} from './repeater';\nimport {parseGuideResolve} from './resolve';\nimport {assembleDomain, getFieldFromDomain} from './scale/domain';\n\nexport function facetSortFieldName(fieldDef: FacetFieldDef, sort: EncodingSortField, expr?: 'datum') {\n return vgField(sort, {expr, suffix: `by_${vgField(fieldDef)}`});\n}\n\nexport class FacetModel extends ModelWithField {\n public readonly type: 'facet' = 'facet';\n public readonly facet: FacetMapping;\n\n public readonly child: Model;\n\n public readonly children: Model[];\n\n constructor(spec: NormalizedFacetSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, repeater, spec.resolve);\n\n\n this.child = buildModel(spec.spec, this, this.getName('child'), undefined, repeater, config, false);\n this.children = [this.child];\n\n const facet: FacetMapping = replaceRepeaterInFacet(spec.facet, repeater);\n\n this.facet = this.initFacet(facet);\n }\n\n private initFacet(facet: FacetMapping): FacetMapping {\n // clone to prevent side effect to the original spec\n return reduce(facet, function(normalizedFacet, fieldDef: FieldDef, channel: Channel) {\n if (!contains([ROW, COLUMN], channel)) {\n // Drop unsupported channel\n log.warn(log.message.incompatibleChannel(channel, 'facet'));\n return normalizedFacet;\n }\n\n if (fieldDef.field === undefined) {\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n return normalizedFacet;\n }\n\n // Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n normalizedFacet[channel] = normalize(fieldDef, channel);\n return normalizedFacet;\n }, {});\n }\n\n public channelHasField(channel: Channel): boolean {\n return !!this.facet[channel];\n }\n\n public fieldDef(channel: Channel): FieldDef {\n return this.facet[channel];\n }\n\n public parseData() {\n this.component.data = parseData(this);\n this.child.parseData();\n }\n\n public parseLayoutSize() {\n parseChildrenLayoutSize(this);\n }\n\n public parseSelection() {\n // As a facet has a single child, the selection components are the same.\n // The child maintains its selections to assemble signals, which remain\n // within its unit.\n this.child.parseSelection();\n this.component.selection = this.child.component.selection;\n }\n\n public parseMarkGroup() {\n this.child.parseMarkGroup();\n }\n\n public parseAxisAndHeader() {\n this.child.parseAxisAndHeader();\n\n this.parseHeader('column');\n this.parseHeader('row');\n\n this.mergeChildAxis('x');\n this.mergeChildAxis('y');\n }\n\n private parseHeader(channel: HeaderChannel) {\n\n if (this.channelHasField(channel)) {\n const fieldDef = this.facet[channel];\n const header = fieldDef.header || {};\n let title = fieldDef.title !== undefined ? fieldDef.title :\n header.title !== undefined ? header.title : fieldDefTitle(fieldDef, this.config);\n\n if (this.child.component.layoutHeaders[channel].title) {\n // merge title with child to produce \"Title / Subtitle / Sub-subtitle\"\n title += ' / ' + this.child.component.layoutHeaders[channel].title;\n this.child.component.layoutHeaders[channel].title = null;\n }\n\n this.component.layoutHeaders[channel] = {\n title,\n facetFieldDef: fieldDef,\n // TODO: support adding label to footer as well\n header: [this.makeHeaderComponent(channel, true)]\n };\n }\n }\n\n private makeHeaderComponent(channel: HeaderChannel, labels: boolean): HeaderComponent {\n const sizeType = channel === 'row' ? 'height' : 'width';\n\n return {\n labels,\n sizeSignal: this.child.component.layoutSize.get(sizeType) ? this.child.getSizeSignalRef(sizeType) : undefined,\n axes: []\n };\n }\n\n private mergeChildAxis(channel: 'x' | 'y') {\n const {child} = this;\n if (child.component.axes[channel]) {\n const {layoutHeaders, resolve} = this.component;\n resolve.axis[channel] = parseGuideResolve(resolve, channel);\n\n if (resolve.axis[channel] === 'shared') {\n // For shared axis, move the axes to facet's header or footer\n const headerChannel = channel === 'x' ? 'column' : 'row';\n\n const layoutHeader = layoutHeaders[headerChannel];\n for (const axisComponent of child.component.axes[channel]) {\n const headerType = getHeaderType(axisComponent.get('orient'));\n layoutHeader[headerType] = layoutHeader[headerType] ||\n [this.makeHeaderComponent(headerChannel, false)];\n\n const mainAxis = assembleAxis(axisComponent, 'main', this.config, {header: true});\n // LayoutHeader no longer keep track of property precedence, thus let's combine.\n layoutHeader[headerType][0].axes.push(mainAxis);\n axisComponent.mainExtracted = true;\n }\n } else {\n // Otherwise do nothing for independent axes\n }\n }\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return this.child.assembleSelectionTopLevelSignals(signals);\n }\n\n public assembleSelectionSignals(): VgSignal[] {\n this.child.assembleSelectionSignals();\n return [];\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return this.child.assembleSelectionData(data);\n }\n\n private getHeaderLayoutMixins(): VgLayout {\n const layoutMixins: VgLayout = {};\n\n ['row', 'column'].forEach((channel: 'row' | 'column') => {\n ['header', 'footer'].forEach((headerType: 'header' | 'footer') => {\n const layoutHeaderComponent = this.component.layoutHeaders[channel];\n const headerComponent = layoutHeaderComponent[headerType];\n if (headerComponent && headerComponent[0]) {\n // set header/footerBand\n const sizeType = channel === 'row' ? 'height' : 'width';\n const bandType = headerType === 'header' ? 'headerBand' : 'footerBand';\n if (!this.child.component.layoutSize.get(sizeType)) {\n // If facet child does not have size signal, then apply headerBand\n layoutMixins[bandType] = layoutMixins[bandType] || {};\n layoutMixins[bandType][channel] = 0.5;\n }\n\n if (layoutHeaderComponent.title) {\n layoutMixins.offset = layoutMixins.offset || {};\n layoutMixins.offset[channel === 'row' ? 'rowTitle' : 'columnTitle'] = 10;\n }\n }\n });\n });\n return layoutMixins;\n }\n\n protected assembleDefaultLayout(): VgLayout {\n const columns = this.channelHasField('column') ? this.columnDistinctSignal() : 1;\n\n // TODO: determine default align based on shared / independent scales\n\n return {\n ...this.getHeaderLayoutMixins(),\n\n columns,\n bounds: 'full',\n align: 'all'\n };\n }\n\n public assembleLayoutSignals(): VgSignal[] {\n // FIXME(https://github.com/vega/vega-lite/issues/1193): this can be incorrect if we have independent scales.\n return this.child.assembleLayoutSignals();\n }\n\n private columnDistinctSignal() {\n if (this.parent && (this.parent instanceof FacetModel)) {\n // For nested facet, we will add columns to group mark instead\n // See discussion in https://github.com/vega/vega/issues/952\n // and https://github.com/vega/vega-view/releases/tag/v1.2.6\n return undefined;\n } else {\n // In facetNode.assemble(), the name is always this.getName('column') + '_layout'.\n const facetLayoutDataName = this.getName('column_domain');\n return {signal: `length(data('${facetLayoutDataName}'))`};\n }\n }\n\n public assembleGroup(signals: VgSignal[]) {\n if (this.parent && (this.parent instanceof FacetModel)) {\n // Provide number of columns for layout.\n // See discussion in https://github.com/vega/vega/issues/952\n // and https://github.com/vega/vega-view/releases/tag/v1.2.6\n return {\n ...(this.channelHasField('column') ? {\n encode: {\n update: {\n // TODO(https://github.com/vega/vega-lite/issues/2759):\n // Correct the signal for facet of concat of facet_column\n columns: {field: vgField(this.facet.column, {prefix: 'distinct'})}\n }\n }\n } : {}),\n ...super.assembleGroup(signals)\n };\n }\n return super.assembleGroup(signals);\n }\n\n /**\n * Aggregate cardinality for calculating size\n */\n private getCardinalityAggregateForChild() {\n const fields: string[] = [];\n const ops: AggregateOp[] = [];\n const as: string[] = [];\n\n if (this.child instanceof FacetModel) {\n if (this.child.channelHasField('column')) {\n const field = vgField(this.child.facet.column);\n fields.push(field);\n ops.push('distinct');\n as.push(`distinct_${field}`);\n }\n } else {\n for (const channel of ['x', 'y'] as ScaleChannel[]) {\n const childScaleComponent = this.child.component.scales[channel];\n if (childScaleComponent && !childScaleComponent.merged) {\n const type = childScaleComponent.get('type');\n const range = childScaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const domain = assembleDomain(this.child, channel);\n const field = getFieldFromDomain(domain);\n if (field) {\n fields.push(field);\n ops.push('distinct');\n as.push(`distinct_${field}`);\n } else {\n log.warn('Unknown field for ${channel}. Cannot calculate view size.');\n }\n }\n }\n }\n }\n return {fields, ops, as};\n }\n\n\n private assembleFacet() {\n const {name, data} = this.component.data.facetRoot;\n const {row, column} = this.facet;\n const {fields, ops, as} = this.getCardinalityAggregateForChild();\n const groupby: string[] = [];\n\n ['row', 'column'].forEach((channel: 'row' | 'column') => {\n const fieldDef = this.facet[channel];\n if (fieldDef) {\n groupby.push(vgField(fieldDef));\n const {sort} = fieldDef;\n if (isSortField(sort)) {\n const {field, op} = sort;\n const outputName = facetSortFieldName(fieldDef, sort);\n if (row && column) {\n // For crossed facet, use pre-calculate field as it requires a different groupby\n // For each calculated field, apply max and assign them to the same name as\n // all values of the same group should be the same anyway.\n fields.push(outputName);\n ops.push('max');\n as.push(outputName);\n } else {\n fields.push(field);\n ops.push(op);\n as.push(outputName);\n }\n } else if (isArray(sort)) {\n const outputName = sortArrayIndexField(fieldDef, channel);\n fields.push(outputName);\n ops.push('max');\n as.push(outputName);\n }\n }\n });\n\n const cross = !!row && !!column;\n\n return {\n name,\n data,\n groupby,\n ...(cross || fields.length ? {\n aggregate: {\n ...(cross ? {cross} : {}),\n ...(fields.length ? {fields, ops, as} : {})\n }\n } : {})\n };\n }\n\n\n private headerSortFields(channel: 'row' | 'column'): string[] {\n const {facet} = this;\n const fieldDef = facet[channel];\n\n if (fieldDef) {\n if (isSortField(fieldDef.sort)) {\n return [facetSortFieldName(fieldDef, fieldDef.sort, 'datum')];\n } else if (isArray(fieldDef.sort)) {\n return [sortArrayIndexField(fieldDef, channel, 'datum')];\n }\n return [vgField(fieldDef, {expr: 'datum'})];\n }\n return [];\n }\n\n private headerSortOrder(channel: 'row' | 'column'): SortOrder[] {\n const {facet} = this;\n const fieldDef = facet[channel];\n if (fieldDef) {\n const {sort} = fieldDef;\n const order = (isSortField(sort) ? sort.order : !isArray(sort) && sort) || 'ascending';\n return [order];\n }\n return [];\n }\n\n public assembleMarks(): VgMarkGroup[] {\n const {child} = this;\n const facetRoot = this.component.data.facetRoot;\n const data = assembleFacetData(facetRoot);\n\n // If we facet by two dimensions, we need to add a cross operator to the aggregation\n // so that we create all groups\n const layoutSizeEncodeEntry = child.assembleLayoutSize();\n\n const title = child.assembleTitle();\n const style = child.assembleGroupStyle();\n\n const markGroup = {\n name: this.getName('cell'),\n type: 'group',\n ...(title? {title} : {}),\n ...(style? {style} : {}),\n from: {\n facet: this.assembleFacet()\n },\n // TODO: move this to after data\n sort: {\n field: [\n ...this.headerSortFields('row'),\n ...this.headerSortFields('column')\n ],\n order: [\n ...this.headerSortOrder('row'),\n ...this.headerSortOrder('column')\n ]\n },\n ...(data.length > 0 ? {data: data} : {}),\n ...(layoutSizeEncodeEntry ? {encode: {update: layoutSizeEncodeEntry}} : {}),\n ...child.assembleGroup()\n };\n\n return [markGroup];\n }\n\n\n protected getMapping() {\n return this.facet;\n }\n}\n\n","import {AggregateOp} from 'vega';\nimport {FacetMapping} from '../../facet';\nimport {vgField} from '../../fielddef';\nimport {isSortField} from '../../sort';\nimport {WindowFieldDef, WindowOnlyOp, WindowTransform} from '../../transform';\nimport {duplicate} from '../../util';\nimport {VgComparator, VgComparatorOrder, VgWindowTransform} from '../../vega.schema';\nimport {facetSortFieldName} from '../facet';\nimport {DataFlowNode} from './dataflow';\n\n/**\n * A class for the window transform nodes\n */\nexport class WindowTransformNode extends DataFlowNode {\n public static makeFromFacet(parent: DataFlowNode, facet: FacetMapping): WindowTransformNode {\n const {row, column} = facet;\n if (row && column) {\n let newParent = null;\n // only need to make one for crossed facet\n for (const fieldDef of [row, column]) {\n if (isSortField(fieldDef.sort)) {\n const {field, op} = fieldDef.sort;\n parent = newParent = new WindowTransformNode(parent, {\n window: [{\n op,\n field,\n as: facetSortFieldName(fieldDef, fieldDef.sort)\n }],\n groupby: [vgField(fieldDef)],\n frame: [null, null]\n });\n }\n }\n return newParent;\n }\n return null;\n }\n\n\n public clone() {\n return new WindowTransformNode(this.parent, duplicate(this.transform));\n }\n\n constructor(parent: DataFlowNode, private transform: WindowTransform) {\n super(parent);\n }\n\n public producedFields() {\n const out = {};\n this.transform.window.forEach(windowFieldDef => {\n out[this.getDefaultName(windowFieldDef)] = true;\n });\n\n return out;\n }\n\n private getDefaultName(windowFieldDef: WindowFieldDef): string {\n return windowFieldDef.as || vgField(windowFieldDef);\n }\n\n public assemble(): VgWindowTransform {\n const fields: string[] = [];\n const ops: (AggregateOp | WindowOnlyOp)[] = [];\n const as = [];\n const params = [];\n for (const window of this.transform.window) {\n ops.push(window.op);\n as.push(this.getDefaultName(window));\n params.push(window.param === undefined ? null : window.param);\n fields.push(window.field === undefined ? null : window.field);\n }\n\n const frame = this.transform.frame;\n const groupby = this.transform.groupby;\n const sortFields: string[] = [];\n const sortOrder: VgComparatorOrder[] = [];\n if (this.transform.sort !== undefined) {\n for (const sortField of this.transform.sort) {\n sortFields.push(sortField.field);\n sortOrder.push(sortField.order || 'ascending');\n }\n }\n const sort: VgComparator = {\n field: sortFields,\n order: sortOrder,\n };\n const ignorePeers = this.transform.ignorePeers;\n\n const result: VgWindowTransform = {\n type: 'window',\n params,\n as,\n ops,\n fields,\n sort,\n };\n\n if (ignorePeers !== undefined) {\n result.ignorePeers = ignorePeers;\n }\n\n if (groupby !== undefined) {\n result.groupby = groupby;\n }\n\n if (frame !== undefined) {\n result.frame = frame;\n }\n\n return result;\n }\n}\n","import {MAIN, RAW} from '../../data';\nimport * as log from '../../log';\nimport {isAggregate, isBin, isCalculate, isFilter, isLookup, isStack, isTimeUnit, isWindow} from '../../transform';\nimport {Dict, keys} from '../../util';\nimport {isFacetModel, isLayerModel, isUnitModel, Model} from '../model';\nimport {requiresSelectionId} from '../selection/selection';\nimport {AggregateNode} from './aggregate';\nimport {BinNode} from './bin';\nimport {CalculateNode} from './calculate';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {FilterNode} from './filter';\nimport {FilterInvalidNode} from './filterinvalid';\nimport {ParseNode} from './formatparse';\nimport {GeoJSONNode} from './geojson';\nimport {GeoPointNode} from './geopoint';\nimport {IdentifierNode} from './identifier';\nimport {AncestorParse, DataComponent} from './index';\nimport {LookupNode} from './lookup';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\nimport {TimeUnitNode} from './timeunit';\nimport {WindowTransformNode} from './window';\n\nfunction parseRoot(model: Model, sources: Dict): DataFlowNode {\n if (model.data || !model.parent) {\n // if the model defines a data source or is the root, create a source node\n const source = new SourceNode(model.data);\n const hash = source.hash();\n if (hash in sources) {\n // use a reference if we already have a source\n return sources[hash];\n } else {\n // otherwise add a new one\n sources[hash] = source;\n return source;\n }\n } else {\n // If we don't have a source defined (overriding parent's data), use the parent's facet root or main.\n return model.parent.component.data.facetRoot ? model.parent.component.data.facetRoot : model.parent.component.data.main;\n }\n}\n\n\n/**\n * Parses a transforms array into a chain of connected dataflow nodes.\n */\nexport function parseTransformArray(head: DataFlowNode, model: Model, ancestorParse: AncestorParse): DataFlowNode {\n let lookupCounter = 0;\n\n model.transforms.forEach(t => {\n if (isCalculate(t)) {\n head = new CalculateNode(head, t);\n ancestorParse.set(t.as, 'derived', false);\n } else if (isFilter(t)) {\n head = ParseNode.makeImplicitFromFilterTransform(head, t, ancestorParse) || head;\n\n head = new FilterNode(head, model, t.filter);\n } else if (isBin(t)) {\n const bin = head = BinNode.makeFromTransform(head, t, model);\n\n for (const field of keys(bin.producedFields())) {\n ancestorParse.set(field, 'number', false);\n }\n\n } else if (isTimeUnit(t)) {\n head = TimeUnitNode.makeFromTransform(head, t);\n\n ancestorParse.set(t.as, 'date', false);\n } else if (isAggregate(t)) {\n const agg = head = AggregateNode.makeFromTransform(head, t);\n\n if (requiresSelectionId(model)) {\n head = new IdentifierNode(head);\n }\n\n for (const field of keys(agg.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else if (isLookup(t)) {\n const lookup = head = LookupNode.make(head, model, t, lookupCounter++);\n\n for (const field of keys(lookup.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else if (isWindow(t)) {\n const window = head = new WindowTransformNode(head, t);\n\n for (const field of keys(window.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else if (isStack(t)) {\n const stack = head = StackNode.makeFromTransform(head, t);\n\n for (const field of keys(stack.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else {\n log.warn(log.message.invalidTransformIgnored(t));\n return;\n }\n });\n\n return head;\n}\n\n/*\nDescription of the dataflow (http://asciiflow.com/):\n +--------+\n | Source |\n +---+----+\n |\n v\n FormatParse\n (explicit)\n |\n v\n Transforms\n(Filter, Calculate, Binning, TimeUnit, Aggregate, Window, ...)\n |\n v\n FormatParse\n (implicit)\n |\n v\n Binning (in `encoding`)\n |\n v\n Timeunit (in `encoding`)\n |\n v\nFormula From Sort Array\n |\n v\n +--+--+\n | Raw |\n +-----+\n |\n v\n Aggregate (in `encoding`)\n |\n v\n Stack (in `encoding`)\n |\n v\n Invalid Filter\n |\n v\n +----------+\n | Main |\n +----------+\n |\n v\n +-------+\n | Facet |----> \"column\", \"column-layout\", and \"row\"\n +-------+\n |\n v\n ...Child data...\n*/\n\nexport function parseData(model: Model): DataComponent {\n let head = parseRoot(model, model.component.data.sources);\n\n const {outputNodes, outputNodeRefCounts} = model.component.data;\n const ancestorParse = model.parent ? model.parent.component.data.ancestorParse.clone() : new AncestorParse();\n\n // format.parse: null means disable parsing\n if (model.data && model.data.format && model.data.format.parse === null) {\n ancestorParse.parseNothing = true;\n }\n\n head = ParseNode.makeExplicit(head, model, ancestorParse) || head;\n\n // Default discrete selections require an identifier transform to\n // uniquely identify data points as the _id field is volatile. Add\n // this transform at the head of our pipeline such that the identifier\n // field is available for all subsequent datasets. Additional identifier\n // transforms will be necessary when new tuples are constructed\n // (e.g., post-aggregation).\n if (requiresSelectionId(model) && (isUnitModel(model) || isLayerModel(model))) {\n head = new IdentifierNode(head);\n }\n\n // HACK: This is equivalent for merging bin extent for union scale.\n // FIXME(https://github.com/vega/vega-lite/issues/2270): Correctly merge extent / bin node for shared bin scale\n const parentIsLayer = model.parent && isLayerModel(model.parent);\n if (isUnitModel(model) || isFacetModel(model)) {\n if (parentIsLayer) {\n head = BinNode.makeFromEncoding(head, model) || head;\n }\n }\n\n if (model.transforms.length > 0) {\n head = parseTransformArray(head, model, ancestorParse);\n }\n\n head = ParseNode.makeImplicitFromEncoding(head, model, ancestorParse) || head;\n\n if (isUnitModel(model)) {\n head = GeoJSONNode.parseAll(head, model);\n head = GeoPointNode.parseAll(head, model);\n }\n\n if (isUnitModel(model) || isFacetModel(model)) {\n\n if (!parentIsLayer) {\n head = BinNode.makeFromEncoding(head, model) || head;\n }\n\n head = TimeUnitNode.makeFromEncoding(head, model) || head;\n head = CalculateNode.parseAllForSortIndex(head, model);\n }\n\n // add an output node pre aggregation\n const rawName = model.getName(RAW);\n const raw = new OutputNode(head, rawName, RAW, outputNodeRefCounts);\n outputNodes[rawName] = raw;\n head = raw;\n\n if (isUnitModel(model)) {\n const agg = AggregateNode.makeFromEncoding(head, model);\n if (agg) {\n head = agg;\n\n if (requiresSelectionId(model)) {\n head = new IdentifierNode(head);\n }\n }\n\n head = StackNode.makeFromEncoding(head, model) || head;\n }\n\n if (isUnitModel(model)) {\n head = FilterInvalidNode.make(head, model) || head;\n }\n\n // output node for marks\n const mainName = model.getName(MAIN);\n const main = new OutputNode(head, mainName, MAIN, outputNodeRefCounts);\n outputNodes[mainName] = main;\n head = main;\n\n // add facet marker\n let facetRoot = null;\n if (isFacetModel(model)) {\n const facetName = model.getName('facet');\n\n // Derive new sort index field for facet's sort array\n head = CalculateNode.parseAllForSortIndex(head, model);\n\n // Derive new aggregate (via window) for facet's sort field\n // TODO: use JoinAggregate once we have it\n // augment data source with new fields for crossed facet\n head = WindowTransformNode.makeFromFacet(head, model.facet) || head;\n\n facetRoot = new FacetNode(head, model, facetName, main.getSource());\n outputNodes[facetName] = facetRoot;\n head = facetRoot;\n }\n\n return {\n ...model.component.data,\n outputNodes,\n outputNodeRefCounts,\n raw,\n main,\n facetRoot,\n ancestorParse\n };\n}\n","import {Config} from '../config';\nimport {Resolve} from '../resolve';\nimport {BaseSpec} from '../spec';\nimport {keys} from '../util';\nimport {VgData, VgSignal} from '../vega.schema';\nimport {parseData} from './data/parse';\nimport {assembleLayoutSignals} from './layoutsize/assemble';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\n\nexport abstract class BaseConcatModel extends Model {\n constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, repeater: RepeaterValue, resolve: Resolve) {\n super(spec, parent, parentGivenName, config, repeater, resolve);\n }\n\n public parseData() {\n this.component.data = parseData(this);\n this.children.forEach((child) => {\n child.parseData();\n });\n }\n public parseSelection() {\n // Merge selections up the hierarchy so that they may be referenced\n // across unit specs. Persist their definitions within each child\n // to assemble signals which remain within output Vega unit groups.\n this.component.selection = {};\n for (const child of this.children) {\n child.parseSelection();\n keys(child.component.selection).forEach((key) => {\n this.component.selection[key] = child.component.selection[key];\n });\n }\n }\n\n public parseMarkGroup() {\n for (const child of this.children) {\n child.parseMarkGroup();\n }\n }\n\n public parseAxisAndHeader() {\n for (const child of this.children) {\n child.parseAxisAndHeader();\n }\n\n // TODO(#2415): support shared axes\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return this.children.reduce((sg, child) => child.assembleSelectionTopLevelSignals(sg), signals);\n }\n\n public assembleSelectionSignals(): VgSignal[] {\n this.children.forEach((child) => child.assembleSelectionSignals());\n return [];\n }\n\n public assembleLayoutSignals(): VgSignal[] {\n return this.children.reduce((signals, child) => {\n return signals.concat(child.assembleLayoutSignals());\n }, assembleLayoutSignals(this));\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return this.children.reduce((db, child) => child.assembleSelectionData(db), data);\n }\n\n public assembleMarks(): any[] {\n // only children have marks\n return this.children.map(child => {\n const title = child.assembleTitle();\n const style = child.assembleGroupStyle();\n const layoutSizeEncodeEntry = child.assembleLayoutSize();\n return {\n type: 'group',\n name: child.getName('group'),\n ...(title ? {title} : {}),\n ...(style ? {style} : {}),\n ...(layoutSizeEncodeEntry ? {\n encode: {\n update: layoutSizeEncodeEntry\n }\n } : {}),\n ...child.assembleGroup()\n };\n });\n }\n}\n","import {Config} from '../config';\nimport * as log from '../log';\nimport {isVConcatSpec, NormalizedConcatSpec} from '../spec';\nimport {VgLayout} from '../vega.schema';\nimport {BaseConcatModel} from './baseconcat';\nimport {buildModel} from './buildmodel';\nimport {parseConcatLayoutSize} from './layoutsize/parse';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\n\nexport class ConcatModel extends BaseConcatModel {\n public readonly type: 'concat' = 'concat';\n\n public readonly children: Model[];\n\n public readonly isVConcat: boolean;\n\n constructor(spec: NormalizedConcatSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, repeater, spec.resolve);\n\n if (spec.resolve && spec.resolve.axis && (spec.resolve.axis.x === 'shared' || spec.resolve.axis.y === 'shared')) {\n log.warn(log.message.CONCAT_CANNOT_SHARE_AXIS);\n }\n\n this.isVConcat = isVConcatSpec(spec);\n\n this.children = (isVConcatSpec(spec) ? spec.vconcat : spec.hconcat).map((child, i) => {\n return buildModel(child, this, this.getName('concat_' + i), undefined, repeater, config, false);\n });\n }\n\n public parseLayoutSize() {\n parseConcatLayoutSize(this);\n }\n\n\n public parseAxisGroup(): void {\n return null;\n }\n\n protected assembleDefaultLayout(): VgLayout {\n return {\n ...(this.isVConcat ? {columns: 1} : {}),\n bounds: 'full',\n // Use align each so it can work with multiple plots with different size\n align: 'each'\n };\n }\n}\n","import {Axis, AxisPart} from '../../axis';\nimport {FieldDefBase} from '../../fielddef';\nimport {duplicate, Omit} from '../../util';\nimport {VgAxis} from '../../vega.schema';\nimport {Split} from '../split';\n\n\nfunction isFalseOrNull(v: boolean | null) {\n return v === false || v === null;\n}\n\nexport type AxisComponentProps = Omit & {\n\n title: string | FieldDefBase[];\n};\n\nexport class AxisComponent extends Split {\n constructor(\n public readonly explicit: Partial = {},\n public readonly implicit: Partial = {},\n public mainExtracted = false\n ) {\n super();\n }\n\n public clone() {\n return new AxisComponent(\n duplicate(this.explicit),\n duplicate(this.implicit), this.mainExtracted\n );\n }\n\n public hasAxisPart(part: AxisPart) {\n // FIXME(https://github.com/vega/vega-lite/issues/2552) this method can be wrong if users use a Vega theme.\n\n if (part === 'axis') { // always has the axis container part\n return true;\n }\n\n if (part === 'grid' || part === 'title') {\n return !!this.get(part);\n }\n // Other parts are enabled by default, so they should not be false or null.\n return !isFalseOrNull(this.get(part));\n }\n}\n\nexport interface AxisComponentIndex {\n x?: AxisComponent[];\n y?: AxisComponent[];\n}\n\nexport interface AxisIndex {\n x?: Axis;\n y?: Axis;\n}\n","import {PositionScaleChannel} from '../../channel';\nimport {Config} from '../../config';\nimport {ScaleType} from '../../scale';\n\nexport function getAxisConfig(property: string, config: Config, channel: PositionScaleChannel, orient: string = '', scaleType: ScaleType) {\n // configTypes to loop, starting from higher precedence\n const configTypes = (scaleType === 'band' ? ['axisBand'] : []).concat([\n channel === 'x' ? 'axisX' : 'axisY',\n 'axis' + orient.substr(0,1).toUpperCase() + orient.substr(1), // axisTop, axisBottom, ...\n 'axis'\n ]);\n for (const configType of configTypes) {\n if (config[configType] && config[configType][property] !== undefined) {\n return config[configType][property];\n }\n }\n\n return undefined;\n}\n","import {Axis} from '../../axis';\nimport {Channel, PositionScaleChannel, X} from '../../channel';\nimport {FieldDef, isTimeFieldDef} from '../../fielddef';\nimport {ScaleType} from '../../scale';\nimport {NOMINAL, ORDINAL} from '../../type';\nimport {contains, keys} from '../../util';\nimport {AxisOrient, HorizontalAlign} from '../../vega.schema';\nimport {timeFormatExpression} from '../common';\nimport {UnitModel} from '../unit';\nimport {getAxisConfig} from './config';\n\nexport function labels(model: UnitModel, channel: PositionScaleChannel, specifiedLabelsSpec: any, orient: AxisOrient) {\n const fieldDef = model.fieldDef(channel) ||\n (\n channel === 'x' ? model.fieldDef('x2') :\n channel === 'y' ? model.fieldDef('y2') :\n undefined\n );\n const axis = model.axis(channel);\n const config = model.config;\n\n let labelsSpec: any = {};\n\n // Text\n if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC;\n\n const expr = timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat, isUTCScale);\n\n if (expr) {\n labelsSpec.text = {signal: expr};\n }\n }\n\n // Label Angle\n let angle = getAxisConfig('labelAngle', model.config, channel, orient, model.getScaleComponent(channel).get('type'));\n if (angle === undefined) {\n angle = labelAngle(axis, channel, fieldDef);\n if (angle) {\n labelsSpec.angle = {value: angle};\n }\n }\n\n if (angle !== undefined) {\n const align = labelAlign(angle, orient);\n if (align) {\n labelsSpec.align = {value: align};\n }\n\n labelsSpec.baseline = labelBaseline(angle, orient);\n }\n\n labelsSpec = {\n ...labelsSpec,\n ...specifiedLabelsSpec\n };\n\n return keys(labelsSpec).length === 0 ? undefined : labelsSpec;\n}\n\nexport function labelBaseline(angle: number, orient: AxisOrient) {\n if (orient === 'top' || orient === 'bottom') {\n if (angle <= 45 || 315 <= angle) {\n return {value: orient === 'top' ? 'bottom' : 'top'};\n } else if (135 <= angle && angle <= 225) {\n return {value: orient === 'top' ? 'top': 'bottom'};\n } else {\n return {value: 'middle'};\n }\n } else {\n if ((angle <= 45 || 315 <= angle) || (135 <= angle && angle <= 225)) {\n return {value: 'middle'};\n } else if (45 <= angle && angle <= 135) {\n return {value: orient === 'left' ? 'top' : 'bottom'};\n } else {\n return {value: orient === 'left' ? 'bottom' : 'top'};\n }\n }\n}\n\nexport function labelAngle(axis: Axis, channel: Channel, fieldDef: FieldDef) {\n if (axis.labelAngle !== undefined) {\n // Make angle within [0,360)\n return ((axis.labelAngle % 360) + 360) % 360;\n } else {\n if (channel === X && contains([NOMINAL, ORDINAL], fieldDef.type)) {\n return 270;\n }\n }\n return undefined;\n}\n\nexport function labelAlign(angle: number, orient: AxisOrient): HorizontalAlign {\n angle = ((angle % 360) + 360) % 360;\n if (orient === 'top' || orient === 'bottom') {\n if (angle % 180 === 0) {\n return 'center';\n } else if (0 < angle && angle < 180) {\n return orient === 'top' ? 'right' : 'left';\n } else {\n return orient === 'top' ? 'left' : 'right';\n }\n } else {\n if ((angle + 90) % 180 === 0) {\n return 'center';\n } else if (90 <= angle && angle < 270) {\n return orient === 'left' ? 'left' : 'right';\n } else {\n return orient === 'left' ? 'right' : 'left';\n }\n }\n}\n\n","import {truncate} from 'vega-util';\nimport {Axis} from '../../axis';\nimport {binToString} from '../../bin';\nimport {PositionScaleChannel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {FieldDef, title as fieldDefTitle, valueArray} from '../../fielddef';\nimport * as log from '../../log';\nimport {hasDiscreteDomain, isSelectionDomain, ScaleType} from '../../scale';\nimport {QUANTITATIVE} from '../../type';\nimport {contains} from '../../util';\nimport {VgSignalRef} from '../../vega.schema';\nimport {UnitModel} from '../unit';\n\n\n// TODO: we need to refactor this method after we take care of config refactoring\n/**\n * Default rules for whether to show a grid should be shown for a channel.\n * If `grid` is unspecified, the default value is `true` for ordinal scales that are not binned\n */\nexport function grid(scaleType: ScaleType, fieldDef: FieldDef) {\n return !hasDiscreteDomain(scaleType) && !fieldDef.bin;\n}\n\nexport function gridScale(model: UnitModel, channel: PositionScaleChannel) {\n const gridChannel: PositionScaleChannel = channel === 'x' ? 'y' : 'x';\n if (model.getScaleComponent(gridChannel)) {\n return model.scaleName(gridChannel);\n }\n return undefined;\n}\n\nexport function labelFlush(fieldDef: FieldDef, channel: PositionScaleChannel, specifiedAxis: Axis) {\n if (specifiedAxis.labelFlush !== undefined) {\n return specifiedAxis.labelFlush;\n }\n if (channel === 'x' && contains(['quantitative', 'temporal'], fieldDef.type)) {\n return true;\n }\n return undefined;\n}\n\nexport function labelOverlap(fieldDef: FieldDef, specifiedAxis: Axis, channel: PositionScaleChannel, scaleType: ScaleType) {\n if (specifiedAxis.labelOverlap !== undefined) {\n return specifiedAxis.labelOverlap;\n }\n\n // do not prevent overlap for nominal data because there is no way to infer what the missing labels are\n if (fieldDef.type !== 'nominal') {\n if (scaleType === 'log') {\n return 'greedy';\n }\n return true;\n }\n\n return undefined;\n}\n\nexport function orient(channel: PositionScaleChannel) {\n switch (channel) {\n case X:\n return 'bottom';\n case Y:\n return 'left';\n }\n /* istanbul ignore next: This should never happen. */\n throw new Error(log.message.INVALID_CHANNEL_FOR_AXIS);\n}\n\nexport function tickCount(channel: PositionScaleChannel, fieldDef: FieldDef, scaleType: ScaleType, size: VgSignalRef) {\n if (!hasDiscreteDomain(scaleType) && scaleType !== 'log' && !contains(['month', 'hours', 'day', 'quarter'], fieldDef.timeUnit)) {\n\n if (fieldDef.bin) {\n // for binned data, we don't want more ticks than maxbins\n return {signal: `ceil(${size.signal}/20)`};\n }\n return {signal: `ceil(${size.signal}/40)`};\n }\n\n return undefined;\n}\n\nexport function title(maxLength: number, fieldDef: FieldDef, config: Config) {\n // if not defined, automatically determine axis title from field def\n const fieldTitle = fieldDefTitle(fieldDef, config);\n return maxLength ? truncate(fieldTitle, maxLength) : fieldTitle;\n}\n\nexport function values(specifiedAxis: Axis, model: UnitModel, fieldDef: FieldDef, channel: PositionScaleChannel) {\n const vals = specifiedAxis.values;\n\n if (vals) {\n return valueArray(fieldDef, vals);\n }\n\n if (fieldDef.bin && fieldDef.type === QUANTITATIVE) {\n const domain = model.scaleDomain(channel);\n if (domain && domain !== 'unaggregated' && !isSelectionDomain(domain)) { // explicit value\n return undefined;\n }\n\n const signal = model.getName(`${binToString(fieldDef.bin)}_${fieldDef.field}_bins`);\n return {signal: `sequence(${signal}.start, ${signal}.stop + ${signal}.step, ${signal}.step)`};\n }\n\n return undefined;\n}\n","import {Axis, AXIS_PARTS, AxisEncoding, isAxisProperty, VG_AXIS_PROPERTIES} from '../../axis';\nimport {POSITION_SCALE_CHANNELS, PositionScaleChannel, X, Y} from '../../channel';\nimport {FieldDefBase, toFieldDefBase} from '../../fielddef';\nimport {keys} from '../../util';\nimport {AxisOrient, VgAxis, VgAxisEncode} from '../../vega.schema';\nimport {getSpecifiedOrDefaultValue, guideEncodeEntry, mergeTitle, mergeTitleComponent, mergeTitleFieldDefs, numberFormat} from '../common';\nimport {LayerModel} from '../layer';\nimport {parseGuideResolve} from '../resolve';\nimport {defaultTieBreaker, Explicit, mergeValuesWithExplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {AxisComponent, AxisComponentIndex, AxisComponentProps} from './component';\nimport {getAxisConfig} from './config';\nimport * as encode from './encode';\nimport * as properties from './properties';\n\n\nexport function parseUnitAxis(model: UnitModel): AxisComponentIndex {\n return POSITION_SCALE_CHANNELS.reduce(function(axis, channel) {\n if (model.component.scales[channel] && model.axis(channel)) {\n axis[channel] = [parseAxis(channel, model)];\n }\n return axis;\n }, {} as AxisComponentIndex);\n}\n\nconst OPPOSITE_ORIENT: {[K in AxisOrient]: AxisOrient} = {\n bottom: 'top',\n top: 'bottom',\n left: 'right',\n right: 'left'\n};\n\nexport function parseLayerAxis(model: LayerModel) {\n const {axes, resolve} = model.component;\n const axisCount: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in AxisOrient]: number\n } = {top: 0, bottom: 0, right: 0, left: 0};\n\n for (const child of model.children) {\n child.parseAxisAndHeader();\n\n for (const channel of keys(child.component.axes)) {\n resolve.axis[channel] = parseGuideResolve(model.component.resolve, channel);\n if (resolve.axis[channel] === 'shared') {\n // If the resolve says shared (and has not been overridden)\n // We will try to merge and see if there is a conflict\n\n axes[channel] = mergeAxisComponents(axes[channel], child.component.axes[channel]);\n\n if (!axes[channel]) {\n // If merge returns nothing, there is a conflict so we cannot make the axis shared.\n // Thus, mark axis as independent and remove the axis component.\n resolve.axis[channel] = 'independent';\n delete axes[channel];\n }\n }\n }\n }\n\n // Move axes to layer's axis component and merge shared axes\n for (const channel of [X, Y]) {\n for (const child of model.children) {\n if (!child.component.axes[channel]) {\n // skip if the child does not have a particular axis\n continue;\n }\n\n if (resolve.axis[channel] === 'independent') {\n // If axes are independent, concat the axisComponent array.\n axes[channel] = (axes[channel] || []).concat(child.component.axes[channel]);\n\n // Automatically adjust orient\n for (const axisComponent of child.component.axes[channel]) {\n const {value: orient, explicit} = axisComponent.getWithExplicit('orient');\n if (axisCount[orient] > 0 && !explicit) {\n // Change axis orient if the number do not match\n const oppositeOrient = OPPOSITE_ORIENT[orient];\n if (axisCount[orient] > axisCount[oppositeOrient]) {\n axisComponent.set('orient', oppositeOrient, false);\n }\n }\n axisCount[orient]++;\n\n // TODO(https://github.com/vega/vega-lite/issues/2634): automaticaly add extra offset?\n }\n }\n\n // After merging, make sure to remove axes from child\n delete child.component.axes[channel];\n }\n }\n}\n\nfunction mergeAxisComponents(mergedAxisCmpts: AxisComponent[], childAxisCmpts: AxisComponent[]): AxisComponent[] {\n if (mergedAxisCmpts) {\n // FIXME: this is a bit wrong once we support multiple axes\n if (mergedAxisCmpts.length !== childAxisCmpts.length) {\n return undefined; // Cannot merge axis component with different number of axes.\n }\n const length = mergedAxisCmpts.length;\n for (let i = 0; i < length ; i++) {\n const merged = mergedAxisCmpts[i];\n const child = childAxisCmpts[i];\n\n if ((!!merged) !== (!!child)) {\n return undefined;\n } else if (merged && child) {\n const mergedOrient = merged.getWithExplicit('orient');\n const childOrient = child.getWithExplicit('orient');\n\n if (mergedOrient.explicit && childOrient.explicit && mergedOrient.value !== childOrient.value) {\n // TODO: throw warning if resolve is explicit (We don't have info about explicit/implicit resolve yet.)\n\n // Cannot merge due to inconsistent orient\n return undefined;\n } else {\n mergedAxisCmpts[i] = mergeAxisComponent(merged, child);\n }\n }\n }\n } else {\n // For first one, return a copy of the child\n return childAxisCmpts.map(axisComponent => axisComponent.clone());\n }\n return mergedAxisCmpts;\n}\n\nfunction mergeAxisComponent(merged: AxisComponent, child: AxisComponent): AxisComponent {\n for (const prop of VG_AXIS_PROPERTIES) {\n const mergedValueWithExplicit = mergeValuesWithExplicit(\n merged.getWithExplicit(prop),\n child.getWithExplicit(prop),\n prop, 'axis',\n\n // Tie breaker function\n (v1: Explicit, v2: Explicit) => {\n switch (prop) {\n case 'title':\n return mergeTitleComponent(v1, v2);\n case 'gridScale':\n return {\n explicit: v1.explicit, // keep the old explicit\n value: v1.value || v2.value\n };\n }\n return defaultTieBreaker(v1, v2, prop, 'axis');\n }\n );\n merged.setWithExplicit(prop, mergedValueWithExplicit);\n }\n return merged;\n}\n\nfunction getFieldDefTitle(model: UnitModel, channel: 'x' | 'y') {\n const channel2 = channel === 'x' ? 'x2' : 'y2';\n const fieldDef = model.fieldDef(channel);\n const fieldDef2 = model.fieldDef(channel2);\n\n const title1 = fieldDef ? fieldDef.title : undefined;\n const title2 = fieldDef2 ? fieldDef2.title : undefined;\n\n if (title1 && title2) {\n return mergeTitle(title1, title2);\n } else if (title1) {\n return title1;\n } else if (title2) {\n return title2;\n } else if (title1 !== undefined) { // falsy value to disable config\n return title1;\n } else if (title2 !== undefined) { // falsy value to disable config\n return title2;\n }\n\n return undefined;\n}\n\nfunction parseAxis(channel: PositionScaleChannel, model: UnitModel): AxisComponent {\n const axis = model.axis(channel);\n\n const axisComponent = new AxisComponent();\n\n // 1.2. Add properties\n VG_AXIS_PROPERTIES.forEach(function(property) {\n const value = getProperty(property, axis, channel, model);\n if (value !== undefined) {\n const explicit =\n // specified axis.values is already respected, but may get transformed.\n property === 'values' ? !!axis.values :\n // both VL axis.encoding and axis.labelAngle affect VG axis.encode\n property === 'encode' ? !!axis.encoding || !!axis.labelAngle :\n // title can be explicit if fieldDef.title is set\n property === 'title' && value === getFieldDefTitle(model, channel) ? true :\n // Otherwise, things are explicit if the returned value matches the specified property\n value === axis[property];\n\n const configValue = getAxisConfig(property, model.config, channel, axisComponent.get('orient'), model.getScaleComponent(channel).get('type'));\n\n // only set property if it is explicitly set or has no config value (otherwise we will accidentally override config)\n if (explicit || configValue === undefined) {\n // Do not apply implicit rule if there is a config value\n axisComponent.set(property, value, explicit);\n } else if (property === 'grid' && configValue) {\n // Grid is an exception because we need to set grid = true to generate another grid axis\n axisComponent.set(property, configValue, false);\n }\n }\n });\n\n // 2) Add guide encode definition groups\n const axisEncoding = axis.encoding || {};\n const axisEncode = AXIS_PARTS.reduce((e: VgAxisEncode, part) => {\n if (!axisComponent.hasAxisPart(part)) {\n // No need to create encode for a disabled part.\n return e;\n }\n\n const axisEncodingPart = guideEncodeEntry(axisEncoding[part] || {}, model);\n\n const value = part === 'labels' ?\n encode.labels(model, channel, axisEncodingPart, axisComponent.get('orient')) :\n axisEncodingPart;\n\n if (value !== undefined && keys(value).length > 0) {\n e[part] = {update: value};\n }\n return e;\n }, {} as VgAxisEncode);\n\n // FIXME: By having encode as one property, we won't have fine grained encode merging.\n if (keys(axisEncode).length > 0) {\n axisComponent.set('encode', axisEncode, !!axis.encoding || axis.labelAngle !== undefined);\n }\n\n return axisComponent;\n}\n\nfunction getProperty(property: K, specifiedAxis: Axis, channel: PositionScaleChannel, model: UnitModel): AxisComponentProps[K] {\n const fieldDef = model.fieldDef(channel);\n switch (property) {\n case 'scale':\n return model.scaleName(channel);\n case 'gridScale':\n return properties.gridScale(model, channel);\n case 'format':\n // We don't include temporal field here as we apply format in encode block\n return numberFormat(fieldDef, specifiedAxis.format, model.config);\n case 'grid': {\n const scaleType = model.getScaleComponent(channel).get('type');\n return getSpecifiedOrDefaultValue(specifiedAxis.grid, properties.grid(scaleType, fieldDef));\n }\n case 'labelFlush':\n return properties.labelFlush(fieldDef, channel, specifiedAxis);\n case 'labelOverlap': {\n const scaleType = model.getScaleComponent(channel).get('type');\n return properties.labelOverlap(fieldDef, specifiedAxis, channel, scaleType);\n }\n case 'orient':\n return getSpecifiedOrDefaultValue(specifiedAxis.orient, properties.orient(channel));\n case 'tickCount': {\n const scaleType = model.getScaleComponent(channel).get('type');\n const sizeType = channel === 'x' ? 'width' : channel === 'y' ? 'height' : undefined;\n const size = sizeType ? model.getSizeSignalRef(sizeType)\n : undefined;\n return getSpecifiedOrDefaultValue(specifiedAxis.tickCount, properties.tickCount(channel, fieldDef, scaleType, size));\n }\n case 'title':\n const channel2 = channel === 'x' ? 'x2' : 'y2';\n const fieldDef2 = model.fieldDef(channel2);\n // Keep undefined so we use default if title is unspecified.\n // For other falsy value, keep them so we will hide the title.\n const fieldDefTitle = getFieldDefTitle(model, channel);\n const specifiedTitle = fieldDefTitle !== undefined ? fieldDefTitle :\n specifiedAxis.title === undefined ? undefined : specifiedAxis.title;\n\n return getSpecifiedOrDefaultValue[]>(\n specifiedTitle,\n // If title not specified, store base parts of fieldDef (and fieldDef2 if exists)\n mergeTitleFieldDefs(\n [toFieldDefBase(fieldDef)],\n fieldDef2 ? [toFieldDefBase(fieldDef2)] : []\n )\n );\n case 'values':\n return properties.values(specifiedAxis, model, fieldDef, channel);\n }\n // Otherwise, return specified property.\n return isAxisProperty(property) ? specifiedAxis[property] : undefined;\n}\n","\nimport {Config} from '../../config';\nimport {Encoding, isAggregate} from '../../encoding';\nimport {FieldDef, isContinuous, isFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {AREA, BAR, CIRCLE, isMarkDef, LINE, Mark, MarkDef, POINT, RECT, RULE, SQUARE, TEXT, TICK} from '../../mark';\nimport {QUANTITATIVE, TEMPORAL} from '../../type';\nimport {contains} from '../../util';\nimport {getMarkConfig} from '../common';\nimport {Orient} from './../../vega.schema';\n\n\nexport function normalizeMarkDef(mark: Mark | MarkDef, encoding: Encoding, config: Config) {\n const markDef: MarkDef = isMarkDef(mark) ? {...mark} : {type: mark};\n\n // set orient, which can be overridden by rules as sometimes the specified orient is invalid.\n const specifiedOrient = markDef.orient || getMarkConfig('orient', markDef, config);\n markDef.orient = orient(markDef.type, encoding, specifiedOrient);\n if (specifiedOrient !== undefined && specifiedOrient !== markDef.orient) {\n log.warn(log.message.orientOverridden(markDef.orient,specifiedOrient));\n }\n\n // set opacity and filled if not specified in mark config\n const specifiedOpacity = markDef.opacity !== undefined ? markDef.opacity : getMarkConfig('opacity', markDef, config);\n if (specifiedOpacity === undefined) {\n markDef.opacity = opacity(markDef.type, encoding);\n }\n\n const specifiedFilled = markDef.filled;\n if (specifiedFilled === undefined) {\n markDef.filled = filled(markDef, config);\n }\n\n // set cursor, which should be pointer if href channel is present unless otherwise specified\n const specifiedCursor = markDef.cursor || getMarkConfig('cursor', markDef, config);\n if (specifiedCursor === undefined) {\n markDef.cursor = cursor(markDef, encoding, config);\n }\n\n return markDef;\n}\n\nfunction cursor(markDef: MarkDef, encoding: Encoding, config: Config) {\n if (encoding.href || markDef.href || getMarkConfig('href', markDef, config)) {\n return 'pointer';\n }\n return markDef.cursor;\n}\n\nfunction opacity(mark: Mark, encoding: Encoding) {\n if (contains([POINT, TICK, CIRCLE, SQUARE], mark)) {\n // point-based marks\n if (!isAggregate(encoding)) {\n return 0.7;\n }\n }\n return undefined;\n}\n\nfunction filled(markDef: MarkDef, config: Config) {\n const filledConfig = getMarkConfig('filled', markDef, config);\n const mark = markDef.type;\n return filledConfig !== undefined ? filledConfig : mark !== POINT && mark !== LINE && mark !== RULE;\n}\n\nfunction orient(mark: Mark, encoding: Encoding, specifiedOrient: Orient): Orient {\n switch (mark) {\n case POINT:\n case CIRCLE:\n case SQUARE:\n case TEXT:\n case RECT:\n // orient is meaningless for these marks.\n return undefined;\n }\n\n const yIsRange = encoding.y2;\n const xIsRange = encoding.x2;\n\n switch (mark) {\n case BAR:\n if (yIsRange || xIsRange) {\n // Ranged bar does not always have clear orientation, so we allow overriding\n if (specifiedOrient) {\n return specifiedOrient;\n }\n\n // If y is range and x is non-range, non-bin Q, y is likely a prebinned field\n const xDef = encoding.x;\n if (!xIsRange && isFieldDef(xDef) && xDef.type === QUANTITATIVE && !xDef.bin) {\n return 'horizontal';\n }\n\n // If x is range and y is non-range, non-bin Q, x is likely a prebinned field\n const yDef = encoding.y;\n if (!yIsRange && isFieldDef(yDef) && yDef.type === QUANTITATIVE && !yDef.bin) {\n return 'vertical';\n }\n }\n /* tslint:disable */\n case RULE: // intentionally fall through\n // return undefined for line segment rule and bar with both axis ranged\n if (xIsRange && yIsRange) {\n return undefined;\n }\n\n case AREA: // intentionally fall through\n // If there are range for both x and y, y (vertical) has higher precedence.\n if (yIsRange) {\n return 'vertical';\n } else if (xIsRange) {\n return 'horizontal';\n } else if (mark === RULE) {\n if (encoding.x && !encoding.y) {\n return 'vertical';\n } else if (encoding.y && !encoding.x) {\n return 'horizontal';\n }\n }\n\n\n case LINE: // intentional fall through\n case TICK: // Tick is opposite to bar, line, area and never have ranged mark.\n\n /* tslint:enable */\n const xIsContinuous = isFieldDef(encoding.x) && isContinuous(encoding.x);\n const yIsContinuous = isFieldDef(encoding.y) && isContinuous(encoding.y);\n if (xIsContinuous && !yIsContinuous) {\n return mark !== 'tick' ? 'horizontal' : 'vertical';\n } else if (!xIsContinuous && yIsContinuous) {\n return mark !== 'tick' ? 'vertical' : 'horizontal';\n } else if (xIsContinuous && yIsContinuous) {\n const xDef = encoding.x as FieldDef; // we can cast here since they are surely fieldDef\n const yDef = encoding.y as FieldDef;\n\n const xIsTemporal = xDef.type === TEMPORAL;\n const yIsTemporal = yDef.type === TEMPORAL;\n\n // temporal without timeUnit is considered continuous, but better serves as dimension\n if (xIsTemporal && !yIsTemporal) {\n return mark !== 'tick' ? 'vertical' : 'horizontal';\n } else if (!xIsTemporal && yIsTemporal) {\n return mark !== 'tick' ? 'horizontal' : 'vertical';\n }\n\n if (!xDef.aggregate && yDef.aggregate) {\n return mark !== 'tick' ? 'vertical' : 'horizontal';\n } else if (xDef.aggregate && !yDef.aggregate) {\n return mark !== 'tick' ? 'horizontal' : 'vertical';\n }\n\n if (specifiedOrient) {\n // When ambiguous, use user specified one.\n return specifiedOrient;\n }\n\n return 'vertical';\n } else {\n // Discrete x Discrete case\n if (specifiedOrient) {\n // When ambiguous, use user specified one.\n return specifiedOrient;\n }\n\n return undefined;\n }\n }\n return 'vertical';\n}\n\n","import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\n\n\nexport const area: MarkCompiler = {\n vgMark: 'area',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'include'}),\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin', model.markDef.orient === 'horizontal' ? 'x2' : 'y2'),\n ...mixins.defined(model)\n };\n }\n};\n","import {isNumber} from 'vega-util';\nimport {X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {isFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {MarkDef} from '../../mark';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {isVgRangeStep, VgEncodeEntry} from '../../vega.schema';\nimport {VgValueRef} from '../../vega.schema';\nimport {ScaleComponent} from '../scale/component';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nexport const bar: MarkCompiler = {\n vgMark: 'rect',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...x(model),\n ...y(model),\n };\n }\n};\n\nfunction x(model: UnitModel): VgEncodeEntry {\n const {config, encoding, markDef, width} = model;\n const orient = markDef.orient;\n const sizeDef = encoding.size;\n\n const xDef = encoding.x;\n const x2Def = encoding.x2;\n const xScaleName = model.scaleName(X);\n const xScale = model.getScaleComponent(X);\n // x, x2, and width -- we must specify two of these in all conditions\n if (orient === 'horizontal' || x2Def) {\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'x2'),\n };\n } else { // vertical\n if (isFieldDef(xDef)) {\n const xScaleType = xScale.get('type');\n if (xDef.bin && !sizeDef && !hasDiscreteDomain(xScaleType)) {\n return mixins.binnedPosition(\n xDef, 'x', model.scaleName('x'), markDef.binSpacing === undefined ? config.bar.binSpacing : markDef.binSpacing,\n xScale.get('reverse')\n );\n } else {\n if (xScaleType === ScaleType.BAND) {\n return mixins.bandPosition(xDef, 'x', model);\n }\n }\n }\n // sized bin, normal point-ordinal axis, quantitative x-axis, or no x\n\n return mixins.centeredBandPosition('x', model,\n {...ref.mid(width)},\n defaultSizeRef(markDef, xScaleName, xScale, config)\n );\n }\n}\n\nfunction y(model: UnitModel) {\n const {config, encoding, height, markDef} = model;\n const orient = markDef.orient;\n const sizeDef = encoding.size;\n\n const yDef = encoding.y;\n const y2Def = encoding.y2;\n const yScaleName = model.scaleName(Y);\n const yScale = model.getScaleComponent(Y);\n\n // y, y2 & height -- we must specify two of these in all conditions\n if (orient === 'vertical' || y2Def) {\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'y2'),\n };\n } else {\n if (isFieldDef(yDef)) {\n const yScaleType = yScale.get('type');\n if (yDef.bin && !sizeDef && !hasDiscreteDomain(yScaleType)) {\n return mixins.binnedPosition(\n yDef, 'y', model.scaleName('y'),\n markDef.binSpacing === undefined ? config.bar.binSpacing : markDef.binSpacing,\n yScale.get('reverse')\n );\n } else if (yScaleType === ScaleType.BAND) {\n return mixins.bandPosition(yDef, 'y', model);\n }\n }\n return mixins.centeredBandPosition('y', model, ref.mid(height),\n defaultSizeRef(markDef, yScaleName, yScale, config)\n );\n }\n}\n\nfunction defaultSizeRef(markDef: MarkDef, scaleName: string, scale: ScaleComponent, config: Config): VgValueRef {\n if (markDef.size !== undefined) {\n return {value: markDef.size};\n } else if (config.bar.discreteBandSize) {\n return {value: config.bar.discreteBandSize};\n } else if (scale) {\n const scaleType = scale.get('type');\n if (scaleType === ScaleType.POINT) {\n const scaleRange = scale.get('range');\n if (isVgRangeStep(scaleRange) && isNumber(scaleRange.step)) {\n return {value: scaleRange.step - 1};\n }\n log.warn(log.message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL);\n } else if (scaleType === ScaleType.BAND) {\n return ref.bandRef(scaleName);\n } else { // non-ordinal scale\n return {value: config.bar.continuousBandSize};\n }\n } else if (config.scale.rangeStep && config.scale.rangeStep !== null) {\n return {value: config.scale.rangeStep - 1};\n }\n return {value: 20};\n}\n\n","import {UnitModel} from '../unit';\nimport * as mixins from './mixins';\n\nimport {isFieldDef, vgField} from '../../fielddef';\nimport {GEOJSON} from '../../type';\nimport {VgGeoShapeTransform, VgPostEncodingTransform} from '../../vega.schema';\nimport {MarkCompiler} from './base';\n\nexport const geoshape: MarkCompiler = {\n vgMark: 'shape',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'})\n };\n },\n postEncodingTransform: (model: UnitModel): VgPostEncodingTransform[] => {\n const {encoding} = model;\n const shapeDef = encoding.shape;\n\n const transform: VgGeoShapeTransform = {\n type: 'geoshape',\n projection: model.projectionName(),\n // as: 'shape',\n ...(shapeDef && isFieldDef(shapeDef) && shapeDef.type === GEOJSON ? {field: vgField(shapeDef, {expr: 'datum'})} : {})\n };\n return [transform];\n }\n};\n","import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\nexport const line: MarkCompiler = {\n vgMark: 'line',\n encodeEntry: (model: UnitModel) => {\n const {width, height} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth' // VL's line size is strokeWidth\n }),\n ...mixins.defined(model)\n };\n }\n};\n\n\nexport const trail: MarkCompiler = {\n vgMark: 'trail',\n encodeEntry: (model: UnitModel) => {\n const {width, height} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'include', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.nonPosition('size', model),\n ...mixins.defined(model)\n };\n }\n};\n","import {Config} from '../../config';\nimport {VgEncodeEntry} from '../../vega.schema';\nimport {getMarkConfig} from '../common';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nfunction encodeEntry(model: UnitModel, fixedShape?: 'circle' | 'square') {\n const {config, width, height} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'include', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.nonPosition('size', model),\n ...shapeMixins(model, config, fixedShape),\n };\n}\n\nexport function shapeMixins(model: UnitModel, config: Config, fixedShape?: 'circle' | 'square'): VgEncodeEntry {\n if (fixedShape) {\n return {shape: {value: fixedShape}};\n }\n return mixins.nonPosition('shape', model, {defaultValue: getMarkConfig('shape', model.markDef, config) as string});\n}\n\nexport const point: MarkCompiler = {\n vgMark: 'symbol',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model);\n }\n};\n\nexport const circle: MarkCompiler = {\n vgMark: 'symbol',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model, 'circle');\n }\n};\n\nexport const square: MarkCompiler = {\n vgMark: 'symbol',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model, 'square');\n }\n};\n","import {X, Y} from '../../channel';\nimport {isFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {RECT} from '../../mark';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {VgEncodeEntry} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\n\nexport const rect: MarkCompiler = {\n vgMark: 'rect',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...x(model),\n ...y(model),\n };\n }\n};\n\nexport function x(model: UnitModel): VgEncodeEntry {\n const xDef = model.encoding.x;\n const x2Def = model.encoding.x2;\n const xScale = model.getScaleComponent(X);\n const xScaleType = xScale ? xScale.get('type') : undefined;\n\n if (isFieldDef(xDef) && xDef.bin && !x2Def) {\n return mixins.binnedPosition(xDef, 'x', model.scaleName('x'), 0, xScale.get('reverse'));\n } else if (isFieldDef(xDef) && xScale && hasDiscreteDomain(xScaleType)) {\n /* istanbul ignore else */\n if (xScaleType === ScaleType.BAND) {\n return mixins.bandPosition(xDef, 'x', model);\n } else {\n // We don't support rect mark with point/ordinal scale\n throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, xScaleType));\n }\n } else { // continuous scale or no scale\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMax'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'x2')\n };\n }\n}\n\nexport function y(model: UnitModel): VgEncodeEntry {\n const yDef = model.encoding.y;\n const y2Def = model.encoding.y2;\n const yScale = model.getScaleComponent(Y);\n const yScaleType = yScale ? yScale.get('type') : undefined;\n\n if (isFieldDef(yDef) && yDef.bin && !y2Def) {\n return mixins.binnedPosition(yDef, 'y', model.scaleName('y'), 0, yScale.get('reverse'));\n } else if (isFieldDef(yDef) && yScale && hasDiscreteDomain(yScaleType)) {\n /* istanbul ignore else */\n if (yScaleType === ScaleType.BAND) {\n return mixins.bandPosition(yDef, 'y', model);\n } else {\n // We don't support rect mark with point/ordinal scale\n throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, yScaleType));\n }\n } else { // continuous scale or no scale\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMax'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'y2')\n };\n }\n}\n","import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\nexport const rule: MarkCompiler = {\n vgMark: 'rule',\n encodeEntry: (model: UnitModel) => {\n const {config: _config, markDef, width, height} = model;\n const orient = markDef.orient;\n\n if (!model.encoding.x && !model.encoding.y && !model.encoding.latitude && !model.encoding.longitude) {\n // Show nothing if we have none of x, y, lat, and long.\n return {};\n }\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, orient === 'horizontal' ? 'zeroOrMin' : ref.mid(width)),\n ...mixins.pointPosition('y', model, orient === 'vertical' ? 'zeroOrMin' : ref.mid(height)),\n\n // include x2 for horizontal or line segment rule\n ...(orient !== 'vertical' ? mixins.pointPosition2(model, 'zeroOrMax', 'x2') : {}),\n\n // include y2 for vertical or line segment rule\n ...(orient !== 'horizontal' ? mixins.pointPosition2(model, 'zeroOrMax', 'y2') : {}),\n\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth', // VL's rule size is strokeWidth\n defaultValue: markDef.size\n })\n };\n }\n};\n","import {Config} from '../../config';\nimport {Encoding} from '../../encoding';\nimport {MarkDef} from '../../mark';\nimport {getMarkConfig} from '../common';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nexport const text: MarkCompiler = {\n vgMark: 'text',\n\n encodeEntry: (model: UnitModel) => {\n const {config, encoding, width, height, markDef} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.text(model),\n ...mixins.nonPosition('size', model, {\n ...(markDef.size ? {defaultValue: markDef.size} : {}),\n vgChannel: 'fontSize' // VL's text size is fontSize\n }),\n ...mixins.valueIfDefined('align', align(model.markDef, encoding, config))\n };\n }\n};\nfunction align(markDef: MarkDef, encoding: Encoding, config: Config) {\n const a = markDef.align || getMarkConfig('align', markDef, config);\n if (a === undefined) {\n return 'center';\n }\n // If there is a config, Vega-parser will process this already.\n return undefined;\n}\n","import {isVgRangeStep} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nexport const tick: MarkCompiler = {\n vgMark: 'rect',\n\n encodeEntry: (model: UnitModel) => {\n const {config, markDef, width, height} = model;\n const orient = markDef.orient;\n\n const vgSizeChannel = orient === 'horizontal' ? 'width' : 'height';\n const vgThicknessChannel = orient === 'horizontal' ? 'height' : 'width';\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n\n ...mixins.pointPosition('x', model, ref.mid(width), 'xc'),\n ...mixins.pointPosition('y', model, ref.mid(height), 'yc'),\n\n // size / thickness => width / height\n ...mixins.nonPosition('size', model, {\n defaultValue: defaultSize(model),\n vgChannel: vgSizeChannel\n }),\n [vgThicknessChannel]: {value: markDef.thickness || config.tick.thickness},\n };\n }\n};\n\nfunction defaultSize(model: UnitModel): number {\n const {config, markDef} = model;\n const orient = markDef.orient;\n const scale = model.getScaleComponent(orient === 'horizontal' ? 'x' : 'y');\n\n if (markDef.size !== undefined) {\n return markDef.size;\n } else if (config.tick.bandSize !== undefined) {\n return config.tick.bandSize;\n } else {\n const scaleRange = scale ? scale.get('range') : undefined;\n const rangeStep = scaleRange && isVgRangeStep(scaleRange) ?\n scaleRange.step :\n config.scale.rangeStep;\n if (typeof rangeStep !== 'number') {\n // FIXME consolidate this log\n throw new Error('Function does not handle non-numeric rangeStep');\n }\n return rangeStep / 1.5;\n }\n}\n","import {isArray} from 'vega-util';\nimport {MAIN} from '../../data';\nimport {Encoding, isAggregate} from '../../encoding';\nimport {getFieldDef, isFieldDef, isValueDef, vgField} from '../../fielddef';\nimport {AREA, isPathMark, LINE, Mark, TRAIL} from '../../mark';\nimport {isSortField} from '../../sort';\nimport {contains, keys} from '../../util';\nimport {getStyles, sortParams} from '../common';\nimport {UnitModel} from '../unit';\nimport {area} from './area';\nimport {bar} from './bar';\nimport {MarkCompiler} from './base';\nimport {geoshape} from './geoshape';\nimport {line, trail} from './line';\nimport {circle, point, square} from './point';\nimport {rect} from './rect';\nimport {rule} from './rule';\nimport {text} from './text';\nimport {tick} from './tick';\n\n\nconst markCompiler: {[m in Mark]: MarkCompiler} = {\n area,\n bar,\n circle,\n geoshape,\n line,\n point,\n rect,\n rule,\n square,\n text,\n tick,\n trail\n};\n\nexport function parseMarkGroup(model: UnitModel): any[] {\n if (contains([LINE, AREA, TRAIL], model.mark)) {\n return parsePathMark(model);\n } else {\n return getMarkGroups(model);\n }\n}\n\nconst FACETED_PATH_PREFIX = 'faceted_path_';\n\nfunction parsePathMark(model: UnitModel) {\n const details = pathGroupingFields(model.mark, model.encoding);\n\n const pathMarks = getMarkGroups(model, {\n // If has subfacet for line/area group, need to use faceted data from below.\n fromPrefix: (details.length > 0 ? FACETED_PATH_PREFIX : '')\n });\n\n if (details.length > 0) { // have level of details - need to facet line into subgroups\n // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?)\n\n return [{\n name: model.getName('pathgroup'),\n type: 'group',\n from: {\n facet: {\n name: FACETED_PATH_PREFIX + model.requestDataName(MAIN),\n data: model.requestDataName(MAIN),\n groupby: details,\n }\n },\n encode: {\n update: {\n width: {field: {group: 'width'}},\n height: {field: {group: 'height'}}\n }\n },\n marks: pathMarks\n }];\n } else {\n return pathMarks;\n }\n}\n\nexport function getSort(model: UnitModel) {\n const {encoding, stack, mark, markDef} = model;\n const order = encoding.order;\n if (!isArray(order) && isValueDef(order)) {\n return undefined;\n } else if ((isArray(order) || isFieldDef(order)) && !stack) {\n // Sort by the order field if it is specified and the field is not stacked. (For stacked field, order specify stack order.)\n return sortParams(order, {expr: 'datum'});\n } else if (isPathMark(mark)) {\n // For both line and area, we sort values based on dimension by default\n const dimensionChannelDef = encoding[markDef.orient === 'horizontal' ? 'y' : 'x'];\n if (isFieldDef(dimensionChannelDef)) {\n const s = dimensionChannelDef.sort;\n const sortField = isSortField(s) ?\n vgField({\n // FIXME: this op might not already exist?\n // FIXME: what if dimensionChannel (x or y) contains custom domain?\n aggregate: isAggregate(model.encoding) ? s.op : undefined,\n field: s.field\n }, {expr: 'datum'}) :\n vgField(dimensionChannelDef, {\n // For stack with imputation, we only have bin_mid\n binSuffix: model.stack && model.stack.impute ? 'mid' : undefined,\n expr: 'datum'\n });\n\n return {\n field: sortField,\n order: 'descending'\n };\n }\n return undefined;\n }\n return undefined;\n}\n\nfunction getMarkGroups(model: UnitModel, opt: {\n fromPrefix: string\n} = {fromPrefix: ''}) {\n const mark = model.mark;\n\n const clip = model.markDef.clip !== undefined ?\n !!model.markDef.clip : scaleClip(model);\n const style = getStyles(model.markDef);\n const key = model.encoding.key;\n const sort = getSort(model);\n\n const postEncodingTransform = markCompiler[mark].postEncodingTransform ? markCompiler[mark].postEncodingTransform(model) : null;\n\n return [{\n name: model.getName('marks'),\n type: markCompiler[mark].vgMark,\n ...(clip ? {clip: true} : {}),\n ...(style ? {style} : {}),\n ...(key ? {key: {field: key.field}} : {}),\n ...(sort ? {sort} : {}),\n from: {data: opt.fromPrefix + model.requestDataName(MAIN)},\n encode: {\n update: markCompiler[mark].encodeEntry(model)\n },\n ...(postEncodingTransform ? {\n transform: postEncodingTransform\n } : {})\n }];\n\n}\n\n/**\n * Returns list of path grouping fields\n * that the model's spec contains.\n */\nexport function pathGroupingFields(mark: Mark, encoding: Encoding): string[] {\n return keys(encoding).reduce((details, channel) => {\n switch (channel) {\n // x, y, x2, y2, lat, long, lat1, long2, order, tooltip, href, cursor should not cause lines to group\n case 'x':\n case 'y':\n case 'order':\n case 'tooltip':\n case 'href':\n case 'x2':\n case 'y2':\n\n case 'latitude':\n case 'longitude':\n case 'latitude2':\n case 'longitude2':\n // TODO: case 'cursor':\n\n // text, shape, shouldn't be a part of line/trail/area\n case 'text':\n case 'shape':\n return details;\n\n case 'detail':\n case 'key':\n const channelDef = encoding[channel];\n if (channelDef) {\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((fieldDef) => {\n if (!fieldDef.aggregate) {\n details.push(vgField(fieldDef, {}));\n }\n });\n }\n return details;\n\n case 'size':\n if (mark === 'trail') {\n // For trail, size should not group trail lines.\n return details;\n }\n // For line, it should group lines.\n\n /* tslint:disable */\n // intentional fall through\n\n case 'color':\n case 'fill':\n case 'stroke':\n case 'opacity':\n // TODO strokeDashOffset:\n\n /* tslint:enable */\n const fieldDef = getFieldDef(encoding[channel]);\n if (fieldDef && !fieldDef.aggregate) {\n details.push(vgField(fieldDef, {}));\n }\n return details;\n default:\n throw new Error(`Bug: Channel ${channel} unimplemented for line mark`);\n }\n }, []);\n}\n\n/**\n * If scales are bound to interval selections, we want to automatically clip\n * marks to account for panning/zooming interactions. We identify bound scales\n * by the domainRaw property, which gets added during scale parsing.\n */\nfunction scaleClip(model: UnitModel) {\n const xScale = model.getScaleComponent('x');\n const yScale = model.getScaleComponent('y');\n return (xScale && xScale.get('domainRaw')) ||\n (yScale && yScale.get('domainRaw')) ? true : false;\n}\n","import {Axis} from '../axis';\nimport {Channel, GEOPOSITION_CHANNELS, NONPOSITION_SCALE_CHANNELS, SCALE_CHANNELS, ScaleChannel, SingleDefChannel, X, Y} from '../channel';\nimport {Config} from '../config';\nimport * as vlEncoding from '../encoding';\nimport {Encoding, normalizeEncoding} from '../encoding';\nimport {ChannelDef, FieldDef, getFieldDef, hasConditionalFieldDef, isFieldDef} from '../fielddef';\nimport {Legend} from '../legend';\nimport {GEOSHAPE, isMarkDef, Mark, MarkDef} from '../mark';\nimport {Projection} from '../projection';\nimport {Domain, Scale} from '../scale';\nimport {SelectionDef} from '../selection';\nimport {LayoutSizeMixins, NormalizedUnitSpec} from '../spec';\nimport {stack, StackProperties} from '../stack';\nimport {Dict, duplicate} from '../util';\nimport {VgData, VgEncodeEntry, VgLayout, VgSignal} from '../vega.schema';\nimport {AxisIndex} from './axis/component';\nimport {parseUnitAxis} from './axis/parse';\nimport {parseData} from './data/parse';\nimport {assembleLayoutSignals} from './layoutsize/assemble';\nimport {parseUnitLayoutSize} from './layoutsize/parse';\nimport {LegendIndex} from './legend/component';\nimport {normalizeMarkDef} from './mark/init';\nimport {parseMarkGroup} from './mark/mark';\nimport {isLayerModel, Model, ModelWithField} from './model';\nimport {RepeaterValue, replaceRepeaterInEncoding} from './repeater';\nimport {ScaleIndex} from './scale/component';\nimport {assembleTopLevelSignals, assembleUnitSelectionData, assembleUnitSelectionMarks, assembleUnitSelectionSignals, parseUnitSelection} from './selection/selection';\n\n\n/**\n * Internal model of Vega-Lite specification for the compiler.\n */\nexport class UnitModel extends ModelWithField {\n public readonly type: 'unit' = 'unit';\n public readonly markDef: MarkDef;\n public readonly encoding: Encoding;\n\n public readonly specifiedScales: ScaleIndex = {};\n\n public readonly stack: StackProperties;\n\n protected specifiedAxes: AxisIndex = {};\n\n protected specifiedLegends: LegendIndex = {};\n\n public specifiedProjection: Projection = {};\n\n public readonly selection: Dict = {};\n public children: Model[] = [];\n\n constructor(spec: NormalizedUnitSpec, parent: Model, parentGivenName: string,\n parentGivenSize: LayoutSizeMixins = {}, repeater: RepeaterValue, config: Config, public fit: boolean) {\n\n super(spec, parent, parentGivenName, config, repeater, undefined);\n this.initSize({\n ...parentGivenSize,\n ...(spec.width ? {width: spec.width} : {}),\n ...(spec.height ? {height: spec.height} : {})\n });\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n\n const encoding = this.encoding = normalizeEncoding(replaceRepeaterInEncoding(spec.encoding || {}, repeater), mark);\n\n this.markDef = normalizeMarkDef(spec.mark, encoding, config);\n\n // calculate stack properties\n this.stack = stack(mark, encoding, this.config.stack);\n this.specifiedScales = this.initScales(mark, encoding);\n\n this.specifiedAxes = this.initAxes(encoding);\n this.specifiedLegends = this.initLegend(encoding);\n this.specifiedProjection = spec.projection;\n\n // Selections will be initialized upon parse.\n this.selection = spec.selection;\n }\n\n public get hasProjection(): boolean {\n const {encoding} = this;\n const isGeoShapeMark = this.mark === GEOSHAPE;\n const hasGeoPosition = encoding && GEOPOSITION_CHANNELS.some(\n channel => isFieldDef(encoding[channel])\n );\n return isGeoShapeMark || hasGeoPosition;\n }\n\n /**\n * Return specified Vega-lite scale domain for a particular channel\n * @param channel\n */\n public scaleDomain(channel: ScaleChannel): Domain {\n const scale = this.specifiedScales[channel];\n return scale ? scale.domain : undefined;\n }\n\n public axis(channel: Channel): Axis {\n return this.specifiedAxes[channel];\n }\n\n public legend(channel: Channel): Legend {\n return this.specifiedLegends[channel];\n }\n\n private initScales(mark: Mark, encoding: Encoding): ScaleIndex {\n return SCALE_CHANNELS.reduce((scales, channel) => {\n let fieldDef: FieldDef;\n let specifiedScale: Scale;\n\n const channelDef = encoding[channel];\n\n if (isFieldDef(channelDef)) {\n fieldDef = channelDef;\n specifiedScale = channelDef.scale;\n } else if (hasConditionalFieldDef(channelDef)) {\n fieldDef = channelDef.condition;\n specifiedScale = channelDef.condition['scale'];\n } else if (channel === 'x') {\n fieldDef = getFieldDef(encoding.x2);\n } else if (channel === 'y') {\n fieldDef = getFieldDef(encoding.y2);\n }\n\n if (fieldDef) {\n scales[channel] = specifiedScale || {};\n }\n return scales;\n }, {} as ScaleIndex);\n }\n\n private initAxes(encoding: Encoding): AxisIndex {\n return [X, Y].reduce(function(_axis, channel) {\n // Position Axis\n\n // TODO: handle ConditionFieldDef\n const channelDef = encoding[channel];\n if (isFieldDef(channelDef) ||\n (channel === X && isFieldDef(encoding.x2)) ||\n (channel === Y && isFieldDef(encoding.y2))) {\n\n const axisSpec = isFieldDef(channelDef) ? channelDef.axis : null;\n\n // We no longer support false in the schema, but we keep false here for backward compatibility.\n if (axisSpec !== null && axisSpec !== false) {\n _axis[channel] = {\n ...axisSpec\n };\n }\n }\n return _axis;\n }, {});\n }\n\n private initLegend(encoding: Encoding): LegendIndex {\n return NONPOSITION_SCALE_CHANNELS.reduce(function(_legend, channel) {\n const channelDef = encoding[channel];\n if (channelDef) {\n const legend = isFieldDef(channelDef) ? channelDef.legend :\n (hasConditionalFieldDef(channelDef)) ? channelDef.condition['legend'] : null;\n\n if (legend !== null && legend !== false) {\n _legend[channel] = {...legend};\n }\n }\n\n return _legend;\n }, {});\n }\n\n public parseData() {\n this.component.data = parseData(this);\n }\n\n public parseLayoutSize() {\n parseUnitLayoutSize(this);\n }\n\n public parseSelection() {\n this.component.selection = parseUnitSelection(this, this.selection);\n }\n\n public parseMarkGroup() {\n this.component.mark = parseMarkGroup(this);\n }\n\n public parseAxisAndHeader() {\n this.component.axes = parseUnitAxis(this);\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return assembleTopLevelSignals(this, signals);\n }\n\n public assembleSelectionSignals(): VgSignal[] {\n return assembleUnitSelectionSignals(this, []);\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return assembleUnitSelectionData(this, data);\n }\n\n public assembleLayout(): VgLayout {\n return null;\n }\n\n public assembleLayoutSignals(): VgSignal[] {\n return assembleLayoutSignals(this);\n }\n\n public assembleMarks() {\n let marks = this.component.mark || [];\n\n // If this unit is part of a layer, selections should augment\n // all in concert rather than each unit individually. This\n // ensures correct interleaving of clipping and brushed marks.\n if (!this.parent || !isLayerModel(this.parent)) {\n marks = assembleUnitSelectionMarks(this, marks);\n }\n\n return marks.map(this.correctDataNames);\n }\n\n public assembleLayoutSize(): VgEncodeEntry {\n return {\n width: this.getSizeSignalRef('width'),\n height: this.getSizeSignalRef('height')\n };\n }\n\n protected getMapping() {\n return this.encoding;\n }\n\n public toSpec(excludeConfig?: any, excludeData?: any) {\n const encoding = duplicate(this.encoding);\n let spec: any;\n\n spec = {\n mark: this.markDef,\n encoding: encoding\n };\n\n if (!excludeConfig) {\n spec.config = duplicate(this.config);\n }\n\n if (!excludeData) {\n spec.data = duplicate(this.data);\n }\n\n // remove defaults\n return spec;\n }\n\n public get mark(): Mark {\n return this.markDef.type;\n }\n\n public channelHasField(channel: Channel) {\n return vlEncoding.channelHasField(this.encoding, channel);\n }\n\n public fieldDef(channel: SingleDefChannel): FieldDef {\n const channelDef = this.encoding[channel] as ChannelDef;\n return getFieldDef(channelDef);\n }\n}\n","import {Config} from '../config';\nimport * as log from '../log';\nimport {isLayerSpec, isUnitSpec, LayoutSizeMixins, NormalizedLayerSpec} from '../spec';\nimport {flatten, keys} from '../util';\nimport {VgData, VgLayout, VgLegend, VgSignal, VgTitle} from '../vega.schema';\nimport {parseLayerAxis} from './axis/parse';\nimport {parseData} from './data/parse';\nimport {assembleLayoutSignals} from './layoutsize/assemble';\nimport {parseLayerLayoutSize} from './layoutsize/parse';\nimport {assembleLegends} from './legend/assemble';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\nimport {assembleLayerSelectionMarks} from './selection/selection';\nimport {UnitModel} from './unit';\n\n\nexport class LayerModel extends Model {\n public readonly type: 'layer' = 'layer';\n\n // HACK: This should be (LayerModel | UnitModel)[], but setting the correct type leads to weird error.\n // So I'm just putting generic Model for now.\n public readonly children: Model[];\n\n\n\n constructor(spec: NormalizedLayerSpec, parent: Model, parentGivenName: string,\n parentGivenSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean) {\n\n super(spec, parent, parentGivenName, config, repeater, spec.resolve);\n\n const layoutSize = {\n ...parentGivenSize,\n ...(spec.width ? {width: spec.width} : {}),\n ...(spec.height ? {height: spec.height} : {})\n };\n\n this.initSize(layoutSize);\n\n this.children = spec.layer.map((layer, i) => {\n if (isLayerSpec(layer)) {\n return new LayerModel(layer, this, this.getName('layer_'+i), layoutSize, repeater, config, fit);\n }\n\n if (isUnitSpec(layer)) {\n return new UnitModel(layer, this, this.getName('layer_'+i), layoutSize, repeater, config, fit);\n }\n\n throw new Error(log.message.INVALID_SPEC);\n });\n }\n\n public parseData() {\n this.component.data = parseData(this);\n for (const child of this.children) {\n child.parseData();\n }\n }\n\n public parseLayoutSize() {\n parseLayerLayoutSize(this);\n }\n\n public parseSelection() {\n // Merge selections up the hierarchy so that they may be referenced\n // across unit specs. Persist their definitions within each child\n // to assemble signals which remain within output Vega unit groups.\n this.component.selection = {};\n for (const child of this.children) {\n child.parseSelection();\n keys(child.component.selection).forEach((key) => {\n this.component.selection[key] = child.component.selection[key];\n });\n }\n }\n\n public parseMarkGroup() {\n for (const child of this.children) {\n child.parseMarkGroup();\n }\n }\n\n public parseAxisAndHeader() {\n parseLayerAxis(this);\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return this.children.reduce((sg, child) => child.assembleSelectionTopLevelSignals(sg), signals);\n }\n\n // TODO: Support same named selections across children.\n public assembleSelectionSignals(): VgSignal[] {\n return this.children.reduce((signals, child) => {\n return signals.concat(child.assembleSelectionSignals());\n }, []);\n }\n\n\n public assembleLayoutSignals(): VgSignal[] {\n return this.children.reduce((signals, child) => {\n return signals.concat(child.assembleLayoutSignals());\n }, assembleLayoutSignals(this));\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return this.children.reduce((db, child) => child.assembleSelectionData(db), data);\n }\n\n public assembleTitle(): VgTitle {\n let title = super.assembleTitle();\n if (title) {\n return title;\n }\n // If title does not provide layer, look into children\n for (const child of this.children) {\n title = child.assembleTitle();\n if (title) {\n return title;\n }\n }\n return undefined;\n }\n\n public assembleLayout(): VgLayout {\n return null;\n }\n\n public assembleMarks(): any[] {\n return assembleLayerSelectionMarks(this, flatten(this.children.map((child) => {\n return child.assembleMarks();\n })));\n }\n\n public assembleLegends(): VgLegend[] {\n return this.children.reduce((legends, child) => {\n return legends.concat(child.assembleLegends());\n }, assembleLegends(this));\n }\n}\n","\nimport {Config} from '../config';\nimport * as log from '../log';\nimport {Repeat} from '../repeat';\nimport {NormalizedRepeatSpec} from '../spec';\nimport {VgLayout} from '../vega.schema';\nimport {BaseConcatModel} from './baseconcat';\nimport {buildModel} from './buildmodel';\nimport {parseRepeatLayoutSize} from './layoutsize/parse';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\n\nexport class RepeatModel extends BaseConcatModel {\n public readonly type: 'repeat' = 'repeat';\n public readonly repeat: Repeat;\n\n public readonly children: Model[];\n\n constructor(spec: NormalizedRepeatSpec, parent: Model, parentGivenName: string, repeatValues: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, repeatValues, spec.resolve);\n\n if (spec.resolve && spec.resolve.axis && (spec.resolve.axis.x === 'shared' || spec.resolve.axis.y === 'shared')) {\n log.warn(log.message.REPEAT_CANNOT_SHARE_AXIS);\n }\n\n this.repeat = spec.repeat;\n this.children = this._initChildren(spec, this.repeat, repeatValues, config);\n }\n\n private _initChildren(spec: NormalizedRepeatSpec, repeat: Repeat, repeater: RepeaterValue, config: Config): Model[] {\n const children: Model[] = [];\n const row = repeat.row || [repeater ? repeater.row : null];\n const column = repeat.column || [repeater ? repeater.column : null];\n\n // cross product\n for (const rowField of row) {\n for (const columnField of column) {\n const name = (rowField ? '_' + rowField : '') + (columnField ? '_' + columnField : '');\n\n const childRepeat = {\n row: rowField,\n column: columnField\n };\n\n children.push(buildModel(spec.spec, this, this.getName('child' + name), undefined, childRepeat, config, false));\n }\n }\n\n return children;\n }\n\n public parseLayoutSize() {\n parseRepeatLayoutSize(this);\n }\n\n protected assembleDefaultLayout(): VgLayout {\n return {\n columns: this.repeat && this.repeat.column ? this.repeat.column.length : 1,\n bounds: 'full',\n align: 'all'\n };\n }\n}\n","import {Config} from '../config';\nimport * as log from '../log';\nimport {isConcatSpec, isFacetSpec, isLayerSpec, isRepeatSpec, isUnitSpec, LayoutSizeMixins, NormalizedSpec} from '../spec';\nimport {ConcatModel} from './concat';\nimport {FacetModel} from './facet';\nimport {LayerModel} from './layer';\nimport {Model} from './model';\nimport {RepeatModel} from './repeat';\nimport {RepeaterValue} from './repeater';\nimport {UnitModel} from './unit';\n\nexport function buildModel(spec: NormalizedSpec, parent: Model, parentGivenName: string,\n unitSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean): Model {\n if (isFacetSpec(spec)) {\n return new FacetModel(spec, parent, parentGivenName, repeater, config);\n }\n\n if (isLayerSpec(spec)) {\n return new LayerModel(spec, parent, parentGivenName, unitSize, repeater, config, fit);\n }\n\n if (isUnitSpec(spec)) {\n return new UnitModel(spec, parent, parentGivenName, unitSize, repeater, config, fit);\n }\n\n if (isRepeatSpec(spec)) {\n return new RepeatModel(spec, parent, parentGivenName, repeater, config);\n }\n\n if (isConcatSpec(spec)) {\n return new ConcatModel(spec, parent, parentGivenName, repeater, config);\n }\n\n throw new Error(log.message.INVALID_SPEC);\n}\n","import {Config, initConfig, stripAndRedirectConfig} from '../config';\nimport * as vlFieldDef from '../fielddef';\nimport * as log from '../log';\nimport {isLayerSpec, isUnitSpec, LayoutSizeMixins, normalize, TopLevel, TopLevelSpec} from '../spec';\nimport {AutoSizeParams, extractTopLevelProperties, normalizeAutoSize, TopLevelProperties} from '../toplevelprops';\nimport {keys, mergeDeep} from '../util';\nimport {buildModel} from './buildmodel';\nimport {assembleRootData} from './data/assemble';\nimport {optimizeDataflow} from './data/optimize';\nimport {Model} from './model';\n\nexport interface CompileOptions {\n config?: Config;\n logger?: log.LoggerInterface;\n\n fieldTitle?: vlFieldDef.FieldTitleFormatter;\n}\n\n/**\n * Vega-Lite's main function, for compiling Vega-lite spec into Vega spec.\n *\n * At a high-level, we make the following transformations in different phases:\n *\n * Input spec\n * |\n * | (Normalization)\n * v\n * Normalized Spec (Row/Column channels in single-view specs becomes faceted specs, composite marks becomes layered specs.)\n * |\n * | (Build Model)\n * v\n * A model tree of the spec\n * |\n * | (Parse)\n * v\n * A model tree with parsed components (intermediate structure of visualization primitives in a format that can be easily merged)\n * |\n * | (Optimize)\n * v\n * A model tree with parsed components with the data component optimized\n * |\n * | (Assemble)\n * v\n * Vega spec\n */\nexport function compile(inputSpec: TopLevelSpec, opt: CompileOptions = {}) {\n // 0. Augment opt with default opts\n if (opt.logger) {\n // set the singleton logger to the provided logger\n log.set(opt.logger);\n }\n\n if (opt.fieldTitle) {\n // set the singleton field title formatter\n vlFieldDef.setTitleFormatter(opt.fieldTitle);\n }\n\n try {\n // 1. Initialize config by deep merging default config with the config provided via option and the input spec.\n const config = initConfig(mergeDeep({}, opt.config, inputSpec.config));\n\n // 2. Normalize: Convert input spec -> normalized spec\n\n // - Decompose all extended unit specs into composition of unit spec. For example, a box plot get expanded into multiple layers of bars, ticks, and rules. The shorthand row/column channel is also expanded to a facet spec.\n const spec = normalize(inputSpec, config);\n // - Normalize autosize to be a autosize properties object.\n const autosize = normalizeAutoSize(inputSpec.autosize, config.autosize, isLayerSpec(spec) || isUnitSpec(spec));\n\n // 3. Build Model: normalized spec -> Model (a tree structure)\n\n // This phases instantiates the models with default config by doing a top-down traversal. This allows us to pass properties that child models derive from their parents via their constructors.\n // See the abstract `Model` class and its children (UnitModel, LayerModel, FacetModel, RepeatModel, ConcatModel) for different types of models.\n const model: Model = buildModel(spec, null, '', undefined, undefined, config, autosize.type === 'fit');\n\n // 4 Parse: Model --> Model with components\n\n // Note that components = intermediate representations that are equivalent to Vega specs.\n // We need these intermediate representation because we need to merge many visualizaiton \"components\" like projections, scales, axes, and legends.\n // We will later convert these components into actual Vega specs in the assemble phase.\n\n // In this phase, we do a bottom-up traversal over the whole tree to\n // parse for each type of components once (e.g., data, layout, mark, scale).\n // By doing bottom-up traversal, we start parsing components of unit specs and\n // then merge child components of parent composite specs.\n //\n // Please see inside model.parse() for order of different components parsed.\n model.parse();\n\n // 5. Optimize the dataflow. This will modify the data component of the model.\n optimizeDataflow(model.component.data);\n\n // 6. Assemble: convert model components --> Vega Spec.\n return assembleTopLevelModel(model, getTopLevelProperties(inputSpec, config, autosize));\n } finally {\n // Reset the singleton logger if a logger is provided\n if (opt.logger) {\n log.reset();\n }\n // Reset the singleton field title formatter if provided\n if (opt.fieldTitle) {\n vlFieldDef.resetTitleFormatter();\n }\n }\n}\n\n\nfunction getTopLevelProperties(topLevelSpec: TopLevel, config: Config, autosize: AutoSizeParams) {\n return {\n autosize: keys(autosize).length === 1 && autosize.type ? autosize.type : autosize,\n ...extractTopLevelProperties(config),\n ...extractTopLevelProperties(topLevelSpec)\n };\n}\n\n/*\n * Assemble the top-level model.\n *\n * Note: this couldn't be `model.assemble()` since the top-level model\n * needs some special treatment to generate top-level properties.\n */\nfunction assembleTopLevelModel(model: Model, topLevelProperties: TopLevelProperties & LayoutSizeMixins) {\n // TODO: change type to become VgSpec\n\n // Config with Vega-Lite only config removed.\n const vgConfig = model.config ? stripAndRedirectConfig(model.config) : undefined;\n\n const data = [].concat(\n model.assembleSelectionData([]),\n // only assemble data in the root\n assembleRootData(model.component.data, topLevelProperties.datasets || {})\n );\n\n delete topLevelProperties.datasets;\n\n const projections = model.assembleProjections();\n const title = model.assembleTitle();\n const style = model.assembleGroupStyle();\n\n let layoutSignals = model.assembleLayoutSignals();\n\n // move width and height signals with values to top level\n layoutSignals = layoutSignals.filter(signal => {\n if ((signal.name === 'width' || signal.name === 'height') && signal.value !== undefined) {\n topLevelProperties[signal.name] = +signal.value;\n return false;\n }\n return true;\n });\n\n const output = {\n $schema: 'https://vega.github.io/schema/vega/v3.json',\n ...(model.description ? {description: model.description} : {}),\n ...topLevelProperties,\n ...(title? {title} : {}),\n ...(style? {style} : {}),\n data: data,\n ...(projections.length > 0 ? {projections: projections} : {}),\n ...model.assembleGroup([\n ...layoutSignals,\n ...model.assembleSelectionTopLevelSignals([])\n ]),\n ...(vgConfig ? {config: vgConfig} : {})\n };\n\n return {\n spec: output\n // TODO: add warning / errors here\n };\n}\n","import {toSet} from 'vega-util';\nimport {isMarkDef} from './mark';\nimport {BAR} from './mark';\nimport {FacetedCompositeUnitSpec} from './spec';\n\n\n\n// TODO: move to vl.spec.validator?\nexport interface RequiredChannelMap {\n [mark: string]: Array;\n}\n\n/**\n * Required Encoding Channels for each mark type\n */\nexport const DEFAULT_REQUIRED_CHANNEL_MAP: RequiredChannelMap = {\n text: ['text'],\n line: ['x', 'y'],\n trail: ['x', 'y'],\n area: ['x', 'y']\n};\n\nexport interface SupportedChannelMap {\n [mark: string]: {\n [channel: string]: boolean\n };\n}\n\n/**\n * Supported Encoding Channel for each mark type\n */\nexport const DEFAULT_SUPPORTED_CHANNEL_TYPE: SupportedChannelMap = {\n bar: toSet(['row', 'column', 'x', 'y', 'size', 'color', 'fill', 'stroke', 'detail']),\n line: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'color', 'detail']),\n trail: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'color', 'detail', 'size']),\n area: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'detail']),\n tick: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'detail']),\n circle: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail']),\n square: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail']),\n point: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail', 'shape']),\n geoshape: toSet(['row', 'column', 'color', 'fill', 'stroke', 'detail', 'shape']),\n text: toSet(['row', 'column', 'size', 'color', 'fill', 'stroke', 'text']) // TODO(#724) revise\n};\n\n// TODO: consider if we should add validate method and\n// requires ZSchema in the main vega-lite repo\n\n/**\n * Further check if encoding mapping of a spec is invalid and\n * return error if it is invalid.\n *\n * This checks if\n * (1) all the required encoding channels for the mark type are specified\n * (2) all the specified encoding channels are supported by the mark type\n * @param {[type]} spec [description]\n * @param {RequiredChannelMap = DefaultRequiredChannelMap} requiredChannelMap\n * @param {SupportedChannelMap = DefaultSupportedChannelMap} supportedChannelMap\n * @return {String} Return one reason why the encoding is invalid,\n * or null if the encoding is valid.\n */\nexport function getEncodingMappingError(spec: FacetedCompositeUnitSpec,\n requiredChannelMap: RequiredChannelMap = DEFAULT_REQUIRED_CHANNEL_MAP,\n supportedChannelMap: SupportedChannelMap = DEFAULT_SUPPORTED_CHANNEL_TYPE\n ) {\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n const encoding = spec.encoding;\n const requiredChannels = requiredChannelMap[mark];\n const supportedChannels = supportedChannelMap[mark];\n\n for (const i in requiredChannels) { // all required channels are in encoding`\n if (!(requiredChannels[i] in encoding)) {\n return 'Missing encoding channel \\\"' + requiredChannels[i] +\n '\\\" for mark \\\"' + mark + '\\\"';\n }\n }\n\n for (const channel in encoding) { // all channels in encoding are supported\n if (!supportedChannels[channel]) {\n return 'Encoding channel \\\"' + channel +\n '\\\" is not supported by mark type \\\"' + mark + '\\\"';\n }\n }\n\n if (mark === BAR && !encoding.x && !encoding.y) {\n return 'Missing both x and y for bar';\n }\n\n return null;\n}\n","import * as aggregate from './aggregate';\nimport * as axis from './axis';\nimport * as bin from './bin';\nimport * as channel from './channel';\nimport * as compositeMark from './compositemark';\nexport {TopLevelSpec} from './spec';\nexport {compile} from './compile/compile';\nexport {Config} from './config';\nimport * as config from './config';\nimport * as data from './data';\nimport * as datetime from './datetime';\nimport * as encoding from './encoding';\nimport * as facet from './facet';\nimport * as fieldDef from './fielddef';\nimport * as header from './header';\nimport * as legend from './legend';\nimport * as mark from './mark';\nimport * as scale from './scale';\nimport * as sort from './sort';\nimport * as spec from './spec';\nimport * as stack from './stack';\nimport * as timeUnit from './timeunit';\nimport * as transform from './transform';\nimport * as type from './type';\nimport * as util from './util';\nimport * as validate from './validate';\n\nimport pkg from '../package.json';\nconst version = pkg.version;\n\nexport {aggregate, axis, bin, channel, compositeMark, config, data, datetime, encoding, facet, fieldDef, header, legend, mark, scale, sort, spec, stack, timeUnit, transform, type, util, validate, version};\n"],"names":["stringValue","Error","error","array","require$$0","require$$1","isArray","stringify","stableStringify","key","TEXT","field","log.warn","log.message","boxplot.BOXPLOT_STYLES","defaultConfig","mark.defaultMarkConfig","mark.defaultBarConfig","mark.defaultTickConfig","defaultSelectionConfig","normalize","compositeMark.normalize","vlEncoding.fieldDefs","parseSelector","title","fieldDefTitle","text","ref.midPoint","ref.text","ref.fieldRef","ref.bandRef","ref.bin","ref.getOffset","ref.position","ref.getDefaultRef","ref.position2","tslib_1.__extends","mixins.color","vals","properties.values","properties.type","log.debug","fieldRef","optimizers.iterateFromLeaves","optimizers.removeUnusedSubtrees","optimizers.moveParseUp","optimizers.removeDuplicateTimeUnits","util.keys","util.hash","util.isBoolean","util.replacePathInField","util.contains","util.unique","zero","defaultType","scales","multiSignals","signals","scalesCompiler","INTERVAL_BRUSH","domain","ANCHOR","DELTA","zoom","onDelta","tslib_1.__assign","contains","singleCompiler","multiCompiler","intervalCompiler","fieldExpr","timeUnitFieldExpr","hash","isTimeUnit","isAggregate","labelAlign","labelBaseline","orient","getProperty","encode.labels","properties.gridScale","properties.grid","properties.labelFlush","properties.labelOverlap","properties.orient","properties.tickCount","mixins.baseEncodeEntry","mixins.pointPosition","mixins.pointPosition2","mixins.defined","mixins.binnedPosition","mixins.bandPosition","mixins.centeredBandPosition","ref.mid","mixins.nonPosition","x","y","mixins.text","mixins.valueIfDefined","getSort","vlEncoding.channelHasField","log.set","vlFieldDef.setTitleFormatter","log.reset","vlFieldDef.resetTitleFormatter","version"],"mappings":"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"} \ No newline at end of file diff --git a/build/vega-lite.min.js b/build/vega-lite.min.js new file mode 100644 index 0000000000..2c7d7eac78 --- /dev/null +++ b/build/vega-lite.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.vl={})}(this,function(e){"use strict";function t(e,t,n){return e.fields=t||[],e.fname=n,e}function n(e){throw Error(e)}function r(e){var t,r,i,o=[],a=null,u=0,c=e.length,s="";function l(){o.push(s+e.substring(t,r)),s="",t=r+1}for(e+="",t=r=0;rt&&l(),u=t=r+1):"]"===i&&(u||n("Access path missing open bracket: "+e),u>0&&l(),u=0,t=r+1):r>t?l():t=r+1}return u&&n("Access path missing closing bracket: "+e),a&&n("Access path missing closing quote: "+e),r>t&&(r++,l()),o}var i=Array.isArray;function o(e){return e===Object(e)}function a(e){return"string"==typeof e}function u(e){return i(e)?"["+e.map(u)+"]":o(e)||a(e)?JSON.stringify(e).replace("\u2028","\\u2028").replace("\u2029","\\u2029"):e}var c=[];(function(e,n){var i=r(e),o="return _["+i.map(u).join("][")+"];";t(Function("_",o),[e=1===i.length?i[0]:e],n||e)})("id"),t(function(e){return e},c,"identity"),t(function(){return 0},c,"zero"),t(function(){return 1},c,"one"),t(function(){return!0},c,"true"),t(function(){return!1},c,"false");function s(e,t,n){var r=[t].concat([].slice.call(n));console[e].apply(console,r)}var l=0,f=1,d=2,p=3,h=4;function m(e){return"boolean"==typeof e}function g(e){return"number"==typeof e}function v(e){for(var t={},n=0,r=e.length;n="0"&&w<="9";)t+=w,T();if("."===w)for(t+=".";T()&&w>="0"&&w<="9";)t+=w;if("e"===w||"E"===w)for(t+=w,T(),"-"!==w&&"+"!==w||(t+=w,T());w>="0"&&w<="9";)t+=w,T();if(e=+t,isFinite(e))return e;_("Bad number")},A=function(){var e,t,n,r="";if('"'===w)for(;T();){if('"'===w)return T(),r;if("\\"===w)if(T(),"u"===w){for(n=0,t=0;t<4&&(e=parseInt(T(),16),isFinite(e));t+=1)n=16*n+e;r+=String.fromCharCode(n)}else{if("string"!=typeof O[w])break;r+=O[w]}else r+=w}_("Bad string")},D=function(){for(;w&&w<=" ";)T()};N=function(){switch(D(),w){case"{":return function(){var e,t={};if("{"===w){if(T("{"),D(),"}"===w)return T("}"),t;for(;w;){if(e=A(),D(),T(":"),Object.hasOwnProperty.call(t,e)&&_('Duplicate key "'+e+'"'),t[e]=N(),D(),"}"===w)return T("}"),t;T(","),D()}}_("Bad object")}();case"[":return function(){var e=[];if("["===w){if(T("["),D(),"]"===w)return T("]"),e;for(;w;){if(e.push(N()),D(),"]"===w)return T("]"),e;T(","),D()}}_("Bad array")}();case'"':return A();case"-":return C();default:return w>="0"&&w<="9"?C():function(){switch(w){case"t":return T("t"),T("r"),T("u"),T("e"),!0;case"f":return T("f"),T("a"),T("l"),T("s"),T("e"),!1;case"n":return T("n"),T("u"),T("l"),T("l"),null}_("Unexpected '"+w+"'")}()}};var I,z,R,L=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,F={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};function j(e){return L.lastIndex=0,L.test(e)?'"'+e.replace(L,function(e){var t=F[e];return"string"==typeof t?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}var U="undefined"!=typeof JSON?JSON:{parse:function(e,t){var n;return k=e,E=0,w=" ",n=N(),D(),w&&_("Syntax error"),"function"==typeof t?function e(n,r){var i,o,a=n[r];if(a&&"object"==typeof a)for(i in a)Object.prototype.hasOwnProperty.call(a,i)&&(void 0!==(o=e(a,i))?a[i]=o:delete a[i]);return t.call(n,r,a)}({"":n},""):n},stringify:function(e,t,n){var r;if(I="",z="","number"==typeof n)for(r=0;r-1}function K(e,t){return e.filter(function(e){return!Q(t,e)})}function J(e,t){for(var n=0,r=0;r=f&&s("error","ERROR",arguments),this},warn:function(){return Jt>=d&&s("warn","WARN",arguments),this},info:function(){return Jt>=p&&s("log","INFO",arguments),this},debug:function(){return Jt>=h&&s("log","DEBUG",arguments),this}}),ln=sn;function fn(){for(var e=[],t=0;t1&&(fn(Zt.droppedDay(e)),delete(e=ce(e)).day),void 0!==e.year?n.push(e.year):void 0!==e.day?n.push(dn):n.push(0),void 0!==e.month){var r=t?function(e){if(g(e))return e-1+"";var t=e.toLowerCase(),n=hn.indexOf(t);if(-1!==n)return n+"";var r=t.substr(0,3),i=mn.indexOf(r);if(-1!==i)return i+"";throw new Error(Zt.invalidTimeUnit("month",e))}(e.month):e.month;n.push(r)}else if(void 0!==e.quarter){var i=t?function(e){if(g(e))return e>4&&fn(Zt.invalidTimeUnit("quarter",e)),e-1+"";throw new Error(Zt.invalidTimeUnit("quarter",e))}(e.quarter):e.quarter;n.push(i+"*3")}else n.push(0);if(void 0!==e.date)n.push(e.date);else if(void 0!==e.day){var o=t?function(e){if(g(e))return e%7+"";var t=e.toLowerCase(),n=gn.indexOf(t);if(-1!==n)return n+"";var r=t.substr(0,3),i=vn.indexOf(r);if(-1!==i)return i+"";throw new Error(Zt.invalidTimeUnit("day",e))}(e.day):e.day;n.push(o+"+1")}else n.push(1);for(var a=0,u=["hours","minutes","seconds","milliseconds"];a-1&&(t!==bn.SECONDS||0===n||"i"!==e.charAt(n-1))}function Fn(e,t){var n=he(t),r=Tn(e)?"utc":"";return yn(En.reduce(function(t,i){var o;return Ln(e,i)&&(t[i]=(o=i)===bn.QUARTER?"("+r+"quarter("+n+")-1)":""+r+o+"("+n+")"),t},{}))}function jn(e,t,n,r){if(e){var i=[],o="",a=Ln(e,bn.YEAR);Ln(e,bn.QUARTER)&&(o="'Q' + quarter("+t+")"),Ln(e,bn.MONTH)&&i.push(!1!==n?"%b":"%B"),Ln(e,bn.DAY)?i.push(n?"%a":"%A"):Ln(e,bn.DATE)&&i.push("%d"+(a?",":"")),a&&i.push(n?"%y":"%Y");var u=[];Ln(e,bn.HOURS)&&u.push("%H"),Ln(e,bn.MINUTES)&&u.push("%M"),Ln(e,bn.SECONDS)&&u.push("%S"),Ln(e,bn.MILLISECONDS)&&u.push("%L");var c=[];return i.length>0&&c.push(i.join(" ")),u.length>0&&c.push(u.join(":")),c.length>0&&(o&&(o+=" + ' ' + "),o+=r?"utcFormat("+t+", '"+c.join(" ")+"')":"timeFormat("+t+", '"+c.join(" ")+"')"),o||void 0}}function Un(e){return"day"!==e&&e.indexOf("day")>=0?(fn(Zt.dayReplacedWithDate(e)),e.replace("day","date")):e}var Pn,Mn=Object.freeze({get TimeUnit(){return bn},TIMEUNIT_PARTS:En,isLocalSingleTimeUnit:wn,isUtcSingleTimeUnit:Nn,isUTCTimeUnit:Tn,getLocalTimeUnit:Cn,TIMEUNITS:Dn,isTimeUnit:function(e){return!!An[e]},convert:function(e,t){for(var n=Tn(e),r=n?new Date(Date.UTC(0,0,1,0,0,0,0)):new Date(0,0,1,0,0,0,0),i=0,o=En;i-1?e[n]=t:fn(Zt.incompatibleChannel(n,jr)),e},{})})}(e)).mark,u=(e.encoding,e.selection),c=(e.projection,S(e,["mark","encoding","selection","projection"])),s=void 0;g(t.box.extent)&&(s=t.box.extent),Ur(a)&&a.extent&&"min-max"===a.extent&&(s=void 0);var l=function(e,t,n){var r=function(e,t){e.mark;var n,r,i=e.encoding;if(e.projection,S(e,["mark","encoding","projection"]),"vertical"===t?(r="y",n=i.y):(r="x",n=i.x),n&&n.aggregate){var o=n.aggregate,a=S(n,["aggregate"]);o!==jr&&fn("Continuous axis should not have customized aggregation function "+o),n=a}return{continuousAxisChannelDef:n,continuousAxis:r}}(e,t),i=r.continuousAxisChannelDef,o=r.continuousAxis,a=e.encoding,u=void 0===n,c=[{op:"q1",field:i.field,as:"lower_box_"+i.field},{op:"q3",field:i.field,as:"upper_box_"+i.field},{op:"median",field:i.field,as:"mid_box_"+i.field}],s=[];c.push({op:"min",field:i.field,as:(u?"lower_whisker_":"min_")+i.field}),c.push({op:"max",field:i.field,as:(u?"upper_whisker_":"max_")+i.field}),u||(s=[{calculate:"datum.upper_box_"+i.field+" - datum.lower_box_"+i.field,as:"iqr_"+i.field},{calculate:"min(datum.upper_box_"+i.field+" + datum.iqr_"+i.field+" * "+n+", datum.max_"+i.field+")",as:"upper_whisker_"+i.field},{calculate:"max(datum.lower_box_"+i.field+" - datum.iqr_"+i.field+" * "+n+", datum.min_"+i.field+")",as:"lower_whisker_"+i.field}]);var l=[],f=[],d=[],p={};return zr(a,function(e,t){if(t!==o)if(tr(e)){if(e.aggregate&&e.aggregate!==jr)c.push({op:e.aggregate,field:e.field,as:or(e)});else if(void 0===e.aggregate){var n=or(e),r=e.bin;if(r){var i=e.field;f.push({bin:r,field:i,as:n})}else if(e.timeUnit){var u=e.timeUnit;i=e.field,d.push({timeUnit:u,field:i,as:n})}l.push(n)}p[t]={field:or(e),type:e.type}}else p[t]=a[t]}),{transform:[].concat(f,d,[{aggregate:c,groupby:l}],s),continuousAxisChannelDef:i,continuousAxis:o,encodingWithoutContinuousAxis:p}}(e,function(e){var t=e.mark,n=e.encoding;if(e.projection,S(e,["mark","encoding","projection"]),tr(n.x)&&ur(n.x)){if(tr(n.y)&&ur(n.y)){if(void 0===n.x.aggregate&&n.y.aggregate===jr)return"vertical";if(void 0===n.y.aggregate&&n.x.aggregate===jr)return"horizontal";if(n.x.aggregate===jr&&n.y.aggregate===jr)throw new Error("Both x and y cannot have aggregate");return Ur(t)&&t.orient?t.orient:"vertical"}return"horizontal"}if(tr(n.y)&&ur(n.y))return"vertical";throw new Error("Need a valid continuous axis for boxplots")}(e),s),f=l.transform,d=l.continuousAxisChannelDef,p=l.continuousAxis,h=l.encodingWithoutContinuousAxis,m=h.size,v=S(h,["color","size"]),y=m?{size:m}:Fr(t.box,"size"),b={};return d.scale&&(b.scale=d.scale),d.axis&&(b.axis=d.axis),x({},c,{transform:f,layer:[{mark:{type:"rule",style:"boxWhisker"},encoding:x((n={},n[p]=x({field:"lower_whisker_"+d.field,type:d.type},b),n[p+"2"]={field:"lower_box_"+d.field,type:d.type},n),v,Fr(t.boxWhisker,"color"))},{mark:{type:"rule",style:"boxWhisker"},encoding:x((r={},r[p]={field:"upper_box_"+d.field,type:d.type},r[p+"2"]={field:"upper_whisker_"+d.field,type:d.type},r),v,Fr(t.boxWhisker,"color"))},x({},u?{selection:u}:{},{mark:{type:"bar",style:"box"},encoding:x((i={},i[p]={field:"lower_box_"+d.field,type:d.type},i[p+"2"]={field:"upper_box_"+d.field,type:d.type},i),h,h.color?{}:Fr(t.box,"color"),y)}),{mark:{type:"tick",style:"boxMid"},encoding:x((o={},o[p]={field:"mid_box_"+d.field,type:d.type},o),v,Fr(t.boxMid,"color"),y)}]})}),Hr("error-bar",function(e){e.mark,e.selection,e.projection;var t=e.encoding,n=S(e,["mark","selection","projection","encoding"]),r=(t.size,S(t,["size"])),i=(t.x2,t.y2,S(t,["x2","y2"])),o=S(i,["x","y"]);if(!t.x2&&!t.y2)throw new Error("Neither x2 or y2 provided");return x({},n,{layer:[{mark:"rule",encoding:r},{mark:"tick",encoding:i},{mark:"tick",encoding:t.x2?x({x:t.x2,y:t.y},o):x({x:t.x,y:t.y2},o)}]})});var Br,Yr=Object.freeze({add:Hr,remove:function(e){delete Mr[e]},COMPOSITE_MARK_STYLES:qr,VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX:Wr,normalize:Gr}),Vr=["shortTimeLabels"],Xr={},Qr={entryPadding:1,format:1,offset:1,orient:1,padding:1,tickCount:1,title:1,type:1,values:1,zindex:1},Kr=x({},Qr,{opacity:1,shape:1,stroke:1,fill:1,size:1,encode:1}),Jr=ue(Qr),Zr=ue(Kr),$r=Object.freeze({defaultLegendConfig:Xr,LEGEND_PROPERTIES:Jr,VG_LEGEND_PROPERTIES:Zr});!function(e){e.LINEAR="linear",e.BIN_LINEAR="bin-linear",e.LOG="log",e.POW="pow",e.SQRT="sqrt",e.TIME="time",e.UTC="utc",e.SEQUENTIAL="sequential",e.QUANTILE="quantile",e.QUANTIZE="quantize",e.THRESHOLD="threshold",e.ORDINAL="ordinal",e.BIN_ORDINAL="bin-ordinal",e.POINT="point",e.BAND="band"}(Br||(Br={}));var ei={linear:"numeric",log:"numeric",pow:"numeric",sqrt:"numeric","bin-linear":"bin-linear",time:"time",utc:"time",sequential:"sequential",ordinal:"ordinal","bin-ordinal":"bin-ordinal",point:"ordinal-position",band:"ordinal-position"},ti=oe(ei);function ni(e,t){var n=ei[e],r=ei[t];return n===r||"ordinal-position"===n&&"time"===r||"ordinal-position"===r&&"time"===n}var ri={linear:0,log:1,pow:1,sqrt:1,time:0,utc:0,point:10,band:11,"bin-linear":0,sequential:0,ordinal:0,"bin-ordinal":0};function ii(e){return ri[e]}var oi=["linear","bin-linear","log","pow","sqrt","time","utc"],ai=v(oi),ui=oi.concat(["sequential"]),ci=v(ui),si=["ordinal","bin-ordinal","point","band"],li=v(si),fi=v(["bin-linear","bin-ordinal"]);function di(e){return e in li}function pi(e){return e in fi}function hi(e){return e in ci}function mi(e){return e in ai}var gi={textXRangeStep:90,rangeStep:21,pointPadding:.5,bandPaddingInner:.1,facetSpacing:16,minBandSize:2,minFontSize:8,maxFontSize:40,minOpacity:.3,maxOpacity:.8,minSize:9,minStrokeWidth:1,maxStrokeWidth:4};function vi(e){return e&&!!e.name}function yi(e){return e&&e.selection}var bi={type:1,domain:1,range:1,rangeStep:1,scheme:1,reverse:1,round:1,clamp:1,nice:1,base:1,exponent:1,interpolate:1,zero:1,padding:1,paddingInner:1,paddingOuter:1},xi=ue(bi),Si=ue(S(bi,["type","domain","range","rangeStep","scheme"])),Ei=function(){for(var e={},t=0,n=ft;t window:mousemove!",encodings:["x","y"],translate:"[mousedown, window:mouseup] > window:mousemove!",zoom:"wheel!",mark:{fill:"#333",fillOpacity:.125,stroke:"white"},resolve:"global"}},style:{},title:{}};function zi(e){return ee(ce(Ii),e)}var Ri=["view"].concat(Vt,qr),Li=["padding","numberFormat","timeFormat","countTitle","stack","scale","selection","invalidValues","overlay"],Fi=x({view:["width","height"]},rn,Wr);function ji(e){e=ce(e);for(var t=0,n=Li;t0?e:void 0}function Ui(e,t,n){var r="title"===t?Ai(e.title).mark:e[t];"view"===t&&(n="cell");var i=x({},r,e.style[t]);oe(i).length>0&&(e.style[n||t]=i),delete e[t]}var Pi=Object.freeze({defaultViewConfig:Di,defaultConfig:Ii,initConfig:zi,stripAndRedirectConfig:ji}),Mi={zero:1,center:1,normalize:1};function Hi(e){return!!Mi[e]}var qi=[Rt,zt,Ht,Ft,Wt,Gt,Lt,jt,Ut],Wi=[Rt,zt];function Gi(e,t,n){var r=Xt(e)?e.type:e;if(!Q(qi,r))return null;var o=function(e){var t=e.x,n=e.y;if(tr(t)&&tr(n))if("quantitative"===t.type&&"quantitative"===n.type){if(t.stack)return"x";if(n.stack)return"y";if(!!t.aggregate!=!!n.aggregate)return t.aggregate?"x":"y"}else{if("quantitative"===t.type)return"x";if("quantitative"===n.type)return"y"}else{if(tr(t)&&"quantitative"===t.type)return"x";if(tr(n)&&"quantitative"===n.type)return"y"}}(t);if(!o)return null;var a=t[o],u=nr(a)?or(a,{}):void 0,c="x"===o?"y":"x",s=t[c],l=nr(s)?or(s,{}):void 0,f=gt.reduce(function(e,n){if(Tr(t,n)){var r=t[n];(i(r)?r:[r]).forEach(function(t){var r=vr(t);if(!r.aggregate){var i=nr(r)?or(r,{}):void 0;(!i||i!==l&&i!==u)&&e.push({channel:n,fieldDef:r})}})}return e},[]);if(0===f.length)return null;var d=void 0;return(d=void 0!==a.stack?a.stack:Q(Wi,r)&&void 0===n?"zero":n)&&Hi(d)?(a.scale&&a.scale.type&&a.scale.type!==Br.LINEAR&&fn(Zt.cannotStackNonLinearScale(a.scale.type)),Tr(t,o===Ue?Me:He)?(void 0!==a.stack&&fn(Zt.cannotStackRangedMark(o)),null):(a.aggregate&&!Q(Ne,a.aggregate)&&fn(Zt.stackNonSummativeAggregate(a.aggregate)),{groupbyChannel:s?c:void 0,fieldChannel:o,impute:Yt(r),stackBy:f,offset:d})):null}var Bi=Object.freeze({isStackOffset:Hi,STACKABLE_MARKS:qi,STACK_BY_DEFAULT_MARKS:Wi,stack:Gi});function Yi(e){return void 0!==e.facet}function Vi(e){return!!e.mark}function Xi(e){return void 0!==e.layer}function Qi(e){return void 0!==e.repeat}function Ki(e){return Ji(e)||Zi(e)}function Ji(e){return void 0!==e.vconcat}function Zi(e){return void 0!==e.hconcat}function $i(e,t){if(Yi(e))return function(e,t){var n=e.spec,r=S(e,["spec"]);return x({},r,{spec:$i(n,t)})}(e,t);if(Xi(e))return function e(t,n,r,i){var o=t.layer,a=t.encoding,u=t.projection,c=S(t,["layer","encoding","projection"]);var s=eo({parentEncoding:r,encoding:a});var l=to({parentProjection:i,projection:u});return x({},c,{layer:o.map(function(t){return Xi(t)?e(t,n,s,l):no(t,n,s,l)})})}(e,t);if(Qi(e))return function(e,t){var n=e.spec,r=S(e,["spec"]);return x({},r,{spec:$i(n,t)})}(e,t);if(Ji(e))return function(e,t){var n=e.vconcat,r=S(e,["vconcat"]);return x({},r,{vconcat:n.map(function(e){return $i(e,t)})})}(e,t);if(Zi(e))return function(e,t){var n=e.hconcat,r=S(e,["hconcat"]);return x({},r,{hconcat:n.map(function(e){return $i(e,t)})})}(e,t);if(Vi(e)){var n=Tr(e.encoding,Ye),r=Tr(e.encoding,Ve);return n||r?function(e,t){var n=e.encoding,r=n.row,i=n.column,o=S(n,["row","column"]),a=e.mark,u=e.width,c=e.projection,s=e.height,l=e.selection,f=(e.encoding,S(e,["mark","width","projection","height","selection","encoding"]));return x({},f,{facet:x({},r?{row:r}:{},i?{column:i}:{}),spec:no(x({},c?{projection:c}:{},{mark:a},u?{width:u}:{},s?{height:s}:{},{encoding:o},l?{selection:l}:{}),t)})}(e,t):no(e,t)}throw new Error(Zt.INVALID_SPEC)}function eo(e){var t=e.parentEncoding,n=e.encoding;if(t&&n){var r=oe(t).reduce(function(e,t){return n[t]&&e.push(t),e},[]);r.length>0&&fn(Zt.encodingOverridden(r))}var i=x({},t||{},n||{});return oe(i).length>0?i:void 0}function to(e){var t=e.parentProjection,n=e.projection;return t&&n&&fn(Zt.projectionOverridden({parentProjection:t,projection:n})),n||t}function no(e,t,n,r){var i=e.encoding,a=e.projection,u=Xt(e.mark)?e.mark.type:e.mark;if(n||r){var c=to({parentProjection:r,projection:a}),s=eo({parentEncoding:n,encoding:i});return no(x({},e,c?{projection:c}:{},s?{encoding:s}:{}),t)}return function(e){return Kt(e.mark)}(e)?Dr(i)?function(e){var t=Tr(e.encoding,Ue),n=Tr(e.encoding,Pe),r=Tr(e.encoding,Me),i=Tr(e.encoding,He);if(r&&!t||i&&!n){var o=ce(e);return r&&!t&&(o.encoding.x=o.encoding.x2,delete o.encoding.x2),i&&!n&&(o.encoding.y=o.encoding.y2,delete o.encoding.y2),o}return e}(e):"line"===u&&(i.x2||i.y2)?(fn(Zt.lineWithRange(!!i.x2,!!i.y2)),no(x({mark:"rule"},e),t,n,r)):Yt(u)?function(e,t){void 0===t&&(t={});var n,r=e.selection,i=e.projection,a=e.encoding,u=e.mark,c=S(e,["selection","projection","encoding","mark"]),s=Xt(u)?u:{type:u},l=function(e,t,n){return"transparent"===e.point?{opacity:0}:e.point?o(e.point)?e.point:{}:void 0!==e.point?null:t.point||n.shape?o(t.point)?t.point:{}:null}(s,t[s.type],a),f="area"===s.type&&function(e,t){return e.line?!0===e.line?{}:e.line:void 0!==e.line?null:t.line?!0===t.line?{}:t.line:null}(s,t[s.type]);if(!l&&!f)return x({},e,{mark:ro(s)});var d=[x({},r?{selection:r}:{},{mark:ro(x({},s,"area"===s.type?{opacity:.7}:{})),encoding:Y(a,["shape"])})],p=Gi(s,a,t?t.stack:void 0),h=a;if(p){var m=p.fieldChannel,g=p.offset;h=x({},a,((n={})[m]=x({},a[m],g?{stack:g}:{}),n))}f&&d.push(x({},i?{projection:i}:{},{mark:x({type:"line"},B(s,["clip","interpolate"]),f),encoding:h}));l&&d.push(x({},i?{projection:i}:{},{mark:x({type:"point",opacity:1,filled:!0},B(s,["clip"]),l),encoding:h}));return x({},c,{layer:d})}(e,t):e:Gr(e,t)}function ro(e){e.point,e.line;var t=S(e,["point","line"]);return oe(t).length>1?t:t.type}function io(e,t){return t.forEach(function(t){var n=X(["field","type","value","timeUnit","bin","aggregate"].reduce(function(e,n){return void 0!==t[n]&&(e[n]=t[n]),e},{}));e[n]=e[n]||t}),e}var oo=Object.freeze({isFacetSpec:Yi,isUnitSpec:Vi,isLayerSpec:Xi,isRepeatSpec:Qi,isConcatSpec:Ki,isVConcatSpec:Ji,isHConcatSpec:Zi,normalize:$i,fieldDefs:function(e){return ae(function e(t,n){return void 0===n&&(n={}),Xi(t)?t.layer.forEach(function(t){Vi(t)?io(n,Ir(t.encoding)):e(t,n)}):Yi(t)?(io(n,Ir(t.facet)),e(t.spec,n)):Qi(t)?e(t.spec,n):Ki(t)?(Ji(t)?t.vconcat:t.hconcat).forEach(function(t){return e(t,n)}):io(n,Ir(t.encoding)),n}(e))},isStacked:function(e,t){return t=t||e.config,!!Kt(e.mark)&&null!==Gi(e.mark,e.encoding,t?t.stack:void 0)}});function ao(e){return a(e)?{type:e}:e||{}}var uo=["background","padding","datasets"];function co(e){return uo.reduce(function(t,n){return e&&void 0!==e[n]&&(t[n]=e[n]),t},{})}function so(e){return!!e.url}function lo(e){return!!e.values}function fo(e){return!!e.name&&!so(e)&&!lo(e)}var po="main",ho="raw",mo=Object.freeze({isUrlData:so,isInlineData:lo,isNamedData:fo,MAIN:po,RAW:ho});function go(e,t,n){return vo=t||bo,yo=n||Co,Do(e.trim()).map(Io)}var vo,yo,bo="view",xo="[",So="]",Eo="{",wo="}",ko=":",No=",",Oo="@",_o=">",To=/[[\]{}]/,Co={"*":1,arc:1,area:1,group:1,image:1,line:1,path:1,rect:1,rule:1,shape:1,symbol:1,text:1,trail:1};function Ao(e,t,n,r,i){for(var o,a=0,u=e.length;t=0?--a:r&&r.indexOf(o)>=0&&++a}return t}function Do(e){for(var t=[],n=0,r=e.length,i=0;i' after between selector: "+e;if(t=t.map(Io),(n=Io(e.slice(1).trim())).between)return{between:t,stream:n};n.between=t;return n}(e):function(e){var t,n,r={source:vo},i=[],o=[0,0],a=0,u=0,c=e.length,s=0;if(e[c-1]===wo){if(!((s=e.lastIndexOf(Eo))>=0))throw"Unmatched right brace: "+e;try{o=function(e){var t=e.split(No);if(!e.length||t.length>2)throw e;return t.map(function(t){var n=+t;if(n!=n)throw e;return n})}(e.substring(s+1,c-1))}catch(t){throw"Invalid throttle specification: "+e}e=e.slice(0,s).trim(),c=e.length,s=0}if(!c)throw e;e[0]===Oo&&(a=++s);(t=Ao(e,s,ko))1?(r.type=i[1],a?r.markname=i[0].slice(1):(l=i[0],yo.hasOwnProperty(l)?r.marktype=i[0]:r.source=i[0])):r.type=i[0];var l;"!"===r.type.slice(-1)&&(r.consume=!0,r.type=r.type.slice(0,-1));null!=n&&(r.filter=n);o[0]&&(r.throttle=o[0]);o[1]&&(r.debounce=o[1]);return r}(e)}function zo(e){return!!e.signal}function Ro(e){return!!e.step}function Lo(e){return!i(e)&&("field"in e&&"data"in e)}var Fo=ue({opacity:1,fill:1,fillOpacity:1,stroke:1,strokeCap:1,strokeWidth:1,strokeOpacity:1,strokeDash:1,strokeDashOffset:1,strokeJoin:1,strokeMiterLimit:1,size:1,shape:1,interpolate:1,tension:1,orient:1,align:1,baseline:1,text:1,dir:1,dx:1,dy:1,ellipsis:1,limit:1,radius:1,theta:1,angle:1,font:1,fontSize:1,fontWeight:1,fontStyle:1,cursor:1,href:1,tooltip:1,cornerRadius:1});function jo(e,t,n,r){void 0===r&&(r={header:!1});var o=e.combine(),a=o.orient,u=o.scale,c=o.title,s=o.zindex,l=S(o,["orient","scale","title","zindex"]);if(oe(l).forEach(function(e){var n=Ae[e];n&&n!==t&&"both"!==n&&delete l[e]}),"grid"===t){if(!l.grid)return;if(l.encode){var f=l.encode.grid;l.encode=x({},f?{grid:f}:{}),0===oe(l.encode).length&&delete l.encode}return x({scale:u,orient:a},l,{domain:!1,labels:!1,maxExtent:0,minExtent:0,ticks:!1,zindex:void 0!==s?s:0})}if(r.header||!e.mainExtracted){if(l.encode){for(var d=0,p=Ce;d=0})}(r))return{scale:n,value:0};"bar"!==o&&"area"!==o||fn(Zt.nonZeroScaleUsedWithLengthMark(o,t,{zeroFalse:!1===r.explicit.zero}))}}return"zeroOrMin"===e?"x"===t?{value:0}:{field:{group:"height"}}:"x"===t?{field:{group:"width"}}:{value:0}}return e}}function ea(e,t){var n,r;void 0===t&&(t={valueOnly:!1});var i=e.markDef,o=e.encoding,a=e.config,u=i.filled,c=i.type,s={fill:ha("fill",i,a),stroke:ha("stroke",i,a),color:ha("color",i,a)},l=Q(["bar","point","circle","square","geoshape"],c)?"transparent":void 0,f={fill:i.fill||s.fill||l,stroke:i.stroke||s.stroke},d=u?"fill":"stroke",p=x({},f.fill?{fill:{value:f.fill}}:{},f.stroke?{stroke:{value:f.stroke}}:{});return o.fill||o.stroke?(i.color&&fn(Zt.droppingColor("property",{fill:"fill"in o,stroke:"stroke"in o})),x({},ia("fill",e,{defaultValue:f.fill||l}),ia("stroke",e,{defaultValue:f.stroke}))):o.color?x({},p,ia("color",e,{vgChannel:d,defaultValue:i[d]||i.color||s[d]||s.color||(u?l:void 0)})):i.fill||i.stroke?(i.color&&fn(Zt.droppingColor("property",{fill:"fill"in i,stroke:"stroke"in i})),p):i.color?x({},p,((n={})[d]={value:i.color},n)):s.fill||s.stroke?p:s.color?x({},l?{fill:{value:"transparent"}}:{},((r={})[d]={value:s.color},r)):{}}function ta(e,t){return x({},function(e,t){return Fo.reduce(function(n,r){return void 0!==e[r]&&"ignore"!==t[r]&&(n[r]={value:e[r]}),n},{})}(e.markDef,t),ea(e),ia("opacity",e),function(e){var t=e.encoding.tooltip;if(i(t)){var n=t.map(function(t){var n=void 0!==t.title?t.title:or(t,{binSuffix:"range"}),r=Jo(t,e.config).signal;return'"'+n+'": '+r});return{tooltip:{signal:"{"+n.join(", ")+"}"}}}return ua(e,"tooltip",t)}(e),aa(e,"href"))}function na(e){return e+" !== null && !isNaN("+e+")"}function ra(e){if("filter"===e.config.invalidValues){var t=["x","y"].map(function(t){var n=e.getScaleComponent(t);if(n&&hi(n.get("type")))return e.vgField(t,{expr:"datum"})}).filter(function(e){return!!e}).map(na);if(t.length>0)return{defined:{signal:t.join(" && ")}}}return{}}function ia(e,t,n){void 0===n&&(n={});var r=n.defaultValue,i=n.vgChannel,o=n.defaultRef||(void 0!==r?{value:r}:void 0),a=t.encoding[e];return oa(t,a,i||e,function(n){return Ko(e,n,t.scaleName(e),t.getScaleComponent(e),null,o)})}function oa(e,t,n,r){var o,a,u=t&&t.condition,c=r(t);if(u){var s=(i(u)?u:[u]).map(function(t){var n=r(t),i=Qn(t)?mc(e,t.selection):Dc(e,t.test);return x({test:i},n)});return(o={})[n]=s.concat(void 0!==c?[c]:[]),o}return void 0!==c?((a={})[n]=c,a):{}}function aa(e,t){return void 0===t&&(t="text"),ua(e,t,e.encoding[t])}function ua(e,t,n){return oa(e,n,t,function(t){return Jo(t,e.config)})}function ca(e,t,n){var r,i,o,a=n.scaleName(t),u="x"===t?"width":"height";if(n.encoding.size||void 0!==n.markDef.size)if(n.markDef.orient){var c=((r={})[t+"c"]=Xo(e,a,{},{band:.5}),r);if(vr(n.encoding.size))return x({},c,ia("size",n,{vgChannel:u}));if(rr(n.encoding.size))return x({},c,ia("size",n,{vgChannel:u}));if(void 0!==n.markDef.size)return x({},c,((i={})[u]={value:n.markDef.size},i))}else fn(Zt.cannotApplySizeToNonOrientedMark(n.markDef.type));return(o={})[t]=Xo(e,a,{binSuffix:"range"}),o[u]=Qo(a),o}function sa(e,t,n,r){var i="x"===e?"width":"height";return x({},fa(e,t,n,"x"===e?"xc":"yc"),ia("size",t,{defaultRef:r,vgChannel:i}))}function la(e,t,n,r,i){return"x"===t?{x2:Vo(e,n,"start",i?0:r),x:Vo(e,n,"end",i?r:0)}:{y2:Vo(e,n,"start",i?r:0),y:Vo(e,n,"end",i?0:r)}}function fa(e,t,n,r){var i,o=t.encoding,a=t.mark,u=t.stack,c=o[e],s=t.scaleName(e),l=t.getScaleComponent(e),f=Yo(e,t.markDef),d=c||!o.latitude&&!o.longitude?x({},function(e,t,n,r,i,o){return tr(t)&&i&&e===i.fieldChannel?Xo(t,n,{suffix:"end"}):Ko(e,t,n,r,i,o)}(e,o[e],s,l,u,$o(n,e,s,l,a)),f?{offset:f}:{}):{field:t.getName(e)};return(i={})[r||e]=d,i}function da(e,t,n){var r,i=e.encoding,o=e.mark,a=e.stack,u="x2"===n?"x":"y",c=i[u],s=e.scaleName(u),l=e.getScaleComponent(u),f=Yo(n,e.markDef),d=c||!i.latitude&&!i.longitude?x({},function(e,t,n,r,i,o,a){return tr(t)&&o&&e.charAt(0)===o.fieldChannel.charAt(0)?Xo(t,r,{suffix:"start"}):Ko(e,n,r,i,o,a)}(n,c,i[n],s,l,a,$o(t,u,s,l,o)),f?{offset:f}:{}):{field:e.getName(n)};return(r={})[n]=d,r}function pa(e){return[].concat(e.type,e.style||[])}function ha(e,t,n){var r=n.mark[e],i=n[t.type];void 0!==i[e]&&(r=i[e]);for(var o=0,a=pa(t);o0?{encode:{update:m}}:{})}var g=o.axes,v=g&&g.length>0;if(c||v){var y="row"===t?"height":"width";return x({name:e.getName(t+"_"+n),type:"group",role:t+"-"+n},r.facetFieldDef?{from:{data:e.getName(t+"_domain")},sort:function(e,t){var n=e.sort;return Wo(n)?{field:or(n,{expr:"datum"}),order:n.order||"ascending"}:i(n)?{field:Da(e,t,"datum"),order:"ascending"}:{field:or(e,{expr:"datum"}),order:n||"ascending"}}(s,t)}:{},c?{title:c}:{},o.sizeSignal?{encode:{update:(a={},a[y]=o.sizeSignal,a)}}:{},v?{axes:g}:{})}}return null}function ja(e,t,n,r){for(var i={},o=0,a=n;o0?t:o<0?n:Va(t,n,r,i)}}function Va(e,t,n,r){return e.explicit&&t.explicit&&fn(Zt.mergeConflictingProperty(n,r,e.value,t.value)),e}function Xa(e,t,n,r,i){return void 0===i&&(i=Va),void 0===e||void 0===e.value?t:e.explicit&&!t.explicit?e:t.explicit&&!e.explicit?t:V(e.value)===V(t.value)?e:i(e,t,n,r)}var Qa=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return b(t,e),t}(Wa);function Ka(e){return Za(e,function(e,t){return Math.max(e,t.value)})}function Ja(e){return Za(e,function(e,t){return void 0!==e?e:t.value})}function Za(e,t){return er(e)?(i(e.condition)?e.condition:[e.condition]).reduce(t,e.value):rr(e)?e.value:void 0}var $a=Object.freeze({symbols:function(e,t,n,r,o){if("gradient"!==o){var a=x({},function(e,t,n){for(var r=0,i=n;r0?a:void 0}},gradient:function(e,t,n,r,i){var o={};if("gradient"===i){var a=Ka(n.encoding.opacity)||n.markDef.opacity;a&&(o.opacity={value:a})}return o=x({},o,t),oe(o).length>0?o:void 0},labels:function(e,t,n,r,i){var o=n.legend(r),a=n.config,u={};if(kr(e)){var c=n.getScaleComponent(r).get("type")===Br.UTC,s=Sa("datum.value",e.timeUnit,o.format,a.legend.shortTimeLabels,a.timeFormat,c);t=x({},s?{text:{signal:s}}:{},t)}return u=x({},u,t),oe(u).length>0?u:void 0}});function eu(e){Mu(e)?e.component.legends=function(e){var t=e.encoding;return[Ke,Je,Ze,Qe,Xe,rt].reduce(function(n,r){var i=t[r];return!e.legend(r)||!e.getScaleComponent(r)||tr(i)&&r===Xe&&i.type===Yn||(n[r]=function(e,t){var n=e.fieldDef(t),r=e.legend(t),i=new Qa({},function(e,t){var n;switch(t){case Ke:var r=e.scaleName(Ke);return e.markDef.filled?{fill:r}:{stroke:r};case Je:case Ze:case Qe:case Xe:case rt:return(n={})[t]=e.scaleName(t),n}}(e,t));Jr.forEach(function(n){var o=function(e,t,n,r){var i=r.fieldDef(n);switch(e){case"format":return va(i,t.format,r.config);case"title":var o=void 0!==i.title?i.title:t.title||(void 0===t.title?void 0:null);return ga(o,mr(i,r.config))||void 0;case"values":return function(e,t){var n=e.values;if(n)return Or(t,n)}(t,i);case"type":return ga(t.type,function(e,t,n){if(st(t)&&("quantitative"===e&&!pi(n)||"temporal"===e&&Q(["time","utc"],n)))return"gradient"}(i.type,n,r.getScaleComponent(n).get("type")))}return t[e]}(n,r,t,e);if(void 0!==o){var a="values"===n?!!r.values:"title"===n&&o===e.fieldDef(t).title||o===r[n];(a||void 0===e.config.legend[n])&&i.set(n,o,a)}});var o=r.encoding||{},a=["labels","legend","title","symbols","gradient"].reduce(function(r,a){var u=_a(o[a]||{},e),c=$a[a]?$a[a](n,u,e,t,i.get("type")):u;return void 0!==c&&oe(c).length>0&&(r[a]={update:c}),r},{});oe(a).length>0&&i.set("encode",a,!!r.encoding);return i}(e,r)),n},{})}(e):e.component.legends=function(e){for(var t=e.component,n=t.legends,r=t.resolve,i=function(t){eu(t),oe(t.component.legends).forEach(function(i){r.legend[i]=qa(e.component.resolve,i),"shared"===r.legend[i]&&(n[i]=tu(n[i],t.component.legends[i]),n[i]||(r.legend[i]="independent",delete n[i]))})},o=0,a=e.children;o1?"["+a.join(", ")+"]":a[0]}},i)]}var ou=["type","clipAngle","clipExtent","center","rotate","precision","coefficient","distance","fraction","lobes","parallel","radius","ratio","spacing","tilt"],au=function(e){function t(t,n,r,i){var o=e.call(this,x({},n),{name:t})||this;return o.specifiedProjection=n,o.size=r,o.data=i,o.merged=!1,o}return b(t,e),t}(Wa);function uu(e){Mu(e)?e.component.projection=function(e){var t=e.specifiedProjection,n=e.config;if(e.hasProjection){var r=[];return[[Ge,qe],[Be,We]].forEach(function(t){(e.channelHasField(t[0])||e.channelHasField(t[1]))&&r.push({signal:e.getName("geojson_"+r.length)})}),e.channelHasField(Xe)&&e.fieldDef(Xe).type===Yn&&r.push({signal:e.getName("geojson_"+r.length)}),0===r.length&&r.push(e.requestDataName(po)),new au(e.projectionName(!0),x({},n.projection||{},t||{}),[e.getSizeSignalRef("width"),e.getSizeSignalRef("height")],r)}return}(e):e.component.projection=function(e){if(0===e.children.length)return;var t,n=Z(e.children,function(e){uu(e);var n=e.component.projection;if(n){if(t){var r=function(e,t){var n=Z(ou,function(n){return!e.explicit.hasOwnProperty(n)&&!t.explicit.hasOwnProperty(n)||!(!e.explicit.hasOwnProperty(n)||!t.explicit.hasOwnProperty(n)||V(e.get(n))!==V(t.get(n)))});if(V(e.size)===V(t.size)){if(n)return e;if(V(e.explicit)===V({}))return t;if(V(t.explicit)===V({}))return e}return null}(t,n);return r&&(t=r),!!r}return t=n,!0}return!0});if(t&&n){var r=e.projectionName(!0),i=new au(r,t.specifiedProjection,t.size,ce(t.data));return e.children.forEach(function(e){e.component.projection&&(i.data=i.data.concat(e.component.projection.data),e.renameProjection(e.component.projection.get("name"),r),e.component.projection.merged=!0)}),i}return}(e)}var cu=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.dimensions=n,i.measures=r,i}return b(t,e),t.prototype.clone=function(){return new t(null,x({},this.dimensions),ce(this.measures))},t.makeFromEncoding=function(e,n){var r=!1;n.forEachFieldDef(function(e){e.aggregate&&(r=!0)});var i={},o={};return r?(n.forEachFieldDef(function(e,t){var r=e.aggregate,a=e.field;r?"count"===r?(i["*"]=i["*"]||{},i["*"].count=or(e)):(i[a]=i[a]||{},i[a][r]=or(e),wt(t)&&"unaggregated"===n.scaleDomain(t)&&(i[a].min=or({field:a,aggregate:"min"}),i[a].max=or({field:a,aggregate:"max"}))):function(e,t,n){n.bin?(e[or(n,{})]=!0,e[or(n,{binSuffix:"end"})]=!0,Oa(n,t)&&(e[or(n,{binSuffix:"range"})]=!0)):e[or(n)]=!0}(o,t,e)}),oe(o).length+oe(i).length===0?null:new t(e,o,i)):null},t.makeFromTransform=function(e,n){for(var r={},i={},o=0,a=n.aggregate;o0?{type:"filter",expr:t.join(" && ")}:null},t}(Ta);var fu=function(e){function t(t,n){var r=e.call(this,t)||this;return r._parse=n,r}return b(t,e),t.prototype.clone=function(){return new t(null,ce(this._parse))},t.makeExplicit=function(e,t,n){var r={},i=t.data;return i&&i.format&&i.format.parse&&(r=i.format.parse),this.makeWithAncestors(e,r,{},n)},t.makeImplicitFromFilterTransform=function(e,t,n){var r={};return function e(t,n){if(G(t))e(t.not,n);else if(W(t))for(var r=0,i=t.and;r1?e.field in r||(r[e.field]="flatten"):ir(e)&&Wo(e.sort)&&ye(e.sort.field)>1&&(e.sort.field in r||(r[e.sort.field]="flatten"))}),this.makeWithAncestors(e,{},r,n)},t.makeWithAncestors=function(e,n,r,i){for(var o=0,a=oe(r);o1}).map(function(e){var n=function(e,t){var n=he(e);return"number"===t?"toNumber("+n+")":"boolean"===t?"toBoolean("+n+")":"string"===t?"toString("+n+")":"date"===t?"toDate("+n+")":"flatten"===t?n:0===t.indexOf("date:")?"timeParse("+n+","+t.slice(5,t.length)+")":0===t.indexOf("utc:")?"utcParse("+n+","+t.slice(4,t.length)+")":(fn(Zt.unrecognizedParse(t)),null)}(e,t._parse[e]);return n?{type:"formula",expr:n,as:ve(e)}:null}).filter(function(e){return null!==e})},t}(Ta),du=function(e){function t(t){var n=e.call(this,null)||this;if(lo(t=t||{name:"source"}))n._data={values:t.values};else if(so(t)){if(n._data={url:t.url},t.format||(t.format={}),!t.format||!t.format.type){var r=/(?:\.([^.]+))?$/.exec(t.url)[1];Q(["json","csv","tsv","dsv","topojson"],r)||(r="json"),t.format.type=r}}else fo(t)&&(n._data={});if(t.name&&(n._name=t.name),t.format){var i=t.format,o=(i.parse,S(i,["parse"]));n._data.format=o}return n}return b(t,e),Object.defineProperty(t.prototype,"data",{get:function(){return this._data},enumerable:!0,configurable:!0}),t.prototype.hasName=function(){return!!this._name},Object.defineProperty(t.prototype,"dataName",{get:function(){return this._name},set:function(e){this._name=e},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"parent",{set:function(e){throw new Error("Source nodes have to be roots.")},enumerable:!0,configurable:!0}),t.prototype.remove=function(){throw new Error("Source nodes are roots and cannot be removed.")},t.prototype.hash=function(){return lo(this._data)?(this._hash||(this._hash=X(this._data)),this._hash):so(this._data)?X([this._data.url,this._data.format]):this._name},t.prototype.assemble=function(){return x({name:this._name},this._data,{transform:[]})},t}(Ta),pu=function(e){function t(t,n){var r=e.call(this,t)||this;return r.formula=n,r}return b(t,e),t.prototype.clone=function(){return new t(null,ce(this.formula))},t.makeFromEncoding=function(e,n){var r=n.reduceFieldDef(function(e,t){if(t.timeUnit){var n=or(t);e[n]={as:n,timeUnit:t.timeUnit,field:t.field}}return e},{});return 0===oe(r).length?null:new t(e,r)},t.makeFromTransform=function(e,n){var r;return new t(e,((r={})[n.field]={as:n.as,timeUnit:n.timeUnit,field:n.field},r))},t.prototype.merge=function(e){this.formula=x({},this.formula,e.formula),e.remove()},t.prototype.producedFields=function(){var e={};return ae(this.formula).forEach(function(t){e[t.as]=!0}),e},t.prototype.dependentFields=function(){var e={};return ae(this.formula).forEach(function(t){e[t.field]=!0}),e},t.prototype.assemble=function(){return ae(this.formula).map(function(e){return{type:"formula",as:e.as,expr:Fn(e.timeUnit,e.field)}})},t}(Ta);function hu(e){return function t(n){if(!(n instanceof du)){var r=n.parent;e(n)&&t(r)}}}function mu(e){var t=e.parent;if(e instanceof fu){if(t instanceof du)return!1;if(t.numChildren()>1)return!0;if(t instanceof fu)t.merge(e);else{if(ie(t.producedFields(),e.dependentFields()))return!0;e.swapWithParent()}}return!0}function gu(e){return!(e instanceof Ca||e.numChildren()>0||e instanceof su)&&(e.remove(),!0)}function vu(e){var t={};return hu(function(e){if(e instanceof pu){var n=e.producedFields();oe(n).every(function(e){return!!t[e]})?e.remove():t=x({},t,n)}return!0})(e)}var yu=function(e){function t(t,n){var r=e.call(this,t)||this;return r._stack=n,r}return b(t,e),t.prototype.clone=function(){return new t(null,ce(this._stack))},t.makeFromTransform=function(e,n){var r=n.stack,o=n.groupby,u=n.as,c=n.offset,s=void 0===c?"zero":c,l=[],f=[];if(void 0!==n.sort)for(var d=0,p=n.sort;d1}(u)?u:a(u)?[u,u+"_end"]:[n.stack+"_start",n.stack+"_end"]})},t.makeFromEncoding=function(e,n){var r,o=n.stack;if(!o)return null;o.groupbyChannel&&(r=n.fieldDef(o.groupbyChannel));var a,u=function(e){return e.stack.stackBy.reduce(function(e,t){var n=or(t.fieldDef);return n&&e.push(n),e},[])}(n),c=n.encoding.order;a=i(c)||tr(c)?Ea(c):u.reduce(function(e,t){return e.field.push(t),e.order.push("descending"),e},{field:[],order:[]});var s=n.vgField(o.fieldChannel);return new t(e,{dimensionFieldDef:r,stackField:s,facetby:[],stackby:u,sort:a,offset:o.offset,impute:o.impute,as:[s+"_start",s+"_end"]})},Object.defineProperty(t.prototype,"stack",{get:function(){return this._stack},enumerable:!0,configurable:!0}),t.prototype.addDimensions=function(e){this._stack.facetby=this._stack.facetby.concat(e)},t.prototype.dependentFields=function(){var e={};e[this._stack.stackField]=!0,this.getGroupbyFields().forEach(function(t){return e[t]=!0}),this._stack.facetby.forEach(function(t){return e[t]=!0});var t=this._stack.sort.field;return i(t)?t.forEach(function(t){return e[t]=!0}):e[t]=!0,e},t.prototype.producedFields=function(){return this._stack.as.reduce(function(e,t){return e[t]=!0,e},{})},t.prototype.getGroupbyFields=function(){var e=this._stack,t=e.dimensionFieldDef,n=e.impute,r=e.groupby;return t?t.bin?n?[or(t,{binSuffix:"mid"})]:[or(t,{}),or(t,{binSuffix:"end"})]:[or(t)]:r||[]},t.prototype.assemble=function(){var e=[],t=this._stack,n=t.facetby,r=t.dimensionFieldDef,i=t.stackField,o=t.stackby,a=t.sort,u=t.offset,c=t.impute,s=t.as;if(c&&r){var l=r?or(r,{binSuffix:"mid"}):void 0;r.bin&&e.push({type:"formula",expr:"("+or(r,{expr:"datum"})+"+"+or(r,{expr:"datum",binSuffix:"end"})+")/2",as:l}),e.push({type:"impute",field:i,groupby:o,key:l,method:"value",value:0})}return e.push({type:"stack",groupby:this.getGroupbyFields().concat(n),field:i,sort:a,as:s,offset:u}),e},t}(Ta),bu="scale_";function xu(e){if(e instanceof su)if(1!==e.numChildren()||e.children[0]instanceof Ca){!function e(t){if(t instanceof Ca&&t.type===po&&1===t.numChildren()){var n=t.children[0];n instanceof su||(n.swapWithParent(),e(t))}}(e.model.component.data.main),$(e.children.map((n=e,function e(t){if(!(t instanceof su)){var r=t.clone();if(r instanceof Ca){var i=bu+r.getSource();r.setSource(i),n.model.component.data.outputNodes[i]=r}else(r instanceof cu||r instanceof yu)&&r.addDimensions(n.fields);return $(t.children.map(e)).forEach(function(e){return e.parent=r}),[r]}return $(t.children.map(e))}))).forEach(function(t){return t.parent=e.model.component.data.main})}else{var t=e.children[0];(t instanceof cu||t instanceof yu)&&t.addDimensions(e.fields),t.swapWithParent(),xu(e)}else e.children.forEach(xu);var n}function Su(e){e instanceof lu&&Z(ae(e.filter),function(e){return null===e})&&e.remove(),e instanceof Ca&&!e.isRequired()&&e.remove(),e.children.forEach(Su)}function Eu(e){var t=[];return e.forEach(function e(n){0===n.numChildren()?t.push(n):n.children.forEach(e)}),t}function wu(e){Mu(e)?function(e){var t=e.specifiedScales,n=e.component.scales;oe(n).forEach(function(r){var i=t[r],o=i?i.domain:void 0,a=function(e,t){var n=e.getScaleComponent(t).get("type"),r=function(e,t,n,r){if("unaggregated"===e){var i=Nu(t,n),o=i.valid,a=i.reason;if(!o)return void fn(a)}else if(void 0===e&&r.useUnaggregatedDomain){var o=Nu(t,n).valid;if(o)return"unaggregated"}return e}(e.scaleDomain(t),e.fieldDef(t),n,e.config.scale);r!==e.scaleDomain(t)&&(e.specifiedScales[t]=x({},e.specifiedScales[t],{domain:r}));if("x"===t&&e.channelHasField("x2"))return e.channelHasField("x")?ku(n,r,e,"x").concat(ku(n,r,e,"x2")):ku(n,r,e,"x2");if("y"===t&&e.channelHasField("y2"))return e.channelHasField("y")?ku(n,r,e,"y").concat(ku(n,r,e,"y2")):ku(n,r,e,"y2");return ku(n,r,e,t)}(e,r),u=n[r];if(u.domains=a,yi(o)&&u.set("domainRaw",{signal:pc+X(o)},!0),e.component.data.isFaceted){for(var c=e;!Hu(c)&&c.parent;)c=c.parent;var s=c.component.resolve.scale[r];if("shared"===s)for(var l=0,f=a;l0){var r=n[0];return n.length>1&&(fn(Zt.MORE_THAN_ONE_SORT),r=!0),x({},a,{sort:r})}return a}var i=ne(n.map(function(e){return!0===e?e:"count"===e.op?e:(fn(Zt.domainSortDropped(e)),!0)}),X),o=void 0;1===i.length?o=i[0]:i.length>1&&(fn(Zt.MORE_THAN_ONE_SORT),o=!0);var a,u=ne(e.map(function(e){return Lo(e)?e.data:null}),function(e){return e});return 1===u.length&&null!==u[0]?a=x({data:u[0],fields:t.map(function(e){return e.field})},o?{sort:o}:{}):x({fields:t},o?{sort:o}:{})}(e.component.scales[t].domains.map(function(t){return Lo(t)&&(t.data=e.lookupDataSource(t.data)),t}))}function Tu(e){return oe(e.component.scales).reduce(function(t,n){var r=e.component.scales[n];if(r.merged)return t;var o=r.combine(),a=o.domainRaw,c=o.range,s=o.name,l=o.type,f=(o.domainRaw,o.range,S(o,["name","type","domainRaw","range"]));return c=function(e,t,n,r){if("x"===r||"y"===r){if(Ro(e))return{step:{signal:t+"_step"}};if(i(e)&&2===e.length){var o=e[0],a=e[1];if(0===o&&zo(a))return[0,{signal:n.getSizeName(a.signal)}];if(zo(o)&&0===a)return[{signal:n.getSizeName(o.signal)},0]}}return e}(c,s,e,n),a&&function(e){return e.signal.indexOf(pc)>=0}(a)&&(a=function(e,t){var n=JSON.parse(t.signal.replace(pc,"")),r=le(n.selection),i=e.component.selection&&e.component.selection[r];if(!i)return i=e.getSelectionComponent(r,n.selection),n.encoding||n.field||(n.field=i.project[0].field,i.project.length>1&&fn('A "field" or "encoding" must be specified when using a selection as a scale domain. Using "field": '+u(n.field)+".")),{signal:vc(i.type).scaleDomain+"("+u(r+lc)+", "+u(n.encoding||null)+", "+u(n.field||null)+("global"===i.resolve?")":", "+u(i.resolve)+")")};fn('Use "bind": "scales" to setup a binding for scales and selections within the same view.');return{signal:"null"}}(e,a)),t.push(x({name:s,type:l,domain:_u(e,n)},a?{domainRaw:a}:{},{range:c},f)),t},[])}var Cu=function(e){function t(t,n){var r=e.call(this,{},{name:t})||this;return r.merged=!1,r.domains=[],r.setWithExplicit("type",n),r}return b(t,e),t}(Wa),Au=["range","rangeStep","scheme"];function Du(e){Mu(e)?function(e){var t=e.component.scales;Et.forEach(function(n){var r=t[n];if(r){var i=e.getScaleComponent(n),o=e.specifiedScales[n],a=e.fieldDef(n),u="x"===n?"width":"y"===n?"height":void 0,c=u?!!e.component.layoutSize.get(u):void 0,s=i.get("type"),l=Q(["point","band"],s)||!!o.rangeStep;u&&e.fit&&!c&&l&&(fn(Zt.CANNOT_FIX_RANGE_STEP_WITH_FIT),c=!0);var f=function(e){var t=[],n=e.getScaleComponent("x"),r=n&&n.get("range");r&&Ro(r)&&g(r.step)&&t.push(r.step);var i=e.getScaleComponent("y"),o=i&&i.get("range");o&&Ro(o)&&g(o.step)&&t.push(o.step);return t}(e),d=function(e,t,n,r,i,o,a,u,c,s){for(var l=u||null===r.rangeStep,f=0,d=Au;f0?Math.min.apply(null,e):t.rangeStep?t.rangeStep:21}function Ru(e,t){Mu(e)?function(e,t){var n=e.component.scales;oe(n).forEach(function(r){var i=e.specifiedScales[r],o=n[r],a=e.getScaleComponent(r),u=e.fieldDef(r),c=e.config,s=i[t],l=a.get("type"),f=wi(l,t),d=ki(r,t);if(void 0!==s&&(f?d&&fn(d):fn(Zt.scalePropertyNotWorkWithScaleType(l,t,r))),f&&void 0===d)if(void 0!==s)o.copyKeyFromObject(t,i);else{var p=function(e,t,n,r,i,o,a,u,c){var s=c.scale;switch(e){case"nice":return function(e,t,n){if(n.bin||Q([Br.TIME,Br.UTC],e))return;return Q([Ue,Pe],t)}(r,t,n);case"padding":return function(e,t,n,r,i,o){if(Q([Ue,Pe],e)){if(mi(t)){if(void 0!==n.continuousPadding)return n.continuousPadding;var a=i.type,u=i.orient;if("bar"===a&&!r.bin&&("vertical"===u&&"x"===e||"horizontal"===u&&"y"===e))return o.continuousBandSize}if(t===Br.POINT)return n.pointPadding}return}(t,r,s,n,u,c.bar);case"paddingInner":return function(e,t,n){if(void 0!==e)return;if(Q([Ue,Pe],t))return n.bandPaddingInner;return}(i,t,s);case"paddingOuter":return function(e,t,n,r,i){if(void 0!==e)return;if(Q([Ue,Pe],t)&&n===Br.BAND)return void 0!==i.bandPaddingOuter?i.bandPaddingOuter:r/2;return}(i,t,r,o,s);case"reverse":return function(e,t){if(hi(e)&&"descending"===t)return!0;return}(r,n.sort);case"zero":return function(e,t,n,r){if(n&&"unaggregated"!==n)return!1;if("size"===e&&"quantitative"===t.type)return!0;if(!t.bin&&Q([Ue,Pe],e)){var i=r.orient,o=r.type;return!Q(["bar","area","line","trail"],o)||!("horizontal"===i&&"y"===e||"vertical"===i&&"x"===e)}return!1}(t,n,a,u)}return s[e]}(t,r,u,a.get("type"),a.get("padding"),a.get("paddingInner"),i.domain,e.markDef,c);void 0!==p&&o.set(t,p,!1)}})}(e,t):Lu(e,t)}function Lu(e,t){for(var n=e.component.scales,r=0,i=e.children;r0?e:void 0},e.prototype.assembleGroup=function(e){void 0===e&&(e=[]);var t={};(e=e.concat(this.assembleSelectionSignals())).length>0&&(t.signals=e);var n=this.assembleLayout();n&&(t.layout=n),t.marks=[].concat(this.assembleHeaderMarks(),this.assembleMarks());var r=!this.parent||Hu(this.parent)?function e(t){return Gu(t)||Wu(t)||qu(t)?t.children.reduce(function(t,n){return t.concat(e(n))},Tu(t)):Tu(t)}(this):[];r.length>0&&(t.scales=r);var i=this.assembleAxes();i.length>0&&(t.axes=i);var o=this.assembleLegends();return o.length>0&&(t.legends=o),t},e.prototype.hasDescendantWithFieldOnChannel=function(e){for(var t=0,n=this.children;t=0&&(s=!0)}),s||n.splice(c+1,0,u),n}};function $u(e,t){var n=t.project,r=Zu.has(t)?"(item().isVoronoi ? datum.datum : datum)":"datum",i=[],o=n.map(function(e){return u(e.channel)}).filter(function(e){return e}).join(", "),a=n.map(function(e){return u(e.field)}).join(", "),c=n.map(function(t){var n=t.channel,o=e.fieldDef(n);return o&&o.bin?(i.push(t.field),"["+he(e.vgField(n,{}),r)+", "+he(e.vgField(n,{binSuffix:"end"}),r)+"]"):""+he(t.field,r)}).join(", ");return[{name:t.name+fc,value:{},on:[{events:t.events,update:"datum && item().mark.marktype !== 'group' ? {unit: "+bc(e)+", encodings: ["+o+"], fields: ["+a+"], values: ["+c+"]"+(i.length?", "+i.map(function(e){return u("bin_"+e)+": 1"}).join(", "):"")+"} : null",force:!0}]}]}var ec={predicate:"vlMulti",scaleDomain:"vlMultiDomain",signals:$u,modifyExpr:function(e,t){return t.name+fc+", "+("global"===t.resolve?"null":"{unit: "+bc(e)+"}")}},tc={predicate:"vlSingle",scaleDomain:"vlSingleDomain",signals:$u,topLevelSignals:function(e,t,n){var r=n.filter(function(e){return e.name===t.name}),i="data("+u(t.name+lc)+")",o=i+"[0].values";return r.length?n:n.concat({name:t.name,update:i+".length && {"+t.project.map(function(e,t){return e.field+": "+o+"["+t+"]"}).join(", ")+"}"})},modifyExpr:function(e,t){return t.name+fc+", "+("global"===t.resolve?"true":"{unit: "+bc(e)+"}")}},nc="_translate_anchor",rc="_translate_delta";function ic(e,t,n,r,i){var o=t.name,a=Vu.has(t),u=i.filter(function(e){return e.name===Sc(t,n,a?"data":"visual")})[0],c=o+nc,s=o+rc,l=e.getSizeSignalRef(r).signal,f=e.getScaleComponent(n),d=f.get("type"),p=c+".extent_"+n,h=(a?"log"===d?"panLog":"pow"===d?"panPow":"panLinear":"panLinear")+"("+p+", "+(""+(a&&n===Ue?"-":"")+s+"."+n+" / "+(a?""+l:"span("+p+")"))+(a&&"pow"===d?", "+(f.get("exponent")||1):"")+")";u.on.push({events:{signal:s},update:a?h:"clampRange("+h+", 0, "+l+")"})}var oc="_zoom_anchor",ac="_zoom_delta";function uc(e,t,n,r,i){var o=t.name,a=Vu.has(t),u=i.filter(function(e){return e.name===Sc(t,n,a?"data":"visual")})[0],c=e.getSizeSignalRef(r).signal,s=e.getScaleComponent(n),l=s.get("type"),f=a?Xu(e,n):u.name,d=o+ac,p=(a?"log"===l?"zoomLog":"pow"===l?"zoomPow":"zoomLinear":"zoomLinear")+"("+f+", "+(""+o+oc+"."+n)+", "+d+(a&&"pow"===l?", "+(s.get("exponent")||1):"")+")";u.on.push({events:{signal:d},update:a?p:"clampRange("+p+", 0, "+c+")"})}var cc={project:{has:function(e){var t=e;return void 0!==t.fields||void 0!==t.encodings},parse:function(e,t,n){var r={},i={};(t.fields||[]).forEach(function(e){return r[e]=null}),(t.encodings||[]).forEach(function(t){var n=e.fieldDef(t);if(n)if(n.timeUnit){var o=e.vgField(t);r[o]=t,i[o]={as:o,field:n.field,timeUnit:n.timeUnit}}else r[n.field]=t;else fn(Zt.cannotProjectOnChannelWithoutField(t))});var o=n.project||(n.project=[]);for(var a in r)r.hasOwnProperty(a)&&o.push({field:a,channel:r[a]});var u=n.fields||(n.fields={});o.filter(function(e){return e.channel}).forEach(function(e){return u[e.channel]=e.field}),oe(i).length&&(n.timeUnit=new pu(null,i))}},toggle:{has:function(e){return"multi"===e.type&&e.toggle},signals:function(e,t,n){return n.concat({name:t.name+"_toggle",value:!1,on:[{events:t.events,update:t.toggle}]})},modifyExpr:function(e,t,n){var r=t.name+fc,i=t.name+"_toggle";return i+" ? null : "+r+", "+("global"===t.resolve?i+" ? null : true, ":i+" ? null : {unit: "+bc(e)+"}, ")+i+" ? "+r+" : null"}},scales:Vu,translate:{has:function(e){return"interval"===e.type&&e.translate},signals:function(e,t,n){var r=t.name,i=Vu.has(t),o=r+nc,a=Ec(t),u=a.x,c=a.y,s=go(t.translate,"scope");return i||(s=s.map(function(e){return e.between[0].markname=r+"_brush",e})),n.push({name:o,value:{},on:[{events:s.map(function(e){return e.between[0]}),update:"{x: x(unit), y: y(unit)"+(null!==u?", extent_x: "+(i?Xu(e,Ue):"slice("+Sc(t,"x","visual")+")"):"")+(null!==c?", extent_y: "+(i?Xu(e,Pe):"slice("+Sc(t,"y","visual")+")"):"")+"}"}]},{name:r+rc,value:{},on:[{events:s,update:"{x: "+o+".x - x(unit), y: "+o+".y - y(unit)}"}]}),null!==u&&ic(e,t,Ue,"width",n),null!==c&&ic(e,t,Pe,"height",n),n}},zoom:{has:function(e){return"interval"===e.type&&e.zoom},signals:function(e,t,n){var r=t.name,i=Vu.has(t),o=r+ac,a=Ec(t),c=a.x,s=a.y,l=u(e.scaleName(Ue)),f=u(e.scaleName(Pe)),d=go(t.zoom,"scope");return i||(d=d.map(function(e){return e.markname=r+"_brush",e})),n.push({name:r+oc,on:[{events:d,update:i?"{"+[l?"x: invert("+l+", x(unit))":"",f?"y: invert("+f+", y(unit))":""].filter(function(e){return!!e}).join(", ")+"}":"{x: x(unit), y: y(unit)}"}]},{name:o,on:[{events:d,force:!0,update:"pow(1.001, event.deltaY * pow(16, event.deltaMode))"}]}),null!==c&&uc(e,t,"x","width",n),null!==s&&uc(e,t,"y","height",n),n}},inputs:{has:function(e){return"single"===e.type&&"global"===e.resolve&&e.bind&&"scales"!==e.bind},topLevelSignals:function(e,t,n){var r=t.name,i=t.project,o=t.bind,a=Zu.has(t)?"(item().isVoronoi ? datum.datum : datum)":"datum";return i.forEach(function(e){var i=le(r+"_"+e.field);n.filter(function(e){return e.name===i}).length||n.unshift({name:i,value:"",on:[{events:t.events,update:"datum && item().mark.marktype !== 'group' ? "+he(e.field,a)+" : null"}],bind:o[e.field]||o[e.channel]||o})}),n},signals:function(e,t,n){var r=t.name,i=t.project,o=n.filter(function(e){return e.name===r+fc})[0],a=i.map(function(e){return u(e.field)}).join(", "),c=i.map(function(e){return le(r+"_"+e.field)});return c.length&&(o.update=c.join(" && ")+" ? {fields: ["+a+"], values: ["+c.join(", ")+"]} : null"),delete o.value,delete o.on,n}},nearest:Zu};function sc(e,t){for(var n in cc)cc[n].has(e)&&t(cc[n])}var lc="_store",fc="_tuple",dc="_modify",pc="_selection_domain_";function hc(e,t){return gc(e,function(n,r){t=r.marks?r.marks(e,n,t):t,sc(n,function(r){r.marks&&(t=r.marks(e,n,t))})}),t}function mc(e,t,n){var r=[];var i=fe(t,function(t){var i=le(t),o=e.getSelectionComponent(i,t),a=u(i+lc);if(o.timeUnit){var c=n||e.component.data.raw,s=o.timeUnit.clone();c.parent?s.insertAsParentOf(c):c.parent=s}return"none"!==o.empty&&r.push(a),vc(o.type).predicate+"("+a+", datum"+("global"===o.resolve?")":", "+u(o.resolve)+")")});return(r.length?"!("+r.map(function(e){return"length(data("+e+"))"}).join(" || ")+") || ":"")+"("+i+")"}function gc(e,t){var n=e.component.selection;for(var r in n)if(n.hasOwnProperty(r)){var i=n[r];t(i,vc(i.type))}}function vc(e){switch(e){case"single":return tc;case"multi":return ec;case"interval":return Ku}return null}function yc(e){for(var t=e.parent;t&&!Hu(t);)t=t.parent;return t}function bc(e){var t=u(e.name),n=yc(e);return n&&(t+=(n.facet.row?" + '_' + ("+he(n.vgField("row"),"facet")+")":"")+(n.facet.column?" + '_' + ("+he(n.vgField("column"),"facet")+")":"")),t}function xc(e){var t=!1;return gc(e,function(e){t=t||e.project.some(function(e){return e.field===Ci})}),t}function Sc(e,t,n){var r=e._signalNames||(e._signalNames={});if(r[t]&&r[t][n])return r[t][n];r[t]=r[t]||{};for(var i=le(e.name+"_"+("visual"===n?t:e.fields[t])),o=i,a=1;r[o];)o=i+"_"+a++;return r[o]=r[t][n]=o}function Ec(e){var t=null,n=null,r=null,i=null;return e.project.forEach(function(e,o){e.channel===Ue?(t=e,n=o):e.channel===Pe&&(r=e,i=o)}),{x:t,xi:n,y:r,yi:i}}function wc(e){return e&&!!e.field&&void 0!==e.equal}function kc(e){return e&&!!e.field&&void 0!==e.lt}function Nc(e){return e&&!!e.field&&void 0!==e.lte}function Oc(e){return e&&!!e.field&&void 0!==e.gt}function _c(e){return e&&!!e.field&&void 0!==e.gte}function Tc(e){return!!(e&&e.field&&i(e.range)&&2===e.range.length)}function Cc(e){return e&&!!e.field&&(i(e.oneOf)||i(e.in))}function Ac(e){return Cc(e)||wc(e)||Tc(e)||kc(e)||Oc(e)||Nc(e)||_c(e)}function Dc(e,t,n){return fe(t,function(t){return a(t)?t:function(e){return e&&e.selection}(t)?mc(e,t.selection,n):zc(t)})}function Ic(e,t){return Nr(e,{timeUnit:t,time:!0})}function zc(e,t){void 0===t&&(t=!0);var n=e.field,r=e.timeUnit,i=r?"time("+Fn(r,n)+")":or(e,{expr:"datum"});if(wc(e))return i+"==="+Ic(e.equal,r);if(kc(e))return i+"<"+Ic(u=e.lt,r);if(Oc(e))return i+">"+Ic(a=e.gt,r);if(Nc(e))return i+"<="+Ic(u=e.lte,r);if(_c(e))return i+">="+Ic(a=e.gte,r);if(Cc(e)){var o=e.oneOf;return"indexof(["+function(e,t){return e.map(function(e){return Ic(e,t)})}(o=o||e.in,r).join(",")+"], "+i+") !== -1"}if(Tc(e)){var a=e.range[0],u=e.range[1];if(null!==a&&null!==u&&t)return"inrange("+i+", ["+Ic(a,r)+", "+Ic(u,r)+"])";var c=[];return null!==a&&c.push(i+" >= "+Ic(a,r)),null!==u&&c.push(i+" <= "+Ic(u,r)),c.length>0?c.join(" && "):"true"}throw new Error("Invalid field predicate: "+JSON.stringify(e))}function Rc(e){return Ac(e)&&e.timeUnit?x({},e,{timeUnit:Un(e.timeUnit)}):e}function Lc(e){return void 0!==e.filter}function Fc(e){return void 0!==e.lookup}function jc(e){return void 0!==e.window}function Uc(e){return void 0!==e.calculate}function Pc(e){return!!e.bin}function Mc(e){return void 0!==e.timeUnit}function Hc(e){return void 0!==e.aggregate}function qc(e){return void 0!==e.stack}function Wc(e){return e.map(function(e){return Lc(e)?{filter:function e(t,n){return G(t)?{not:e(t.not,n)}:W(t)?{and:t.and.map(function(t){return e(t,n)})}:q(t)?{or:t.or.map(function(t){return e(t,n)})}:n(t)}(e.filter,Rc)}:e})}var Gc=Object.freeze({isFilter:Lc,isLookup:Fc,isWindow:jc,isCalculate:Uc,isBin:Pc,isTimeUnit:Mc,isAggregate:Hc,isStack:qc,normalizeTransform:Wc});function Bc(e,t){var n;n=function(e){return"as"in e}(e)?a(e.as)?[e.as,e.as+"_end"]:[e.as[0],e.as[1]]:[or(e,{}),or(e,{binSuffix:"end"})];var r=xr(e.bin,void 0)||{},i=function(e,t){return Tt(e)+"_"+t}(r,e.field),o=function(e,t){return{signal:e.getName(t+"_bins"),extentSignal:e.getName(t+"_extent")}}(t,i),u=o.signal,c=o.extentSignal;return{key:i,binComponent:x({bin:r,field:e.field,as:n},u?{signal:u}:{},c?{extentSignal:c}:{})}}var Yc=function(e){function t(t,n){var r=e.call(this,t)||this;return r.bins=n,r}return b(t,e),t.prototype.clone=function(){return new t(null,ce(this.bins))},t.makeFromEncoding=function(e,n){var r=n.reduceFieldDef(function(e,t,r){if(t.bin){var i=Bc(t,n),o=i.key,a=i.binComponent;e[o]=x({},a,e[o],function(e,t,n,r){if(Oa(t,n)){var i=Mu(e)&&(e.axis(n)||e.legend(n))||{},o=or(t,{expr:"datum"}),a=or(t,{expr:"datum",binSuffix:"end"});return{formulaAs:or(t,{binSuffix:"range"}),formula:xa(o,a,i.format,r)}}return{}}(n,t,r,n.config))}return e},{});return 0===oe(r).length?null:new t(e,r)},t.makeFromTransform=function(e,n,r){var i,o=Bc(n,r),a=o.key,u=o.binComponent;return new t(e,((i={})[a]=u,i))},t.prototype.merge=function(e){this.bins=x({},this.bins,e.bins),e.remove()},t.prototype.producedFields=function(){var e={};return ae(this.bins).forEach(function(t){t.as.forEach(function(t){return e[t]=!0})}),e},t.prototype.dependentFields=function(){var e={};return ae(this.bins).forEach(function(t){e[t.field]=!0}),e},t.prototype.assemble=function(){return $(ae(this.bins).map(function(e){var t=[],n=x({type:"bin",field:e.field,as:e.as,signal:e.signal},e.bin);return!e.bin.extent&&e.extentSignal&&(t.push({type:"extent",field:e.field,signal:e.extentSignal}),n.extent={signal:e.extentSignal}),t.push(n),e.formula&&t.push({type:"formula",expr:e.formula,as:e.formulaAs}),t}))},t}(Ta),Vc=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.model=n,i.filter=r,i.expr=Dc(i.model,i.filter,i),i}return b(t,e),t.prototype.clone=function(){return new t(null,this.model,ce(this.filter))},t.prototype.assemble=function(){return{type:"filter",expr:this.expr}},t}(Ta),Xc=function(e){function t(t,n,r,i){var o=e.call(this,t)||this;return o.fields=n,o.geojson=r,o.signal=i,o}return b(t,e),t.prototype.clone=function(){return new t(null,ce(this.fields),this.geojson,this.signal)},t.parseAll=function(e,n){var r=0;if([[Ge,qe],[Be,We]].forEach(function(i){var o=i.map(function(e){return n.channelHasField(e)?n.fieldDef(e).field:void 0});(o[0]||o[1])&&(e=new t(e,o,null,n.getName("geojson_"+r++)))}),n.channelHasField(Xe)){var i=n.fieldDef(Xe);i.type===Yn&&(e=new t(e,null,i.field,n.getName("geojson_"+r++)))}return e},t.prototype.assemble=function(){return x({type:"geojson"},this.fields?{fields:this.fields}:{},this.geojson?{geojson:this.geojson}:{},{signal:this.signal})},t}(Ta),Qc=function(e){function t(t,n,r,i){var o=e.call(this,t)||this;return o.projection=n,o.fields=r,o.as=i,o}return b(t,e),t.prototype.clone=function(){return new t(null,this.projection,ce(this.fields),ce(this.as))},t.parseAll=function(e,n){return n.projectionName()?([[Ge,qe],[Be,We]].forEach(function(r){var i=r.map(function(e){return n.channelHasField(e)?n.fieldDef(e).field:void 0}),o=r[0]===Be?"2":"";(i[0]||i[1])&&(e=new t(e,n.projectionName(),i,[n.getName("x"+o),n.getName("y"+o)]))}),e):e},t.prototype.assemble=function(){return{type:"geopoint",projection:this.projection,fields:this.fields,as:this.as}},t}(Ta),Kc=function(e){function t(t){return e.call(this,t)||this}return b(t,e),t.prototype.clone=function(){return new t(null)},t.prototype.producedFields=function(){var e;return(e={})[Ci]=!0,e},t.prototype.assemble=function(){return{type:"identifier",as:Ci}},t}(Ta),Jc=function(e){function t(t,n,r){void 0===t&&(t={}),void 0===n&&(n={}),void 0===r&&(r=!1);var i=e.call(this,t,n)||this;return i.explicit=t,i.implicit=n,i.parseNothing=r,i}return b(t,e),t.prototype.clone=function(){var t=e.prototype.clone.call(this);return t.parseNothing=this.parseNothing,t},t}(Wa),Zc=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.transform=n,i.secondary=r,i}return b(t,e),t.make=function(e,n,r,i){var o=n.component.data.sources,a=new du(r.from.data),u=o[a.hash()];u||(o[a.hash()]=a,u=a);var c=n.getName("lookup_"+i),s=new Ca(u,c,"lookup",n.component.data.outputNodeRefCounts);return n.component.data.outputNodes[c]=s,new t(e,r,s.getSource())},t.prototype.producedFields=function(){return v(this.transform.from.fields||(this.transform.as instanceof Array?this.transform.as:[this.transform.as]))},t.prototype.assemble=function(){var e;if(this.transform.from.fields)e=x({values:this.transform.from.fields},this.transform.as?{as:this.transform.as instanceof Array?this.transform.as:[this.transform.as]}:{});else{var t=this.transform.as;a(t)||(fn(Zt.NO_FIELDS_NEEDS_AS),t="_lookup"),e={as:[t]}}return x({type:"lookup",from:this.secondary,key:this.transform.from.key,fields:[this.transform.lookup]},e,this.transform.default?{default:this.transform.default}:{})},t}(Ta);function $c(e){var t=0;return function n(r,i){r instanceof du&&(so(r.data)||(e.push(i),i={name:null,source:i.name,transform:[]}));if(r instanceof fu&&(r.parent instanceof du&&!i.source?(i.format=x({},i.format||{},{parse:r.assembleFormatParse()}),i.transform=i.transform.concat(r.assembleTransforms(!0))):i.transform=i.transform.concat(r.assembleTransforms())),r instanceof su)return i.name||(i.name="data_"+t++),!i.source||i.transform.length>0?(e.push(i),r.data=i.name):r.data=i.source,void r.assemble().forEach(function(t){return e.push(t)});(r instanceof Vc||r instanceof Aa||r instanceof Qc||r instanceof Xc||r instanceof cu||r instanceof Zc||r instanceof fs||r instanceof Kc)&&i.transform.push(r.assemble()),(r instanceof lu||r instanceof Yc||r instanceof pu||r instanceof yu)&&(i.transform=i.transform.concat(r.assemble())),r instanceof cu&&(i.name||(i.name="data_"+t++)),r instanceof Ca&&(i.source&&0===i.transform.length?r.setSource(i.source):r.parent instanceof Ca?r.setSource(i.name):(i.name||(i.name="data_"+t++),r.setSource(i.name),1===r.numChildren()&&(e.push(i),i={name:null,source:i.name,transform:[]})));switch(r.numChildren()){case 0:r instanceof Ca&&(!i.source||i.transform.length>0)&&e.push(i);break;case 1:n(r.children[0],i);break;default:i.name||(i.name="data_"+t++);var o=i.name;!i.source||i.transform.length>0?e.push(i):o=i.source,r.children.forEach(function(e){n(e,{name:null,source:o,transform:[]})})}}}function es(e){ns(e);var t=e.component.layoutSize;t.setWithExplicit("width",rs(e,"width")),t.setWithExplicit("height",rs(e,"height"))}var ts=es;function ns(e){for(var t=0,n=e.children;t0?{data:t}:{},n?{encode:{update:n}}:{},e.assembleGroup())]},t.prototype.getMapping=function(){return this.facet},t}(Yu),fs=function(e){function t(t,n){var r=e.call(this,t)||this;return r.transform=n,r}return b(t,e),t.makeFromFacet=function(e,n){var r=n.row,i=n.column;if(r&&i){for(var o=null,a=0,u=[r,i];a0&&(t=function(e,t,n){var r=0;return t.transforms.forEach(function(i){if(Uc(i))e=new Aa(e,i),n.set(i.as,"derived",!1);else if(Lc(i))e=fu.makeImplicitFromFilterTransform(e,i,n)||e,e=new Vc(e,t,i.filter);else if(Pc(i))for(var o=e=Yc.makeFromTransform(e,i,t),a=0,u=oe(o.producedFields());a0&&(n[o]={update:u}),n},{});oe(o).length>0&&r.set("encode",o,!!n.encoding||void 0!==n.labelAngle);return r}(n,e)]),t},{})}var bs={bottom:"top",top:"bottom",left:"right",right:"left"};function xs(e,t){if(!e)return t.map(function(e){return e.clone()});if(e.length===t.length){for(var n=e.length,r=0;r0?Ts:""});var r,o;return t.length>0?[{name:e.getName("pathgroup"),type:"group",from:{facet:{name:Ts+e.requestDataName(po),data:e.requestDataName(po),groupby:t}},encode:{update:{width:{field:{group:"width"}},height:{field:{group:"height"}}}},marks:n}]:n}(e):Cs(e)}var Ts="faceted_path_";function Cs(e,t){void 0===t&&(t={fromPrefix:""});var n=e.mark,r=void 0!==e.markDef.clip?!!e.markDef.clip:function(e){var t=e.getScaleComponent("x"),n=e.getScaleComponent("y");return!!(t&&t.get("domainRaw")||n&&n.get("domainRaw"))}(e),o=pa(e.markDef),a=e.encoding.key,u=function(e){var t=e.encoding,n=e.stack,r=e.mark,o=e.markDef,a=t.order;if(i(a)||!rr(a)){if((i(a)||tr(a))&&!n)return Ea(a,{expr:"datum"});if(Yt(r)){var u=t["horizontal"===o.orient?"y":"x"];if(tr(u)){var c=u.sort;return{field:Wo(c)?or({aggregate:Cr(e.encoding)?c.op:void 0,field:c.field},{expr:"datum"}):or(u,{binSuffix:e.stack&&e.stack.impute?"mid":void 0,expr:"datum"}),order:"descending"}}}}}(e),c=Os[n].postEncodingTransform?Os[n].postEncodingTransform(e):null;return[x({name:e.getName("marks"),type:Os[n].vgMark},r?{clip:!0}:{},o?{style:o}:{},a?{key:{field:a.field}}:{},u?{sort:u}:{},{from:{data:t.fromPrefix+e.requestDataName(po)},encode:{update:Os[n].encodeEntry(e)}},c?{transform:c}:{})]}var As=function(e){function t(t,n,r,i,o,a,u){void 0===i&&(i={});var c=e.call(this,t,n,r,a,o,void 0)||this;c.fit=u,c.type="unit",c.specifiedScales={},c.specifiedAxes={},c.specifiedLegends={},c.specifiedProjection={},c.selection={},c.children=[],c.initSize(x({},i,t.width?{width:t.width}:{},t.height?{height:t.height}:{}));var s=Xt(t.mark)?t.mark.type:t.mark,l=c.encoding=Ar(function(e,t){return cs(e,t)}(t.encoding||{},o),s);return c.markDef=ws(t.mark,l,a),c.stack=Gi(s,l,c.config.stack),c.specifiedScales=c.initScales(s,l),c.specifiedAxes=c.initAxes(l),c.specifiedLegends=c.initLegend(l),c.specifiedProjection=t.projection,c.selection=t.selection,c}return b(t,e),Object.defineProperty(t.prototype,"hasProjection",{get:function(){var e=this.encoding,t=this.mark===qt,n=e&&ut.some(function(t){return tr(e[t])});return t||n},enumerable:!0,configurable:!0}),t.prototype.scaleDomain=function(e){var t=this.specifiedScales[e];return t?t.domain:void 0},t.prototype.axis=function(e){return this.specifiedAxes[e]},t.prototype.legend=function(e){return this.specifiedLegends[e]},t.prototype.initScales=function(e,t){return Et.reduce(function(e,n){var r,i,o=t[n];return tr(o)?(r=o,i=o.scale):$n(o)?(r=o.condition,i=o.condition.scale):"x"===n?r=vr(t.x2):"y"===n&&(r=vr(t.y2)),r&&(e[n]=i||{}),e},{})},t.prototype.initAxes=function(e){return[Ue,Pe].reduce(function(t,n){var r=e[n];if(tr(r)||n===Ue&&tr(e.x2)||n===Pe&&tr(e.y2)){var i=tr(r)?r.axis:null;null!==i&&!1!==i&&(t[n]=x({},i))}return t},{})},t.prototype.initLegend=function(e){return xt.reduce(function(t,n){var r=e[n];if(r){var i=tr(r)?r.legend:$n(r)?r.condition.legend:null;null!==i&&!1!==i&&(t[n]=x({},i))}return t},{})},t.prototype.parseData=function(){this.component.data=ds(this)},t.prototype.parseLayoutSize=function(){!function(e){var t=e.component.layoutSize;if(!t.explicit.width){var n=is(e,"width");t.set("width",n,!1)}if(!t.explicit.height){var r=is(e,"height");t.set("height",r,!1)}}(this)},t.prototype.parseSelection=function(){this.component.selection=function(e,t){var n={},r=e.config.selection,i=function(i){if(!t.hasOwnProperty(i))return"continue";var o=t[i],u=r[o.type];for(var c in u)"encodings"===c&&o.fields||"fields"===c&&o.encodings||("mark"===c&&(o[c]=x({},u[c],o[c])),void 0!==o[c]&&!0!==o[c]||(o[c]=u[c]||o[c]));i=le(i);var s=n[i]=x({},o,{name:i,events:a(o.on)?go(o.on,"scope"):o.on});sc(s,function(t){t.parse&&t.parse(e,o,s)})};for(var o in t)i(o);return n}(this,this.selection)},t.prototype.parseMarkGroup=function(){this.component.mark=_s(this)},t.prototype.parseAxisAndHeader=function(){this.component.axes=ys(this)},t.prototype.assembleSelectionTopLevelSignals=function(e){return n=e,r=!1,gc(t=this,function(e,i){i.topLevelSignals&&(n=i.topLevelSignals(t,e,n)),sc(e,function(r){r.topLevelSignals&&(n=r.topLevelSignals(t,e,n))}),r=!0}),r&&(n.filter(function(e){return"unit"===e.name}).length||n.unshift({name:"unit",value:{},on:[{events:"mousemove",update:"isTuple(group()) ? group() : unit"}]})),n;var t,n,r},t.prototype.assembleSelectionSignals=function(){return function(e,t){gc(e,function(n,r){var i=n.name,o=r.modifyExpr(e,n);t.push.apply(t,r.signals(e,n)),sc(n,function(r){r.signals&&(t=r.signals(e,n,t)),r.modifyExpr&&(o=r.modifyExpr(e,n,o))}),t.push({name:i+dc,on:[{events:{signal:i+fc},update:"modify("+u(n.name+lc)+", "+o+")"}]})});var n=yc(e);if(t.length&&n){var r=u(n.getName("cell"));t.unshift({name:"facet",value:{},on:[{events:go("mousemove","scope"),update:"isTuple(facet) ? facet : group("+r+").datum"}]})}return t}(this,[])},t.prototype.assembleSelectionData=function(e){return function(e,t){return gc(e,function(e){t.filter(function(t){return t.name===e.name+lc}).length||t.push({name:e.name+lc})}),t}(this,e)},t.prototype.assembleLayout=function(){return null},t.prototype.assembleLayoutSignals=function(){return Ua(this)},t.prototype.assembleMarks=function(){var e=this.component.mark||[];return this.parent&&Gu(this.parent)||(e=hc(this,e)),e.map(this.correctDataNames)},t.prototype.assembleLayoutSize=function(){return{width:this.getSizeSignalRef("width"),height:this.getSizeSignalRef("height")}},t.prototype.getMapping=function(){return this.encoding},t.prototype.toSpec=function(e,t){var n,r=ce(this.encoding);return n={mark:this.markDef,encoding:r},e||(n.config=ce(this.config)),t||(n.data=ce(this.data)),n},Object.defineProperty(t.prototype,"mark",{get:function(){return this.markDef.type},enumerable:!0,configurable:!0}),t.prototype.channelHasField=function(e){return Tr(this.encoding,e)},t.prototype.fieldDef=function(e){return vr(this.encoding[e])},t}(Yu),Ds=function(e){function t(n,r,i,o,a,u,c){var s=e.call(this,n,r,i,u,a,n.resolve)||this;s.type="layer";var l=x({},o,n.width?{width:n.width}:{},n.height?{height:n.height}:{});return s.initSize(l),s.children=n.layer.map(function(e,n){if(Xi(e))return new t(e,s,s.getName("layer_"+n),l,a,u,c);if(Vi(e))return new As(e,s,s.getName("layer_"+n),l,a,u,c);throw new Error(Zt.INVALID_SPEC)}),s}return b(t,e),t.prototype.parseData=function(){this.component.data=ds(this);for(var e=0,t=this.children;e0&&!x){var S=bs[b];i[b]>i[S]&&v.set("orient",S,!1)}i[b]++}}delete h.component.axes[s]}}}}(this)},t.prototype.assembleSelectionTopLevelSignals=function(e){return this.children.reduce(function(e,t){return t.assembleSelectionTopLevelSignals(e)},e)},t.prototype.assembleSelectionSignals=function(){return this.children.reduce(function(e,t){return e.concat(t.assembleSelectionSignals())},[])},t.prototype.assembleLayoutSignals=function(){return this.children.reduce(function(e,t){return e.concat(t.assembleLayoutSignals())},Ua(this))},t.prototype.assembleSelectionData=function(e){return this.children.reduce(function(e,t){return t.assembleSelectionData(e)},e)},t.prototype.assembleTitle=function(){var t=e.prototype.assembleTitle.call(this);if(t)return t;for(var n=0,r=this.children;n0})).forEach(hu(gu)),Eu(i=i.filter(function(e){return e.numChildren()>0})).forEach(hu(mu)),Eu(i).forEach(vu),i.forEach(xu),oe(r.sources).forEach(function(e){0===r.sources[e].numChildren()&&delete r.sources[e]}),function(e,t){var n=e.config?ji(e.config):void 0,r=[].concat(e.assembleSelectionData([]),function(e,t){var n=ae(e.sources),r=[],i=$c(r),o=0;n.forEach(function(e){e.hasName()||(e.dataName="source_"+o++);var t=e.assemble();i(e,t)}),r.forEach(function(e){0===e.transform.length&&delete e.transform});for(var a=0,u=0;u0?{projections:i}:{},e.assembleGroup(u.concat(e.assembleSelectionTopLevelSignals([]))),n?{config:n}:{})}}(c,function(e,t,n){return x({autosize:1===oe(n).length&&n.type?n.type:n},co(t),co(e))}(e,o,u))}finally{t.logger&&(ln=sn),t.fieldTitle&&hr()}},Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file diff --git a/build/vega-lite.min.js.map b/build/vega-lite.min.js.map new file mode 100644 index 0000000000..26d03db501 --- /dev/null +++ b/build/vega-lite.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../node_modules/vega-util/src/accessor.js","../node_modules/vega-util/src/error.js","../node_modules/vega-util/src/splitAccessPath.js","../node_modules/vega-util/src/isArray.js","../node_modules/vega-util/src/isObject.js","../node_modules/vega-util/src/isString.js","../node_modules/vega-util/src/stringValue.js","../node_modules/vega-util/src/accessors.js","../node_modules/vega-util/src/field.js","../node_modules/vega-util/src/logger.js","../node_modules/vega-util/src/isBoolean.js","../node_modules/vega-util/src/isNumber.js","../node_modules/vega-util/src/toSet.js","../node_modules/tslib/tslib.es6.js","../node_modules/jsonify/lib/parse.js","../node_modules/jsonify/lib/stringify.js","../node_modules/json-stable-stringify/index.js","../src/logical.ts","../src/util.ts","../src/aggregate.ts","../src/axis.ts","../src/channel.ts","../src/bin.ts","../src/mark.ts","../src/log.ts","../src/datetime.ts","../src/timeunit.ts","../src/type.ts","../src/fielddef.ts","../src/encoding.ts","../src/compositemark/common.ts","../src/compositemark/boxplot.ts","../src/compositemark/index.ts","../src/compositemark/errorbar.ts","../src/scale.ts","../src/guide.ts","../src/legend.ts","../src/selection.ts","../src/title.ts","../src/config.ts","../src/stack.ts","../src/spec.ts","../src/toplevelprops.ts","../src/data.ts","../node_modules/vega-event-selector/src/event-selector.js","../src/vega.schema.ts","../src/compile/axis/assemble.ts","../src/header.ts","../src/sort.ts","../src/compile/mark/valueref.ts","../node_modules/vega-util/src/isFunction.js","../src/compile/mark/mixins.ts","../src/compile/common.ts","../src/compile/data/dataflow.ts","../src/compile/data/calculate.ts","../src/compile/header/index.ts","../src/compile/layoutsize/assemble.ts","../src/compile/resolve.ts","../src/compile/split.ts","../src/compile/legend/component.ts","../src/compile/legend/encode.ts","../src/compile/legend/parse.ts","../src/compile/legend/properties.ts","../src/compile/legend/assemble.ts","../src/compile/projection/assemble.ts","../src/projection.ts","../src/compile/projection/component.ts","../src/compile/projection/parse.ts","../src/compile/data/aggregate.ts","../src/compile/data/facet.ts","../src/compile/data/filterinvalid.ts","../src/compile/data/formatparse.ts","../src/compile/data/source.ts","../src/compile/data/timeunit.ts","../src/compile/data/optimizers.ts","../src/compile/data/stack.ts","../src/compile/data/optimize.ts","../src/compile/scale/domain.ts","../src/compile/scale/assemble.ts","../src/compile/selection/selection.ts","../src/compile/scale/component.ts","../src/compile/scale/range.ts","../src/compile/scale/properties.ts","../src/compile/scale/type.ts","../src/compile/scale/parse.ts","../src/compile/model.ts","../src/compile/selection/transforms/scales.ts","../src/compile/selection/interval.ts","../src/compile/selection/transforms/nearest.ts","../src/compile/selection/multi.ts","../src/compile/selection/single.ts","../src/compile/selection/transforms/translate.ts","../src/compile/selection/transforms/zoom.ts","../src/compile/selection/transforms/transforms.ts","../src/compile/selection/transforms/project.ts","../src/compile/selection/transforms/toggle.ts","../src/compile/selection/transforms/inputs.ts","../src/predicate.ts","../src/transform.ts","../src/compile/data/bin.ts","../src/compile/data/filter.ts","../src/compile/data/geojson.ts","../src/compile/data/geopoint.ts","../src/compile/data/identifier.ts","../src/compile/data/index.ts","../src/compile/data/lookup.ts","../src/compile/data/assemble.ts","../src/compile/layoutsize/parse.ts","../src/compile/repeater.ts","../src/compile/facet.ts","../src/compile/data/window.ts","../src/compile/data/parse.ts","../src/compile/baseconcat.ts","../src/compile/concat.ts","../src/compile/axis/component.ts","../src/compile/axis/config.ts","../src/compile/axis/encode.ts","../src/compile/axis/parse.ts","../src/compile/axis/properties.ts","../src/compile/mark/init.ts","../src/compile/mark/bar.ts","../src/compile/mark/point.ts","../src/compile/mark/mark.ts","../src/compile/mark/area.ts","../src/compile/mark/geoshape.ts","../src/compile/mark/line.ts","../src/compile/mark/rect.ts","../src/compile/mark/rule.ts","../src/compile/mark/text.ts","../src/compile/mark/tick.ts","../src/compile/unit.ts","../src/compile/layer.ts","../src/compile/repeat.ts","../src/compile/buildmodel.ts","../src/validate.ts","../src/index.ts","../src/compile/compile.ts"],"names":["accessor","fn","fields","name","fname","error","message","Error","splitAccessPath","p","i","j","c","path","q","b","n","length","s","push","substring","isArray","Array","isObject","_","Object","isString","$","x","map","JSON","stringify","replace","empty","field","code","stringValue","join","Function","log","method","level","input","args","concat","slice","call","console","apply","None","Warn","Info","Debug","isBoolean","isNumber","toSet","extendStatics","setPrototypeOf","__proto__","d","hasOwnProperty","__extends","__","this","constructor","prototype","create","__assign","assign","t","arguments","__rest","e","indexOf","getOwnPropertySymbols","at","ch","text","value","escapee","\"","\\","/","f","r","m","next","charAt","number","string","isFinite","hex","uffff","parseInt","String","fromCharCode","white","key","object","array","word","gap","indent","rep","escapable","meta","\b","\t","\n","\f","\r","quote","lastIndex","test","a","charCodeAt","toString","json","source","reviver","result","walk","holder","k","v","undefined","","replacer","space","str","partial","mind","toJSON","jsonStableStringify","obj","opts","cmp","cycles","node","aobj","bobj","seen","parent","colonSeparator","out","item","TypeError","keys","objectKeys","sort","keyValue","splice","has","op","or","isLogicalAnd","and","isLogicalNot","not","pick","props","copy","_i","props_1","prop","omit","props_2","stableStringify","hash","h","contains","without","excludedItems","filter","some","arr","every","flatten","arrays","mergeDeep","dest","src","_a","src_1","deepMerge_","unique","values","results","u","values_1","val","differ","dict","other","hasIntersection","vals","_vals","flagKeys","duplicate","parse","isBoolean$1","varName","alphanumericS","match","logicalExpr","cb","isLogicalOr","deleteNestedProperty","orderedProps","shift","titlecase","toUpperCase","substr","accessPathWithDatum","datum","pieces","prefixes","prefix","flatAccessWithDatum","replacePathInField","removePathFromField","accessPathDepth","num","isNaN","AGGREGATE_OP_INDEX","argmax","argmin","average","count","distinct","max","mean","median","min","missing","q1","q3","ci0","ci1","stderr","stdev","stdevp","sum","valid","variance","variancep","AGGREGATE_OPS","isAggregateOp","COUNTING_OPS","isCountingAggregateOp","aggregate","SUM_OPS","SHARED_DOMAIN_OPS","SHARED_DOMAIN_OP_INDEX","AXIS_PARTS","AXIS_PROPERTY_TYPE","grid","gridScale","domain","labels","labelFlush","labelOverlap","minExtent","maxExtent","offset","ticks","title","scale","zindex","COMMON_AXIS_PROPERTIES_INDEX","orient","format","labelBound","labelPadding","position","tickCount","tickSize","titlePadding","AXIS_PROPERTIES_INDEX","encoding","labelAngle","titleMaxLength","isAxisProperty","Channel","VG_AXIS_PROPERTIES","encode","AXIS_PROPERTIES","ROW","COLUMN","X","Y","X2","Y2","LATITUDE","LONGITUDE","LATITUDE2","LONGITUDE2","COLOR","FILL","STROKE","SHAPE","SIZE","OPACITY","TEXT","ORDER","DETAIL","KEY","TOOLTIP","HREF","GEOPOSITION_CHANNEL_INDEX","longitude","longitude2","latitude","latitude2","GEOPOSITION_CHANNELS","UNIT_CHANNEL_INDEX","y","x2","y2","color","fill","stroke","opacity","size","shape","order","detail","tooltip","href","isColorChannel","channel","CHANNEL_INDEX","row","column","CHANNELS","SINGLE_DEF_CHANNELS","isChannel","UNIT_CHANNELS","NONPOSITION_CHANNEL_INDEX","NONPOSITION_CHANNELS","POSITION_SCALE_CHANNEL_INDEX","POSITION_SCALE_CHANNELS","NONPOSITION_SCALE_CHANNEL_INDEX","NONPOSITION_SCALE_CHANNELS","SCALE_CHANNEL_INDEX","SCALE_CHANNELS","isScaleChannel","supportMark","mark","getSupportedMark","point","tick","rule","circle","square","bar","rect","line","trail","area","geoshape","rangeType","bin","isBinParams","autoMaxBins","Mark","AREA","BAR","LINE","POINT","RECT","RULE","TICK","TRAIL","CIRCLE","SQUARE","GEOSHAPE","MARK_INDEX","isPathMark","PRIMITIVE_MARKS","isMarkDef","PRIMITIVE_MARK_INDEX","isPrimitiveMark","type","STROKE_CONFIG","FILL_CONFIG","FILL_STROKE_CONFIG","VL_ONLY_MARK_CONFIG_PROPERTIES","VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX","defaultMarkConfig","defaultBarConfig","binSpacing","continuousBandSize","defaultTickConfig","thickness","main","warn","info","debug","current","INVALID_SPEC","FIT_NON_SINGLE","CANNOT_FIX_RANGE_STEP_WITH_FIT","cannotProjectOnChannelWithoutField","nearestNotSupportForContinuous","selectionNotFound","SCALE_BINDINGS_CONTINUOUS","noSuchRepeatedValue","CONCAT_CANNOT_SHARE_AXIS","REPEAT_CANNOT_SHARE_AXIS","cannotSetTitleAnchor","unrecognizedParse","differentParse","local","ancestor","invalidTransformIgnored","transform","NO_FIELDS_NEEDS_AS","encodingOverridden","channels","projectionOverridden","opt","parentProjection","projection","primitiveChannelDef","invalidFieldType","nonZeroScaleUsedWithLengthMark","scaleType","zeroFalse","invalidFieldTypeForCountAggregate","invalidAggregate","emptyOrInvalidFieldType","newType","droppingColor","emptyFieldDef","fieldDef","latLongDeprecated","newChannel","LINE_WITH_VARYING_SIZE","incompatibleChannel","markOrFacet","when","invalidEncodingChannel","facetChannelShouldBeDiscrete","discreteChannelCannotEncode","BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL","lineWithRange","hasX2","hasY2","orientOverridden","original","actual","CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN","cannotUseScalePropertyWithNonColor","unaggregateDomainHasNoEffectForRawField","unaggregateDomainWithNonSharedDomainOp","unaggregatedDomainWithLogScale","cannotApplySizeToNonOrientedMark","rangeStepDropped","scaleTypeNotWorkWithChannel","defaultScaleType","scaleTypeNotWorkWithFieldDef","scalePropertyNotWorkWithScaleType","propName","scaleTypeNotWorkWithMark","mergeConflictingProperty","property","propertyOf","v1","v2","independentScaleMeansIndependentGuide","domainSortDropped","UNABLE_TO_MERGE_DOMAINS","MORE_THAN_ONE_SORT","INVALID_CHANNEL_FOR_AXIS","cannotStackRangedMark","cannotStackNonLinearScale","stackNonSummativeAggregate","invalidTimeUnit","unitName","dayReplacedWithDate","fullTimeUnit","droppedDay","SUNDAY_YEAR","isDateTime","o","year","quarter","month","date","day","hours","minutes","seconds","milliseconds","MONTHS","SHORT_MONTHS","DAYS","SHORT_DAYS","dateTimeExpr","normalize","units","log.warn","log.message","lowerM","toLowerCase","monthIndex","shortM","shortMonthIndex","normalizeMonth","normalizeQuarter","lowerD","dayIndex","shortD","shortDayIndex","normalizeDay","timeUnit","utc","TimeUnit","YEAR","MONTH","DAY","DATE","HOURS","MINUTES","SECONDS","MILLISECONDS","YEARMONTH","YEARMONTHDATE","YEARMONTHDATEHOURS","YEARMONTHDATEHOURSMINUTES","YEARMONTHDATEHOURSMINUTESSECONDS","MONTHDATE","HOURSMINUTES","HOURSMINUTESSECONDS","MINUTESSECONDS","SECONDSMILLISECONDS","QUARTER","YEARQUARTER","QUARTERMONTH","YEARQUARTERMONTH","UTCYEAR","UTCMONTH","UTCDAY","UTCDATE","UTCHOURS","UTCMINUTES","UTCSECONDS","UTCMILLISECONDS","UTCYEARMONTH","UTCYEARMONTHDATE","UTCYEARMONTHDATEHOURS","UTCYEARMONTHDATEHOURSMINUTES","UTCYEARMONTHDATEHOURSMINUTESSECONDS","UTCMONTHDATE","UTCHOURSMINUTES","UTCHOURSMINUTESSECONDS","UTCMINUTESSECONDS","UTCSECONDSMILLISECONDS","UTCQUARTER","UTCYEARQUARTER","UTCQUARTERMONTH","UTCYEARQUARTERMONTH","LOCAL_SINGLE_TIMEUNIT_INDEX","TIMEUNIT_PARTS","isLocalSingleTimeUnit","UTC_SINGLE_TIMEUNIT_INDEX","utcyear","utcquarter","utcmonth","utcday","utcdate","utchours","utcminutes","utcseconds","utcmilliseconds","isUtcSingleTimeUnit","UTC_MULTI_TIMEUNIT_INDEX","utcyearquarter","utcyearquartermonth","utcyearmonth","utcyearmonthdate","utcyearmonthdatehours","utcyearmonthdatehoursminutes","utcyearmonthdatehoursminutesseconds","utcquartermonth","utcmonthdate","utchoursminutes","utchoursminutesseconds","utcminutesseconds","utcsecondsmilliseconds","UTC_TIMEUNIT_INDEX","isUTCTimeUnit","getLocalTimeUnit","TIMEUNIT_INDEX","yearquarter","yearquartermonth","yearmonth","yearmonthdate","yearmonthdatehours","yearmonthdatehoursminutes","yearmonthdatehoursminutesseconds","quartermonth","monthdate","hoursminutes","hoursminutesseconds","minutesseconds","secondsmilliseconds","TIMEUNITS","SET_DATE_METHOD","dateMethods","singleUnit","isUtc","rawSetDateMethod","setDateMethod","getDateMethod","getTimeUnitParts","reduce","parts","part","containsTimeUnit","index","fieldExpr","fieldRef","dateExpr","tu","formatExpression","shortTimeLabels","isUTCScale","dateComponents","expression","hasYear","timeComponents","dateTimeComponents","normalizeTimeUnit","Type","unit","isUTC","Date","UTC","TIMEUNIT_PARTS_1","timeUnitPart","getDateMethod_1","Math","floor","_b","QUANTITATIVE","ORDINAL","TEMPORAL","NOMINAL","GEOJSON","TYPE_INDEX","quantitative","ordinal","temporal","nominal","geojson","getFullName","isRepeatRef","toFieldDefBase","field$$1","isConditionalDef","channelDef","condition","hasConditionalFieldDef","isFieldDef","hasConditionalValueDef","isValueDef","isStringFieldDef","isScaleFieldDef","vgField","suffix","isCount","nofn","isOpFieldDef","binToString","binSuffix","expr","isDiscrete","isContinuous","verbalTitleFormatter","config","countTitle","functionalTitleFormatter","defaultTitleFormatter","fieldTitle","titleFormatter","setTitleFormatter","formatter","resetTitleFormatter","defaultType","getFieldDef","primitiveType","normalizeFieldDef","fieldDefWithoutAggregate","normalizeBin","fullType","channelCompatibility","compatible","warning","maxbins","step","COMPATIBLE","isNumberFieldDef","isTimeFieldDef","valueExpr","time","undefinedIfExprNotRequired","valueArray","signal","isAggregate","channelHasField","normalizeEncoding","normalizedEncoding","defs","newEncoding","isRanged","fieldDefs","forEach","def","mapping","thisArg","init","r1","markSpecificConfig","BOXPLOT","isBoxPlotDef","supportedChannels","normalizerRegistry","add","normalizer","COMPOSITE_MARK_STYLES","VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX","box","boxWhisker","boxMid","normalize$1","spec","filterUnsupportedChannels","selection","outerSpec","kIQRScalar","extent","_e","continuousAxisChannelDef","continuousAxis","continuousAxisWithoutAggregate","boxContinousAxis","isMinMax","as","postAggregateCalculates","calculate","groupby","bins","timeUnits","encodingWithoutContinuousAxis","transformedField","boxParams","boxOrient","encodingWithoutSizeColorAndContinuousAxis","sizeMixins","getMarkSpecificConfigMixins","continuousAxisScaleAndAxis","axis","layer","style","_c","_d","encodingWithoutSize","encodingWithoutX2Y2","encodingWithoutX_X2_Y_Y2","ScaleType","VL_ONLY_GUIDE_CONFIG","defaultLegendConfig","COMMON_LEGEND_PROPERTY_INDEX","entryPadding","padding","VG_LEGEND_PROPERTY_INDEX","LEGEND_PROPERTIES","VG_LEGEND_PROPERTIES","LINEAR","BIN_LINEAR","LOG","POW","SQRT","TIME","SEQUENTIAL","QUANTILE","QUANTIZE","THRESHOLD","BIN_ORDINAL","BAND","SCALE_CATEGORY_INDEX","linear","pow","sqrt","bin-linear","sequential","bin-ordinal","band","SCALE_TYPES","scaleCompatible","scaleType1","scaleType2","scaleCategory1","scaleCategory2","SCALE_PRECEDENCE_INDEX","scaleTypePrecedence","CONTINUOUS_TO_CONTINUOUS_SCALES","CONTINUOUS_TO_CONTINUOUS_INDEX","CONTINUOUS_DOMAIN_SCALES","CONTINUOUS_DOMAIN_INDEX","DISCRETE_DOMAIN_SCALES","DISCRETE_DOMAIN_INDEX","BIN_SCALES_INDEX","hasDiscreteDomain","isBinScale","hasContinuousDomain","isContinuousToContinuous","defaultScaleConfig","textXRangeStep","rangeStep","pointPadding","bandPaddingInner","facetSpacing","minBandSize","minFontSize","maxFontSize","minOpacity","maxOpacity","minSize","minStrokeWidth","maxStrokeWidth","isExtendedScheme","scheme","isSelectionDomain","SCALE_PROPERTY_INDEX","range","reverse","round","clamp","nice","base","exponent","interpolate","zero","paddingInner","paddingOuter","SCALE_PROPERTIES","NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES","SCALE_TYPE_INDEX","CHANNELS_1","fieldDefType","SCALE_TYPES_1","generateScaleTypeIndexKey","channelSupportScaleType","scaleTypeSupportDataType","generateScaleTypeIndex","scaleTypeSupportProperty","channelScalePropertyIncompatability","specifiedType","SELECTION_ID","titleConfig","anchor","titleMarkConfig","nonMark","defaultViewConfig","width","height","defaultConfig","timeFormat","invalidValues","view","mark.defaultMarkConfig","mark.defaultBarConfig","mark.defaultTickConfig","axisX","axisY","axisLeft","axisRight","axisTop","axisBottom","axisBand","legend","single","on","resolve","multi","toggle","interval","encodings","translate","zoom","fillOpacity","initConfig","MARK_STYLES","VL_ONLY_CONFIG_PROPERTIES","VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX","stripAndRedirectConfig","VL_ONLY_CONFIG_PROPERTIES_1","VL_ONLY_GUIDE_CONFIG_1","VL_ONLY_GUIDE_CONFIG_2","VL_ONLY_MARK_CONFIG_PROPERTIES_1","MARK_STYLES_1","markType","VL_ONLY_MARK_CONFIG_PROPERTIES_2","vlOnlyMarkSpecificConfigs","_f","vlOnlyMarkSpecificConfigs_1","redirectConfig","toProp","propConfig","extractTitleConfig","STACK_OFFSET_INDEX","center","isStackOffset","STACKABLE_MARKS","STACK_BY_DEFAULT_MARKS","stack","stackConfig","fieldChannel","xDef","yDef","potentialStackedChannel","stackedFieldDef","stackedField","dimensionChannel","dimensionDef","dimensionField","stackBy","sc","cDef","groupbyChannel","impute","isFacetSpec","isUnitSpec","isLayerSpec","isRepeatSpec","isConcatSpec","isVConcatSpec","isHConcatSpec","normalize$2","subspec","rest","normalizeFacet","normalizeLayer","parentEncoding","mergedEncoding","mergeEncoding","mergedProjection","mergeProjection","normalizeNonFacetUnit","normalizeRepeat","vconcat","normalizeVConcat","hconcat","normalizeHConcat","hasRow","hasColumn","facet","normalizeFacetedUnit","overriden","merged","isNonFacetUnitSpecWithPrimitiveMark","hasX","hasY","normalizedSpec","normalizeRangedUnit","markDef","pointOverlay","markConfig","getPointOverlay","lineOverlay","getLineOverlay","dropLineAndPoint","stackProps","overlayEncoding","stackFieldChannel","filled","normalizePathOverlay","compositeMark.normalize","accumulate","fieldDefIndex","vlEncoding.fieldDefs","child","_normalizeAutoSize","autosize","TOP_LEVEL_PROPERTIES","extractTopLevelProperties","data","isInlineData","isNamedData","isUrlData","MAIN","RAW","parseSelector","selector","marks","DEFAULT_SOURCE","VIEW","MARKS","DEFAULT_MARKS","parseMerge","trim","LBRACK","RBRACK","LBRACE","RBRACE","COLON","COMMA","NAME","GT","ILLEGAL","*","arc","group","image","symbol","find","endChar","pushChar","popChar","output","start","stream","between","parseBetween","throttle","markname","lastIndexOf","split","parseThrottle","marktype","consume","debounce","parseStream","isVgRangeStep","isDataRefDomain","VG_MARK_CONFIGS","strokeCap","strokeWidth","strokeOpacity","strokeDash","strokeDashOffset","strokeJoin","strokeMiterLimit","tension","align","baseline","dir","dx","dy","ellipsis","limit","radius","theta","angle","font","fontSize","fontWeight","fontStyle","cursor","cornerRadius","assembleAxis","axisCmpt","kind","header","combine","propType","mainExtracted","AXIS_PARTS_1","hasAxisPart","titleString","fieldDefTitle","assembleTitle","HEADER_TITLE_PROPERTIES_MAP","titleAnchor","titleAngle","titleBaseline","titleColor","titleFont","titleFontSize","titleFontWeight","titleLimit","HEADER_LABEL_PROPERTIES_MAP","labelColor","labelFont","labelFontSize","labelLimit","HEADER_TITLE_PROPERTIES","HEADER_LABEL_PROPERTIES","isSortArray","getOffset","markDefOffsetValue","bin$1","scaleName","side","mixins","ref","bandRef","midPoint","defaultRef","binMidSignal","binRequiresRange","get","text$1","textDef","formatSignalRef","mid","sizeRef","mult","getDefaultRef","domains","domainDefinitelyIncludeZero","explicit","model","valueOnly","configValue","getMarkConfig","transparentIfNeeded","defaultValue","colorVgChannel","fillStrokeMarkDefAndConfig","nonPosition","vgChannel","baseEncodeEntry","ignore","markDefProperties","keyValues","ref.text","textCommon","validPredicate","vgRef","defined","scaleComponent","getScaleComponent","wrapCondition","ref.midPoint","refFn","valueRef","vgConditions","conditionValueRef","isConditionalSelection","selectionPredicate","text$2","bandPosition","sizeChannel","centeredBandPositionMixins","ref.fieldRef","ref.bandRef","centeredBandPosition","defaultPosRef","defaultSizeRef","pointPosition","binnedPosition","spacing","ref.bin","ref.getOffset","ref.position","ref.getDefaultRef","getName","pointPosition2","baseChannel","aFieldDef","a2fieldDef","ref.position2","getStyles","styles_1","styleConfig","specifiedFormat","numberFormat","binFormatExpression","formatExpr","timeFormatExpression","getSpecifiedOrDefaultValue","specifiedValue","numberFormatExpr","startField","endField","timeFormatConfig","alwaysReturn","sortParams","orderDef","fieldRefOption","orderChannelDef","mergeTitleFieldDefs","f1","f2","fdToMerge","merged_1","fieldDef1","mergeTitle","title1","title2","mergeTitleComponent","guideEncodeEntry","valueDef","DataFlowNode","debugName","_children","_parent","clone","producedFields","dependentFields","defineProperty","addChild","numChildren","removeChild","oldChild","remove","insertAsParentOf","swapWithParent","newParent","OutputNode","_super","refCounts","_this","_source","_name","tslib_1.__extends","cloneObj","getSource","isRequired","setSource","CalculateNode","parseAllForSortIndex","forEachFieldDef","field_1","timeUnit_1","sortValue","fieldFilterExpression","equal","sortArrayIndexField","assemble","HEADER_CHANNELS","HEADER_TYPES","getTitleGroup","component","layoutHeaders","textOrient","facetFieldDef","role","getHeaderProperties","getHeaderGroups","layoutHeader","groups","HEADER_TYPES_1","headerType","headerCmpt","getHeaderGroup","update","axes","hasAxes","from","isSortField","getSort","title$$1","sizeSignal","properties","propertiesMap","properties_1","sizeSignals","sizeType","layoutSize","getSizeSignalRef","isFacetModel","stepSignal","sizeExpr","cardinality","parseGuideResolve","channelScaleResolve","guide","Split","implicit","getWithExplicit","setWithExplicit","set","copyKeyFromSplit","copyKeyFromObject","copyAll","makeImplicit","tieBreakByComparing","compare","diff","defaultTieBreaker","mergeValuesWithExplicit","tieBreaker","LegendComponent","getMaxValue","getConditionValue","conditionalDef","getFirstConditionValue","reducer","symbolsSpec","propsList","propsList_2","applyMarkConfig","mixins.color","gradientSpec","labelsSpec","isUnitModel","legends","legendComponent","legendCmpt","getLegendDefWithScale","specifiedLegend","specifiedTitle","properties.values","properties.type","getProperty","legendEncoding","legendEncode","legendEncodingPart","parseLegendForChannel","parseUnitLegend","parseLegend","mergeLegendComponent","children","parseNonUnitLegend","mergedLegend","childLegend","mergedOrient","childOrient","typeMerged","mergedValueWithExplicit","VG_LEGEND_PROPERTIES_1","gradient","legendComponentIndex","legendByDomain","domainHash","isLayerModel","isConcatModel","isRepeatModel","projections","assembleProjections","assembleProjectionForModel","assembleProjectionsForModelAndChildren","fit","sources","isVgSignalRef","lookupDataSource","PROJECTION_PROPERTIES","ProjectionComponent","specifiedProjection","hasProjection","data_1","posssiblePair","requestDataName","projectionName","parseUnitProjection","nonUnitProjection","mergable","parseProjection","merge","first","second","allPropertiesShared","mergeIfNoConflict","name_1","modelProjection_1","renameProjection","parseNonUnitProjections","AggregateNode","dimensions","measures","makeFromEncoding","fd","meas","dims","scaleDomain","addDimension","makeFromTransform","log.debug","parentMeasures","childMeasures","ops","mergeMeasures","addDimensions","FacetNode","sortField","sortIndexField","childModel","getChildIndependentFieldsWithStep","childIndependentFieldsWithStep","childScaleComponent","scales","getFieldFromDomain","assembleDomain","assembleRowColumnData","crossedDataName","childChannel","FilterInvalidNode","make","reduceFieldDef","aggregator","filters","vegaFilters","ParseNode","_parse","makeExplicit","ancestorParse","makeWithAncestors","makeImplicitFromFilterTransform","forEachLeaf","isFieldPredicate","isFieldEqualPredicate","isFieldRangePredicate","isFieldOneOfPredicate","oneOf","makeImplicitFromEncoding","parsedAs","parseNothing","assembleFormatParse","formatParse","assembleTransforms","onlyNested","parseExpression","SourceNode","_data","url","defaultExtension","exec","hasName","_hash","TimeUnitNode","formula","timeUnitComponent","iterateFromLeaves","optimizeNextFromLeaves","moveParseUp","removeUnusedSubtrees","removeDuplicateTimeUnits","leaf","pfields","StackNode","_stack","stackTransform","sortFields","sortOrder","stackField","facetby","isValidAsArray","dimensionFieldDef","stackProperties","stackby","by","_field","getStackByFields","getGroupbyFields","FACET_SCALE_PREFIX","moveFacetDown","moveMainDownToFacet","copy_1","newName","outputNodes","removeUnnecessaryNodes","getLeaves","roots","leaves","append","specifiedScales","localScaleComponents","util.keys","specifiedScale","specifiedDomain","scaleConfig","canUseUnaggregatedDomain","reason","useUnaggregatedDomain","normalizeUnaggregatedDomain","parseSingleChannelDomain","parseDomainForChannel","localScaleCmpt","SELECTION_DOMAIN","util.hash","isFaceted","facetParent","domains_1","parseUnitScaleDomain","parseScaleDomain","domainRaw","childComponent","dr","parseNonUnitScaleDomain","mapDomainToDataSignal","util.replacePathInField","util.contains","domainSort","util.isBoolean","isDataRefUnionedDomain","nonUnionDomain","isFieldRefUnionDomain","uniqueDomains","util.unique","sorts","sort_1","simpleSorts","allData","mergeDomains","assembleScalesForModel","otherScaleProps","scaleRange","r0","getSizeName","assembleScaleRange","isRawSelectionDomain","selDomain","selCmpt","getSelectionComponent","project","compiler","STORE","selectionScaleDomain","ScaleComponent","typeWithExplicit","RANGE_PROPERTIES","parseScaleRange","mergedScaleCmpt","sizeSpecified","xyRangeSteps","xScale","xRange","yScale","yRange","getXYRangeStep","rangeWithExplicit","noRangeStep","RANGE_PROPERTIES_1","supportedByScaleType","channelIncompatability","parseScheme","rangeMin","sizeRangeMin","rangeMax","maxBandSize","minXYRangeStep","maxSize","pointStep","sizeRangeMax","defaultRange","parseRangeForChannel","parseUnitScaleRange","parseNonUnitScaleProperty","sType","scalePadding","scalePaddingInner","barConfig","continuousPadding","paddingValue","paddingInnerValue","bandPaddingOuter","getDefaultValue","parseUnitScaleProperty","parseScaleProperty","valueWithExplicit","parseScaleCore","scaleComponents","specifiedScaleType","parseUnitScaleCore","scaleTypeWithExplicitIndex","defaultScaleResolve","explicitScaleType","childScaleType","scaleTypeTieBreaker","childScale","renameScale","parseNonUnitScaleCore","st1","st2","NameMap","nameMap","rename","oldName","Model","parentGivenName","repeater","bounds","correctDataNames","scaleNameMap","projectionNameMap","layoutSizeNameMap","description","transforms","normalizeTransform","layout","outputNodeRefCounts","initSize","parseScale","parseLayoutSize","renameTopLevelLayoutSize","parseSelection","parseData","parseAxisAndHeader","parseMarkGroup","NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES_1","renameLayoutSize","assembleGroupStyle","assembleLayoutSize","assembleLayout","assembleDefaultLayout","assembleHeaderMarks","headerMarks","HEADER_CHANNELS_1","HEADER_CHANNELS_2","assembleAxes","axisComponents","assembleLegends","assembleGroup","signals","assembleSelectionSignals","assembleMarks","assembleScales","hasDescendantWithFieldOnChannel","fullName","oldSizeName","originalScaleName","localScaleComponent","variableName","origName","sel","ModelWithField","getMapping","acc","cd","scaleBindings","bind","selDef","bound","channelSignalName","topLevelSignals","domain$1","SCALE_TRIGGER","predicate","hasScales","intervals","tupleTriggers","scaleTriggers","filterExpr_1","events","evt","cs","vname","dname","scaleStr","coord","channelSignals","toNum","TUPLE","modifyExpr","positionalProjections","xi","yi","store","vgStroke","clip","enter","nearest","cellDef","isVoronoi","exists","proj","force","multiSignals","hasSignal","ANCHOR","DELTA","onDelta","scalesCompiler","delta","sizeSg","scaleCmpt","onDelta$1","compilers","tuField","tpl","sx","sy","inputs","sgname","unshift","forEachTransform","MODIFY","assembleUnitSelectionMarks","forEachSelection","selCompiler","txCompiler","selections","dfnode","stores","predicateStr","raw","tunode","name_3","singleCompiler","multiCompiler","intervalCompiler","getFacetModel","requiresSelectionId","identifier","sgNames","_signalNames","basename","counter","isFieldLTPredicate","lt","isFieldLTEPredicate","lte","isFieldGTPredicate","gt","isFieldGTEPredicate","gte","in","filterOp","isSelectionPredicate","predicateValueExpr","useInRange","timeUnitFieldExpr","upper","lower","predicateValuesExpr","exprs","normalizePredicate","isLookup","isWindow","isCalculate","isBin","isTimeUnit$1","isAggregate$1","isStack","isFilter","normalizeLogicalOperand","createBinComponent","isBinTransform","binKey","extentSignal","getSignalsFromModel","key$$1","binComponent","BinNode","binComponentIndex","formulaAs","rangeFormula","binTrans","FilterNode","GeoJSONNode","parseAll","geoJsonCounter","coordinates","pair","GeoPointNode","IdentifierNode","AncestorParse","LookupNode","secondary","fromSource","fromOutputName","fromOutputNode","foreign","asName","lookup","default","makeWalkTree","datasetIndex","walkTree","dataSource","WindowTransformNode","source_1","parseChildrenLayoutSize","layoutSizeCmpt","parseNonUnitLayoutSizeForChannel","parseRepeatLayoutSize","parseLayerLayoutSize","mergedSize","childSize","scaleResolve","defaultUnitSize","replaceRepeat","repeat","replaceRepeaterInFieldDef","replaceRepeaterInChannelDef","tslib_1.__assign","replaceRepeater","FacetModel","buildModel","replaceRepeaterInFacet","initFacet","normalizedFacet","parseHeader","mergeChildAxis","makeHeaderComponent","headerChannel","axisComponent","mainAxis","assembleSelectionTopLevelSignals","assembleSelectionData","getHeaderLayoutMixins","layoutMixins","layoutHeaderComponent","headerComponent","bandType","columns","columnDistinctSignal","assembleLayoutSignals","getCardinalityAggregateForChild","assembleFacet","facetRoot","outputName","facetSortFieldName","cross","headerSortFields","headerSortOrder","root","assembleFacetData","layoutSizeEncodeEntry","makeFromFacet","window","frame","windowFieldDef","getDefaultName","params","window_1","param","ignorePeers","head","parseRoot","parentIsLayer","lookupCounter","isTimeUnit","agg","_g","_h","_j","parseTransformArray","rawName","mainName","facetName","BaseConcatModel","sg","db","ConcatModel","isVConcat","sizeTypeToMerge","parseConcatLayoutSize","parseAxisGroup","AxisComponent","configTypes_1","configType","specifiedLabelsSpec","getAxisConfig","labelAlign","labelBaseline","specifiedAxis","gridChannel","properties.gridScale","properties.grid","properties.labelFlush","properties.labelOverlap","properties.orient","properties.tickCount","channel2","fieldDef2","getFieldDefTitle","axisEncoding","axisEncode","axisEncodingPart","encode.labels","parseAxis","OPPOSITE_ORIENT","bottom","top","left","right","mergeAxisComponents","mergedAxisCmpts","childAxisCmpts","length_1","mergeAxisComponent","VG_AXIS_PROPERTIES_1","specifiedOrient","yIsRange","xIsRange","xIsContinuous","yIsContinuous","xIsTemporal","yIsTemporal","filledConfig","discreteBandSize","encodeEntry","fixedShape","mixins.baseEncodeEntry","mixins.pointPosition","ref.mid","mixins.nonPosition","shapeMixins","markCompiler","vgMark","mixins.pointPosition2","mixins.defined","sizeDef","x2Def","xScaleName","xScaleType","mixins.binnedPosition","mixins.bandPosition","mixins.centeredBandPosition","y2Def","yScaleName","yScaleType","postEncodingTransform","shapeDef","mixins.text","mixins.valueIfDefined","vgSizeChannel","vgThicknessChannel","bandSize","defaultSize","details","pathMarks","getMarkGroups","fromPrefix","FACETED_PATH_PREFIX","parsePathMark","scaleClip","dimensionChannelDef","UnitModel","parentGivenSize","specifiedAxes","specifiedLegends","replaceRepeaterInEncoding","normalizeMarkDef","initScales","initAxes","initLegend","isGeoShapeMark","hasGeoPosition","_axis","axisSpec","_legend","layoutSizeComponent","parseUnitLayoutSize","selDefs","selCmpts","selectionConfig","cfg","parseUnitSelection","parseUnitAxis","needsUnit","facetModel","name_2","assembleUnitSelectionSignals","assembleUnitSelectionData","toSpec","excludeConfig","excludeData","vlEncoding.channelHasField","LayerModel","axisCount","_k","_l","oppositeOrient","parseLayerAxis","RepeatModel","repeatValues","_initChildren","row_1","rowField","column_1","columnField","childRepeat","unitSize","DEFAULT_REQUIRED_CHANNEL_MAP","DEFAULT_SUPPORTED_CHANNEL_TYPE","requiredChannelMap","supportedChannelMap","requiredChannels","version","inputSpec","newLogger","dataComponent","logger","vlFieldDef.setTitleFormatter","topLevelAutosize","configAutosize","isUnitOrLayer","normalizeAutoSize","optimizers.iterateFromLeaves","optimizers.removeUnusedSubtrees","optimizers.moveParseUp","optimizers.removeDuplicateTimeUnits","topLevelProperties","vgConfig","datasets","sourceIndex","dataName","newData","whereTo","data_2","assembleRootData","layoutSignals","$schema","assembleTopLevelModel","topLevelSpec","getTopLevelProperties","vlFieldDef.resetTitleFormatter"],"mappings":"qLAAe,SAAAA,EAASC,EAAIC,EAAQC,GAGlC,OAFAF,EAAGC,OAASA,MACZD,EAAGG,MAAQD,EACJF,ECHM,SAAAI,EAASC,GACtB,MAAMC,MAAMD,GCCC,SAAAE,EAASC,GACtB,IAKIC,EAAGC,EAAGC,EALNC,KACAC,EAAI,KACJC,EAAI,EACJC,EAAIP,EAAEQ,OACNC,EAAI,GAKR,SAASC,IACPN,EAAKM,KAAKD,EAAIT,EAAEW,UAAUV,EAAGC,IAC7BO,EAAI,GACJR,EAAIC,EAAI,EAGV,IARAF,GAAQ,GAQHC,EAAEC,EAAE,EAAGA,EAAEK,IAAKL,EAEjB,GAAU,QADVC,EAAIH,EAAEE,IAEJO,GAAKT,EAAEW,UAAUV,EAAGC,GACpBD,IAAMC,OACD,GAAIC,IAAME,EACfK,IACAL,EAAI,KACJC,GAAK,MACA,CAAA,GAAID,EACT,SACSJ,IAAMK,GAAW,MAANH,GACpBF,EAAIC,EAAI,EACRG,EAAIF,GACKF,IAAMK,GAAW,MAANH,GACpBF,EAAIC,EAAI,EACRG,EAAIF,GACW,MAANA,GAAcG,EAMR,MAANH,GACLD,EAAID,GAAGS,IACXJ,EAAIL,EAAIC,EAAI,GACG,MAANC,IACJG,GAAGV,EAAM,qCAAuCI,GACjDM,EAAI,GAAGI,IACXJ,EAAI,EACJL,EAAIC,EAAI,GAZJA,EAAID,EACNS,IAEAT,EAAIC,EAAI,EAqBd,OARII,GAAGV,EAAM,wCAA0CI,GACnDK,GAAGT,EAAM,sCAAwCI,GAEjDE,EAAID,IACNC,IACAQ,KAGKN,EC5DT,IAAAQ,EAAeC,MAAMD,QCAN,SAAAE,EAASC,GACtB,OAAOA,IAAMC,OAAOD,GCDP,SAAAE,EAASF,GACtB,MAAoB,iBAANA,ECGD,SAASG,EAAEC,GACxB,OAAOP,EAAQO,GAAK,IAAMA,EAAEC,IAAIF,GAAK,IACjCJ,EAASK,IAAMF,EAASE,GAGxBE,KAAKC,UAAUH,GAAGI,QAAQ,SAAS,WAAWA,QAAQ,SAAU,WAChEJ,ECPN,IAAIK,MCCW,SAASC,EAAO/B,GAC7B,IAAIU,EAAOL,EAAgB0B,GACvBC,EAAO,YAActB,EAAKgB,IAAIO,GAAaC,KAAK,MAAQ,KAErDrC,EACLsC,SAAS,IAAKH,IACZD,EAAsB,IAAdrB,EAAKI,OAAaJ,EAAK,GAAKqB,GACtC/B,GAAQ+B,IDNIA,CAAM,MAEAlC,EAAS,SAASwB,GAAK,OAAOA,GAAMS,EAAO,YAE/CjC,EAAS,WAAa,OAAO,GAAMiC,EAAO,QAE3CjC,EAAS,WAAa,OAAO,GAAMiC,EAAO,OAEvCjC,EAAS,WAAa,OAAO,GAASiC,EAAO,QAE9CjC,EAAS,WAAa,OAAO,GAAUiC,EAAO,SEfjE,SAASM,EAAIC,EAAQC,EAAOC,GAC1B,IAAIC,GAAQF,GAAOG,UAAUC,MAAMC,KAAKJ,IACxCK,QAAQP,GAAQQ,MAAMD,QAASJ,GAG1B,IAAIM,EAAQ,EACR1C,EAAQ,EACR2C,EAAQ,EACRC,EAAQ,EACRC,EAAQ,ECTJ,SAAAC,EAAS7B,GACtB,MAAoB,kBAANA,ECDD,SAAA8B,EAAS9B,GACtB,MAAoB,iBAANA,ECDD,SAAA+B,EAAS/B,GACtB,IAAK,IAAIN,KAAMR,EAAE,EAAGM,EAAEQ,EAAEP,OAAQP,EAAEM,IAAKN,EAAGQ,EAAEM,EAAEd,KAAM,EACpD,OAAOQ,ECcT,IAAIsC,EAAgB/B,OAAOgC,iBACpBC,wBAA2BpC,OAAS,SAAUqC,EAAG5C,GAAK4C,EAAED,UAAY3C,IACvE,SAAU4C,EAAG5C,GAAK,IAAK,IAAIN,KAAKM,EAAOA,EAAE6C,eAAenD,KAAIkD,EAAElD,GAAKM,EAAEN,KAElE,SAASoD,EAAUF,EAAG5C,GAEzB,SAAS+C,IAAOC,KAAKC,YAAcL,EADnCH,EAAcG,EAAG5C,GAEjB4C,EAAEM,UAAkB,OAANlD,EAAaU,OAAOyC,OAAOnD,IAAM+C,EAAGG,UAAYlD,EAAEkD,UAAW,IAAIH,GAG5E,IAAIK,EAAW1C,OAAO2C,QAAU,SAAkBC,GACrD,IAAK,IAAInD,EAAGR,EAAI,EAAGM,EAAIsD,UAAUrD,OAAQP,EAAIM,EAAGN,IAE5C,IAAK,IAAID,KADTS,EAAIoD,UAAU5D,GACOe,OAAOwC,UAAUL,eAAed,KAAK5B,EAAGT,KAAI4D,EAAE5D,GAAKS,EAAET,IAE9E,OAAO4D,GAGJ,SAASE,EAAOrD,EAAGsD,GACtB,IAAIH,KACJ,IAAK,IAAI5D,KAAKS,EAAOO,OAAOwC,UAAUL,eAAed,KAAK5B,EAAGT,IAAM+D,EAAEC,QAAQhE,GAAK,IAC9E4D,EAAE5D,GAAKS,EAAET,IACb,GAAS,MAALS,GAAqD,mBAAjCO,OAAOiD,sBACtB,CAAA,IAAIhE,EAAI,EAAb,IAAgBD,EAAIgB,OAAOiD,sBAAsBxD,GAAIR,EAAID,EAAEQ,OAAQP,IAAS8D,EAAEC,QAAQhE,EAAEC,IAAM,IAC1F2D,EAAE5D,EAAEC,IAAMQ,EAAET,EAAEC,KACtB,OAAO2D,ECzCX,IAAIM,EACAC,EAWAC,EA4IAC,EAtJAC,GACIC,IAAM,IACNC,KAAM,KACNC,IAAM,IACNnE,EAAM,KACNoE,EAAM,KACNnE,EAAM,KACNoE,EAAM,KACNf,EAAM,MAIVhE,EAAQ,SAAUgF,GAEd,MACIlF,KAAS,cACTG,QAAS+E,EACTV,GAASA,EACTE,KAASA,IAIjBS,EAAO,SAAU1E,GAWb,OATIA,GAAKA,IAAMgE,GACXvE,EAAM,aAAeO,EAAI,iBAAmBgE,EAAK,KAMrDA,EAAKC,EAAKU,OAAOZ,GACjBA,GAAM,EACCC,GAGXY,EAAS,WAEL,IAAIA,EACAC,EAAS,GAMb,IAJW,MAAPb,IACAa,EAAS,IACTH,EAAK,MAEFV,GAAM,KAAOA,GAAM,KACtBa,GAAUb,EACVU,IAEJ,GAAW,MAAPV,EAEA,IADAa,GAAU,IACHH,KAAUV,GAAM,KAAOA,GAAM,KAChCa,GAAUb,EAGlB,GAAW,MAAPA,GAAqB,MAAPA,EAOd,IANAa,GAAUb,EACVU,IACW,MAAPV,GAAqB,MAAPA,IACda,GAAUb,EACVU,KAEGV,GAAM,KAAOA,GAAM,KACtBa,GAAUb,EACVU,IAIR,GADAE,GAAUC,EACLC,SAASF,GAGV,OAAOA,EAFPnF,EAAM,eAMdoF,EAAS,WAEL,IAAIE,EACAjF,EAEAkF,EADAH,EAAS,GAIb,GAAW,MAAPb,EACA,KAAOU,KAAQ,CACX,GAAW,MAAPV,EAEA,OADAU,IACOG,EACJ,GAAW,OAAPb,EAEP,GADAU,IACW,MAAPV,EAAY,CAEZ,IADAgB,EAAQ,EACHlF,EAAI,EAAGA,EAAI,IACZiF,EAAME,SAASP,IAAQ,IAClBI,SAASC,IAFCjF,GAAK,EAKpBkF,EAAgB,GAARA,EAAaD,EAEzBF,GAAUK,OAAOC,aAAaH,OAC3B,CAAA,GAA2B,iBAAhBb,EAAQH,GAGtB,MAFAa,GAAUV,EAAQH,QAKtBa,GAAUb,EAItBvE,EAAM,eAGV2F,EAAQ,WAIJ,KAAOpB,GAAMA,GAAM,KACfU,KA+FZR,EAAQ,WAMJ,OADAkB,IACQpB,GACR,IAAK,IACD,OA1CK,WAIL,IAAIqB,EACAC,KAEJ,GAAW,MAAPtB,EAAY,CAGZ,GAFAU,EAAK,KACLU,IACW,MAAPpB,EAEA,OADAU,EAAK,KACEY,EAEX,KAAOtB,GAAI,CASP,GARAqB,EAAMR,IACNO,IACAV,EAAK,KACD7D,OAAOmC,eAAed,KAAKoD,EAAQD,IACnC5F,EAAM,kBAAoB4F,EAAM,KAEpCC,EAAOD,GAAOnB,IACdkB,IACW,MAAPpB,EAEA,OADAU,EAAK,KACEY,EAEXZ,EAAK,KACLU,KAGR3F,EAAM,cAWC6F,GACX,IAAK,IACD,OAvEI,WAIJ,IAAIC,KAEJ,GAAW,MAAPvB,EAAY,CAGZ,GAFAU,EAAK,KACLU,IACW,MAAPpB,EAEA,OADAU,EAAK,KACEa,EAEX,KAAOvB,GAAI,CAGP,GAFAuB,EAAMhF,KAAK2D,KACXkB,IACW,MAAPpB,EAEA,OADAU,EAAK,KACEa,EAEXb,EAAK,KACLU,KAGR3F,EAAM,aA+CC8F,GACX,IAAK,IACD,OAAOV,IACX,IAAK,IACD,OAAOD,IACX,QACI,OAAOZ,GAAM,KAAOA,GAAM,IAAMY,IA3G7B,WAIH,OAAQZ,GACR,IAAK,IAKD,OAJAU,EAAK,KACLA,EAAK,KACLA,EAAK,KACLA,EAAK,MACE,EACX,IAAK,IAMD,OALAA,EAAK,KACLA,EAAK,KACLA,EAAK,KACLA,EAAK,KACLA,EAAK,MACE,EACX,IAAK,IAKD,OAJAA,EAAK,KACLA,EAAK,KACLA,EAAK,KACLA,EAAK,KACE,KAEXjF,EAAM,eAAiBuE,EAAK,KAkFewB,KAOnD,IC5OIC,EACAC,EAUAC,EAZAC,EAAY,2HAGZC,GACIC,KAAM,MACNC,KAAM,MACNC,KAAM,MACNC,KAAM,MACNC,KAAM,MACN9B,IAAM,MACNC,KAAM,QAId,SAAS8B,EAAMtB,GAOX,OADAe,EAAUQ,UAAY,EACfR,EAAUS,KAAKxB,GAAU,IAAMA,EAAOzD,QAAQwE,EAAW,SAAUU,GACtE,IAAItG,EAAI6F,EAAKS,GACb,MAAoB,iBAANtG,EAAiBA,EAC3B,OAAS,OAASsG,EAAEC,WAAW,GAAGC,SAAS,KAAKvE,OAAO,KAC1D,IAAM,IAAM4C,EAAS,IAmG9B,IC7HI4B,EAAuB,oBAATvF,KAAuBA,YF8OxB,SAAUwF,EAAQC,GAC/B,IAAIC,EAiBJ,OAfA3C,EAAOyC,EACP3C,EAAK,EACLC,EAAK,IACL4C,EAAS1C,IACTkB,IACIpB,GACAvE,EAAM,gBASgB,mBAAZkH,EAA0B,SAASE,EAAKC,EAAQzB,GAC1D,IAAI0B,EAAGC,EAAG9C,EAAQ4C,EAAOzB,GACzB,GAAInB,GAA0B,iBAAVA,EAChB,IAAK6C,KAAK7C,EACFrD,OAAOwC,UAAUL,eAAed,KAAKgC,EAAO6C,UAElCE,KADVD,EAAIH,EAAK3C,EAAO6C,IAEZ7C,EAAM6C,GAAKC,SAEJ9C,EAAM6C,IAK7B,OAAOJ,EAAQzE,KAAK4E,EAAQzB,EAAKnB,GAdD,EAejCgD,GAAIN,GAAS,IAAOA,aClJV,SAAU1C,EAAOiD,EAAUC,GACxC,IAAItH,EAMJ,GALA2F,EAAM,GACNC,EAAS,GAIY,iBAAV0B,EACP,IAAKtH,EAAI,EAAGA,EAAIsH,EAAOtH,GAAK,EACxB4F,GAAU,QAIQ,iBAAV0B,IACZ1B,EAAS0B,GAMb,GADAzB,EAAMwB,EACFA,GAAgC,mBAAbA,IACC,iBAAbA,GAAoD,iBAApBA,EAAS9G,QAChD,MAAM,IAAIV,MAAM,kBAKpB,OA3HJ,SAAS0H,EAAIhC,EAAKyB,GAEd,IAAIhH,EACAiH,EACAC,EACA3G,EAEAiH,EADAC,EAAO9B,EAEPvB,EAAQ4C,EAAOzB,GAenB,OAZInB,GAA0B,iBAAVA,GACY,mBAAjBA,EAAMsD,SACjBtD,EAAQA,EAAMsD,OAAOnC,IAKN,mBAARM,IACPzB,EAAQyB,EAAIzD,KAAK4E,EAAQzB,EAAKnB,WAInBA,GACX,IAAK,SACD,OAAOiC,EAAMjC,GAEjB,IAAK,SAED,OAAOY,SAASZ,GAASgB,OAAOhB,GAAS,OAE7C,IAAK,UACL,IAAK,OAID,OAAOgB,OAAOhB,GAElB,IAAK,SACD,IAAKA,EAAO,MAAO,OAKnB,GAJAuB,GAAOC,EACP4B,KAG+C,mBAA3CzG,OAAOwC,UAAUmD,SAASpE,MAAM8B,GAA6B,CAE7D,IADA7D,EAAS6D,EAAM7D,OACVP,EAAI,EAAGA,EAAIO,EAAQP,GAAK,EACzBwH,EAAQxH,GAAKuH,EAAIvH,EAAGoE,IAAU,OASlC,OAJA8C,EAAuB,IAAnBM,EAAQjH,OAAe,KAAOoF,EAC9B,MAAQA,EAAM6B,EAAQ7F,KAAK,MAAQgE,GAAO,KAAO8B,EAAO,IACxD,IAAMD,EAAQ7F,KAAK,KAAO,IAC9BgE,EAAM8B,EACCP,EAKX,GAAIrB,GAAsB,iBAARA,EAEd,IADAtF,EAASsF,EAAItF,OACRP,EAAI,EAAGA,EAAIO,EAAQP,GAAK,EAER,iBADjBiH,EAAIpB,EAAI7F,MAEJkH,EAAIK,EAAIN,EAAG7C,KAEPoD,EAAQ/G,KAAK4F,EAAMY,IAAMtB,EAAM,KAAO,KAAOuB,QAOzD,IAAKD,KAAK7C,EACFrD,OAAOwC,UAAUL,eAAed,KAAKgC,EAAO6C,KAC5CC,EAAIK,EAAIN,EAAG7C,KAEPoD,EAAQ/G,KAAK4F,EAAMY,IAAMtB,EAAM,KAAO,KAAOuB,GAajE,OAJAA,EAAuB,IAAnBM,EAAQjH,OAAe,KAAOoF,EAC9B,MAAQA,EAAM6B,EAAQ7F,KAAK,MAAQgE,GAAO,KAAO8B,EAAO,IACxD,IAAMD,EAAQ7F,KAAK,KAAO,IAC9BgE,EAAM8B,EACCP,GA+BJK,CAAI,IAAKH,GAAIhD,MCtJxBuD,EAAiB,SAAUC,EAAKC,GACvBA,IAAMA,MACS,mBAATA,IAAqBA,GAASC,IAAKD,IAC9C,IAAIP,EAAQO,EAAKP,OAAS,GACL,iBAAVA,IAAoBA,EAAQ1G,MAAM0G,EAAM,GAAG3F,KAAK,MAC3D,IAGiC8C,EAH7BsD,EAAiC,kBAAhBF,EAAKE,QAAwBF,EAAKE,OACnDV,EAAWQ,EAAKR,UAAY,SAAS9B,EAAKnB,GAAS,OAAOA,GAE1D0D,EAAMD,EAAKC,MAAkBrD,EAQ9BoD,EAAKC,IAPG,SAAUE,GACb,OAAO,SAAUxB,EAAGnG,GAChB,IAAI4H,GAAS1C,IAAKiB,EAAGpC,MAAO4D,EAAKxB,IAC7B0B,GAAS3C,IAAKlF,EAAG+D,MAAO4D,EAAK3H,IACjC,OAAOoE,EAAEwD,EAAMC,MAKvBC,KACJ,OAAO,SAAU9G,EAAW+G,EAAQ7C,EAAKyC,EAAMjG,GAC3C,IAAI6D,EAAS0B,EAAS,KAAO,IAAI1G,MAAMmB,EAAQ,GAAGJ,KAAK2F,GAAU,GAC7De,EAAiBf,EAAQ,KAAO,IAQpC,GANIU,GAAQA,EAAKN,QAAiC,mBAAhBM,EAAKN,SACnCM,EAAOA,EAAKN,eAKHP,KAFba,EAAOX,EAASjF,KAAKgG,EAAQ7C,EAAKyC,IAElC,CAGA,GAAoB,iBAATA,GAA8B,OAATA,EAC5B,OAAOrB,EAAKtF,UAAU2G,GAE1B,GAAIrH,EAAQqH,GAAO,CAEf,IADA,IAAIM,KACKtI,EAAI,EAAGA,EAAIgI,EAAKzH,OAAQP,IAAK,CAClC,IAAIuI,EAAOlH,EAAU2G,EAAMhI,EAAGgI,EAAKhI,GAAI+B,EAAM,IAAM4E,EAAKtF,UAAU,MAClEiH,EAAI7H,KAAKmF,EAAS0B,EAAQiB,GAE9B,MAAO,IAAMD,EAAI3G,KAAK,KAAOiE,EAAS,IAGtC,IAA4B,IAAxBuC,EAAKpE,QAAQiE,GAAc,CAC3B,GAAID,EAAQ,OAAOpB,EAAKtF,UAAU,aAClC,MAAM,IAAImH,UAAU,yCAEnBL,EAAK1H,KAAKuH,GAEf,IAAIS,EAAOC,EAAWV,GAAMW,KAAKb,GAAOA,EAAIE,IAE5C,IADIM,KACKtI,EAAI,EAAGA,EAAIyI,EAAKlI,OAAQP,IAAK,CAClC,IACIoE,EAAQ/C,EAAU2G,EADlBzC,EAAMkD,EAAKzI,GACkBgI,EAAKzC,GAAMxD,EAAM,GAElD,GAAIqC,EAAJ,CAEA,IAAIwE,EAAWjC,EAAKtF,UAAUkE,GACxB8C,EACAjE,EAENkE,EAAI7H,KAAKmF,EAAS0B,EAAQsB,IAG9B,OADAT,EAAKU,OAAOV,EAAKpE,QAAQiE,GAAO,GACzB,IAAMM,EAAI3G,KAAK,KAAOiE,EAAS,KA9CvC,EAgDFwB,GAAIQ,GAAO,GAAIA,EAAK,IAGzBjH,EAAUC,MAAMD,SAAW,SAAUO,GACrC,MAA+B,sBAArBwF,SAAStE,KAAKlB,IAGxBwH,EAAa3H,OAAO0H,MAAQ,SAAUb,GACtC,IAAIkB,EAAM/H,OAAOwC,UAAUL,gBAAkB,WAAc,OAAO,GAC9DuF,KACJ,IAAK,IAAIlD,KAAOqC,EACRkB,EAAI1G,KAAKwF,EAAKrC,IAAMkD,EAAKhI,KAAK8E,GAEtC,OAAOkD,cCpEiBM,GAC1B,QAASA,EAAGC,GAGd,SAAAC,EAA6BF,GAC3B,QAASA,EAAGG,IAGd,SAAAC,EAA6BJ,GAC3B,QAASA,EAAGK,ICTd,SAAAC,EAA0DzB,EAAQ0B,GAEhE,IADA,IAAMC,KACaC,EAAA,EAAAC,EAAAH,EAAAE,EAAAC,EAAAlJ,OAAAiJ,IAAO,CAArB,IAAME,EAAID,EAAAD,GACT5B,EAAI1E,eAAewG,KACrBH,EAAKG,GAAQ9B,EAAI8B,IAGrB,OAAOH,EAOT,SAAAI,EAA0D/B,EAAQ0B,GAEhE,IADA,IAAMC,EAAI9F,KAAOmE,GACE4B,EAAA,EAAAI,EAAAN,EAAAE,EAAAI,EAAArJ,OAAAiJ,IAAO,QACjBD,EADMK,EAAAJ,IAGf,OAAOD,EAMF,IAAMlI,EAAYwI,EAKzB,SAAAC,EAAqBtD,GACnB,GAAI5D,EAAS4D,GACX,OAAOA,EAGT,IAAMe,EAAMvG,EAASwF,GAAKA,EAAIqD,EAAgBrD,GAG9C,GAAIe,EAAIhH,OAAS,IACf,OAAOgH,EAKT,IADA,IAAIwC,EAAI,EACC/J,EAAI,EAAGA,EAAIuH,EAAIhH,OAAQP,IAAK,CAEnC+J,GAAMA,GAAG,GAAGA,EADCxC,EAAId,WAAWzG,GAE5B+J,GAAQA,EAEV,OAAOA,EAGT,SAAAC,EAA4BvE,EAAY8C,GACtC,OAAO9C,EAAM1B,QAAQwE,IAAS,EAIhC,SAAA0B,EAA2BxE,EAAYyE,GACrC,OAAOzE,EAAM0E,OAAO,SAAA5B,GAAQ,OAACyB,EAASE,EAAe3B,KAUvD,SAAA6B,EAAwBC,EAAU5F,GAEhC,IADA,IAAIzE,EAAI,EACCiH,EAAI,EAAGA,EAAEoD,EAAI9J,OAAQ0G,IAC5B,GAAIxC,EAAE4F,EAAIpD,GAAIA,EAAGjH,KACf,OAAO,EAGX,OAAO,EAMR,SAAAsK,EAAyBD,EAAU5F,GAElC,IADA,IAAIzE,EAAI,EACCiH,EAAI,EAAGA,EAAEoD,EAAI9J,OAAQ0G,IAC5B,IAAKxC,EAAE4F,EAAIpD,GAAIA,EAAGjH,KAChB,OAAO,EAGX,OAAO,EAGT,SAAAuK,EAAwBC,GACtB,SAAUtI,OAAOI,SAAUkI,GAM7B,SAAAC,GAA6BC,OAAS,IAAAC,KAAAnB,EAAA,EAAAA,EAAA5F,UAAArD,OAAAiJ,IAAAmB,EAAAnB,EAAA,GAAA5F,UAAA4F,GACpC,IAAgB,IAAAoB,EAAA,EAAAC,EAAAF,EAAAC,EAAAC,EAAAtK,OAAAqK,IAAK,CACnBF,EAAOI,GAAWJ,EADRG,EAAAD,IAGZ,OAAOF,EAIT,SAAAI,GAAoBJ,EAAWC,GAC7B,GAAmB,iBAARA,GAA4B,OAARA,EAC7B,OAAOD,EAGT,IAAK,IAAM3K,KAAK4K,EACTA,EAAIzH,eAAenD,SAGToH,IAAXwD,EAAI5K,KAGc,iBAAX4K,EAAI5K,IAAmBY,EAAQgK,EAAI5K,KAAkB,OAAX4K,EAAI5K,GACvD2K,EAAK3K,GAAK4K,EAAI5K,GACc,iBAAZ2K,EAAK3K,IAA+B,OAAZ2K,EAAK3K,GAC7C2K,EAAK3K,GAAK0K,GAAU9J,EAAQgK,EAAI5K,GAAGuD,mBAAwBqH,EAAI5K,IAE/D0K,GAAUC,EAAK3K,GAAI4K,EAAI5K,KAG3B,OAAO2K,EAGT,SAAAK,GAA0BC,EAAavG,GAIrC,IAHA,IAEIyC,EAFE+D,KACAC,KAEY1B,EAAA,EAAA2B,EAAAH,EAAAxB,EAAA2B,EAAA5K,OAAAiJ,IAAQ,CAArB,IAAM4B,EAAGD,EAAA3B,IACZtC,EAAIzC,EAAE2G,MACGF,IAGTA,EAAEhE,GAAK,EACP+D,EAAQxK,KAAK2K,IAEf,OAAOH,EAYT,SAAAI,GAA0BC,EAAeC,GACvC,IAAK,IAAMhG,KAAO+F,EAChB,GAAIA,EAAKpI,eAAeqC,IAClBgG,EAAMhG,IAAQ+F,EAAK/F,IAAQgG,EAAMhG,KAAS+F,EAAK/F,GACjD,OAAO,EAIb,OAAO,EAGT,SAAAiG,GAAgChF,EAAcnG,GAC5C,IAAK,IAAMkF,KAAOiB,EAChB,GAAIjB,KAAOlF,EACT,OAAO,EAGX,OAAO,EAyBF,IAAMoI,GAAO1H,OAAO0H,KAE3B,SAAAgD,GAAwBvK,GACtB,IAAMwK,KACN,IAAK,IAAMzE,KAAK/F,EACVA,EAAEgC,eAAe+D,IACnByE,EAAMjL,KAAKS,EAAE+F,IAGjB,OAAOyE,EAST,SAAAC,GAA2ClH,GACzC,OAAOgE,GAAKhE,GAGd,SAAAmH,GAA6BhE,GAC3B,OAAOxG,KAAKyK,MAAMzK,KAAKC,UAAUuG,IAGnC,SAAAkE,GAA0BzL,GACxB,OAAa,IAANA,IAAoB,IAANA,EAMvB,SAAA0L,GAAwBvL,GAEtB,IAAMwL,EAAgBxL,EAAEc,QAAQ,MAAO,KAGvC,OAAQd,EAAEyL,MAAM,QAAU,IAAM,IAAMD,EAGxC,SAAAE,GAA+BnD,EAAuBoD,GACpD,OAAIhD,EAAaJ,GACR,KAAOmD,GAAYnD,EAAGK,IAAK+C,GAAM,IAC/BlD,EAAaF,GACf,IAAMA,EAAGG,IAAI/H,IAAI,SAAC+H,GAA2B,OAAAgD,GAAYhD,EAAKiD,KAAKxK,KAAK,UAAY,IAClFyK,EAAYrD,GACd,IAAMA,EAAGC,GAAG7H,IAAI,SAAC6H,GAA0B,OAAAkD,GAAYlD,EAAImD,KAAKxK,KAAK,UAAY,IAEjFwK,EAAGpD,GASd,SAAAsD,GAAqCzE,EAAU0E,GAC7C,GAA4B,IAAxBA,EAAa/L,OACf,OAAO,EAET,IAAMmJ,EAAO4C,EAAaC,QAI1B,OAHIF,GAAqBzE,EAAI8B,GAAO4C,WAC3B1E,EAAI8B,GAEsB,IAA5B3I,OAAO0H,KAAKb,GAAKrH,OAG1B,SAAAiM,GAA0BhM,GACxB,OAAOA,EAAEqE,OAAO,GAAG4H,cAAgBjM,EAAEkM,OAAO,GAQ9C,SAAAC,GAAoCxM,EAAcyM,QAAA,IAAAA,IAAAA,EAAA,SAGhD,IAFA,IAAMC,EAAS/M,EAAgBK,GACzB2M,KACG9M,EAAI,EAAGA,GAAK6M,EAAOtM,OAAQP,IAAK,CACvC,IAAM+M,EAAS,IAAIF,EAAO1K,MAAM,EAAEnC,GAAGmB,IAAIO,GAAaC,KAAK,MAAK,IAChEmL,EAASrM,KAAK,GAAGmM,EAAQG,GAE3B,OAAOD,EAASnL,KAAK,QAQvB,SAAAqL,GAAoC7M,EAAcyM,GAChD,YADgD,IAAAA,IAAAA,EAAA,SACtCA,EAAK,IAAIlL,EAAY5B,EAAgBK,GAAMwB,KAAK,MAAK,IAOjE,SAAAsL,GAAmC9M,GACjC,MAAO,GAAGL,EAAgBK,GAAMgB,IAAI,SAAApB,GAAK,OAAAA,EAAEuB,QAAQ,IAAK,SAAQK,KAAK,OAOvE,SAAAuL,GAAoC/M,GAClC,MAAO,GAAGL,EAAgBK,GAAMwB,KAAK,KAMvC,SAAAwL,GAAgChN,GAC9B,OAAKA,EAGEL,EAAgBK,GAAMI,OAFpB,oFA5PX,SAAyBkF,EAAY8F,GACnC,OAAO9F,EAAMvD,OAAO+H,EAAQsB,EAAO9F,4FA+GrC,SAA0B2H,GACxB,OAAQC,MAAMD,gBAGhB,SAA+B3H,EAAY8F,GACzC,GAAI9F,EAAMlF,SAAWgL,EAAMhL,OACzB,OAAO,EAGTkF,EAAMkD,OACN4C,EAAM5C,OAEN,IAAK,IAAI3I,EAAI,EAAGA,EAAIyF,EAAMlF,OAAQP,IAChC,GAAIuL,EAAMvL,KAAOyF,EAAMzF,GACrB,OAAO,EAIX,OAAO,wOCzMHsN,IACJC,OAAQ,EACRC,OAAQ,EACRC,QAAS,EACTC,MAAO,EACPC,SAAU,EACVC,IAAK,EACLC,KAAM,EACNC,OAAQ,EACRC,IAAK,EACLC,QAAS,EACTC,GAAI,EACJC,GAAI,EACJC,IAAK,EACLC,IAAK,EACLC,OAAQ,EACRC,MAAO,EACPC,OAAQ,EACRC,IAAK,EACLC,MAAO,EACPzD,OAAQ,EACR0D,SAAU,EACVC,UAAW,GAGAC,GAAgBjD,GAAS2B,IAEtC,SAAAuB,GAA8BrI,GAC5B,QAAS8G,GAAmB9G,GAGvB,IAAMsI,IAA+B,QAAS,QAAS,UAAW,YAEzE,SAAAC,GAAsCC,GACpC,OAAOA,GAAahF,EAAS8E,GAAcE,GAItC,IAAMC,IACT,QACA,MACA,WACA,QACA,WAMSC,IACT,OACA,UACA,SACA,KACA,KACA,MACA,OAGSC,GAAyBtM,EAAMqM,6JCc/BE,IAA0B,SAAU,OAAQ,SAAU,QAAS,SAQ/DC,IAIXC,KAAM,OACNC,UAAW,OAEXC,OAAQ,OACRC,OAAQ,OACRC,WAAY,OACZC,aAAc,OACdC,UAAW,OACXC,UAAW,OACXC,OAAQ,OACRC,MAAO,OACPC,MAAO,OACPhF,OAAQ,OAERiF,MAAO,OACPC,OAAQ,QAmCJC,IACJC,OAAQ,EAERZ,OAAQ,EACRa,OAAQ,EACRf,KAAM,EACNgB,WAAY,EACZZ,WAAY,EACZa,aAAc,EACdd,OAAQ,EACRE,aAAc,EACdE,UAAW,EACXD,UAAW,EACXE,OAAQ,EACRU,SAAU,EACVC,UAAW,EACXV,MAAO,EACPW,SAAU,EACVV,MAAO,EACPW,aAAc,EACd3F,OAAQ,EACRkF,OAAQ,GAGJU,GAAqBnN,KACtB0M,IACHU,SAAU,EACVC,WAAY,EACZC,eAAgB,IAUlB,SAAAC,GAA+BtH,GAC7B,QAASkH,GAAsBlH,GAG1B,IC1KUuH,GD0KJC,GAAqBvF,GAXJlI,GAC5BwM,MAAO,GACJE,IACHZ,UAAW,EACX4B,OAAQ,KAUGC,GAAkBzF,GAASiF,wHC7KxC,SAAiBK,GAEFA,EAAAI,IAAa,MACbJ,EAAAK,OAAmB,SAGnBL,EAAAM,EAAS,IACTN,EAAAO,EAAS,IACTP,EAAAQ,GAAW,KACXR,EAAAS,GAAW,KAGXT,EAAAU,SAAuB,WACvBV,EAAAW,UAAyB,YACzBX,EAAAY,UAAyB,YACzBZ,EAAAa,WAA2B,aAG3Bb,EAAAc,MAAiB,QAEjBd,EAAAe,KAAe,OAEff,EAAAgB,OAAmB,SAEnBhB,EAAAiB,MAAiB,QACjBjB,EAAAkB,KAAe,OACflB,EAAAmB,QAAqB,UAGrBnB,EAAAoB,KAAe,OACfpB,EAAAqB,MAAiB,QACjBrB,EAAAsB,OAAmB,SACnBtB,EAAAuB,IAAa,MAEbvB,EAAAwB,QAAqB,UACrBxB,EAAAyB,KAAe,OAnC9B,CAAiBzB,KAAAA,QAwCV,IAAMM,GAAIN,GAAQM,EACZC,GAAIP,GAAQO,EACZC,GAAKR,GAAQQ,GACbC,GAAKT,GAAQS,GAEbC,GAAWV,GAAQU,SACnBE,GAAYZ,GAAQY,UACpBD,GAAYX,GAAQW,UACpBE,GAAab,GAAQa,WAErBT,GAAMJ,GAAQI,IACdC,GAASL,GAAQK,OACjBY,GAAQjB,GAAQiB,MAChBC,GAAOlB,GAAQkB,KACfJ,GAAQd,GAAQc,MAEhBC,GAAOf,GAAQe,KACfC,GAAShB,GAAQgB,OACjBI,GAAOpB,GAAQoB,KACfE,GAAStB,GAAQsB,OACjBC,GAAMvB,GAAQuB,IACdF,GAAQrB,GAAQqB,MAChBF,GAAUnB,GAAQmB,QAClBK,GAAUxB,GAAQwB,QAClBC,GAAOzB,GAAQyB,KAIfC,IACXC,UAAW,EACXC,WAAY,EACZC,SAAU,EACVC,UAAW,GAGAC,GAAuBrH,GAASgH,IAEvCM,GAAkBxP,GAEtBvC,EAAG,EACHgS,EAAG,EACHC,GAAI,EACJC,GAAI,GAEDT,IAGHU,MAAO,EACPC,KAAM,EACNC,OAAQ,EAGRC,QAAS,EACTC,KAAM,EACNC,MAAO,EAGPC,MAAO,EACPxP,KAAM,EACNyP,OAAQ,EACRrO,IAAK,EACLsO,QAAS,EACTC,KAAM,IAKR,SAAAC,GAA+BC,GAC7B,MAAmB,UAAZA,GAAmC,SAAZA,GAAkC,WAAZA,EAGtD,IAKMC,GAAaxQ,KACdwP,IALHiB,IAAK,EACLC,OAAQ,IAQGC,GAAWzI,GAASsI,IAYpBI,IAVNJ,GAAAN,MAAWM,GAAAL,OAUqCjI,GAVzB9H,EAAAoQ,IAAA,QAAA,aAsB9B,SAAAK,GAA0B/M,GACxB,QAAS0M,GAAc1M,GAIlB,IAAMgN,GAAgB5I,GAASsH,IAWpCuB,IANAvB,GAAA/R,EAAO+R,GAAAC,EAEPD,GAAAE,GAASF,GAAAG,GACTH,GAAAH,SAAqBG,GAAAL,UACrBK,GAAAF,UAAuBE,GAAAJ,WAEvBhP,EAAAoP,IAAA,IAAA,IAAA,KAAA,KAAA,WAAA,YAAA,YAAA,gBAGWwB,GAAuB9I,GAAS6I,IAIvCE,IAA4CxT,EAAE,EAAGgS,EAAE,GAC5CyB,GAA0BhJ,GAAS+I,IAW9CE,GAAA/Q,EAAA2Q,IAAA,OAAA,UAAA,OAAA,SAAA,MAAA,UAEWK,GAA6BlJ,GAASiJ,IAI7CE,GAAmBrR,KACpBiR,GACAE,IAIQG,GAAiBpJ,GAASmJ,IAGvC,SAAAE,GAA+BhB,GAC7B,QAASc,GAAoBd,GAa/B,SAAAiB,GAA4BjB,EAAkBkB,GAC5C,OAAOA,KAAQC,GAAiBnB,GAQlC,SAAAmB,GAAiCnB,GAC/B,OAAQA,GACN,KAAKjC,GACL,KAAKC,GACL,KAAKC,GAEL,KAAKM,GACL,KAAKC,GACL,KAAKC,GACL,KAAKC,GACL,KAAKJ,GACL,KAAKF,GACL,KAAKf,GACL,KAAKC,GACH,OACE8D,OAAO,EAAMC,MAAM,EAAMC,MAAM,EAAMC,QAAQ,EAAMC,QAAQ,EAC3DC,KAAK,EAAMC,MAAM,EAAMC,MAAM,EAAMC,OAAO,EAAMC,MAAM,EAAM1R,MAAM,EAAM2R,UAAU,GAEtF,KAAKvE,GACL,KAAKC,GACL,KAAKG,GACL,KAAKC,GACH,OACEwD,OAAO,EAAMC,MAAM,EAAMC,MAAM,EAAMC,QAAQ,EAAMC,QAAQ,EAC3DC,KAAK,EAAMC,MAAM,EAAMC,MAAM,EAAMC,OAAO,EAAMC,MAAM,EAAM1R,MAAM,GAEtE,KAAKsN,GACL,KAAKC,GACL,KAAKG,GACL,KAAKC,GACH,OACEwD,MAAM,EAAMG,KAAK,EAAMC,MAAM,EAAMG,MAAM,GAE7C,KAAK1D,GACH,OACEiD,OAAO,EAAMC,MAAM,EAAMC,MAAM,EAAMC,QAAQ,EAAMC,QAAQ,EAC3DC,KAAK,EAAMtR,MAAM,EAAMwR,MAAM,EAAMC,OAAO,GAE9C,KAAK1D,GACH,OAAQkD,OAAO,EAAMU,UAAU,GACjC,KAAKzD,GACH,OAAQlO,MAAM,IAIpB,SAAA4R,GAA0B/B,GACxB,OAAQA,GACN,KAAKzC,GACL,KAAKC,GACL,KAAKW,GACL,KAAKC,GAEL,KAAKX,GACL,KAAKC,GACH,MAAO,aAET,KAAKL,GACL,KAAKC,GACL,KAAKY,GAEL,KAAKG,GACL,KAAKI,GACL,KAAKC,GACH,MAAO,WAGT,KAAKX,GACL,KAAKC,GACL,KAAKC,GACH,MAAO,WAIT,KAAKN,GACL,KAAKC,GACL,KAAKC,GACL,KAAKC,GACL,KAAKS,GACL,KAAKC,GACL,KAAKF,GACH,OAGJ,MAAM,IAAIzS,MAAM,iCAAmCmU,ojBCnPzBgC,GAC1B,OAAIrT,EAAUqT,GACL,MAEF,MAAQvN,GAAKuN,GAAK7U,IAAI,SAAApB,GAAK,OAAAgM,GAAQ,IAAIhM,EAAC,IAAIiW,EAAIjW,MAAO4B,KAAK,IAGrE,SAAAsU,GAA4BD,GAC1B,OAAOA,IAAQrT,EAAUqT,GAG3B,SAAAE,GAA4BlC,GAC1B,OAAQA,GACN,KAAK3C,GACL,KAAKC,GACL,KAAKa,GACL,KAAKJ,GACL,KAAKC,GACL,KAAKC,GACL,KAAKG,GAGL,KAAKF,GACH,OAAO,EACT,QACE,OAAO,QCzFIiE,qEAAjB,SAAiBA,GACFA,EAAAC,KAAe,OACfD,EAAAE,IAAa,MACbF,EAAAG,KAAe,OACfH,EAAAI,MAAiB,QACjBJ,EAAAK,KAAe,OACfL,EAAAM,KAAe,OACfN,EAAA9D,KAAe,OACf8D,EAAAO,KAAe,OACfP,EAAAQ,MAAiB,QACjBR,EAAAS,OAAmB,SACnBT,EAAAU,OAAmB,SACnBV,EAAAW,SAAuB,WAZtC,CAAiBX,KAAAA,QAqBV,IAAMC,GAAOD,GAAKC,KACZC,GAAMF,GAAKE,IACXC,GAAOH,GAAKG,KACZC,GAAQJ,GAAKI,MACblE,GAAO8D,GAAK9D,KACZqE,GAAOP,GAAKO,KACZC,GAAQR,GAAKQ,MACbH,GAAOL,GAAKK,KACZC,GAAON,GAAKM,KACZK,GAAWX,GAAKW,SAEhBF,GAAST,GAAKS,OACdC,GAASV,GAAKU,OAGrBE,IACJlB,KAAM,EACNJ,IAAK,EACLE,KAAM,EACNP,MAAO,EACPjR,KAAM,EACNkR,KAAM,EACNO,MAAO,EACPF,KAAM,EACNI,SAAU,EACVR,KAAM,EACNC,OAAQ,EACRC,OAAQ,GAOV,SAAAwB,GAA2BrS,GACzB,OAAOqF,GAAU,OAAQ,OAAQ,SAAUrF,GAGtC,IAAMsS,GAAkBtL,GAASoL,IA+CxC,SAAAG,GAA0BhC,GACxB,OAAOA,EAAW,KAGpB,IAAMiC,GAAuBtU,EAAMoU,IAEnC,SAAAG,GAAgClC,GAE9B,OADiBgC,GAAUhC,GAAQA,EAAKmC,KAAOnC,KAC5BiC,GAGd,Id9GDpV,GeiFWnC,GD6BJ0X,IAAiB,SAAU,cACtC,aAAc,mBAAoB,gBAAiB,aAAc,oBAEtDC,IAAe,OAAQ,eAEvBC,MAAwBtV,OAAOoV,GAAeC,IAE9CE,IAAwD,SAAU,SAElEC,IAGX7B,MAAO,OAAQ,SACfJ,KAAM,aAAc,qBAAsB,oBAC1CE,MAAO,SACPxR,MAAO,mBACPkR,MAAO,WAAY,cAGRsC,IACXtE,MAAO,WA6JIuE,IACXC,WAAY,EACZC,mBAAoB,GAoBTC,IACXC,UAAW,2JA1Qb,SAAuBrT,GACrB,QAASoS,GAAWpS,4QClChBsT,IfXAlW,GeWcS,GfXDD,GAEfR,MAAO,SAASjB,GACd,OAAI8C,UAAUrD,QACZwB,IAASjB,EACFuC,MAEAtB,IAGXpC,MAAO,WAEL,OADIoC,IAASlC,GAAOgC,EAAI,QAAS,QAAS+B,WACnCP,MAET6U,KAAM,WAEJ,OADInW,IAASS,GAAMX,EAAI,OAAQ,OAAQ+B,WAChCP,MAET8U,KAAM,WAEJ,OADIpW,IAASU,GAAMZ,EAAI,MAAO,OAAQ+B,WAC/BP,MAET+U,MAAO,WAEL,OADIrW,IAASW,GAAOb,EAAI,MAAO,QAAS+B,WACjCP,QeZTgV,GAA2BJ,GAsD/B,SAAAC,SAAqB,IAAApX,KAAA0I,EAAA,EAAAA,EAAA5F,UAAArD,OAAAiJ,IAAA1I,EAAA0I,GAAA5F,UAAA4F,GACnB6O,GAAQH,KAAK5V,MAAM+V,GAASzU,YAc9B,SAAiBhE,GACFA,EAAA0Y,aAAe,eAGf1Y,EAAA2Y,eAAiB,gEAEjB3Y,EAAA4Y,+BAAiC,oEAG9B5Y,EAAA6Y,mCAAhB,SAAmDzE,GACjD,MAAO,mDAAmDA,EAAO,0BAGnDpU,EAAA8Y,+BAAhB,SAA+CxD,GAC7C,MAAO,gDAAgDA,EAAI,WAG7CtV,EAAA+Y,kBAAhB,SAAkClZ,GAChC,MAAO,kCAAkCA,EAAI,KAGlCG,EAAAgZ,0BAA4B,4FAGzBhZ,EAAAiZ,oBAAhB,SAAoCrX,GAClC,MAAO,2BAA2BA,EAAK,MAI5B5B,EAAAkZ,yBAA2B,+CAG3BlZ,EAAAmZ,yBAA2B,2CAGxBnZ,EAAAoZ,qBAAhB,SAAqC3B,GACnC,MAAO,mCAAmCA,EAAI,SAIhCzX,EAAAqZ,kBAAhB,SAAkClZ,GAChC,MAAO,uBAAuBA,EAAC,MAGjBH,EAAAsZ,eAAhB,SAA+B1X,EAAe2X,EAAeC,GAC3D,MAAO,6BAA6B5X,EAAK,QAAQ4X,EAAQ,4CAA4CD,EAAK,KAI5FvZ,EAAAyZ,wBAAhB,SAAwCC,GACtC,MAAO,kCAAkCjY,EAAUiY,GAAU,KAGlD1Z,EAAA2Z,mBAAqB,uIAIlB3Z,EAAA4Z,mBAAhB,SAAmCC,GACjC,MAAO,kBAAkBA,EAAS9X,KAAK,KAAI,aAAgC,IAApB8X,EAASlZ,OAAe,KAAO,OAAK,cAE7EX,EAAA8Z,qBAAhB,SAAqCC,GAC5B,IAAAC,EAAAD,EAAAC,iBAAkBC,EAAAF,EAAAE,WACzB,MAAO,6BAA6BxY,EAAUuY,GAAiB,wCAAwCvY,EAAUwY,GAAW,KAG9Gja,EAAAka,oBAAhB,SAAoC9F,EAAkBqD,EAAuCjT,GAC3F,MAAO,WAAW4P,EAAO,SAASqD,EAAI,0BAA0BhW,EAAU+C,GAAM,MAGlExE,EAAAma,iBAAhB,SAAiC1C,GAC/B,MAAO,uBAAuBA,EAAI,KAGpBzX,EAAAoa,+BAAhB,SACE9E,EAAsBlB,EACtB2F,GAMA,MAAO,MAJWA,EAAIM,UAAeN,EAAIM,UAAS,SAChDN,EAAIO,UAAY,wBAChB,+CAEmB,sBAAsBhF,EAAI,MAAMlB,EAAO,oCAA+C,MAAZA,EAAkB,QAAU,UAAQ,WAAWkB,EAAI,wFAGpItV,EAAAua,kCAAhB,SAAkD9C,EAAYrI,GAC5D,MAAO,uBAAuBqI,EAAI,qBAAqBrI,EAAS,oCAGlDpP,EAAAwa,iBAAhB,SAAiCpL,GAC/B,MAAO,iCAAiCA,EAAS,KAGnCpP,EAAAya,wBAAhB,SAAwChD,EAAqBrD,EAAkBsG,GAC7E,MAAO,uBAAuBjD,EAAI,kBAAkBrD,EAAO,aAAasG,EAAO,cAEjE1a,EAAA2a,cAAhB,SAA8BlD,EAA+BsC,GACpD,IAAArG,EAAAqG,EAAArG,KAAMC,EAAAoG,EAAApG,OACb,MAAO,kBAAkB8D,EAAI,0BAC3B/D,GAAQC,EAAS,kBAAoBD,EAAO,OAAS,WAIzC1T,EAAA4a,cAAhB,SAA8BC,EAA4BzG,GACxD,MAAO,YAAY3S,EAAUoZ,GAAS,kBAAkBzG,EAAO,oDAEjDpU,EAAA8a,kBAAhB,SAAkC1G,EAAkBqD,EAAYsD,GAC9D,OAAU3G,EAAO,uBAAuBqD,EAAI,kCAAkCsD,EAAU,cAG7E/a,EAAAgb,uBAAyB,mGAEtBhb,EAAAib,oBAAhB,SAAoC7G,EAAkB8G,EAA6CC,GACjG,OAAU/G,EAAO,wCAAwC8G,EAAW,KAAIC,EAAO,SAASA,EAAS,IAAE,KAGrFnb,EAAAob,uBAAhB,SAAuChH,GACrC,OAAUA,EAAO,2BAA2BA,EAAO,qCAGrCpU,EAAAqb,6BAAhB,SAA6CjH,GAC3C,OAAUA,EAAO,8DAGHpU,EAAAsb,4BAAhB,SAA4ClH,EAAkBqD,GAC5D,MAAO,2BAA2BrD,EAAO,gBAAgBqD,EAAI,oDAA4D,YAATA,EAAqB,QAAU,aAAW,KAI/IzX,EAAAub,wCAA0C,sGAEvCvb,EAAAwb,cAAhB,SAA8BC,EAAgBC,GAE5C,MAAO,mEADUD,GAASC,EAAQ,YAAcD,EAAQ,KAAO,MACkB,wDAGnEzb,EAAA2b,iBAAhB,SAAiCC,EAAkBC,GACjD,MAAO,qBAAqBD,EAAQ,sBAAsBC,EAAM,KAIrD7b,EAAA8b,6CAA+C,wEAE5C9b,EAAA+b,mCAAhB,SAAmDjS,GACjD,MAAO,kCAAkCA,EAAI,6BAG/B9J,EAAAgc,wCAAhB,SAAwDnB,GACtD,MAAO,2DAA2DpZ,EAAUoZ,GAAS,MAGvE7a,EAAAic,uCAAhB,SAAuD7M,GACrD,MAAO,2CAA2CA,EAAS,4EAG7CpP,EAAAkc,+BAAhB,SAA+CrB,GAC7C,MAAO,+DAA+DpZ,EAAUoZ,GAAS,MAG3E7a,EAAAmc,iCAAhB,SAAiD7G,GAC/C,MAAO,2CAA2CA,EAAI,MAGxCtV,EAAAoc,iBAAhB,SAAiChI,GAC/B,MAAO,kBAAkBA,EAAO,8BAClB,MAAZA,EAAkB,QAAU,UAAQ,iBAGxBpU,EAAAqc,4BAAhB,SAA4CjI,EAAkBiG,EAAsBiC,GAClF,MAAO,YAAYlI,EAAO,yBAAyBiG,EAAS,0BAA0BiC,EAAgB,oBAGxFtc,EAAAuc,6BAAhB,SAA6ClC,EAAsBiC,GACjE,MAAO,gCAAgCjC,EAAS,0BAA0BiC,EAAgB,oBAG5Etc,EAAAwc,kCAAhB,SAAkDnC,EAAsBoC,EAAkBrI,GACxF,OAAUA,EAAO,cAAaqI,EAAQ,yCAAyCpC,EAAS,WAG1Era,EAAA0c,yBAAhB,SAAyCpH,EAAY+E,GACnD,MAAO,eAAeA,EAAS,8BAA8B/E,EAAI,MAGnDtV,EAAA2c,yBAAhB,SAA4CC,EAAoCC,EAAsCC,EAAOC,GAC3H,MAAO,eAAeF,EAAW/V,WAAU,cAAc8V,EAAS9V,WAAU,MAAMrF,EAAUqb,GAAG,QAAQrb,EAAUsb,GAAG,aAAatb,EAAUqb,GAAG,KAGhI9c,EAAAgd,sCAAhB,SAAsD5I,GACpD,MAAO,4CAA4CA,EAAO,6EAG5CpU,EAAAid,kBAAhB,SAAkClU,GAChC,MAAO,0BAA0BtH,EAAUsH,GAAK,2DAGrC/I,EAAAkd,wBAA0B,0BAE1Bld,EAAAmd,mBAAqB,4FAGrBnd,EAAAod,yBAA2B,4BAGxBpd,EAAAqd,sBAAhB,SAAsCjJ,GACpC,MAAO,iBAAiBA,EAAO,0BAA0BA,EAAO,MAGlDpU,EAAAsd,0BAAhB,SAA0CjD,GACxC,MAAO,kCAAkCA,EAAS,KAGpCra,EAAAud,2BAAhB,SAA2CnO,GACzC,MAAO,6EAA6EA,EAAS,MAI/EpP,EAAAwd,gBAAhB,SAAgCC,EAAkBjZ,GAChD,MAAO,WAAWiZ,EAAQ,KAAKhc,EAAU+C,IAG3BxE,EAAA0d,oBAAhB,SAAoCC,GAClC,MAAO,cAAcA,EAAY,gDAC/BA,EAAajc,QAAQ,MAAO,QAAO,KAGvB1B,EAAA4d,WAAhB,SAA2Bva,GACzB,MAAO,8BAA8B5B,EAAU4B,GAAE,gDAlOrD,CAAiBrD,KAAAA,QCnFjB,IAAM6d,GAAc,KA8GpB,SAAAC,GAA2BC,GACzB,SAASA,IAAQA,EAAEC,MAAUD,EAAEE,SAAaF,EAAEG,OAAWH,EAAEI,MAAUJ,EAAEK,KACnEL,EAAEM,OAAWN,EAAEO,SAAaP,EAAEQ,SAAaR,EAAES,eAG5C,IAAMC,IAAU,UAAW,WAAY,QAAS,QAAS,MAAO,OAAQ,OAAQ,SAAU,YAAa,UAAW,WAAY,YACxHC,GAAeD,GAAOld,IAAI,SAACwD,GAAM,OAAAA,EAAE+H,OAAO,EAAG,KAE7C6R,IAAQ,SAAU,SAAU,UAAW,YAAa,WAAY,SAAU,YAC1EC,GAAaD,GAAKpd,IAAI,SAAC8B,GAAM,OAAAA,EAAEyJ,OAAO,EAAE,KA6DrD,SAAA+R,GAA6Bxb,EAA4Byb,QAAA,IAAAA,IAAAA,GAAA,GACvD,IAAMC,KAmBN,GAjBID,QAAuBvX,IAAVlE,EAAE+a,KACbvV,GAAKxF,GAAG1C,OAAS,IACnBqe,GAASC,GAAYrB,WAAWva,WAChCA,EAAI2I,GAAU3I,IACL+a,UAIE7W,IAAXlE,EAAE2a,KACJe,EAAMle,KAAKwC,EAAE2a,WACMzW,IAAVlE,EAAE+a,IAEXW,EAAMle,KAAKgd,IAEXkB,EAAMle,KAAK,QAGG0G,IAAZlE,EAAE6a,MAAqB,CACzB,IAAMA,EAAQY,EAnElB,SAAwB/Z,GACtB,GAAI/B,EAAS+B,GAEX,OAAQA,EAAI,EAAK,GAEjB,IAAMma,EAASna,EAAEoa,cACXC,EAAaX,GAAOta,QAAQ+a,GAClC,IAAoB,IAAhBE,EACF,OAAOA,EAAa,GAEtB,IAAMC,EAASH,EAAOpS,OAAO,EAAG,GAC1BwS,EAAkBZ,GAAava,QAAQkb,GAC7C,IAAyB,IAArBC,EACF,OAAOA,EAAkB,GAG3B,MAAM,IAAIrf,MAAMgf,GAAYzB,gBAAgB,QAASzY,IAmD3Bwa,CAAelc,EAAE6a,OAAS7a,EAAE6a,MACtDa,EAAMle,KAAKqd,QACN,QAAkB3W,IAAdlE,EAAE4a,QAAuB,CAClC,IAAMA,EAAUa,EAnFpB,SAA0Bte,GACxB,GAAIwC,EAASxC,GAKX,OAJIA,EAAI,GACNwe,GAASC,GAAYzB,gBAAgB,UAAWhd,IAG1CA,EAAI,EAAK,GAGjB,MAAM,IAAIP,MAAMgf,GAAYzB,gBAAgB,UAAWhd,IA0E3Bgf,CAAiBnc,EAAE4a,SAAW5a,EAAE4a,QAC5Dc,EAAMle,KAAKod,EAAU,WAErBc,EAAMle,KAAK,GAGb,QAAe0G,IAAXlE,EAAE8a,KACJY,EAAMle,KAAKwC,EAAE8a,WACR,QAAc5W,IAAVlE,EAAE+a,IAAmB,CAG9B,IAAMA,EAAMU,EA7DhB,SAAsBzb,GACpB,GAAIL,EAASK,GAGX,OAAQA,EAAI,EAAK,GAEjB,IAAMoc,EAASpc,EAAE8b,cACXO,EAAWf,GAAKxa,QAAQsb,GAC9B,IAAkB,IAAdC,EACF,OAAOA,EAAW,GAEpB,IAAMC,EAASF,EAAO3S,OAAO,EAAG,GAC1B8S,EAAgBhB,GAAWza,QAAQwb,GACzC,IAAuB,IAAnBC,EACF,OAAOA,EAAgB,GAGzB,MAAM,IAAI3f,MAAMgf,GAAYzB,gBAAgB,MAAOna,IA4C3Bwc,CAAaxc,EAAE+a,KAAO/a,EAAE+a,IAChDW,EAAMle,KAAKud,EAAM,WAEjBW,EAAMle,KAAK,GAKb,IAAuB,IAAA+I,EAAA,EAAAoB,GAAC,QAAS,UAAW,UAAW,gBAAhCpB,EAAAoB,EAAArK,OAAAiJ,IAAiD,CAAnE,IAAMkW,EAAQ9U,EAAApB,QACGrC,IAAhBlE,EAAEyc,GACJf,EAAMle,KAAKwC,EAAEyc,IAEbf,EAAMle,KAAK,GAIf,OAAIwC,EAAE0c,IACG,OAAOhB,EAAMhd,KAAK,MAAK,IAEvB,YAAYgd,EAAMhd,KAAK,MAAK,QChPtBie,sGAAjB,SAAiBA,GACFA,EAAAC,KAAe,OACfD,EAAAE,MAAiB,QACjBF,EAAAG,IAAa,MACbH,EAAAI,KAAe,OACfJ,EAAAK,MAAiB,QACjBL,EAAAM,QAAqB,UACrBN,EAAAO,QAAqB,UACrBP,EAAAQ,aAA+B,eAC/BR,EAAAS,UAAyB,YACzBT,EAAAU,cAAiC,gBACjCV,EAAAW,mBAA2C,qBAC3CX,EAAAY,0BAAyD,4BACzDZ,EAAAa,iCAAuE,mCAGvEb,EAAAc,UAAyB,YACzBd,EAAAe,aAA+B,eAC/Bf,EAAAgB,oBAA6C,sBAC7ChB,EAAAiB,eAAmC,iBACnCjB,EAAAkB,oBAA6C,sBAC7ClB,EAAAmB,QAAqB,UACrBnB,EAAAoB,YAA6B,cAC7BpB,EAAAqB,aAA+B,eAC/BrB,EAAAsB,iBAAuC,mBACvCtB,EAAAuB,QAAqB,UACrBvB,EAAAwB,SAAuB,WACvBxB,EAAAyB,OAAmB,SACnBzB,EAAA0B,QAAqB,UACrB1B,EAAA2B,SAAuB,WACvB3B,EAAA4B,WAA2B,aAC3B5B,EAAA6B,WAA2B,aAC3B7B,EAAA8B,gBAAqC,kBACrC9B,EAAA+B,aAA+B,eAC/B/B,EAAAgC,iBAAuC,mBACvChC,EAAAiC,sBAAiD,wBACjDjC,EAAAkC,6BAA+D,+BAC/DlC,EAAAmC,oCAA6E,sCAG7EnC,EAAAoC,aAA+B,eAC/BpC,EAAAqC,gBAAqC,kBACrCrC,EAAAsC,uBAAmD,yBACnDtC,EAAAuC,kBAAyC,oBACzCvC,EAAAwC,uBAAmD,yBACnDxC,EAAAyC,WAA2B,aAC3BzC,EAAA0C,eAAmC,iBACnC1C,EAAA2C,gBAAqC,kBACrC3C,EAAA4C,oBAA6C,sBAhD5D,CAAiB5C,KAAAA,QA+DjB,IAAM6C,IACJ7E,KAAM,EACNC,QAAS,EACTC,MAAO,EACPE,IAAK,EACLD,KAAM,EACNE,MAAO,EACPC,QAAS,EACTC,QAAS,EACTC,aAAc,GAGHsE,GAAiB/W,GAAS8W,IAEvC,SAAAE,GAAsCjD,GACpC,QAAS+C,GAA4B/C,GAcvC,IAAMkD,IACJC,QAAS,EACTC,WAAY,EACZC,SAAU,EACVC,OAAQ,EACRC,QAAS,EACTC,SAAU,EACVC,WAAY,EACZC,WAAY,EACZC,gBAAiB,GAGnB,SAAAC,GAAoC5D,GAClC,QAASkD,GAA0BlD,GAerC,IA+BM6D,IACJC,eAAgB,EAChBC,oBAAqB,EAErBC,aAAc,EACdC,iBAAkB,EAClBC,sBAAuB,EACvBC,6BAA8B,EAC9BC,oCAAqC,EAErCC,gBAAiB,EAEjBC,aAAc,EAEdC,gBAAiB,EACjBC,uBAAwB,EAExBC,kBAAmB,EAEnBC,uBAAwB,GASpBC,GAAkB5gB,KACnBmf,GACAW,IAGL,SAAAe,GAA8B3gB,GAC5B,QAAS0gB,GAAmB1gB,GAG9B,SAAA4gB,GAAiC5gB,GAC/B,OAAOA,EAAE+I,OAAO,GAKlB,IAAM8X,GAAc/gB,KACfgf,GACAG,IA3EH6B,YAAa,EACbC,iBAAkB,EAElBC,UAAW,EACXC,cAAe,EACfC,mBAAoB,EACpBC,0BAA2B,EAC3BC,iCAAkC,EAElCC,aAAc,EAEdC,UAAW,EAEXC,aAAc,EACdC,oBAAqB,EAErBC,eAAgB,EAEhBC,oBAAqB,GA2DlB9B,IAGQ+B,GAAY3Z,GAAS6Y,IAQlC,IAAMe,IACJ3H,KAAM,cACNE,MAAO,WACPC,KAAM,UACNE,MAAO,WACPC,QAAS,aACTC,QAAS,aACTC,aAAc,kBAEdP,QAAS,KACTG,IAAK,MAkCP,SAAAwH,GAAqBC,EAA4BC,GAC/C,IAAMC,EAAmBJ,GAAgBE,GAGzC,OAAQG,cAFcF,EAAQ,SAAWC,EAAiBjZ,OAAO,GAAKiZ,EAE/CE,cADD,OAASH,EAAQ,MAAQ,IAAMC,EAAiBjZ,OAAO,IAI/E,SAAAoZ,GAAiCpG,GAC/B,OAAOgD,GAAeqD,OAAO,SAACC,EAAOC,GACnC,OAAIC,GAAiBxG,EAAUuG,GACtBD,EAAM9jB,OAAO+jB,GAEfD,OAKX,SAAAE,GAAiC3I,EAAwBmC,GACvD,IAAMyG,EAAQ5I,EAAaxZ,QAAQ2b,GACnC,OAAOyG,GAAS,IAEZzG,IAAaE,GAASO,SACZ,IAAVgG,GACiC,MAAjC5I,EAAa1Y,OAAOshB,EAAM,IAOhC,SAAAC,GAA0B7I,EAAwB/b,GAChD,IAAM6kB,EAAW1Z,GAAoBnL,GAE/Bme,EAAM2E,GAAc/G,GAAgB,MAAQ,GAiBlD,OAAOkB,GAPGiE,GAAeqD,OAAO,SAACO,EAAwBC,GATzD,IAAc7G,EAaZ,OAHIwG,GAAiB3I,EAAcgJ,KACjCD,EAASC,IAXC7G,EAWU6G,KAVL3G,GAASmB,QAEjB,IAAIpB,EAAG,WAAW0G,EAAQ,OAE1B,GAAG1G,EAAMD,EAAQ,IAAI2G,EAAQ,KAQ/BC,QASX,SAAAE,GAAiC9G,EAAoBle,EAAeilB,EAA0BC,GAC5F,GAAKhH,EAAL,CAIA,IAAMiH,KACFC,EAAa,GACXC,EAAUX,GAAiBxG,EAAUE,GAASC,MAEhDqG,GAAiBxG,EAAUE,GAASmB,WAEtC6F,EAAa,iBAAiBplB,EAAK,KAGjC0kB,GAAiBxG,EAAUE,GAASE,QAEtC6G,EAAelmB,MAAyB,IAApBgmB,EAA4B,KAAO,MAGrDP,GAAiBxG,EAAUE,GAASG,KACtC4G,EAAelmB,KAAKgmB,EAAkB,KAAO,MACpCP,GAAiBxG,EAAUE,GAASI,OAC7C2G,EAAelmB,KAAK,MAAQomB,EAAU,IAAM,KAG1CA,GACFF,EAAelmB,KAAKgmB,EAAkB,KAAO,MAG/C,IAAMK,KAEFZ,GAAiBxG,EAAUE,GAASK,QACtC6G,EAAermB,KAAK,MAElBylB,GAAiBxG,EAAUE,GAASM,UACtC4G,EAAermB,KAAK,MAElBylB,GAAiBxG,EAAUE,GAASO,UACtC2G,EAAermB,KAAK,MAElBylB,GAAiBxG,EAAUE,GAASQ,eACtC0G,EAAermB,KAAK,MAGtB,IAAMsmB,KAyBN,OAxBIJ,EAAepmB,OAAS,GAC1BwmB,EAAmBtmB,KAAKkmB,EAAehlB,KAAK,MAE1CmlB,EAAevmB,OAAS,GAC1BwmB,EAAmBtmB,KAAKqmB,EAAenlB,KAAK,MAG1ColB,EAAmBxmB,OAAS,IAC1BqmB,IAEFA,GAAc,aAOdA,GADEF,EACY,aAAallB,EAAK,MAAMulB,EAAmBplB,KAAK,KAAI,KAEpD,cAAcH,EAAK,MAAMulB,EAAmBplB,KAAK,KAAI,MAKhEilB,QAAczf,GAGvB,SAAA6f,GAAkCtH,GAChC,MAAiB,QAAbA,GAAsBA,EAAS3b,QAAQ,QAAU,GACnD6a,GAASC,GAAYvB,oBAAoBoC,IAClCA,EAASpe,QAAQ,MAAO,SAE1Boe,MClYQuH,8KD2MjB,SAA2BtjB,GACzB,QAAS6gB,GAAe7gB,YAuB1B,SAAwBujB,EAAgBnJ,GAMpC,IALF,IAAMoJ,EAAQ7C,GAAc4C,GACtBpgB,EAAeqgB,EAEnB,IAAIC,KAAKA,KAAKC,IAAI,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,IACpC,IAAID,KAAK,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACA5d,EAAA,EAAA8d,EAAA5E,GAAAlZ,EAAA8d,EAAA/mB,OAAAiJ,IAAgB,CAAtC,IAAM+d,EAAYD,EAAA9d,GACvB,GAAI0c,GAAiBgB,EAAMK,GACzB,OAAQA,GACN,KAAK3H,GAASG,IACZ,MAAM,IAAIlgB,MAAM,gDAClB,KAAK+f,GAASmB,QACN,IAAAnW,EAAA4a,GAAA,QAAA2B,GAACK,EAAA5c,EAAAib,cAEP/e,EAFsB8D,EAAAgb,eAE0C,EAAzC6B,KAAKC,MAAM3J,EAAKyJ,KAAmB,IAC1D,MAEF,QACQ,IAAAG,EAAAnC,GAAA+B,EAAAJ,GAACtB,EAAA8B,EAAA9B,cACP/e,EADsB6gB,EAAA/B,eACA7H,EAAK8H,OAInC,OAAO/e,oGC1PT,SAAiBmgB,GACFA,EAAAW,aAA+B,eAC/BX,EAAAY,QAAqB,UACrBZ,EAAAa,SAAuB,WACvBb,EAAAc,QAAqB,UAErBd,EAAAtV,SAAuB,WACvBsV,EAAArV,UAAyB,YACzBqV,EAAAe,QAAqB,UARpC,CAAiBf,KAAAA,QAeV,IAAMgB,IACXC,aAAc,EACdC,QAAS,EACTC,SAAU,EACVC,QAAS,EACTvV,SAAU,EACVF,UAAW,EACX0V,QAAS,GAOJ,IAAMV,GAAeX,GAAKW,aACpBC,GAAUZ,GAAKY,QACfC,GAAWb,GAAKa,SAChBC,GAAUd,GAAKc,QAEfC,GAAUf,GAAKe,QAO5B,SAAAO,GAA4BlR,GAC1B,GAAIA,EAEF,OADAA,EAAOA,EAAK0H,eAEV,IAAK,IACL,KAAK6I,GACH,MAAO,eACT,IAAK,IACL,KAAKE,GACH,MAAO,WACT,IAAK,IACL,KAAKD,GACH,MAAO,UACT,IAAK,IACL,KAAKE,GACH,MAAO,UACT,KAAKd,GAAKtV,SACR,MAAO,WACT,KAAKsV,GAAKrV,UACR,MAAO,YACT,KAAKoW,GACH,MAAO,4EArCf,SAAuBrkB,GACrB,QAASskB,GAAWtkB,8FCuBoBzD,GACxC,OAAOA,EAAa,UAoDtB,SAAAsoB,GAA4BhnB,GAC1B,OAAOA,IAAUR,EAASQ,IAAU,WAAYA,EAiDlD,SAAAinB,GAA+BhO,GACtB,IAAAjZ,EAAAA,EAAAA,MAAOke,EAAAjF,EAAAiF,SAAU1J,EAAAyE,EAAAzE,IAAKhH,EAAAyL,EAAAzL,UAC7B,OAAAvL,KACMic,GAAYA,SAAQA,MACpB1J,GAAOA,IAAGA,MACVhH,GAAaA,UAASA,OAC1BxN,MAAKknB,IA4GT,SAAAC,GAAoCC,GAClC,QAASA,KAAgBA,EAAWC,UAMtC,SAAAC,GAA0CF,GACxC,QAASA,KAAgBA,EAAWC,YAAcloB,EAAQioB,EAAWC,YAAcE,GAAWH,EAAWC,WAG3G,SAAAG,GAA0CJ,GACxC,QAASA,KAAgBA,EAAWC,YAClCloB,EAAQioB,EAAWC,YAAcI,GAAWL,EAAWC,YAI3D,SAAAE,GAA8BH,GAC5B,SAASA,IAAiBA,EAAkB,OAAiC,UAA5BA,EAAsB,WAGzE,SAAAM,GAAiCzO,GAC/B,OAAOsO,GAAWtO,IAAazZ,EAASyZ,EAASjZ,OAGnD,SAAAynB,GAA8BL,GAC5B,OAAOA,GAAc,UAAWA,QAAsCzhB,IAAxByhB,EAAkB,MAGlE,SAAAO,GAAmCP,GACjC,SAASA,IAAiBA,EAAkB,QAAOA,EAAiB,MAoBtE,SAAAQ,GAAwB3O,EAAsEd,QAAA,IAAAA,IAAAA,MAC5F,IAAInY,EAAQiZ,EAASjZ,MACfuL,EAAS4M,EAAI5M,OACfsc,EAAS1P,EAAI0P,OAEjB,GAAIC,GAAQ7O,GACVjZ,EAAQ,cACH,CACL,IAAIjC,OAAa4H,EAEZwS,EAAI4P,QAdb,SAAsB9O,GACpB,QAASA,EAAa,GAcd+O,CAAa/O,GAENA,EAASzE,KAClBzW,EAAKkqB,GAAYhP,EAASzE,KAC1BqT,EAAS1P,EAAI+P,WAAa,IACjBjP,EAASzL,UAClBzP,EAAK6F,OAAOqV,EAASzL,WACZyL,EAASiF,WAClBngB,EAAK6F,OAAOqV,EAASiF,WAPrBngB,EAAKkb,EAAS1R,IAWdxJ,IACFiC,EAAQA,EAAWjC,EAAE,IAAIiC,EAAUjC,GAYvC,OARI8pB,IACF7nB,EAAWA,EAAK,IAAI6nB,GAGlBtc,IACFvL,EAAWuL,EAAM,IAAIvL,GAGnBmY,EAAIgQ,KAEC3c,GAAoBxL,EAAOmY,EAAIgQ,MAG/B1c,GAAmBzL,GAI9B,SAAAooB,GAA2BnP,GACzB,OAAQA,EAASpD,MACf,IAAK,UACL,IAAK,UACL,IAAK,UACH,OAAO,EACT,IAAK,eACH,QAASoD,EAASzE,IACpB,IAAK,WACL,IAAK,YACL,IAAK,WACH,OAAO,EAEX,MAAM,IAAInW,MAAMgf,GAAY9E,iBAAiBU,EAASpD,OAGxD,SAAAwS,GAA6BpP,GAC3B,OAAQmP,GAAWnP,GAGrB,SAAA6O,GAAwB7O,GACtB,MAA8B,UAAvBA,EAASzL,UAKlB,SAAA8a,GAAqCrP,EAAgCsP,GAC5D,IAAAvoB,EAAAA,EAAAA,MAAcwU,EAAAyE,EAAAzE,IAAK0J,EAAAjF,EAAAiF,SAAU1Q,EAAAyL,EAAAzL,UACpC,MAAkB,UAAdA,EACK+a,EAAOC,WACLhU,EACCxU,EAAK,YACNke,EAECle,EAAK,KADDskB,GAAiBpG,GAAU/d,KAAK,KACrB,IAChBqN,EACCxC,GAAUwC,GAAU,OAAOxN,EAEhCA,EAGT,SAAAyoB,GAAyCxP,EAAgCsP,GACvE,IAAMxqB,EAAKkb,EAASzL,WAAayL,EAASiF,UAAajF,EAASzE,KAAO,MACvE,OAAIzW,EACKA,EAAGkN,cAAgB,IAAMgO,EAASjZ,MAAQ,IAE1CiZ,EAASjZ,MAIb,IAAM0oB,GAA6C,SAACzP,EAAgCsP,GACzF,OAAQA,EAAOI,YACb,IAAK,QACH,OAAO1P,EAASjZ,MAClB,IAAK,aACH,OAAOyoB,GAAyBxP,GAClC,QACE,OAAOqP,GAAqBrP,EAAUsP,KAIxCK,GAAiBF,GAErB,SAAAG,GAAkCC,GAChCF,GAAiBE,EAGnB,SAAAC,KACEF,GAAkBH,IAGpB,SAAAla,GAAsByK,EAAgCsP,GACpD,OAAOK,GAAe3P,EAAUsP,GAGlC,SAAAS,GAA4B/P,EAA2BzG,GACrD,GAAIyG,EAASiF,SACX,MAAO,WAET,GAAIjF,EAASzE,IACX,MAAO,eAET,OAAQD,GAAU/B,IAChB,IAAK,aACH,MAAO,eACT,IAAK,WAEL,IAAK,WACH,MAAO,UACT,QACE,MAAO,gBAQb,SAAAyW,GAA+B7B,GAC7B,OAAIG,GAAWH,GACNA,EACEE,GAAuBF,GACzBA,EAAWC,eADb,EAST,SAAAnK,GAA0BkK,EAAgC5U,GACxD,GAAIhT,EAAS4nB,IAAehmB,EAASgmB,IAAejmB,EAAUimB,GAAa,CACzE,IAAM8B,EAAgB1pB,EAAS4nB,GAAc,SAC3ChmB,EAASgmB,GAAc,SAAW,UAEpC,OADAhK,GAASC,GAAY/E,oBAAoB9F,EAAS0W,EAAe9B,KACzDxkB,MAAOwkB,GAIjB,OAAIG,GAAWH,GACN+B,GAAkB/B,EAAY5U,GAC5B8U,GAAuBF,GAChCnlB,KACKmlB,GAEHC,UAAW8B,GAAkB/B,EAAWC,UAAW7U,KAGhD4U,EAET,SAAA+B,GAAkClQ,EAA4BzG,GAE5D,GAAIyG,EAASzL,YAAcH,GAAc4L,EAASzL,WAAY,CACrDyL,EAAAzL,UAAA,IAAW4b,EAAA/mB,EAAA4W,GAAA,cAClBmE,GAASC,GAAYzE,iBAAiBK,EAASzL,YAC/CyL,EAAWmQ,EAoBb,GAhBInQ,EAASiF,WACXjF,EAAQhX,KACHgX,GACHiF,SAAUsH,GAAkBvM,EAASiF,aAKrCjF,EAASzE,MACXyE,EAAQhX,KACHgX,GACHzE,IAAK6U,GAAapQ,EAASzE,IAAKhC,MAKhCyG,EAASpD,KAAM,CACjB,IAAMyT,EAAWvC,GAAY9N,EAASpD,MAClCoD,EAASpD,OAASyT,IAEpBrQ,EAAQhX,KACHgX,GACHpD,KAAMyT,KAGY,iBAAlBrQ,EAASpD,MACPtI,GAAsB0L,EAASzL,aACjC4P,GAASC,GAAY1E,kCAAkCM,EAASpD,KAAMoD,EAASzL,YAC/EyL,EAAQhX,KACHgX,GACHpD,KAAM,sBAIP,CAEL,IAAMiD,EAAUkQ,GAAY/P,EAAUzG,GACtC4K,GAASC,GAAYxE,wBAAwBI,EAASpD,KAAMrD,EAASsG,IACrEG,EAAQhX,KACDgX,GACLpD,KAAMiD,IAIJ,IAAA1P,EAAAmgB,GAAAtQ,EAAAzG,GAACgX,EAAApgB,EAAAogB,WAAYC,EAAArgB,EAAAqgB,QAInB,OAHKD,GACHpM,GAASqM,GAEJxQ,EAGT,SAAAoQ,GAA6B7U,EAAwBhC,GACnD,OAAIrR,EAAUqT,IACJkV,QAAShV,GAAYlC,IACnBgC,EAAIkV,SAAYlV,EAAImV,KAGvBnV,EAFPvS,KAAWuS,GAAKkV,QAAShV,GAAYlC,KAMzC,IAAMoX,IAAcJ,YAAY,GAChC,SAAAD,GAAqCtQ,EAA2BzG,GAC9D,IAAMqD,EAAOoD,EAASpD,KAEtB,OAAQrD,GACN,IAAK,MACL,IAAK,SACH,OAAI6V,GAAapP,IAEbuQ,YAAY,EACZC,QAASpM,GAAY5D,6BAA6BjH,IAG/CoX,GAET,IAAK,IACL,IAAK,IACL,IAAK,QACL,IAAK,OACL,IAAK,SACL,IAAK,OACL,IAAK,SACL,IAAK,MACL,IAAK,UACL,IAAK,OACH,OAAOA,GAET,IAAK,YACL,IAAK,aACL,IAAK,WACL,IAAK,YACH,OAAI/T,IAASuQ,IAEToD,YAAY,EACZC,QAAS,WAAWjX,EAAO,uDAAuDyG,EAASpD,KAAI,WAG5F+T,GAET,IAAK,UACL,IAAK,OACL,IAAK,KACL,IAAK,KACH,MAAc,YAAT/T,IAAuBoD,EAAe,MAAe,YAATpD,GAE7C2T,YAAY,EACZC,QAAS,WAAWjX,EAAO,wDAGxBoX,GAET,IAAK,QACH,MAAsB,YAAlB3Q,EAASpD,MAAwC,YAAlBoD,EAASpD,MAExC2T,YAAY,EACZC,QAAS,yEAGNG,GAET,IAAK,QACH,MAAsB,YAAlB3Q,EAASpD,MAAwB,SAAUoD,EAMxC2Q,IAJHJ,YAAY,EACZC,QAAS,kFAKjB,MAAM,IAAIprB,MAAM,oDAAsDmU,GAGxE,SAAAqX,GAAiC5Q,GAC/B,MAAyB,iBAAlBA,EAASpD,QAA6BoD,EAASzE,IAGxD,SAAAsV,GAA+B7Q,GAC7B,MAAyB,aAAlBA,EAASpD,QAAyBoD,EAASiF,SAQpD,SAAA6L,GACErkB,EACA0D,SAAC8U,EAAA9U,EAAA8U,SAAUrI,EAAAzM,EAAAyM,KAAMmU,EAAA5gB,EAAA4gB,KAAMC,EAAA7gB,EAAA6gB,2BAQnB9B,OAAOxiB,EAgBX,OAfIuW,GAAWxW,GACbyiB,EAAOlL,GAAavX,GAAG,IACdlG,EAASkG,IAAMtE,EAASsE,MAC7BwY,GAAqB,aAATrI,KAEZsS,EADEhH,GAAsBjD,GACjBjB,KAAYkJ,MAAGjI,GAAWxY,EAACygB,IAAG,GAC5BrE,GAAoB5D,GAEtB6L,GAAUrkB,GAAIwY,SAAU6E,GAAiB7E,KAGzC,YAAYte,KAAKC,UAAU6F,GAAE,KAItCyiB,EACK6B,EAAO,QAAQ7B,EAAI,IAAMA,EAG3B8B,OAA6BtkB,EAAY/F,KAAKC,UAAU6F,GAMjE,SAAAwkB,GACEjR,EACAzP,GAEO,IAAA0U,EAAAjF,EAAAiF,SAAUrI,EAAAoD,EAAApD,KACjB,OAAOrM,EAAO7J,IAAI,SAAA+F,GAChB,IAAMyiB,EAAO4B,GAAUrkB,GAAIwY,SAAQA,EAAErI,KAAIA,EAAEoU,4BAA4B,IAEvE,YAAatkB,IAATwiB,GACMgC,OAAQhC,GAGXziB,6kBClhBqB2J,EAAoCmD,GAClE,IAAM4U,EAAa/X,GAAYA,EAASmD,GACxC,QAAI4U,IACEjoB,EAAQioB,GACHxe,EAAKwe,EAAY,SAACnO,GAAa,QAAEA,EAASjZ,QAE1CunB,GAAWH,IAAeE,GAAuBF,IAO9D,SAAAgD,GAA4B/a,GAC1B,OAAOzG,EAAKgK,GAAU,SAACJ,GACrB,GAAI6X,GAAgBhb,EAAUmD,GAAU,CACtC,IAAM4U,EAAa/X,EAASmD,GAC5B,GAAIrT,EAAQioB,GACV,OAAOxe,EAAKwe,EAAY,SAACnO,GAAa,QAAEA,EAASzL,YAEjD,IAAMyL,EAAWgQ,GAAY7B,GAC7B,OAAOnO,KAAcA,EAASzL,UAGlC,OAAO,IAIX,SAAA8c,GAAkCjb,EAA4BqE,GAC3D,OAAOzM,GAAKoI,GAAUkV,OAAO,SAACgG,EAAsC/X,SACnE,IAAKM,GAAUN,GAGb,OADA4K,GAASC,GAAY7D,uBAAuBhH,IACrC+X,EAGT,IAAK9W,GAAYjB,EAASkB,GAIxB,OADA0J,GAASC,GAAYhE,oBAAoB7G,EAASkB,IAC3C6W,EAIT,GAAgB,SAAZ/X,GAA+B,SAATkB,KAClBuF,EAAWgQ,GAAY5Z,EAASmD,MACtByG,EAASzL,WAEvB,OADA4P,GAASC,GAAYjE,wBACdmR,EAKV,GAAgB,UAAZ/X,IAAwB,SAAUnD,GAAY,WAAYA,GAE5D,OADA+N,GAASC,GAAYtE,cAAc,YAAajH,KAAM,SAAUzC,EAAU0C,OAAQ,WAAY1C,KACvFkb,EAGV,IAAMnD,EAAa/X,EAASmD,GAC5B,GACc,WAAZA,GACa,UAAZA,IAAwBrT,EAAQioB,KAAgBK,GAAWL,IAC/C,YAAZ5U,GAAyBrT,EAAQioB,GAE9BA,IAEFmD,EAAmB/X,IAAYrT,EAAQioB,GAAcA,GAAcA,IAChE7C,OAAO,SAACiG,EAA0BvR,GAMjC,OALKsO,GAAWtO,GAGduR,EAAKvrB,KAAKkqB,GAAkBlQ,EAAUzG,IAFtC4K,GAASC,GAAYrE,cAAcC,EAAUzG,IAIxCgY,YAGR,CAEL,IAAMvR,EACN,IADMA,EAAWgQ,GAAY5Z,EAASmD,MACtBhK,GAAUid,GAAKtV,SAAUsV,GAAKrV,WAAY6I,EAASpD,MAAO,CACxE,IAAOsQ,EAAA3T,EAAciY,GAAdF,EAAApE,GAAc9jB,EAAAkoB,GAAA,iBAAApE,EAAAA,EAAAA,EAAA,MACfhN,EAAyB,MAAZ3G,EAAkB,YACvB,MAAZA,EAAkB,WACN,OAAZA,EAAmB,aACP,OAAZA,EAAmB,iBAAc7M,EAEnC,OADAyX,GAASC,GAAYnE,kBAAkB1G,EAASyG,EAASpD,KAAMsD,IAC/DlX,KACKwoB,IAAWrhB,MACb+P,GAAUlX,KACNib,GAAUjE,EAAiBzG,IAC9BqD,KAAM,iBAAczM,IAK1B,IAAKme,GAAWH,KAAgBK,GAAWL,KAAgBD,GAAiBC,GAE1E,OADAhK,GAASC,GAAYrE,cAAcoO,EAAY5U,IACxC+X,EAETA,EAAmB/X,GAAW0K,GAAUkK,EAAkC5U,GAE5E,OAAO+X,OAKX,SAAAG,GAAyBrb,GACvB,OAAOA,MAAgBA,EAAS3P,KAAO2P,EAASsC,MAAUtC,EAASqC,KAAOrC,EAASuC,IAGrF,SAAA+Y,GAA0Btb,GACxB,IAAMxG,KAaN,OAZA+J,GAASgY,QAAQ,SAASpY,GACxB,GAAI6X,GAAgBhb,EAAUmD,GAAU,CACtC,IAAM4U,EAAa/X,EAASmD,IAC3BrT,EAAQioB,GAAcA,GAAcA,IAAawD,QAAQ,SAACC,GACrDtD,GAAWsD,GACbhiB,EAAI5J,KAAK4rB,GACAvD,GAAuBuD,IAChChiB,EAAI5J,KAAK4rB,EAAIxD,gBAKdxe,EAGT,SAAA+hB,GAAwBE,EACpB7nB,EACA8nB,GACF,GAAKD,EAIL,mBAAWtY,GACLrT,EAAQ2rB,EAAQtY,IAClBsY,EAAQtY,GAASoY,QAAQ,SAASxD,GAChCnkB,EAAErC,KAAKmqB,EAAS3D,EAAY5U,KAG9BvP,EAAErC,KAAKmqB,EAASD,EAAQtY,GAAUA,IANhBxK,EAAA,EAAAoB,EAAAnC,GAAK6jB,GAAL9iB,EAAAoB,EAAArK,OAAAiJ,IAAa,GAAjBoB,EAAApB,KAWpB,SAAAuc,GAA4DuG,EACxD7nB,EACA+nB,EAASD,GACX,OAAKD,EAIE7jB,GAAK6jB,GAASvG,OAAO,SAACrhB,EAAGsP,GAC9B,IAAM7S,EAAMmrB,EAAQtY,GACpB,OAAIrT,EAAQQ,GACHA,EAAI4kB,OAAO,SAAC0G,EAAO7D,GACxB,OAAOnkB,EAAErC,KAAKmqB,EAASE,EAAI7D,EAAY5U,IACtCtP,GAEID,EAAErC,KAAKmqB,EAAS7nB,EAAGvD,EAAK6S,IAEhCwY,GAZMA,2IC1TiCE,EAAgC1Y,SACpE5P,EAAQsoB,EAAmB1Y,GACjC,YAAiB7M,IAAV/C,IAAmBwG,MAAKoJ,IAAW5P,MAAKA,GAACwG,MCS3C,IAAM+hB,GAAsB,WA0BnC,SAAAC,GAA6B1X,GAC3B,QAASA,EAAW,KAGf,IAsCD2X,IAAgC,IAAK,IAAK,QAAS,SAAU,UAAW,QC/D9E,IAAMC,MAEN,SAAAC,GAAoB7X,EAAc8X,GAChCF,GAAmB5X,GAAQ8X,EAatB,IAAMC,IDSkC,aAAc,MAAO,UCJvDC,GAAqDzpB,MDqChE0pB,KAAM,OAAQ,QAAS,UACvBC,YAAa,SACbC,QAAS,WC7BX,SAAAC,GAEIC,EACAxD,GAGF,IAAM7U,EAAOgC,GAAUqW,EAAKrY,MAAQqY,EAAKrY,KAAKmC,KAAOkW,EAAKrY,KACpD8X,EAAaF,GAAmB5X,GACtC,GAAI8X,EACF,OAAOA,EAAWO,EAAMxD,GAG1B,MAAM,IAAIlqB,MAAM,sBAAsBqV,EAAI,KAlB5C6X,GAAIJ,GDqDJ,SAAiCY,EAA+DxD,eAGvF7U,GAFPqY,EAfF,SAA0CA,GACxC,OAAA9pB,KACK8pB,GACH1c,SAAUkV,GAAOwH,EAAK1c,SAAU,SAACob,EAAaxR,EAAUzG,GAMtD,OALI6Y,GAAkB9oB,QAAQiQ,IAAY,EACxCiY,EAAYjY,GAAWyG,EAEvBmE,GAASC,GAAYhE,oBAAoB7G,EAAS2Y,KAE7CV,SAMJuB,CAA0BD,IAE1BrY,KAAgBuY,GAAVF,EAAA1c,SAAU0c,EAAAE,WAA2BC,GAAhBH,EAAA1T,WAAgBhW,EAAA0pB,GAAA,OAAA,WAAA,YAAA,gBAE9CI,OAAqBxmB,EACrBvE,EAASmnB,EAAOoD,IAAIS,UACtBD,EAAa5D,EAAOoD,IAAIS,QAGtBhB,GAAa1X,IACXA,EAAK0Y,QACY,YAAhB1Y,EAAK0Y,SACND,OAAaxmB,GAKnB,IACM0mB,EA2JR,SAAmBN,EAA+Dnd,EAAgBud,GAE1F,IAAA/iB,EA9BR,SAA0B2iB,EAA+Dnd,GAChFmd,EAAArY,KAAA,IAEH4Y,EACAC,EAHeld,EAAA0c,EAAA1c,SAanB,GAbuC0c,EAAA1T,WAAgBhW,EAAA0pB,GAAA,OAAA,WAAA,eAKxC,aAAXnd,GACF2d,EAAiB,IACjBD,EAA2Bjd,EAASqC,IAEpC6a,EAAiB,IACjBD,EAA2Bjd,EAAS3P,GAGlC4sB,GAA4BA,EAAyB9e,UAAW,CAC3D,IAAAA,EAAA8e,EAAA9e,UAAWgf,EAAAnqB,EAAAiqB,GAAA,cACd9e,IAAc2d,IAChB/N,GAAS,mEAAmE5P,GAE9E8e,EAA2BE,EAG7B,OACEF,yBAAwBA,EACxBC,eAAcA,GAMVE,CAAAV,EAAAnd,GAAC0d,EAAAljB,EAAAkjB,yBAA0BC,EAAAnjB,EAAAmjB,eAC3Bld,EAAW0c,EAAK1c,SAEhBqd,OAA0B/mB,IAAfwmB,EACX3e,IAEFjG,GAAI,KACJvH,MAAOssB,EAAyBtsB,MAChC2sB,GAAI,aAAeL,EAAyBtsB,QAG5CuH,GAAI,KACJvH,MAAOssB,EAAyBtsB,MAChC2sB,GAAI,aAAeL,EAAyBtsB,QAG5CuH,GAAI,SACJvH,MAAOssB,EAAyBtsB,MAChC2sB,GAAI,WAAaL,EAAyBtsB,QAG1C4sB,KAEJpf,EAAUvO,MACRsI,GAAI,MACJvH,MAAOssB,EAAyBtsB,MAChC2sB,IAAKD,EAAW,iBAAmB,QAAUJ,EAAyBtsB,QAExEwN,EAAUvO,MACRsI,GAAI,MACJvH,MAAOssB,EAAyBtsB,MAChC2sB,IAAMD,EAAW,iBAAmB,QAAUJ,EAAyBtsB,QAGpE0sB,IACHE,IAEIC,UAAW,mBAAmBP,EAAyBtsB,MAAK,sBAAsBssB,EAAyBtsB,MAC3G2sB,GAAI,OAASL,EAAyBtsB,QAGtC6sB,UAAW,uBAAuBP,EAAyBtsB,MAAK,gBAAgBssB,EAAyBtsB,MAAK,MAAMmsB,EAAU,eAAeG,EAAyBtsB,MAAK,IAC3K2sB,GAAI,iBAAmBL,EAAyBtsB,QAGhD6sB,UAAW,uBAAuBP,EAAyBtsB,MAAK,gBAAgBssB,EAAyBtsB,MAAK,MAAMmsB,EAAU,eAAeG,EAAyBtsB,MAAK,IAC3K2sB,GAAI,iBAAmBL,EAAyBtsB,SAKtD,IAAM8sB,KACAC,KACAC,KAEAC,KAuCN,OAtCArC,GAAQvb,EAAU,SAAC+X,EAAY5U,GAC7B,GAAIA,IAAY+Z,EAIhB,GAAIhF,GAAWH,GAAa,CAC1B,GAAIA,EAAW5Z,WAAa4Z,EAAW5Z,YAAc2d,GACnD3d,EAAUvO,MACRsI,GAAI6f,EAAW5Z,UACfxN,MAAOonB,EAAWpnB,MAClB2sB,GAAI/E,GAAQR,UAET,QAA6BzhB,IAAzByhB,EAAW5Z,UAAyB,CAC7C,IAAM0f,EAAmBtF,GAAQR,GAG3B5S,EAAM4S,EAAW5S,IACvB,GAAIA,EAAK,CACA,IAAAxU,EAAAA,EAAAA,MACP+sB,EAAK9tB,MAAMuV,IAAGA,EAAExU,MAAKknB,EAAEyF,GAAIO,SACtB,GAAI9F,EAAWlJ,SAAU,CACvB,IAAAA,EAAAkJ,EAAAlJ,SAAUle,EAAAA,EAAAA,MACjBgtB,EAAU/tB,MAAMif,SAAQA,EAAEle,MAAKknB,EAAEyF,GAAIO,IAGvCJ,EAAQ7tB,KAAKiuB,GAGfD,EAA8Bza,IAC5BxS,MAAO4nB,GAAQR,GACfvR,KAAMuR,EAAWvR,WAInBoX,EAA8Bza,GAAWnD,EAASmD,MAKpDsF,aAAcpX,OACZqsB,EACAC,IACExf,UAASA,EAAEsf,QAAOA,IACpBF,GAEFN,yBAAwBA,EACxBC,eAAcA,EACdU,8BAA6BA,GApQzBE,CAAApB,EA4FR,SAAmBA,GACV,IAAArY,EAAAqY,EAAArY,KAAYrE,EAAA0c,EAAA1c,SAEnB,GAFuC0c,EAAA1T,WAAgBhW,EAAA0pB,GAAA,OAAA,WAAA,eAEnDxE,GAAWlY,EAAS3P,IAAM2oB,GAAahZ,EAAS3P,GAAI,CAEtD,GAAI6nB,GAAWlY,EAASqC,IAAM2W,GAAahZ,EAASqC,GAAI,CAEtD,QAA6B/L,IAAzB0J,EAAS3P,EAAE8N,WAA2B6B,EAASqC,EAAElE,YAAc2d,GACjE,MAAO,WACF,QAA6BxlB,IAAzB0J,EAASqC,EAAElE,WAA2B6B,EAAS3P,EAAE8N,YAAc2d,GACxE,MAAO,aACF,GAAI9b,EAAS3P,EAAE8N,YAAc2d,IAAW9b,EAASqC,EAAElE,YAAc2d,GACtE,MAAM,IAAI9sB,MAAM,sCAEhB,OAAI+sB,GAAa1X,IAASA,EAAK9E,OACtB8E,EAAK9E,OAIP,WAKX,MAAO,aACF,GAAI2Y,GAAWlY,EAASqC,IAAM2W,GAAahZ,EAASqC,GAEzD,MAAO,WAGP,MAAM,IAAIrT,MAAM,6CA3HK+uB,CAAUrB,GAC3BI,GAACrU,EAAAuU,EAAAvU,UAAWwU,EAAAD,EAAAC,yBAA0BC,EAAAF,EAAAE,eAAgBU,EAAAZ,EAAAY,8BAE9Chb,EAAAgb,EAAAhb,KAAMob,EAAAhrB,EAAA4qB,GAAA,QAAA,SAGdK,EAAarb,GAAQA,KAAIA,GAAIsb,GAA4BhF,EAAOoD,IAAK,QAErE6B,KAQN,OAPIlB,EAAyB7d,QAC3B+e,EAAkC,MAAIlB,EAAyB7d,OAE7D6d,EAAyBmB,OAC3BD,EAAiC,KAAIlB,EAAyBmB,MAGhExrB,KACKiqB,GACHpU,UAASA,EACT4V,QAEIha,MACEmC,KAAM,OACN8X,MAAO,cAETte,SAAQpN,GAAAmH,KAAAA,EACLmjB,GAActqB,GACbjC,MAAO,iBAAmBssB,EAAyBtsB,MACnD6V,KAAMyW,EAAyBzW,MAC5B2X,GAA0BpkB,EAE9BmjB,EAAiB,MAChBvsB,MAAO,aAAessB,EAAyBtsB,MAC/C6V,KAAMyW,EAAyBzW,MAChCzM,GACEikB,EACAE,GAA4BhF,EAAOqD,WAAY,YAGpDlY,MACEmC,KAAM,OACN8X,MAAO,cAETte,SAAQpN,GAAAkkB,KAAAA,EACLoG,IACCvsB,MAAO,aAAessB,EAAyBtsB,MAC/C6V,KAAMyW,EAAyBzW,MAChCsQ,EACAoG,EAAiB,MAChBvsB,MAAO,iBAAmBssB,EAAyBtsB,MACnD6V,KAAMyW,EAAyBzW,MAChCsQ,GACEkH,EACAE,GAA4BhF,EAAOqD,WAAY,gBAGhDK,GAAaA,UAASA,OAC1BvY,MACEmC,KAAM,MACN8X,MAAO,OAETte,SAAQpN,GAAA2rB,KAAAA,EACLrB,IACCvsB,MAAO,aAAessB,EAAyBtsB,MAC/C6V,KAAMyW,EAAyBzW,MAChC+X,EACArB,EAAiB,MAChBvsB,MAAO,aAAessB,EAAyBtsB,MAC/C6V,KAAMyW,EAAyBzW,MAChC+X,GACEX,EACCA,EAA8Bpb,SAAa0b,GAA4BhF,EAAOoD,IAAK,SACpF2B,MAGL5Z,MACEmC,KAAM,OACN8X,MAAO,UAETte,SAAQpN,GAAA4rB,KAAAA,EACLtB,IACCvsB,MAAO,WAAassB,EAAyBtsB,MAC7C6V,KAAMyW,EAAyBzW,MAChCgY,GACER,EACAE,GAA4BhF,EAAOsD,OAAQ,SAC3CyB,SC5Jb/B,GCxCqC,YAGrC,SAAkCQ,GAEzBA,EAAArY,KAAUqY,EAAAE,UAAiBF,EAAA1T,WAA3B,IAA2ChJ,EAAA0c,EAAA1c,SAAU6c,EAAA7pB,EAAA0pB,GAAA,OAAA,YAAA,aAAA,aAC3C+B,GAAVze,EAAA4C,KAAU5P,EAAAgN,GAAA,UACQ0e,GAAlB1e,EAAAsC,GAAStC,EAAAuC,GAASvP,EAAAgN,GAAA,KAAA,QACJ2e,EAAA3rB,EAAA0rB,GAAA,IAAA,MAErB,IAAK1e,EAASsC,KAAOtC,EAASuC,GAC5B,MAAM,IAAIvT,MAAM,6BAGlB,OAAA4D,KACKiqB,GACHwB,QAEIha,KAAM,OACNrE,SAAUye,IAEVpa,KAAM,OACNrE,SAAU0e,IAEVra,KAAM,OACNrE,SAAUA,EAASsC,GAAE1P,GACnBvC,EAAG2P,EAASsC,GACZD,EAAGrC,EAASqC,GACTsc,GAAwB/rB,GAE3BvC,EAAG2P,EAAS3P,EACZgS,EAAGrC,EAASuC,IACToc,aC5BIC,mCFgBjB,SAAuBva,UACd4X,GAAmB5X,qGGiBfwa,IAAqD,mBC+BrDC,MAEPC,IACJC,aAAc,EACdxf,OAAQ,EACRP,OAAQ,EACRM,OAAQ,EACR0f,QAAS,EACTrf,UAAW,EACXT,MAAO,EACPqH,KAAM,EACNrM,OAAQ,EACRkF,OAAQ,GAGJ6f,GAAwBtsB,KACzBmsB,IAEHpc,QAAS,EACTE,MAAO,EACPH,OAAQ,EACRD,KAAM,EACNG,KAAM,EAENtC,OAAQ,IAGG6e,GAAoBrkB,GAASikB,IAE7BK,GAAuBtkB,GAASokB,6FF9F7C,SAAiBN,GAEFA,EAAAS,OAAmB,SACnBT,EAAAU,WAA2B,aAC3BV,EAAAW,IAAa,MACbX,EAAAY,IAAa,MACbZ,EAAAa,KAAe,OAEfb,EAAAc,KAAe,OACfd,EAAApI,IAAa,MAEboI,EAAAe,WAA2B,aAG3Bf,EAAAgB,SAAuB,WACvBhB,EAAAiB,SAAuB,WACvBjB,EAAAkB,UAAyB,YAEzBlB,EAAA5H,QAAqB,UACrB4H,EAAAmB,YAA6B,cAC7BnB,EAAAlZ,MAAiB,QACjBkZ,EAAAoB,KAAe,OArB9B,CAAiBpB,KAAAA,QAoCjB,IAAMqB,IAIJC,OAAQ,UACRlvB,IAAK,UACLmvB,IAAK,UACLC,KAAM,UACNC,aAAc,aACd1F,KAAM,OACN7L,IAAK,OACLwR,WAAY,aACZhJ,QAAS,UACTiJ,cAAe,cACfhc,MAAO,mBACPic,KAAM,oBAGKC,GAAc7oB,GAAKqoB,IAKhC,SAAAS,GAAgCC,EAAuBC,GACrD,IAAMC,EAAiBZ,GAAqBU,GACtCG,EAAiBb,GAAqBW,GAC5C,OAAOC,IAAmBC,GACJ,qBAAnBD,GAA4D,SAAnBC,GACtB,qBAAnBA,GAA4D,SAAnBD,EAM9C,IAAME,IAKJb,OAAQ,EACRlvB,IAAK,EACLmvB,IAAK,EACLC,KAAM,EAENzF,KAAM,EACN7L,IAAK,EAELvK,MAAO,GACPic,KAAM,GAENH,aAAc,EACdC,WAAY,EACZhJ,QAAS,EACTiJ,cAAe,GAMjB,SAAAS,GAAoC5X,GAClC,OAAO2X,GAAuB3X,GAGzB,IAAM6X,IAAgD,SAAU,aAAc,MAAO,MAAO,OAAQ,OAAQ,OAC7GC,GAAiClvB,EAAMivB,IAEhCE,GAAwCF,GAAgC5vB,QAAQ,eACvF+vB,GAA0BpvB,EAAMmvB,IAEzBE,IAAuC,UAAW,cAAe,QAAS,QACjFC,GAAwBtvB,EAAMqvB,IAE9BE,GAAmBvvB,GAAO,aAAc,gBAI9C,SAAAwvB,GAAkChb,GAChC,OAAOA,KAAQ8a,GAGjB,SAAAG,GAA2Bjb,GACzB,OAAOA,KAAQ+a,GAGjB,SAAAG,GAAoClb,GAGlC,OAAOA,KAAQ4a,GAGjB,SAAAO,GAAyCnb,GACvC,OAAOA,KAAQ0a,GAmLV,IAAMU,IACXC,eAAgB,GAChBC,UAAW,GACXC,aAAc,GACdC,iBAAkB,GAClBC,aAAc,GAEdC,YAAa,EAEbC,YAAa,EACbC,YAAa,GAEbC,WAAY,GACZC,WAAY,GAGZC,QAAS,EAETC,eAAgB,EAChBC,eAAgB,GAmDlB,SAAAC,GAAiCC,GAC/B,OAAOA,KAAYA,EAAa,KAGlC,SAAAC,GAAkCjkB,GAChC,OAAOA,GAAUA,EAAkB,UA4KrC,IAAMkkB,IACJrc,KAAM,EACN7H,OAAQ,EACRmkB,MAAO,EACPhB,UAAW,EACXa,OAAQ,EAERI,QAAS,EACTC,MAAO,EAEPC,MAAO,EACPC,KAAM,EAENC,KAAM,EACNC,SAAU,EACVC,YAAa,EACbC,KAAM,EAENrE,QAAS,EACTsE,aAAc,EACdC,aAAc,GAGHC,GAAmB3oB,GAAS+nB,IAI5Ba,GAA8C5oB,GAFZ9H,EAAA6vB,IAAA,OAAA,SAAA,QAAA,YAAA,YAIlCc,GAyHb,WAEE,IADA,IAAMrO,KACgB3c,EAAA,EAAAirB,EAAArgB,GAAA5K,EAAAirB,EAAAl0B,OAAAiJ,IACpB,IADG,IAAMwK,EAAOygB,EAAAjrB,GACWoB,EAAA,EAAA+c,EAAAlf,GAAKwf,IAALrd,EAAA+c,EAAApnB,OAAAqK,IACzB,IADG,IAAM8pB,EAAY/M,EAAA/c,GACGwkB,EAAA,EAAAuF,EAAArD,GAAAlC,EAAAuF,EAAAp0B,OAAA6uB,IACtB,IADG,IAAMnV,EAAS0a,EAAAvF,GACAC,EAAA,EAAAxB,IAAC,GAAO,GAARwB,EAAAxB,EAAAttB,OAAA8uB,IAAe,CAA5B,IAAMrZ,EAAG6X,EAAAwB,GACN9pB,EAAMqvB,GAA0B5gB,EAAS0gB,EAAc1e,GACzD6e,GAAwB7gB,EAASiG,IAAc6a,GAAyB7a,EAAWya,EAAc1e,KACnGmQ,EAAM5gB,GAAO4gB,EAAM5gB,OACnB4gB,EAAM5gB,GAAK9E,KAAKwZ,IAM1B,OAAOkM,EAxIuB4O,GAEhC,SAAAC,GAAyC/a,EAAsBoC,GAC7D,OAAQA,GACN,IAAK,OACL,IAAK,SACL,IAAK,UACL,IAAK,QACH,OAAO,EACT,IAAK,SACH,OAAOrS,GAAU,aAAc,UAAW,cAAe,WAAY,YAAaiQ,GACpF,IAAK,cAEH,OAAOjQ,GAAU,SAAU,aAAc,MAAO,MAAO,OAAQ,MAAO,QAASiQ,GACjF,IAAK,QACH,OAAOuY,GAAyBvY,IAA4B,SAAdA,GAAsC,UAAdA,EACxE,IAAK,UACH,OAAOuY,GAAyBvY,IAAcjQ,GAAU,QAAS,QAASiQ,GAC5E,IAAK,eACL,IAAK,YACH,OAAOjQ,GAAU,QAAS,QAASiQ,GACrC,IAAK,eACH,MAAqB,SAAdA,EACT,IAAK,QACH,OAAOuY,GAAyBvY,IAA4B,eAAdA,EAChD,IAAK,OACH,OAAOuY,GAAyBvY,IAA4B,eAAdA,GAAmD,aAArBA,EAC9E,IAAK,WACH,MAAqB,QAAdA,EACT,IAAK,OACH,MAAqB,QAAdA,EACT,IAAK,OACH,OAAOsY,GAAoBtY,KAAejQ,GACxC,MACA,OAAQ,MACR,aACA,YACA,YACCiQ,GAGP,MAAM,IAAIpa,MAAM,0BAA0Bwc,EAAQ,KAMpD,SAAA4Y,GAAoDjhB,EAAkBqI,GACpE,OAAQA,GACN,IAAK,cACL,IAAK,SACH,OAAKtI,GAAeC,QAGpB,EAFS6K,GAAYlD,mCAAmC3H,GAG1D,IAAK,OACL,IAAK,SACL,IAAK,QACL,IAAK,OACL,IAAK,WACL,IAAK,OACL,IAAK,UACL,IAAK,eACL,IAAK,eACL,IAAK,YACL,IAAK,UACL,IAAK,QACL,IAAK,QACL,IAAK,OACH,OAGJ,MAAM,IAAInU,MAAM,2BAA2Bwc,EAAQ,MAGrD,SAAAyY,GAAyCI,EAA0BR,EAAoB1e,GACrF,OAAIhM,GAAUid,GAAKY,QAASZ,GAAKc,SAAU2M,QAChBvtB,IAAlB+tB,GAA+B7C,GAAkB6C,GAC/CR,IAAiBzN,GAAKa,SACxB9d,GAAUylB,GAAUc,KAAMd,GAAUpI,IAAKoI,GAAUe,gBAAYrpB,GAAY+tB,GACzER,IAAiBzN,GAAKW,cAEtB5d,EADLgM,GACeyZ,GAAUU,WAAYV,GAAUmB,YAAanB,GAAUS,SAEzDT,GAAUW,IAAKX,GAAUY,IAAKZ,GAAUa,KAAMb,GAAUgB,SAAUhB,GAAUiB,SAAUjB,GAAUS,OAAQT,GAAUe,gBAAYrpB,GAF5D+tB,GAQvF,SAAAL,GAAwC7gB,EAAkBiG,GACxD,OAAQjG,GACN,KAAK/C,GAAQM,EACb,KAAKN,GAAQO,EACb,KAAKP,GAAQkB,KACb,KAAKlB,GAAQmB,QAGX,OAAOogB,GAAyBvY,IAAcjQ,GAAU,OAAQ,SAAUiQ,GAE5E,KAAKhJ,GAAQc,MACb,KAAKd,GAAQe,KACb,KAAKf,GAAQgB,OACX,MAAqB,SAAdgI,EAET,KAAKhJ,GAAQiB,MACX,MAAqB,YAAd+H,EAGX,OAAO,EA8BT,SAAA2a,GAAmC5gB,EAAkB0gB,EAAoB1e,GACvE,IAAMzQ,EAAMyO,EAAU,IAAM0gB,EAC5B,OAAO1e,EAAMzQ,EAAM,OAASA,uNArmBgB,OAAQ,mYAwkBtD,SAAsCyO,EAAkB0gB,EAAoB1e,GAC1E,OAAOwe,GAAiBI,GAA0B5gB,EAAS0gB,EAAc1e,OG7rB9Dmf,GAAe,sBCqCOC,GAM/B,IAAAC,EAAAD,EAAAC,OAAQvlB,EAAAslB,EAAAtlB,OAAQM,EAAAglB,EAAAhlB,OAEhBiD,EAAA+hB,EAAA/hB,MAEAiiB,EAAAzxB,EAAAuxB,GAAA,SAAA,SAAA,SAAA,UAcF,OAAQlgB,KAXEzR,KACL6xB,EACAjiB,GAASC,KAAMD,OASNkiB,QAND9xB,KACR4xB,GAAUA,OAAMA,MAChBvlB,GAAUA,OAAMA,MAChBM,GAAUA,OAAMA,QCsDhB,IAAMolB,IACXC,MAAO,IACPC,OAAQ,KAkIGC,IACX7F,QAAS,EACT8F,WAAY,GACZ5L,WAAY,oBAEZ6L,cAAe,SAEfC,KAAMN,GAENtgB,KAAM6gB,GACNlgB,QACAJ,IAAKugB,GACLzgB,UACAO,YACAH,QACAP,SACAM,QACAJ,MAAOjC,MAAO,SACdmC,UACArR,MAAOkP,MAAO,SACdgC,KAAM4gB,GACNrgB,SAEAuX,KAAM1Z,KAAM,GAAIma,OAAQ,KACxBR,cACAC,QAASha,MAAO,SAEhBpD,MAAOwiB,GACP5Y,cACAoV,QACAiH,SACAC,OAAQvmB,UAAW,IACnBwmB,YACAC,aACAC,WACAC,cACAC,YACAC,OAAQ9G,GAERlC,WF/EAiJ,QACEC,GAAI,QACJn3B,QAAS21B,IACTyB,QAAS,SACTr1B,MAAO,OAETs1B,OACEF,GAAI,QACJn3B,QAAS21B,IACT2B,OAAQ,iBACRF,QAAS,SACTr1B,MAAO,OAETw1B,UACEJ,GAAI,kDACJK,WAAY,IAAK,KACjBC,UAAW,kDACXC,KAAM,SACNhiB,MAAO5B,KAAM,OAAQ6jB,YAAa,KAAO5jB,OAAQ,SACjDqjB,QAAS,WE6DXzH,SAEAnf,UAGF,SAAAonB,GAA2BrN,GACzB,OAAOtf,GAAUmB,GAAU+pB,IAAgB5L,GAG7C,IAAMsN,IAAe,QAAQn1B,OAAO+U,GAAiBgW,IAG/CqK,IACJ,UAAW,eAAgB,aAAc,aACzC,QAAS,QAAS,YAAa,gBAC/B,WAGIC,GAA+C9zB,GACnDqyB,MAAO,QAAS,WACbpe,GACAwV,IAGL,SAAAsK,GAAuCzN,GACrCA,EAASne,GAAUme,GAEnB,IAAmB,IAAAvgB,EAAA,EAAAiuB,EAAAH,GAAA9tB,EAAAiuB,EAAAl3B,OAAAiJ,IAA2B,QACrCugB,EADErgB,EAAI+tB,EAAAjuB,IAKf,GAAIugB,EAAOkF,KACT,IAAmB,IAAArkB,EAAA,EAAA8sB,EAAAhI,GAAA9kB,EAAA8sB,EAAAn3B,OAAAqK,IAAsB,CAApC,IAAMlB,EAAIguB,EAAA9sB,UACNmf,EAAOkF,KAAKvlB,GAGvB,GAAIqgB,EAAO0M,OACT,IAAmB,IAAA9O,EAAA,EAAAgQ,EAAAjI,GAAA/H,EAAAgQ,EAAAp3B,OAAAonB,IAAsB,CAA9Bje,EAAIiuB,EAAAhQ,UACNoC,EAAO0M,OAAO/sB,GAKzB,GAAIqgB,EAAO7U,KACT,IAAmB,IAAAka,EAAA,EAAAwI,EAAAngB,GAAA2X,EAAAwI,EAAAr3B,OAAA6uB,IAAgC,CAAxC1lB,EAAIkuB,EAAAxI,UACNrF,EAAO7U,KAAKxL,GAIvB,IAAuB,IAAA2lB,EAAA,EAAAwI,EAAAR,GAAAhI,EAAAwI,EAAAt3B,OAAA8uB,IAAa,CAElC,IAFG,IAAMyI,EAAQD,EAAAxI,GAEExB,EAAA,EAAAkK,EAAAtgB,GAAAoW,EAAAkK,EAAAx3B,OAAAstB,IAAgC,CAAxCnkB,EAAIquB,EAAAlK,UACN9D,EAAO+N,GAAUpuB,GAI1B,IAAMsuB,EAA4BT,GAAgDO,GAClF,GAAIE,EACF,IAAmB,IAAAC,EAAA,EAAAC,EAAAF,EAAAC,EAAAC,EAAA33B,OAAA03B,IAA2B,CAAnCvuB,EAAIwuB,EAAAD,UACNlO,EAAO+N,GAAUpuB,GAO5ByuB,GAAepO,EAAQ+N,GAQzB,IAAK,IAAMpuB,KAHXyuB,GAAepO,EAAQ,QAAS,eAGbA,EACblpB,EAASkpB,EAAOrgB,KAAwC,IAA9BjB,GAAKshB,EAAOrgB,IAAOnJ,eACxCwpB,EAAOrgB,GAIlB,OAAOjB,GAAKshB,GAAQxpB,OAAS,EAAIwpB,OAAS5iB,EAG5C,SAAAgxB,GAAwBpO,EAAgBrgB,EAAoD0uB,GAC1F,IAAMC,EAAoC,UAAT3uB,EAAmB4uB,GAAmBvO,EAAO/Z,OAAOkF,KAAO6U,EAAOrgB,GAEtF,SAATA,IACF0uB,EAAS,QAGX,IAAMjJ,EAAK1rB,KACN40B,EACAtO,EAAOoF,MAAMzlB,IAGdjB,GAAK0mB,GAAO5uB,OAAS,IACvBwpB,EAAOoF,MAAMiJ,GAAU1uB,GAAQylB,UAE1BpF,EAAOrgB,yGCrXV6uB,IACJpE,KAAM,EACNqE,OAAQ,EACR9Z,UAAW,GAGb,SAAA+Z,GAA8Bj4B,GAC5B,QAAS+3B,GAAmB/3B,GA2BvB,IAAMk4B,IAAmBriB,GAAKD,GAAMK,GAAMF,GAAOK,GAAQC,GAAQP,GAAMjE,GAAMqE,IACvEiiB,IAA0BtiB,GAAKD,IAiC5C,SAAAwiB,GAAsBj0B,EAAmBkM,EAA2BgoB,GAClE,IAAM3jB,EAAOgC,GAAUvS,GAAKA,EAAE0S,KAAO1S,EAErC,IAAKqF,EAAS0uB,GAAiBxjB,GAC7B,OAAO,KAGT,IAAM4jB,EArCR,SAAiCjoB,GAC/B,IAAMkoB,EAAOloB,EAAS3P,EAChB83B,EAAOnoB,EAASqC,EAEtB,GAAI6V,GAAWgQ,IAAShQ,GAAWiQ,GACjC,GAAkB,iBAAdD,EAAK1hB,MAAyC,iBAAd2hB,EAAK3hB,KAAyB,CAChE,GAAI0hB,EAAKH,MACP,MAAO,IACF,GAAII,EAAKJ,MACd,MAAO,IAGT,KAAOG,EAAK/pB,aAAkBgqB,EAAKhqB,UACjC,OAAO+pB,EAAK/pB,UAAY,IAAM,QAE3B,CAAA,GAAkB,iBAAd+pB,EAAK1hB,KACd,MAAO,IACF,GAAkB,iBAAd2hB,EAAK3hB,KACd,MAAO,QAEJ,CAAA,GAAI0R,GAAWgQ,IAAuB,iBAAdA,EAAK1hB,KAClC,MAAO,IACF,GAAI0R,GAAWiQ,IAAuB,iBAAdA,EAAK3hB,KAClC,MAAO,KAcY4hB,CAAwBpoB,GAC7C,IAAKioB,EACH,OAAO,KAGT,IAAMI,EAAkBroB,EAASioB,GAC3BK,EAAejQ,GAAiBgQ,GAAmB9P,GAAQ8P,WAAuB/xB,EAElFiyB,EAAoC,MAAjBN,EAAuB,IAAM,IAChDO,EAAexoB,EAASuoB,GACxBE,EAAiBpQ,GAAiBmQ,GAAgBjQ,GAAQiQ,WAAoBlyB,EAG9EoyB,EAAU9kB,GAAqBsR,OAAO,SAACyT,EAAIxlB,GAC/C,GAAI6X,GAAgBhb,EAAUmD,GAAU,CACtC,IAAM4U,EAAa/X,EAASmD,IAC3BrT,EAAQioB,GAAcA,GAAcA,IAAawD,QAAQ,SAACqN,GACzD,IAAMhf,EAAWgQ,GAAYgP,GAC7B,IAAIhf,EAASzL,UAAb,CAKA,IAAMvK,EAAIykB,GAAiBzO,GAAY2O,GAAQ3O,WAAgBtT,IAG5D1C,GAEAA,IAAM60B,GAAkB70B,IAAM00B,IAE/BK,EAAG/4B,MAAMuT,QAAOA,EAAEyG,SAAQA,OAIhC,OAAO+e,OAGT,GAAuB,IAAnBD,EAAQh5B,OACV,OAAO,KAIT,IAAIuP,OAAsB3I,EAU1B,OARE2I,OAD4B3I,IAA1B+xB,EAAgBN,MACTM,EAAgBN,MAChB5uB,EAAS2uB,GAAwBzjB,SAEjB/N,IAAhB0xB,EAA4B,OAE5BA,IAGKJ,GAAc3oB,IAK1BopB,EAAgBjpB,OAASipB,EAAgBjpB,MAAMoH,MAAQ6hB,EAAgBjpB,MAAMoH,OAASoY,GAAUS,QAClGtR,GAASC,GAAY3B,0BAA0Bgc,EAAgBjpB,MAAMoH,OAInEwU,GAAgBhb,EAAUioB,IAAiBvnB,GAAIE,GAAKC,UACxBvK,IAA1B+xB,EAAgBN,OAClBha,GAASC,GAAY5B,sBAAsB6b,IAEtC,OAILI,EAAgBlqB,YAAchF,EAASiF,GAASiqB,EAAgBlqB,YAClE4P,GAASC,GAAY1B,2BAA2B+b,EAAgBlqB,aAIhE0qB,eAAgBL,EAAeD,OAAmBjyB,EAClD2xB,aAAYA,EACZa,OAAQ3iB,GAAW9B,GACnBqkB,QAAOA,EACPzpB,OAAMA,KA1BC,oGC4HX,SAAA8pB,GAA4BrM,GAC1B,YAAyBpmB,IAAlBomB,EAAY,MAGrB,SAAAsM,GAA2BtM,GACzB,QAASA,EAAW,KAGtB,SAAAuM,GAA4BvM,GAC1B,YAAyBpmB,IAAlBomB,EAAY,MAGrB,SAAAwM,GAA6BxM,GAC3B,YAA0BpmB,IAAnBomB,EAAa,OAGtB,SAAAyM,GAA6BzM,GAG3B,OAAO0M,GAAc1M,IAAS2M,GAAc3M,GAG9C,SAAA0M,GAA8B1M,GAC5B,YAA2BpmB,IAApBomB,EAAc,QAGvB,SAAA2M,GAA8B3M,GAC5B,YAA2BpmB,IAApBomB,EAAc,QAOvB,SAAA4M,GAA0B5M,EAAmGxD,GAC3H,GAAI6P,GAAYrM,GACd,OA0BJ,SAAwBA,EAA8DxD,GAC7E,IAAAqQ,EAAA7M,EAAAA,KAAe8M,EAAAx2B,EAAA0pB,GAAA,SACtB,OAAA9pB,KACK42B,GAEH9M,KAAM7O,GAAU0b,EAASrQ,KA/BlBuQ,CAAe/M,EAAMxD,GAE9B,GAAI+P,GAAYvM,GACd,OA8DJ,SAAAgN,EACEhN,EACAxD,EACAyQ,EACA5gB,GAEO,IAAAsV,EAAA3B,EAAA2B,MAAOre,EAAA0c,EAAA1c,SAAUgJ,EAAA0T,EAAA1T,WAAYwgB,EAAAx2B,EAAA0pB,GAAA,QAAA,WAAA,eACpC,IAAMkN,EAAiBC,IAAeF,eAAcA,EAAE3pB,SAAQA,IAC9D,IAAM8pB,EAAmBC,IAAiBhhB,iBAAgBA,EAAEC,WAAUA,IACtE,OAAApW,KACK42B,GACHnL,MAAOA,EAAM/tB,IAAI,SAACi5B,GAChB,OAAIN,GAAYM,GACPG,EAAeH,EAASrQ,EAAQ0Q,EAAgBE,GAElDE,GAAsBT,EAASrQ,EAAQ0Q,EAAgBE,OA7EzDJ,CAAehN,EAAMxD,GAE9B,GAAIgQ,GAAaxM,GACf,OA+EJ,SAAyBA,EAA+DxD,GAC/E,IAAAqQ,EAAA7M,EAAAA,KAAe8M,EAAAx2B,EAAA0pB,GAAA,SACtB,OAAA9pB,KACK42B,GACH9M,KAAM7O,GAAU0b,EAASrQ,KAnFlB+Q,CAAgBvN,EAAMxD,GAE/B,GAAIkQ,GAAc1M,GAChB,OAoFJ,SAA0BA,EAAgExD,GACjF,IAAAgR,EAAAxN,EAAAwN,QAAkBV,EAAAx2B,EAAA0pB,GAAA,YACzB,OAAA9pB,KACK42B,GACHU,QAASA,EAAQ55B,IAAI,SAACi5B,GAAY,OAAA1b,GAAU0b,EAASrQ,OAxF9CiR,CAAiBzN,EAAMxD,GAEhC,GAAImQ,GAAc3M,GAChB,OAyFJ,SAA0BA,EAAgExD,GACjF,IAAAkR,EAAA1N,EAAA0N,QAAkBZ,EAAAx2B,EAAA0pB,GAAA,YACzB,OAAA9pB,KACK42B,GACHY,QAASA,EAAQ95B,IAAI,SAACi5B,GAAY,OAAA1b,GAAU0b,EAASrQ,OA7F9CmR,CAAiB3N,EAAMxD,GAEhC,GAAI8P,GAAWtM,GAAO,CACpB,IAAM4N,EAAStP,GAAgB0B,EAAK1c,SAAUQ,IACxC+pB,EAAYvP,GAAgB0B,EAAK1c,SAAUS,IAEjD,OAAI6pB,GAAUC,EA2FlB,SAA8B7N,EAAgCxD,GAG5D,IAAMnf,EAAA2iB,EAAA1c,SAACqD,EAAAtJ,EAAAsJ,IAAUC,EAAAvJ,EAAAuJ,OAAgBtD,EAAAhN,EAAA+G,GAAA,MAAA,WAG1BsK,EAAAqY,EAAArY,KAAMugB,EAAAlI,EAAAkI,MAAO5b,EAAA0T,EAAA1T,WAAY6b,EAAAnI,EAAAmI,OAAQjI,EAAAF,EAAAE,UAAwBC,GAAbH,EAAA1c,SAAahN,EAAA0pB,GAAA,OAAA,QAAA,aAAA,SAAA,YAAA,cAEhE,OAAA9pB,KACKiqB,GACH2N,MAAK53B,KACCyQ,GAAOA,IAAGA,MACVC,GAAUA,OAAMA,OAEtBoZ,KAAMsN,GAAqBp3B,KACrBoW,GAAcA,WAAUA,OAC5B3E,KAAIA,GACAugB,GAASA,MAAKA,MACdC,GAAUA,OAAMA,OACpB7kB,SAAQA,GACJ4c,GAAaA,UAASA,OACzB1D,KA/GMuR,CAAqB/N,EAAMxD,GAE7B8Q,GAAsBtN,EAAMxD,GAErC,MAAM,IAAIlqB,MAAMgf,GAAYvG,cAY9B,SAAAoiB,GAAuB/gB,GACd,IAAA6gB,EAAA7gB,EAAA6gB,eAAgB3pB,EAAA8I,EAAA9I,SACvB,GAAI2pB,GAAkB3pB,EAAU,CAC9B,IAAM0qB,EAAY9yB,GAAK+xB,GAAgBzU,OAAO,SAACpI,EAAGpY,GAIhD,OAHIsL,EAAStL,IACXoY,EAAEld,KAAK8E,GAEFoY,OAGL4d,EAAUh7B,OAAS,GACrBqe,GAASC,GAAYrF,mBAAmB+hB,IAI5C,IAAMC,EAAM/3B,KACN+2B,MACA3pB,OAEN,OAAOpI,GAAK+yB,GAAQj7B,OAAS,EAAIi7B,OAASr0B,EAG5C,SAAAyzB,GAAyBjhB,GAChB,IAAAC,EAAAD,EAAAC,iBAAkBC,EAAAF,EAAAE,WAIzB,OAHID,GAAoBC,GACtB+E,GAASC,GAAYnF,sBAAsBE,iBAAgBA,EAAEC,WAAUA,KAElEA,GAAcD,EA6GvB,SAAAihB,GACEtN,EAAiDxD,EACjDyQ,EAA+C5gB,GAExC,IAAA/I,EAAA0c,EAAA1c,SAAUgJ,EAAA0T,EAAA1T,WACX3E,EAAOgC,GAAUqW,EAAKrY,MAAQqY,EAAKrY,KAAKmC,KAAOkW,EAAKrY,KAI1D,GAAIslB,GAAkB5gB,EAAkB,CACtC,IAAM+gB,EAAmBC,IAAiBhhB,iBAAgBA,EAAEC,WAAUA,IAChE4gB,EAAiBC,IAAeF,eAAcA,EAAE3pB,SAAQA,IAC9D,OAAOgqB,GAAqBp3B,KACvB8pB,EACCoN,GAAoB9gB,WAAY8gB,MAChCF,GAAkB5pB,SAAU4pB,OAC/B1Q,GAGL,OAxDF,SAA6CwD,GAEzC,OAAOnW,GAAgBmW,EAAKrY,MAsD1BumB,CAAoClO,GAElCrB,GAASrb,GAuBjB,SAA6B0c,GAC3B,IAAMmO,EAAO7P,GAAgB0B,EAAK1c,SAAUU,IACtCoqB,EAAO9P,GAAgB0B,EAAK1c,SAAUW,IACtC6J,EAAQwQ,GAAgB0B,EAAK1c,SAAUY,IACvC6J,EAAQuQ,GAAgB0B,EAAK1c,SAAUa,IAC7C,GAAK2J,IAAUqgB,GAAUpgB,IAAUqgB,EAAO,CACxC,IAAMC,EAAiBhwB,GAAU2hB,GAUjC,OATIlS,IAAUqgB,IACZE,EAAe/qB,SAAS3P,EAAI06B,EAAe/qB,SAASsC,UAC7CyoB,EAAe/qB,SAASsC,IAE7BmI,IAAUqgB,IACZC,EAAe/qB,SAASqC,EAAI0oB,EAAe/qB,SAASuC,UAC7CwoB,EAAe/qB,SAASuC,IAG1BwoB,EAET,OAAOrO,EAxCIsO,CAAoBtO,GAGhB,SAATrY,IAAoBrE,EAASsC,IAAMtC,EAASuC,KAC9CwL,GAASC,GAAYzD,gBAAgBvK,EAASsC,KAAMtC,EAASuC,KAEtDynB,GAAqBp3B,GAC1ByR,KAAM,QACHqY,GACFxD,EAAQyQ,EAAgB5gB,IAGzB5C,GAAW9B,GAqCnB,SAA8BqY,EAA0BxD,QAAA,IAAAA,IAAAA,YAI/C0D,EAAAF,EAAAE,UAAW5T,EAAA0T,EAAA1T,WAAYhJ,EAAA0c,EAAA1c,SAAUqE,EAAAqY,EAAArY,KAAMwY,EAAA7pB,EAAA0pB,GAAA,YAAA,aAAA,WAAA,SACxCuO,EAAU5kB,GAAUhC,GAAQA,GAAQmC,KAAMnC,GAE1C6mB,EA9GR,SAAyBD,EAAkBE,EAAwBnrB,GACjE,MAAsB,gBAAlBirB,EAAQ1mB,OACF5B,QAAS,GACRsoB,EAAQ1mB,MACVvU,EAASi7B,EAAQ1mB,OAAS0mB,EAAQ1mB,cACdjO,IAAlB20B,EAAQ1mB,MACV,KAEH4mB,EAAW5mB,OAASvE,EAAS6C,MAExB7S,EAASm7B,EAAW5mB,OAAS4mB,EAAW5mB,SAG1C,KAiGY6mB,CAAgBH,EAAS/R,EAAO+R,EAAQzkB,MAAOxG,GAC9DqrB,EAA+B,SAAjBJ,EAAQzkB,MA9F9B,SAAwBykB,EAAkBE,GACxC,OAAIF,EAAQnmB,MACc,IAAjBmmB,EAAQnmB,QAAqBmmB,EAAQnmB,UAClBxO,IAAjB20B,EAAQnmB,KACV,KAEHqmB,EAAWrmB,MAEc,IAApBqmB,EAAWrmB,QAAqBqmB,EAAWrmB,KAG7C,KAmFsCwmB,CAAeL,EAAS/R,EAAO+R,EAAQzkB,OAEtF,IAAK0kB,IAAiBG,EACpB,OAAAz4B,KACK8pB,GAEHrY,KAAMknB,GAAiBN,KAI3B,IAAM5M,GAA8BzrB,KAC9BgqB,GAAaA,UAASA,OAE1BvY,KAAMknB,GAAgB34B,KACjBq4B,EAGkB,SAAjBA,EAAQzkB,MAAmB7D,QAAS,SAG1C3C,SAAUlH,EAAKkH,GAAW,aAMtBwrB,EAAazD,GAAMkD,EAASjrB,EAAUkZ,EAASA,EAAO6O,WAAQzxB,GAEhEm1B,EAAkBzrB,EACtB,GAAIwrB,EAAY,CACP,IAAAE,EAAAF,EAAAvD,aAAiChpB,EAAAusB,EAAAvsB,OACxCwsB,EAAe74B,KACVoN,IAAQjG,MACV2xB,GAAiB94B,KACboN,EAAS0rB,GACRzsB,GAAU8oB,MAAO9oB,OAAYlF,IAKnCsxB,GACFhN,EAAMzuB,KAAIgD,KACJoW,GAAcA,WAAUA,OAC5B3E,KAAIzR,GACF4T,KAAM,QACHhO,EAAKyyB,GAAU,OAAQ,gBACvBI,GAELrrB,SAAUyrB,KAGVP,GACF7M,EAAMzuB,KAAIgD,KACJoW,GAAcA,WAAUA,OAC5B3E,KAAIzR,GACF4T,KAAM,QACN7D,QAAS,EACTgpB,QAAQ,GACLnzB,EAAKyyB,GAAU,SACfC,GAELlrB,SAAUyrB,KAId,OAAA74B,KACKiqB,GACHwB,MAAKA,IA/GIuN,CAAqBlP,EAAMxD,GAG7BwD,EAEAmP,GAAwBnP,EAAMxD,GAyBzC,SAAAqS,GAA0BN,GACjBA,EAAA1mB,MAAe0mB,EAAAnmB,KAAf,IAA4BT,EAAArR,EAAAi4B,GAAA,QAAA,SAEnC,OAAOrzB,GAAKyM,GAAM3U,OAAS,EAAI2U,EAAOA,EAAKmC,KAqF7C,SAAAslB,GAAoBrxB,EAAW0gB,GAY7B,OAXAA,EAAKI,QAAQ,SAAS3R,GAEpB,IAMMlV,EAAMuE,GANU,QAAS,OAAQ,QAAS,WAAY,MAAO,aAAaic,OAAO,SAACthB,EAAGc,GAIzF,YAHsB4B,IAAlBsT,EAASlV,KACXd,EAAEc,GAAOkV,EAASlV,IAEbd,QAGT6G,EAAK/F,GAAO+F,EAAK/F,IAAQkV,IAEpBnP,6JA6BT,SAA0BiiB,GACxB,OAAO9hB,GA1BT,SAAAmxB,EAA0BrP,EAA6BjiB,GAqBrD,YArBqD,IAAAA,IAAAA,MAEjDwuB,GAAYvM,GACdA,EAAK2B,MAAM9C,QAAQ,SAAA8C,GACb2K,GAAW3K,GACbyN,GAAWrxB,EAAMuxB,GAAqB3N,EAAMre,WAE5C+rB,EAAc1N,EAAO5jB,KAGhBsuB,GAAYrM,IACrBoP,GAAWrxB,EAAMuxB,GAAqBtP,EAAK8N,QAC3CuB,EAAcrP,EAAKA,KAAMjiB,IAChByuB,GAAaxM,GACtBqP,EAAcrP,EAAKA,KAAMjiB,GAChB0uB,GAAazM,IACJ0M,GAAc1M,GAAQA,EAAKwN,QAAUxN,EAAK0N,SAClD7O,QAAQ,SAAA0Q,GAAS,OAAAF,EAAcE,EAAOxxB,KAEhDqxB,GAAWrxB,EAAMuxB,GAAqBtP,EAAK1c,WAEtCvF,EAKKsxB,CAAcrP,eAG5B,SAA0BA,EAA0CxD,GAElE,OADAA,EAASA,GAAUwD,EAAKxD,SACpB3S,GAAgBmW,EAAKrY,OAGX,OAFL0jB,GAAMrL,EAAKrY,KAAMqY,EAAK1c,SACrBkZ,EAASA,EAAO6O,WAAQzxB,MC9gBpC,SAAA41B,GAA4BC,GAC1B,OAAOh8B,EAASg8B,IAAa3lB,KAAM2lB,GAAYA,MAoBjD,IAAMC,IACJ,aAAc,UAAW,YAI3B,SAAAC,GAAwEv5B,GACtE,OAAOs5B,GAAqBlX,OAAO,SAACpI,EAAG5d,GAIrC,OAHI4D,QAAcwD,IAATxD,EAAE5D,KACT4d,EAAE5d,GAAK4D,EAAE5D,IAEJ4d,mBCnDewf,GACxB,QAASA,EAAU,IAGrB,SAAAC,GAA6BD,GAC3B,QAASA,EAAa,OAGxB,SAAAE,GAA4BF,GAC1B,QAASA,EAAW,OAAMG,GAAUH,KAAUC,GAAaD,GAKtD,IAAMI,GAAe,OACfC,GAAa,qFC3IX,SAAAC,GAASC,EAAU92B,EAAQ+2B,GAGxC,OAFAC,GAAiBh3B,GAAUi3B,GAC3BC,GAAQH,GAASI,GACVC,GAAWN,EAASO,QAAQ98B,IAAIs8B,IAGzC,IAUIG,GACAE,GAXAD,GAAU,OACVK,GAAU,IACVC,GAAU,IACVC,GAAU,IACVC,GAAU,IACVC,GAAU,IACVC,GAAU,IACVC,GAAU,IACVC,GAAU,IACVC,GAAU,UAGVX,IACEY,IAAK,EACLC,IAAK,EACL/oB,KAAM,EACNgpB,MAAO,EACPC,MAAO,EACPnpB,KAAM,EACNxV,KAAM,EACNuV,KAAM,EACNJ,KAAM,EACN5B,MAAO,EACPqrB,OAAQ,EACR56B,KAAM,EACNyR,MAAO,GAOb,SAASopB,GAAKx+B,EAAGR,EAAGi/B,EAASC,EAAUC,GAIrC,IAHA,IAEIj/B,EAFAwN,EAAQ,EACRpN,EAAIE,EAAED,OAEHP,EAAEM,IAAKN,EAAG,CAEf,GADAE,EAAIM,EAAER,IACD0N,GAASxN,IAAM++B,EAAS,OAAOj/B,EAC3Bm/B,GAAWA,EAAQp7B,QAAQ7D,IAAM,IAAKwN,EACtCwxB,GAAYA,EAASn7B,QAAQ7D,IAAM,KAAKwN,EAEnD,OAAO1N,EAGT,SAASg+B,GAAWx9B,GAMlB,IALA,IAAI4+B,KACAC,EAAQ,EACR/+B,EAAIE,EAAED,OACNP,EAAI,EAEDA,EAAIM,GACTN,EAAIg/B,GAAKx+B,EAAGR,EAAGu+B,GAAOL,GAASE,GAAQD,GAASE,IAChDe,EAAO3+B,KAAKD,EAAEE,UAAU2+B,EAAOr/B,GAAGi+B,QAClCoB,IAAUr/B,EAGZ,GAAsB,IAAlBo/B,EAAO7+B,OACT,KAAM,yBAA2BC,EAEnC,OAAO4+B,EAGT,SAAS3B,GAAcj9B,GACrB,MAAgB,MAATA,EAAE,GAKX,SAAsBA,GACpB,IAEIH,EAAGi/B,EAFHh/B,EAAIE,EAAED,OACNP,EAAI,EAIR,IADAA,EAAIg/B,GAAKx+B,EAAGR,EAAGm+B,GAAQD,GAAQC,OACrB79B,EACR,KAAM,2BAA6BE,EAIrC,GAAiB,KADjBH,EAAI29B,GAAWx9B,EAAEE,UAAU,EAAGV,KACxBO,OACJ,KAAM,4CAA8CC,EAItD,IADAA,EAAIA,EAAE2B,MAAMnC,EAAI,GAAGi+B,QACb,KAAOQ,GACX,KAAM,wCAA4Cj+B,EAMpD,GAHAH,EAAIA,EAAEc,IAAIs8B,KAEV6B,EAAS7B,GAAcj9B,EAAE2B,MAAM,GAAG87B,SACvBsB,QACT,OACEA,QAASl/B,EACTi/B,OAAQA,GAGVA,EAAOC,QAAUl/B,EAGnB,OAAOi/B,EApCHE,CAAah/B,GAuCnB,SAAqBA,GACnB,IAMWP,EACPkK,EAPAm1B,GAAU14B,OAAQg3B,IAClBh3B,KACA64B,GAAY,EAAG,GACfC,EAAW,EACXL,EAAQ,EACR/+B,EAAIE,EAAED,OACNP,EAAI,EAIR,GAAIQ,EAAEF,EAAE,KAAO+9B,GAAQ,CAErB,MADAr+B,EAAIQ,EAAEm/B,YAAYvB,MACT,GAQF,KAAM,0BAA4B59B,EAPvC,IACEi/B,EAsER,SAAuBj/B,GACrB,IAAIgG,EAAIhG,EAAEo/B,MAAMrB,IAChB,IAAK/9B,EAAED,QAAUiG,EAAEjG,OAAS,EAAG,MAAMC,EACrC,OAAOgG,EAAErF,IAAI,SAASL,GACpB,IAAII,GAAKJ,EACT,GAAII,GAAMA,EAAG,MAAMV,EACnB,OAAOU,IA5EQ2+B,CAAcr/B,EAAEE,UAAUV,EAAE,EAAGM,EAAE,IAC5C,MAAOwD,GACP,KAAM,mCAAqCtD,EAE7CA,EAAIA,EAAE2B,MAAM,EAAGnC,GAAGi+B,OAClB39B,EAAIE,EAAED,OAERP,EAAI,EAGN,IAAKM,EAAG,MAAME,EAGVA,EAAE,KAAOg+B,KAAMkB,IAAa1/B,IAGhCC,EAAI++B,GAAKx+B,EAAGR,EAAGs+B,KACPh+B,IACNsG,EAAOnG,KAAKD,EAAEE,UAAU2+B,EAAOp/B,GAAGg+B,QAClCoB,EAAQr/B,IAAMC,GAKhB,IADAD,EAAIg/B,GAAKx+B,EAAGR,EAAGk+B,OACL59B,EACRsG,EAAOnG,KAAKD,EAAEE,UAAU2+B,EAAO/+B,GAAG29B,aAKlC,GAHAr3B,EAAOnG,KAAKD,EAAEE,UAAU2+B,EAAOr/B,GAAGi+B,QAClC9zB,MACAk1B,IAAUr/B,KACIM,EAAG,KAAM,2BAA6BE,EAItD,KAAOR,EAAIM,GAAG,CAEZ,IADAN,EAAIg/B,GAAKx+B,EAAGR,EAAGm+B,OACL79B,EAAG,KAAM,2BAA6BE,EAEhD,GADA2J,EAAO1J,KAAKD,EAAEE,UAAU2+B,EAAOr/B,GAAGi+B,QAC9Bj+B,EAAIM,EAAE,GAAKE,IAAIR,KAAOk+B,GAAQ,KAAM,0BAA4B19B,EACpE6+B,IAAUr/B,EAIZ,KAAMM,EAAIsG,EAAOrG,SAAWm+B,GAAQn4B,KAAKK,EAAOtG,EAAE,IAChD,KAAM,2BAA6BE,EAGjCF,EAAI,GACNg/B,EAAOjoB,KAAOzQ,EAAO,GACjB84B,EACFJ,EAAOI,SAAW94B,EAAO,GAAGzE,MAAM,IA7IpBkV,EA8IMzQ,EAAO,GA7IxBk3B,GAAM56B,eAAemU,GA8IxBioB,EAAOQ,SAAWl5B,EAAO,GAEzB04B,EAAO14B,OAASA,EAAO,KAGzB04B,EAAOjoB,KAAOzQ,EAAO,GApJzB,IAAoByQ,EAsJY,MAA1BioB,EAAOjoB,KAAKlV,OAAO,KACrBm9B,EAAOS,SAAU,EACjBT,EAAOjoB,KAAOioB,EAAOjoB,KAAKlV,MAAM,GAAI,IAExB,MAAVgI,IAAgBm1B,EAAOn1B,OAASA,GAChCs1B,EAAS,KAAIH,EAAOG,SAAWA,EAAS,IACxCA,EAAS,KAAIH,EAAOU,SAAWP,EAAS,IAE5C,OAAOH,EAxHHW,CAAYz/B,eCrBYmd,GAC5B,QAASA,EAAU,OAoCrB,SAAAuiB,GAA8BvM,GAC5B,QAASA,EAAY,KA4IvB,SAAAwM,GAAgC3wB,GAC9B,OAAK7O,EAAQ6O,KACH,UAAWA,GAAU,SAAUA,GAy+B3C,IA+Ca4wB,GAAkBz0B,IA9C7B6H,QAAS,EACTF,KAAM,EACN6jB,YAAa,EACb5jB,OAAQ,EACR8sB,UAAW,EACXC,YAAa,EACbC,cAAe,EACfC,WAAY,EACZC,iBAAkB,EAClBC,WAAY,EACZC,iBAAkB,EAClBltB,KAAM,EACNC,MAAO,EACPwgB,YAAa,EACb0M,QAAS,EACTxwB,OAAQ,EACRywB,MAAO,EACPC,SAAU,EACV38B,KAAM,EACN48B,IAAK,EACLC,GAAI,EACJC,GAAI,EACJC,SAAU,EACVC,MAAO,EACPC,OAAQ,EACRC,MAAO,EACPC,MAAO,EACPC,KAAM,EACNC,SAAU,EACVC,WAAY,EACZC,UAAW,EACXC,OAAQ,EACR7tB,KAAM,EACND,QAAS,EACT+tB,aAAc,ICvuChB,SAAAC,GACEC,EACAC,EACAhY,EACApQ,QAAA,IAAAA,IAAAA,GAEKqoB,QAAQ,IAEb,IAAMp3B,EAAAk3B,EAAAG,UAAC7xB,EAAAxF,EAAAwF,OAAQH,EAAArF,EAAAqF,MAAOD,EAAAA,EAAAA,MAAOE,EAAAtF,EAAAsF,OAAQ+e,EAAAprB,EAAA+G,GAAA,SAAA,QAAA,QAAA,WAUrC,GAPAnC,GAAKwmB,GAAM7C,QAAQ,SAAC7mB,GAClB,IAAM28B,EAAW7yB,GAAmB9J,GAChC28B,GAAYA,IAAaH,GAAqB,SAAbG,UAC5BjT,EAAK1pB,KAIH,SAATw8B,EAAiB,CACnB,IAAK9S,EAAK3f,KACR,OAIF,GAAI2f,EAAK9d,OAAQ,CAER,IAAA7B,EAAA2f,EAAA9d,OAAA7B,KACP2f,EAAK9d,OAAM1N,KACL6L,GAAQA,KAAIA,OAGe,IAA7B7G,GAAKwmB,EAAK9d,QAAQ5Q,eACb0uB,EAAK9d,OAIhB,OAAA1N,GACEwM,MAAKA,EACLG,OAAMA,GACH6e,GACHzf,QAAQ,EACRC,QAAQ,EAIRI,UAAW,EACXD,UAAW,EACXG,OAAO,EACPG,YAAmB/I,IAAX+I,EAAuBA,EAAS,IAI1C,GAAKyJ,EAAIqoB,SAAUF,EAASK,cAA5B,CAMA,GAAIlT,EAAK9d,OAAQ,CACf,IAAmB,IAAA3H,EAAA,EAAA44B,EAAAhzB,GAAA5F,EAAA44B,EAAA7hC,OAAAiJ,IAAY,CAA1B,IAAMyc,EAAImc,EAAA54B,GAEVs4B,EAASO,YAAYpc,WAEfgJ,EAAK9d,OAAO8U,GAGU,IAA7Bxd,GAAKwmB,EAAK9d,QAAQ5Q,eACb0uB,EAAK9d,OAIhB,IAAMmxB,EA9EV,SAAuBtyB,EAAwC+Z,GAC7D,OAAIppB,EAAQqP,GACHA,EAAM7O,IAAI,SAAAsZ,GAAY,OAAA8nB,GAAc9nB,EAAUsP,KAASpoB,KAAK,MAE9DqO,EA0EewyB,CAAcxyB,EAAO+Z,GAEzC,OAAAtmB,GACEwM,MAAKA,EACLG,OAAMA,EACNd,MAAM,GACFgzB,GAAetyB,MAAOsyB,MACvBrT,GACH/e,YAAmB/I,IAAX+I,EAAuBA,EAAS,KC3FvC,IAAMuyB,IAGXC,YAAa,SACbC,WAAY,QACZC,cAAe,WACfC,WAAY,QACZC,UAAW,OACXC,cAAe,WACfC,gBAAiB,aACjBC,WAAY,SAGDC,IAGXpyB,WAAY,QACZqyB,WAAY,QACZC,UAAW,OACXC,cAAe,WACfC,WAAY,SAGDC,GAA0BxiC,OAAO0H,KAAKg6B,IAEtCe,GAA0BziC,OAAO0H,KAAKy6B,wJCuBpBv6B,GAC7B,SAASA,GAAwB,UAAfA,EAAS,KAAmBA,EAAY,QAAQA,EAAS,IAG7E,SAAA86B,GAA+B96B,GAC7B,QAASA,GAAQhI,EAAQgI,yDCE3B,SAAA+6B,GAA0B1vB,EAAkC8nB,GAC1D,IAGM6H,EAAqB7H,EAHL9nB,EAAU,UAIhC,GAAI2vB,EACF,OAAOA,EASX,SAAAC,GAAoBnpB,EAA4BopB,EAAmBC,EAAuBh0B,GAExF,OAAOuW,GAAS5L,EAAUopB,GAAYna,UADX,UAAToa,OAAmB38B,EAAY,OACC2I,GAAUA,OAAMA,OAGpE,SAAAuW,GACI5L,EAA4BopB,EAAmBlqB,EAC/CoqB,GAGF,IAAMC,EAAGvgC,KACHogC,GAAa5zB,MAAO4zB,OACxBriC,MAAO4nB,GAAQ3O,EAAUd,KAG3B,OAAIoqB,EACFtgC,KACKugC,EACAD,GAGAC,EAGT,SAAAC,GAAwBJ,EAAmBxS,GACzC,YADyC,IAAAA,IAAAA,GAAA,IAEvCphB,MAAO4zB,EACPxS,KAAMA,GAoBV,SAAA6S,GACElwB,EACA4U,EACAib,EACA5zB,EACA2oB,EACAuL,GAIA,GAAIvb,EAAY,CAGd,GAAIG,GAAWH,GAAa,CAC1B,GAAIA,EAAW5S,IAGb,OAAIhM,GAAUuH,GAAGC,IAAIwC,IAAY4U,EAAWvR,OAASuQ,GAC/CgR,GAASA,EAAMe,OAEVtT,GAASuC,EAAYib,GAAYna,UAAW,QAjC/D,SAAsBjP,EAA4BopB,GAChD,OACElY,OAAQ,WACIkY,EAAS,MAAMza,GAAQ3O,GAAWkP,KAAM,UAAS,cAEjDka,EAAS,MAAMza,GAAQ3O,GAAWiP,UAAW,MAAOC,KAAM,UAAS,QA+BlEya,CAAaxb,EAAYib,GAE3Bxd,GAASuC,EAAYib,EAAWQ,GAAiBzb,EAAY5U,IAAY0V,UAAW,aAG7F,GAAIzZ,EAAO,CACT,IAAMgK,EAAYhK,EAAMq0B,IAAI,QAC5B,GAAIjS,GAAkBpY,GACpB,MAAkB,SAAdA,EAEKoM,GAASuC,EAAYib,GAAYna,UAAW,UAAW2H,KAAM,KAE/DhL,GAASuC,EAAYib,GAAYna,UAAW,UAGvD,OAAOrD,GAASuC,EAAYib,MACvB,GAAI5a,GAAWL,GAAa,CACjC,IAAMxkB,EAAQwkB,EAAWxkB,MAEzB,OAAI4F,GAAU,IAAK,MAAOgK,IAAsB,UAAV5P,GAC5B5C,OAAQq9B,MAAO,UACd70B,GAAU,IAAK,MAAOgK,IAAsB,WAAV5P,GACnC5C,OAAQq9B,MAAO,YAGjBz6B,MAAKA,IAOjB,MC/KoB,mBD+KF+/B,EAAcA,IAAeA,EAGjD,SAAAI,GAAqBC,EAAwDza,GAE3E,GAAIya,EAAS,CACX,GAAIzb,GAAWyb,GACb,OAAOC,GAAgBD,EAASA,EAAQn0B,OAAQ,QAAS0Z,GACpD,GAAId,GAAWub,GACpB,OAAQpgC,MAAOogC,EAAQpgC,QAM7B,SAAAsgC,GAAoBC,GAClB,OAAAlhC,KAAWkhC,GAASC,KAAM,KAiB5B,SAAAC,GACEV,EACAnwB,EAAoB6vB,EAAmB5zB,EAAuBiF,GAE9D,OAAO,WACL,GAAIlU,EAASmjC,GAAa,CACxB,GAAIN,EAAW,CACb,IAAM5pB,EAAYhK,EAAMq0B,IAAI,QAC5B,GAAIt6B,GAAUylB,GAAUW,IAAKX,GAAUc,KAAMd,GAAUpI,KAAMpN,GAK9C,QAAT/E,GAA2B,SAATA,GACpB0J,GAASC,GAAY7E,+BAA+B9E,EAAMlB,GAAUiG,UAASA,SAE1E,CACL,GA5BV,SAAqChK,GACnC,IAA0B,IAAtBA,EAAMq0B,IAAI,QACZ,OAAO,EAET,IAAMQ,EAAU70B,EAAM60B,QACtB,QAAInkC,EAAQmkC,IACH16B,EAAK06B,EAAS,SAAC7hC,GAAM,OAAAtC,EAAQsC,IAAmB,IAAbA,EAAE1C,QAAgB0C,EAAE,IAAK,GAAKA,EAAE,IAAM,IAsBtE8hC,CAA4B90B,GAC9B,OACEA,MAAO4zB,EACPz/B,MAAO,GAGE,QAAT8Q,GAA2B,SAATA,GACpB0J,GAASC,GAAY7E,+BACnB9E,EAAMlB,GAAUkG,WAAmC,IAAxBjK,EAAM+0B,SAAS7Q,SAMlD,MAAmB,cAAfgQ,EACiB,MAAZnwB,GAAmB5P,MAAO,IAAM5C,OAAQq9B,MAAO,WAEnC,MAAZ7qB,GAAmBxS,OAAQq9B,MAAO,WAAaz6B,MAAO,GAGjE,OAAO+/B,eE7NWc,EAAkBtrB,gBAAA,IAAAA,IAAAA,GAA6BurB,WAAW,IACvE,IAAApJ,EAAAmJ,EAAAnJ,QAASjrB,EAAAo0B,EAAAp0B,SAAUkZ,EAAAkb,EAAAlb,OACnByS,EAAAV,EAAAU,OAAQ1E,EAAAgE,EAAAzkB,KAET8tB,GACJ7xB,KAAM8xB,GAAc,OAAQtJ,EAAS/R,GACrCxW,OAAQ6xB,GAAc,SAAUtJ,EAAS/R,GACzC1W,MAAO+xB,GAAc,QAAStJ,EAAS/R,IAGnCsb,EAAsBr7B,GAAU,MAAO,QAAS,SAAU,SAAU,YAAa8tB,GAAY,mBAAgB3wB,EAE7Gm+B,GACJhyB,KAAMwoB,EAAQxoB,MAAQ6xB,EAAY7xB,MAGhC+xB,EACF9xB,OAAQuoB,EAAQvoB,QAAU4xB,EAAY5xB,QAGlCgyB,EAAiB/I,EAAS,OAAS,SAEnCgJ,EAA0B/hC,KAC1B6hC,EAAahyB,MACfA,MAAOlP,MAAOkhC,EAAahyB,UAEzBgyB,EAAa/xB,QACfA,QAASnP,MAAOkhC,EAAa/xB,aAIjC,OAAI1C,EAASyC,MAAQzC,EAAS0C,QAExBuoB,EAAQzoB,OAEVuL,GAASC,GAAYtE,cAAc,YAAajH,KAAM,SAAUzC,EAAU0C,OAAQ,WAAY1C,KAGhGpN,KACKgiC,GAAY,OAAQR,GAAQK,aAAcA,EAAahyB,MAAQ+xB,IAC/DI,GAAY,SAAUR,GAAQK,aAAcA,EAAa/xB,WAErD1C,EAASwC,MAElB5P,KACK+hC,EAEAC,GAAY,QAASR,GACtBS,UAAWH,EAEXD,aAAcxJ,EAAQyJ,IAAmBzJ,EAAQzoB,OAAS8xB,EAAYI,IAAmBJ,EAAY9xB,QAAUmpB,EAAS6I,OAAsBl+B,MAGzI20B,EAAQxoB,MAAQwoB,EAAQvoB,QAE7BuoB,EAAQzoB,OACVuL,GAASC,GAAYtE,cAAc,YAAajH,KAAM,SAAUwoB,EAASvoB,OAAQ,WAAYuoB,KAExF0J,GACE1J,EAAQzoB,MACjB5P,KACK+hC,IAA0B56B,MAG5B26B,IAAkBnhC,MAAO03B,EAAQzoB,OAAMzI,IAEjCu6B,EAAY7xB,MAAQ6xB,EAAY5xB,OAElCiyB,EACEL,EAAY9xB,MACrB5P,KACM4hC,GAAuB/xB,MAAOlP,MAAO,qBAAoBujB,MAC5D4d,IAAkBnhC,MAAO+gC,EAAY9xB,OAAMsU,OAQlD,SAAAge,GAAgCV,EAAkBW,GAChD,OAAAniC,KASF,SAA2ByR,EAAe0wB,GACxC,OAAOxF,GAAgBra,OAAO,SAACphB,EAAG+E,GAIhC,YAHmBvC,IAAf+N,EAAKxL,IAAwC,WAAjBk8B,EAAOl8B,KACrC/E,EAAE+E,IAAStF,MAAO8Q,EAAKxL,KAElB/E,OAbJkhC,CAAkBZ,EAAMnJ,QAAS8J,GACjCvyB,GAAM4xB,GACNQ,GAAY,UAAWR,GAuG9B,SAAwBA,GACtB,IACMrc,EAAaqc,EAAMp0B,SAAgB,QACzC,GAAIlQ,EAAQioB,GAAa,CACvB,IAAMkd,EAAYld,EAAWznB,IAAI,SAACsZ,GAChC,IAAMlV,OAAyB4B,IAAnBsT,EAASzK,MAAsByK,EAASzK,MAAQoZ,GAAQ3O,GAAWiP,UAAW,UACpFtlB,EAAQ2hC,GAAStrB,EAAUwqB,EAAMlb,QAAQ4B,OAC/C,MAAO,IAAIpmB,EAAG,MAAMnB,IAEtB,OAAQyP,SAAU8X,OAAQ,IAAIma,EAAUnkC,KAAK,MAAK,MAGlD,OAAOqkC,GAAWf,EAXJ,UAWoBrc,GAlH/B/U,CAAQoxB,GACR9gC,GAAK8gC,EAAO,SAoBnB,SAAAgB,GAAwBC,GACtB,OAAUA,EAAK,uBAAuBA,EAAK,IAG7C,SAAAC,GAAwBlB,GACtB,GAAmC,WAA/BA,EAAMlb,OAAO8L,cAA4B,CAC3C,IAAMr2B,GAAU,IAAK,KAAK2B,IAAI,SAAC6S,GAC3B,IAAMoyB,EAAiBnB,EAAMoB,kBAAkBryB,GAC/C,GAAIoyB,GAIE7T,GAHc6T,EAAe9B,IAAI,SAInC,OAAOW,EAAM7b,QAAQpV,GAAU2V,KAAM,YAK1Cxf,OAAO,SAAA3I,GAAS,QAAEA,IAClBL,IAAI8kC,IAEP,GAAIzmC,EAAOe,OAAS,EAClB,OACE4lC,SAAUxa,OAAQnsB,EAAOmC,KAAK,UAKpC,SAMF,SAAA8jC,GAA4BzxB,EAA+CixB,EAAkBtrB,QAAA,IAAAA,IAAAA,MACpF,IAAA2rB,EAAA3rB,EAAA2rB,aAAcI,EAAA/rB,EAAA+rB,UACfvB,EAAaxqB,EAAIwqB,kBAAgCh9B,IAAjBm+B,GAA8BlhC,MAAOkhC,QAAgBn+B,GAErFyhB,EAAaqc,EAAMp0B,SAASmD,GAElC,OAAOsyB,GAAcrB,EAAOrc,EAAY8c,GAAa1xB,EAAS,SAACylB,GAC7D,OAAO8M,GACLvyB,EAASylB,EAAMwL,EAAMpB,UAAU7vB,GAC/BixB,EAAMoB,kBAAkBryB,GACxB,KACAmwB,KASN,SAAAmC,GACIrB,EAAkBrc,EAAgC8c,EAClDc,WAEI3d,EAAYD,GAAcA,EAAWC,UACrC4d,EAAWD,EAAM5d,GACvB,GAAIC,EAAW,CACb,IACM6d,GADa/lC,EAAQkoB,GAAaA,GAAaA,IACrB1nB,IAAI,SAACjB,GACnC,IAAMymC,EAAoBH,EAAMtmC,GAC1BqG,EAAOqgC,GAAuB1mC,GAAK2mC,GAAmB5B,EAAO/kC,EAAEutB,WAAa7G,GAAWqe,EAAO/kC,EAAEqG,MACtG,OAAA9C,GACE8C,KAAIA,GACDogC,KAGP,OAAA/7B,MACG86B,GACIgB,EAAYxkC,YACEiF,IAAbs/B,GAA0BA,SAIlC,YAAoBt/B,IAAbs/B,IAAsB9e,MAAK+d,GAAYe,EAAQ9e,MAoB1D,SAAAmf,GAAqB7B,EAAkBjxB,GAErC,YAFqC,IAAAA,IAAAA,EAAA,QAE9BgyB,GAAWf,EAAOjxB,EADNixB,EAAMp0B,SAASmD,IAIpC,SAAAgyB,GAAoBf,EAAkBjxB,EAAsC4U,GAC1E,OAAO0d,GAAcrB,EAAOrc,EAAY5U,EAAS,SAACylB,GAAS,OAAAsM,GAAStM,EAAMwL,EAAMlb,UAGlF,SAAAgd,GAA6BtsB,EAA4BzG,EAAkBixB,aACnEpB,EAAYoB,EAAMpB,UAAU7vB,GAC5BgzB,EAA0B,MAAZhzB,EAAkB,QAAU,SAEhD,GAAIixB,EAAMp0B,SAAS4C,WAA+BtM,IAAvB89B,EAAMnJ,QAAQroB,KAEvC,GADewxB,EAAMnJ,QAAQ1rB,OACjB,CACV,IAAM62B,IAA0Br8B,MAG7BoJ,EAAQ,KAAMkzB,GAAazsB,EAAUopB,MAAgBxS,KAAM,QAG9D,GAAI5G,GAAYwa,EAAMp0B,SAAS4C,MAC7B,OAAAhQ,KACKwjC,EACAxB,GAAY,OAAQR,GAAQS,UAAWsB,KAEvC,GAAI/d,GAAWgc,EAAMp0B,SAAS4C,MACnC,OAAAhQ,KACKwjC,EACAxB,GAAY,OAAQR,GAAQS,UAAWsB,KAEvC,QAA2B7/B,IAAvB89B,EAAMnJ,QAAQroB,KACvB,OAAAhQ,KACKwjC,IAA0Btf,MAC5Bqf,IAAe5iC,MAAO6gC,EAAMnJ,QAAQroB,MAAKkU,SAI9C/I,GAASC,GAAY9C,iCAAiCkpB,EAAMnJ,QAAQzkB,OAGxE,OAAA+X,MACGpb,GAAUkzB,GAAazsB,EAAUopB,GAAYna,UAAW,UACzD0F,EAAC4X,GAAcG,GAAYtD,KAI/B,SAAAuD,GAAqCpzB,EAAoBixB,EAAkBoC,EAA2BC,GACpG,IACMN,EAA0B,MAAZhzB,EAAkB,QAAU,SAChD,OAAAvQ,KACK8jC,GAAcvzB,EAASixB,EAAOoC,EAHY,MAAZrzB,EAAkB,KAAO,MAIvDyxB,GAAY,OAAQR,GAAQd,WAAYmD,EAAgB5B,UAAWsB,KAI1E,SAAAQ,GAA+B/sB,EAA4BzG,EAAkB6vB,EAAmB4D,EAAiB7T,GAC/G,MAAgB,MAAZ5f,GAEAb,GAAIu0B,GAAQjtB,EAAUopB,EAAW,QAASjQ,EAAU,EAAI6T,GACxDvmC,EAAGwmC,GAAQjtB,EAAUopB,EAAW,MAAOjQ,EAAU6T,EAAU,KAI3Dr0B,GAAIs0B,GAAQjtB,EAAUopB,EAAW,QAASjQ,EAAU6T,EAAU,GAC9Dv0B,EAAGw0B,GAAQjtB,EAAUopB,EAAW,MAAOjQ,EAAU,EAAI6T,IAS3D,SAAAF,GAA8BvzB,EAAkBixB,EAAkBd,EAAoDuB,SAG7G70B,EAAAo0B,EAAAp0B,SAAUqE,EAAA+vB,EAAA/vB,KAAM0jB,EAAAqM,EAAArM,MAEjBhQ,EAAa/X,EAASmD,GACtB6vB,EAAYoB,EAAMpB,UAAU7vB,GAC5B/D,EAAQg1B,EAAMoB,kBAAkBryB,GAGhClE,EAAS63B,GAAc3zB,EAASixB,EAAMnJ,SAGtC2K,EAAY7d,IAAe/X,EAASiC,WAAYjC,EAAS+B,UAE9BnP,KF5RnC,SAAyBuQ,EAAoB4U,EAAgCib,EAAmB5zB,EAC5F2oB,EAAwBuL,GAC1B,OAAIpb,GAAWH,IAAegQ,GAAS5kB,IAAY4kB,EAAME,aAEhDzS,GAASuC,EAAYib,GAAYxa,OAAQ,QAE3C6a,GAASlwB,EAAS4U,EAAYib,EAAW5zB,EAAO2oB,EAAOuL,GEwRvDyD,CAAa5zB,EAASnD,EAASmD,GAAU6vB,EAAW5zB,EAAO2oB,EAC5DiP,GAAkB1D,EAAYnwB,EAAS6vB,EAAW5zB,EAAOiF,IAExDpF,GAAUA,OAAMA,QALpBtO,MAAOyjC,EAAM6C,QAAQ9zB,IAQxB,OAAApJ,MACG86B,GAAa1xB,GAAUyyB,IAQ5B,SAAAsB,GAA+B9C,EAAkBd,EAAuCnwB,SAC/EnD,EAAAo0B,EAAAp0B,SAAUqE,EAAA+vB,EAAA/vB,KAAM0jB,EAAAqM,EAAArM,MAEjBoP,EAA0B,OAAZh0B,EAAmB,IAAM,IACvC4U,EAAa/X,EAASm3B,GACtBnE,EAAYoB,EAAMpB,UAAUmE,GAC5B/3B,EAAQg1B,EAAMoB,kBAAkB2B,GAEhCl4B,EAAS63B,GAAc3zB,EAASixB,EAAMnJ,SAEtC2K,EAAY7d,IAAe/X,EAASiC,WAAYjC,EAAS+B,UAE9BnP,KF7SnC,SAA0BuQ,EAAsBi0B,EAA+BC,EAAgCrE,EAAmB5zB,EAChI2oB,EAAwBuL,GACxB,OAAIpb,GAAWkf,IAAcrP,GAEzB5kB,EAAQnP,OAAO,KAAO+zB,EAAME,aAAaj0B,OAAO,GAE3CwhB,GAAS4hB,EAAWpE,GAAYxa,OAAQ,UAE1C6a,GAASlwB,EAASk0B,EAAYrE,EAAW5zB,EAAO2oB,EAAOuL,GEuSvDgE,CAAcn0B,EAAS4U,EAAY/X,EAASmD,GAAU6vB,EAAW5zB,EAAO2oB,EACzEiP,GAAkB1D,EAAY6D,EAAanE,EAAW5zB,EAAOiF,IAE3DpF,GAAUA,OAAMA,QALrBtO,MAAOyjC,EAAM6C,QAAQ9zB,IAQxB,OAAApJ,MAASoJ,GAAUyyB,EAAQ77B,EC5T7B,SAAAw9B,GAA0BlzB,GACxB,SAAUhT,OAAOgT,EAAKmC,KAAMnC,EAAKia,WAOnC,SAAAiW,GAA0D17B,EAASwL,EAAe6U,GAEhF,IAAI3lB,EAAQ2lB,EAAO7U,KAAKxL,GAGlBgjB,EAAqB3C,EAAO7U,EAAKmC,WACNlQ,IAA7BulB,EAAmBhjB,KACrBtF,EAAQsoB,EAAmBhjB,IAK7B,IADA,IACoBF,EAAA,EAAA6+B,EADLD,GAAUlzB,GACL1L,EAAA6+B,EAAA9nC,OAAAiJ,IAAQ,CAAvB,IAAM2lB,EAAKkZ,EAAA7+B,GACR8+B,EAAcve,EAAOoF,MAAMA,GAI3BpvB,EAAI2J,EACN4+B,QAAkCnhC,IAAnBmhC,EAAYvoC,KAC7BqE,EAAQkkC,EAAYvoC,IAIxB,OAAOqE,EAGT,SAAAqgC,GAAgChqB,EAA4B8tB,EAAyB5e,EAA0BI,GAC7G,IAAM1Z,EAASm4B,GAAa/tB,EAAU8tB,EAAiBxe,GACvD,GAAItP,EAASzE,IAGX,OACE2V,OAAQ8c,GAHSrf,GAAQ3O,GAAWkP,KAAIA,IACzBP,GAAQ3O,GAAWkP,KAAIA,EAAED,UAAW,QAEDrZ,EAAQ0Z,IAEvD,GAAsB,iBAAlBtP,EAASpD,KAClB,OACEsU,OAAQ,GAAG+c,GAAWtf,GAAQ3O,GAAWkP,KAAIA,EAAED,UAAW,UAAWrZ,IAElE,GAAIib,GAAe7Q,GAAW,CACnC,IAAMiM,EAAayC,GAAgB1O,IAAaA,EAAgB,OAAKA,EAAgB,MAAEpD,OAASoY,GAAUpI,IAC1G,OACEsE,OAAQgd,GAAqBvf,GAAQ3O,GAAWkP,KAAIA,IAAIlP,EAASiF,SAAU6oB,EAAiBxe,EAAO5lB,KAAKsiB,gBAAiBsD,EAAO6L,WAAYlP,GAAY,IAG1J,OACEiF,OAAQ,MAAMvC,GAAQ3O,GAAWkP,KAAIA,KAK3C,SAAAif,GAA8CC,EAAmBvD,GAC/D,YAAuBn+B,IAAnB0hC,EACKA,EAEFvD,EAQT,SAAAkD,GAA6B/tB,EAA4B8tB,EAAyBxe,GAChF,GAAItP,EAASpD,OAASuQ,GAIpB,OAAI2gB,GAKGxe,EAAOye,aAKlB,SAAAE,GAAoBlnC,EAAe6O,GACjC,MAAO,UAAU7O,EAAK,OAAM6O,GAAU,IAAE,KAG1C,SAAAy4B,GAAiCtnC,EAAe+mC,EAAyBxe,GACvE,OAAO2e,GAAWlnC,EAAO+mC,GAAmBxe,EAAOye,cAIrD,SAAAC,GAAoCM,EAAoBC,EAAkB34B,EAAgB0Z,GACxF,OAAUgf,EAAU,sBAAsBA,EAAU,gBAAgBD,GAAiBC,EAAY14B,EAAQ0Z,GAAO,cAAc+e,GAAiBE,EAAU34B,EAAQ0Z,GAOnK,SAAA4e,GAAqCnnC,EAAeke,EAAoBrP,EAAgBoW,EAA0BwiB,EAA0BviB,EAAqBwiB,GAC/J,YAD+J,IAAAA,IAAAA,GAAA,IAC1JxpB,GAAYrP,GAEfA,EAASA,GAAU44B,IAELC,GACFxiB,EAAa,MAAQ,QAAM,UAAUllB,EAAK,MAAM6O,EAAM,UAEhE,EAGKmW,GAAiB9G,EAAUle,EAAOilB,EAAiBC,GAO9D,SAAAyiB,GAA2BC,EAA2DC,GACpF,OAAQ1oC,EAAQyoC,GAAYA,GAAYA,IAAWrjB,OAAO,SAACvlB,EAAG8oC,GAG5D,OAFA9oC,EAAEgB,MAAMf,KAAK2oB,GAAQkgB,EAAiBD,IACtC7oC,EAAEmT,MAAMlT,KAAK6oC,EAAgB3gC,MAAQ,aAC9BnI,IACLgB,SAAUmS,WAKhB,SAAA41B,GAAoCC,EAA4BC,GAC9D,IAAMjO,EAAagO,EAAErnC,QAWrB,OATAsnC,EAAGrd,QAAQ,SAACsd,GACV,IAAwB,IAAAlgC,EAAA,EAAAmgC,EAAAnO,EAAAhyB,EAAAmgC,EAAAppC,OAAAiJ,IAAQ,CAA3B,IAAMogC,EAASD,EAAAngC,GAElB,GAAInI,EAAUuoC,KAAevoC,EAAUqoC,GACrC,OAGJlO,EAAO/6B,KAAKipC,KAEPlO,EAGT,SAAAqO,GAA2BC,EAAgBC,GACzC,OAAOD,IAAWC,EAChBD,EACAA,EAAS,KAAOC,EAGpB,SAAAC,GACEttB,EAAkCC,GAElC,GAAIhc,EAAQ+b,EAAGtY,QAAUzD,EAAQgc,EAAGvY,OAClC,OACE4gC,SAAUtoB,EAAGsoB,SACb5gC,MAAOmlC,GAAoB7sB,EAAGtY,MAAOuY,EAAGvY,QAErC,IAAKzD,EAAQ+b,EAAGtY,SAAWzD,EAAQgc,EAAGvY,OAC3C,OACE4gC,SAAUtoB,EAAGsoB,SACb5gC,MAAOylC,GAAWntB,EAAGtY,MAAOuY,EAAGvY,QAInC,MAAM,IAAIvE,MAAM,8BAMlB,SAAAwkC,GAAiC5pB,EAA4BzG,GAC3D,OAAKyG,EAASzE,IAOPhB,GAAehB,IAAYhK,GAAU,UAAW,WAAYyQ,EAASpD,OAN1EhV,QAAQ6V,KAAK,gDACN,GAQX,SAAA+xB,GAAiCp5B,EAA8Bo0B,GAC7D,OAAOx8B,GAAKoI,GAAUkV,OAAO,SAAC5U,EAAQ6C,GACpC,IAAMk2B,EAAWr5B,EAASmD,GAC1B,OAAAvQ,KACK0N,EACAm1B,GAAcrB,EAAOiF,EAAUl2B,EAAS,SAAC9S,GAAgB,OAAEkD,MAAOlD,EAAEkD,eC3N7E,IAAA+lC,GAAA,WAKE,SAAAA,EAAY/hC,EAAsCgiC,GAAA/mC,KAAA+mC,UAAAA,EAJ1C/mC,KAAAgnC,aAEAhnC,KAAAinC,QAAwB,KAG1BliC,IACF/E,KAAK+E,OAASA,GAyFpB,OAlFS+hC,EAAA5mC,UAAAgnC,MAAP,WACE,MAAM,IAAI1qC,MAAM,sBAMXsqC,EAAA5mC,UAAAinC,eAAP,WACE,UAGKL,EAAA5mC,UAAAknC,gBAAP,WACE,UAGF1pC,OAAA2pC,eAAIP,EAAA5mC,UAAA,cAAJ,WACE,OAAOF,KAAKinC,aAMd,SAAWliC,GACT/E,KAAKinC,QAAUliC,EACfA,EAAOuiC,SAAStnC,uCAGlBtC,OAAA2pC,eAAIP,EAAA5mC,UAAA,gBAAJ,WACE,OAAOF,KAAKgnC,2CAGPF,EAAA5mC,UAAAqnC,YAAP,WACE,OAAOvnC,KAAKgnC,UAAU9pC,QAGjB4pC,EAAA5mC,UAAAonC,SAAP,SAAgB7N,GACdz5B,KAAKgnC,UAAU5pC,KAAKq8B,IAGfqN,EAAA5mC,UAAAsnC,YAAP,SAAmBC,GACjBznC,KAAKgnC,UAAUxhC,OAAOxF,KAAKgnC,UAAUtmC,QAAQ+mC,GAAW,IAMnDX,EAAA5mC,UAAAwnC,OAAP,WACE,IAAoB,IAAAvhC,EAAA,EAAAoB,EAAAvH,KAAKgnC,UAAL7gC,EAAAoB,EAAArK,OAAAiJ,IAAgB,CAApBoB,EAAApB,GACRpB,OAAS/E,KAAKinC,QAEtBjnC,KAAKinC,QAAQO,YAAYxnC,OAMpB8mC,EAAA5mC,UAAAynC,iBAAP,SAAwBz/B,GACtB,IAAMnD,EAASmD,EAAMnD,OACrBA,EAAOyiC,YAAYxnC,MACnBA,KAAK+E,OAASA,EACdmD,EAAMnD,OAAS/E,MAGV8mC,EAAA5mC,UAAA0nC,eAAP,WAKE,IAJA,IAAM7iC,EAAS/E,KAAKinC,QACdY,EAAY9iC,EAAOA,OAGLoB,EAAA,EAAAoB,EAAAvH,KAAKgnC,UAAL7gC,EAAAoB,EAAArK,OAAAiJ,IAAgB,CAApBoB,EAAApB,GACRpB,OAASA,EAIjB/E,KAAKgnC,aACLjiC,EAAOyiC,YAAYxnC,MACnB+E,EAAOA,OAAOyiC,YAAYziC,GAI1B/E,KAAK+E,OAAS8iC,EACd9iC,EAAOA,OAAS/E,MAEpB8mC,EAhGA,GAkGAgB,GAAA,SAAAC,GAqBE,SAAAD,EAAY/iC,EAAsBxB,EAAgCyQ,EAAuCg0B,GAAzG,IAAAC,EACEF,EAAAhpC,KAAAiB,KAAM+E,EAAQxB,IAAOvD,YAD2CioC,EAAAj0B,KAAAA,EAAuCi0B,EAAAD,UAAAA,EAGvGC,EAAKC,QAAUD,EAAKE,MAAQ5kC,GAExB0kC,EAAKD,WAAeC,EAAKE,SAASF,EAAKD,YACzCC,EAAKD,UAAUC,EAAKE,OAAS,KAyBnC,OApDgCC,EAAAA,EAAAA,GAKvBN,EAAA5nC,UAAAgnC,MAAP,WACE,IAAMmB,EAAW,IAAUroC,KAAKC,YAOhC,OANAooC,EAAStB,UAAY,SAAW/mC,KAAK+mC,UACrCsB,EAASH,QAAUloC,KAAKkoC,QACxBG,EAASF,MAAQ,SAAWnoC,KAAKmoC,MACjCE,EAASr0B,KAAOhU,KAAKgU,KACrBq0B,EAASL,UAAYhoC,KAAKgoC,UAC1BK,EAASL,UAAUK,EAASF,OAAS,EAC9BE,GA2BFP,EAAA5nC,UAAAooC,UAAP,WAEE,OADAtoC,KAAKgoC,UAAUhoC,KAAKmoC,SACbnoC,KAAKkoC,SAGPJ,EAAA5nC,UAAAqoC,WAAP,WACE,QAASvoC,KAAKgoC,UAAUhoC,KAAKmoC,QAGxBL,EAAA5nC,UAAAsoC,UAAP,SAAiBjlC,GACfvD,KAAKkoC,QAAU3kC,GAEnBukC,EApDA,CAAgChB,IC5FhC2B,GAAA,SAAAV,GAKE,SAAAU,EAAY1jC,EAA8BkR,GAA1C,IAAAgyB,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YAD2BioC,EAAAhyB,UAAAA,IAwC5C,OA7CmCmyB,EAAAA,EAAAA,GAC1BK,EAAAvoC,UAAAgnC,MAAP,WACE,OAAO,IAAIuB,EAAc,KAAMlgC,GAAUvI,KAAKiW,aAOlCwyB,EAAAC,qBAAd,SAAmC3jC,EAAsB68B,GAoBvD,OAlBAA,EAAM+G,gBAAgB,SAACvxB,EAA4BzG,GACjD,GAAKmV,GAAgB1O,IAGjBgpB,GAAYhpB,EAAS9R,MAAO,CACvB,IAAAsjC,EAAAxxB,EAAAjZ,MAAO0qC,EAAAzxB,EAAAiF,SACR/W,EAAiD8R,EAAS9R,KAE1D0lB,EAAY1lB,EAAKxH,IAAI,SAACgrC,EAAWnsC,GACrC,OAAUosC,IAAuB5qC,MAAKyqC,EAAEvsB,SAAQwsB,EAAEG,MAAOF,IAAW,MAAMnsC,EAAC,QAC1E2B,KAAK,IAAMgH,EAAKpI,OAEnB6H,EAAS,IAAI0jC,EAAc1jC,GACzBimB,UAASA,EACTF,GAAIme,GAAoB7xB,EAAUzG,QAIjC5L,GAGF0jC,EAAAvoC,UAAAinC,eAAP,WACE,IAAMliC,KAEN,OADAA,EAAIjF,KAAKiW,UAAU6U,KAAM,EAClB7lB,GAGFwjC,EAAAvoC,UAAAgpC,SAAP,WACE,OACEl1B,KAAM,UACNsS,KAAMtmB,KAAKiW,UAAU+U,UACrBF,GAAI9qB,KAAKiW,UAAU6U,KAGzB2d,EA7CA,CAAmC3B,gBA+CC1vB,EAA4BzG,EAA2B2V,GACzF,OAAOP,GAAQ3O,GAAW1N,OAAQiH,EAASqV,OAAQ,aAAcM,KAAIA,IC7ChE,IAAM6iB,IAAoC,MAAO,UAG3CC,IAA8B,SAAU,UA+CrD,SAAAC,GAA8BzH,EAAcjxB,GAC1C,IAAMhE,EAAQi1B,EAAM0H,UAAUC,cAAc54B,GAAShE,MAC/C68B,EAAyB,QAAZ74B,EAAoB,YAAS7M,EAC1C4iB,EAASkb,EAAMlb,OAAQkb,EAAMlb,YAAS5iB,EACtC2lC,EAAgB7H,EAAM0H,UAAUC,cAAc54B,GAAS84B,cAAe7H,EAAM0H,UAAUC,cAAc54B,GAAS84B,mBAAgB3lC,EAEnI,OACE1H,KAASuU,EAAO,SAChBqD,KAAM,QACN01B,KAAS/4B,EAAO,SAChBhE,MAAKvM,GACHU,KAAM6L,EACNF,OAAQ,GACRM,OAAQy8B,EACR1d,MAAO,eACJ6d,GAAoBjjB,EAAQ+iB,EAAevJ,GAAyBd,MAK7E,SAAAwK,GAAgChI,EAAcjxB,GAG5C,IAFA,IAAMk5B,EAAejI,EAAM0H,UAAUC,cAAc54B,GAC7Cm5B,KACmB3jC,EAAA,EAAA4jC,EAAAX,GAAAjjC,EAAA4jC,EAAA7sC,OAAAiJ,IAAc,CAAlC,IAAM6jC,EAAUD,EAAA5jC,GACnB,GAAI0jC,EAAaG,GACf,IAAyB,IAAAziC,EAAA,EAAA+c,EAAAulB,EAAaG,GAAbziC,EAAA+c,EAAApnB,OAAAqK,IAA0B,CAA9C,IAAM0iC,EAAU3lB,EAAA/c,GACnBuiC,EAAO1sC,KAAK8sC,GAAetI,EAAOjxB,EAASq5B,EAAYH,EAAcI,KAI3E,OAAOH,EA+CT,SAAAI,GAA+BtI,EAAcjxB,EAAwBq5B,EAAwBH,EAAqCI,SA1CvGhM,EA2CzB,GAAIgM,EAAY,CACd,IAAIt9B,EAAQ,KACL88B,EAAAI,EAAAJ,cACP,GAAIA,GAAiBQ,EAAW79B,OAAQ,CAC/B,IAAAkY,EAAAmlB,EAAA9K,OAAAA,OAAA,IAAAra,KAAAA,EACAtX,EAAA2xB,EAAA3xB,OAAQS,EAAAkxB,EAAAlxB,WACTiZ,EAASkb,EAAMlb,OAAQkb,EAAMlb,YAAS5iB,EAEtCqmC,EAAM/pC,MAhDH,IADb69B,IAFyBA,EAoDLxwB,GAlDF,IAAO,KAAO,MACb,KAAQ,KAEhBwwB,EAAQ,IAAM,IAAMA,GACrBT,OAAQz8B,MAAO,UACd,KAAOk9B,GAASA,EAAQ,KACzBT,OAAQz8B,MAAO,aA+CrB4L,EAAKvM,GACHU,KAAMsgC,GAAgBqI,EAAez8B,EAAQ,SAAU40B,EAAMlb,QAC7Dja,OAAQ,GACRM,OAAoB,QAAZ4D,EAAoB,OAAS,MACrCmb,MAAO,eACJ6d,GAAoBjjB,EAAQ+iB,EAAetJ,GAAyBN,IACnEz6B,GAAK+kC,GAAQjtC,OAAS,GAAK4Q,QAASq8B,OAAMA,QAIlD,IAAMC,EAAOH,EAAWG,KAElBC,EAAUD,GAAQA,EAAKltC,OAAS,EACtC,GAAIyP,GAAS09B,EAAS,CACpB,IAAM1G,EAA0B,QAAZhzB,EAAoB,SAAW,QAInD,OAAAvQ,GACEhE,KAAMwlC,EAAM6C,QAAW9zB,EAAO,IAAIq5B,GAClCh2B,KAAM,QACN01B,KAAS/4B,EAAO,IAAIq5B,GAChBH,EAAaJ,eACfa,MAAOxQ,KAAM8H,EAAM6C,QAAQ9zB,EAAU,YACrCrL,KAzDV,SAAiBmkC,EAAsC94B,GAC9C,IAAArL,EAAAmkC,EAAAnkC,KACP,OAAIilC,GAAYjlC,IAEZnH,MAAO4nB,GAAQzgB,GAAOghB,KAAM,UAC5BhW,MAAOhL,EAAKgL,OAAS,aAEdhT,EAAQgI,IAEfnH,MAAO8qC,GAAoBQ,EAAe94B,EAAS,SACnDL,MAAO,cAIPnS,MAAO4nB,GAAQ0jB,GAAgBnjB,KAAM,UACrChW,MAAOhL,GAAQ,aA0CLklC,CAAQf,EAAe94B,OAE3BhE,GAASA,MAAK89B,MACdR,EAAWS,YACb58B,QACEq8B,QAAM5iC,KACJA,EAACo8B,GAAcsG,EAAWS,mBAI5BL,GAAWD,KAAIA,QAIzB,OAAO,KAGT,SAAAT,GAAoCjjB,EAAgB+iB,EAAsCkB,EAAsBC,GAE9G,IADA,IAAM3kC,KACaE,EAAA,EAAA0kC,EAAAF,EAAAxkC,EAAA0kC,EAAA3tC,OAAAiJ,IAAY,CAA1B,IAAME,EAAIwkC,EAAA1kC,GACTugB,GAAUA,EAAOiY,QACfjY,EAAOiY,OAAOt4B,KAChBJ,EAAM2kC,EAAcvkC,IAASqgB,EAAOiY,OAAOt4B,IAG3CojC,GAAiBA,EAAc9K,QAC7B8K,EAAc9K,OAAOt4B,KACvBJ,EAAM2kC,EAAcvkC,IAASojC,EAAc9K,OAAOt4B,IAIxD,OAAOJ,cC9M6B27B,GACpC,SAAU/iC,OACRisC,GAAYlJ,EAAO,SACnBkJ,GAAYlJ,EAAO,WAIvB,SAAAkJ,GAA4BlJ,EAAcmJ,GACxC,IAAMp6B,EAAuB,UAAbo6B,EAAuB,IAAM,IACvC36B,EAAOwxB,EAAM0H,UAAU0B,WAAW/J,IAAI8J,GAC5C,IAAK36B,GAAiB,WAATA,EACX,SAIF,IAAMhU,EAAOwlC,EAAMqJ,iBAAiBF,GAAUziB,OAE9C,GAAa,eAATlY,EAAuB,CACzB,IAAM2yB,EAAiBnB,EAAMoB,kBAAkBryB,GAE/C,GAAIoyB,EAAgB,CAClB,IAAM/uB,EAAO+uB,EAAe9B,IAAI,QAC1B3Q,EAAQyS,EAAe9B,IAAI,SAEjC,GAAIjS,GAAkBhb,IAAS6oB,GAAcvM,GAAQ,CACnD,IAAMkQ,EAAYoB,EAAMpB,UAAU7vB,GAElC,GAAIu6B,GAAatJ,EAAM78B,QAKrB,GAAqC,gBADf68B,EAAM78B,OAAOukC,UAAU/V,QAC3B3mB,MAAM+D,GACtB,OAAQw6B,GAAW3K,EAAWlQ,IAIlC,OACE6a,GAAW3K,EAAWlQ,IAEpBl0B,KAAIA,EACJ+tC,OAAQiB,GAAS5K,EAAWuC,EAAgB,WAAWvC,EAAS,gBAMxE,MAAM,IAAIhkC,MAAM,6DAEhB,QACEJ,KAAIA,EACJ2E,MAAOqP,IAKb,SAAA+6B,GAAoB3K,EAAmBlQ,GACrC,OACEl0B,KAAMokC,EAAY,QAClBz/B,MAAOuvB,EAAMxI,MAIjB,SAAAsjB,GAAyB5K,EAAmBuC,EAAgCsI,GAC1E,IAAMr3B,EAAO+uB,EAAe9B,IAAI,QAC1BxU,EAAUsW,EAAe9B,IAAI,WAC/BjQ,EAAe+R,EAAe9B,IAAI,gBACtCjQ,OAAgCltB,IAAjBktB,EAA6BA,EAAevE,EAE3D,IAAIsE,EAAegS,EAAe9B,IAAI,gBAOtC,MAAO,aAAaoK,EAAW,MAN/Bta,EAAwB,SAAT/c,OAEKlQ,IAAjBitB,EAA6BA,EAAetE,EAG7C,GAC8C,KAAKuE,EAAY,OAAOwP,EAAS,QClEnF,SAAA8K,GAAkC/X,EAAkB5iB,GAClD,IAAM46B,EAAsBhY,EAAQ3mB,MAAM+D,GACpC66B,EAAQ7kC,EAAS2K,GAAyBX,GAAW,OAAS,SAEpE,MAA4B,gBAAxB46B,GAC8B,WAA5BhY,EAAQiY,GAAO76B,IACjB4K,GAASC,GAAYjC,sCAAsC5I,IAEtD,eAGF4iB,EAAQiY,GAAO76B,IAAY,SCjBpC,IAAA86B,GAAA,WACE,SAAAA,EACkB9J,EACA+J,QADA,IAAA/J,IAAAA,WACA,IAAA+J,IAAAA,MADA1rC,KAAA2hC,SAAAA,EACA3hC,KAAA0rC,SAAAA,EAoEpB,OAjESD,EAAAvrC,UAAAgnC,MAAP,WACE,OAAO,IAAIuE,EAAMljC,GAAUvI,KAAK2hC,UAAWp5B,GAAUvI,KAAK0rC,YAGrDD,EAAAvrC,UAAA0+B,QAAP,WAGE,OAAAx+B,KACKJ,KAAK2hC,SACL3hC,KAAK0rC,WAILD,EAAAvrC,UAAA+gC,IAAP,SAA8B/+B,GAE5B,YAA8B4B,IAAvB9D,KAAK2hC,SAASz/B,GAAqBlC,KAAK2hC,SAASz/B,GAAOlC,KAAK0rC,SAASxpC,IAGxEupC,EAAAvrC,UAAAyrC,gBAAP,SAA0CzpC,GAExC,YAA2B4B,IAAvB9D,KAAK2hC,SAASz/B,IACRy/B,UAAU,EAAM5gC,MAAOf,KAAK2hC,SAASz/B,SACb4B,IAAvB9D,KAAK0rC,SAASxpC,IACfy/B,UAAU,EAAO5gC,MAAOf,KAAK0rC,SAASxpC,KAExCy/B,UAAU,EAAO5gC,WAAO+C,IAG3B2nC,EAAAvrC,UAAA0rC,gBAAP,SAA0C1pC,EAAQnB,QAC5B+C,IAAhB/C,EAAMA,OACRf,KAAK6rC,IAAI3pC,EAAKnB,EAAMA,MAAOA,EAAM4gC,WAI9B8J,EAAAvrC,UAAA2rC,IAAP,SAA8B3pC,EAAQnB,EAAa4gC,GAGjD,cAFO3hC,KAAK2hC,EAAW,WAAa,YAAYz/B,GAChDlC,KAAK2hC,EAAW,WAAa,YAAYz/B,GAAOnB,EACzCf,MAGFyrC,EAAAvrC,UAAA4rC,iBAAP,SAAqC5pC,EAAc/E,QAEzB2G,IAApB3G,EAAEwkC,SAASz/B,GACblC,KAAK6rC,IAAI3pC,EAAK/E,EAAEwkC,SAASz/B,IAAM,QACF4B,IAApB3G,EAAEuuC,SAASxpC,IACpBlC,KAAK6rC,IAAI3pC,EAAK/E,EAAEuuC,SAASxpC,IAAM,IAG5BupC,EAAAvrC,UAAA6rC,kBAAP,SAA+C7pC,EAAc/E,QAE5C2G,IAAX3G,EAAE+E,IACJlC,KAAK6rC,IAAI3pC,EAAK/E,EAAE+E,IAAM,IAQnBupC,EAAAvrC,UAAA8rC,QAAP,SAAe9jC,GACb,IAAkB,IAAA/B,EAAA,EAAAoB,EAAAnC,GAAK8C,EAAM02B,WAAXz4B,EAAAoB,EAAArK,OAAAiJ,IAAuB,CAApC,IAAMjE,EAAGqF,EAAApB,GACN4B,EAAMG,EAAMyjC,gBAAgBzpC,GAClClC,KAAK4rC,gBAAgB1pC,EAAK6F,KAGhC0jC,EAvEA,eA+EgC1qC,GAC9B,OACE4gC,UAAU,EACV5gC,MAAKA,GAIT,SAAAkrC,GAAgClrC,GAC9B,OACE4gC,UAAU,EACV5gC,MAAKA,GAIT,SAAAmrC,GAA0CC,GACxC,OAAO,SAAC9yB,EAAiBC,EAAiBH,EAA2BC,GACnE,IAAMgzB,EAAOD,EAAQ9yB,EAAGtY,MAAOuY,EAAGvY,OAClC,OAAIqrC,EAAO,EACF/yB,EACE+yB,EAAO,EACT9yB,EAEF+yB,GAAwBhzB,EAAIC,EAAIH,EAAUC,IAIrD,SAAAizB,GAAwChzB,EAAiBC,EAAiBH,EAAmBC,GAK3F,OAJIC,EAAGsoB,UAAYroB,EAAGqoB,UACpBpmB,GAASC,GAAYtC,yBAAyBC,EAAUC,EAAYC,EAAGtY,MAAOuY,EAAGvY,QAG5EsY,EAGT,SAAAizB,GACIjzB,EAAiBC,EACjBH,EACAC,EACAmzB,GAEF,YAFE,IAAAA,IAAAA,EAAAF,SAESvoC,IAAPuV,QAAiCvV,IAAbuV,EAAGtY,MAElBuY,EAGLD,EAAGsoB,WAAaroB,EAAGqoB,SACdtoB,EACEC,EAAGqoB,WAAatoB,EAAGsoB,SACrBroB,EACEtb,EAAUqb,EAAGtY,SAAW/C,EAAUsb,EAAGvY,OACvCsY,EAEAkzB,EAAWlzB,EAAIC,EAAIH,EAAUC,GCvIxC,IAAAozB,GAAA,SAAAzE,GAAA,SAAAyE,mDAAsD,OAAjBpE,EAAAA,EAAAA,GAAiBoE,EAAtD,CAAqCf,IC0IrC,SAAAgB,GAAqBlnB,GACnB,OAAOmnB,GAAkBnnB,EACvB,SAAC1hB,EAAW8oC,GAAmB,OAAAvoB,KAAK7Z,IAAI1G,EAAG8oC,EAAe5rC,SAI9D,SAAA6rC,GAAgCrnB,GAC9B,OAAOmnB,GAAkBnnB,EACvB,SAAC1hB,EAAW8oC,GAAmB,YAAM7oC,IAAND,EAAkBA,EAAI8oC,EAAe5rC,QAIxE,SAAA2rC,GACEnnB,EACAsnB,GAGA,OAAIlnB,GAAuBJ,IACjBjoB,EAAQioB,EAAWC,WAAaD,EAAWC,WAAaD,EAAWC,YACxE9C,OAAOmqB,EAAStnB,EAAWxkB,OACrB6kB,GAAWL,GACbA,EAAWxkB,WADb,yCA9IeqW,EAA4B01B,EAAkBlL,EAAkBjxB,EAAkBqD,GACxG,GAAa,aAATA,EAAJ,CAIA,IAAI/O,EAAG7E,cREuBK,EAAkBmhC,EAAkBmL,GAClE,IAAuB,IAAA5mC,EAAA,EAAA6mC,EAAAD,EAAA5mC,EAAA6mC,EAAA9vC,OAAAiJ,IAAW,CAA7B,IAAMgT,EAAQ6zB,EAAA7mC,GACXpF,EAAQghC,GAAc5oB,EAAUyoB,EAAMnJ,QAASmJ,EAAMlb,aAC7C5iB,IAAV/C,IACFN,EAAE0Y,IAAapY,MAAOA,IAG1B,OAAON,EQRFwsC,IAAoBrL,EAAOztB,IAC3B+4B,GAAatL,IAGlB,OAAQA,EAAM/vB,MACZ,KAAKmB,GACL,KAAKK,GACL,KAAKrE,GACH/J,EAAIoL,OAAStP,MAAO,UACpB,MACF,KAAKwS,GACL,KAAKC,GACHvO,EAAIoL,OAAStP,MAAO6gC,EAAM/vB,MAUvB,IAAA4mB,EAAAmJ,EAAAnJ,QAASjrB,EAAAo0B,EAAAp0B,SACV2rB,EAASV,EAAQU,OAEvB,GAAIl0B,EAAIgL,KAEN,GAAgB,SAAZU,GAAuBwoB,GAAUxoB,IAAYjC,UACxCzJ,EAAIgL,UAEX,GAAIhL,EAAIgL,KAAY,aAEXhL,EAAIgL,UACN,GAAI3S,EAAQ2H,EAAIgL,MAAO,CAC5B,IAAMA,EAAO28B,GAAuBp/B,EAASyC,MAAQzC,EAASwC,QAAUyoB,EAAQxoB,MAASkpB,GAAUV,EAAQzoB,MACvGC,IACFhL,EAAIgL,MAAQlP,MAAOkP,IAM3B,GAAIhL,EAAIiL,OACN,GAAgB,WAAZS,IAA0BwoB,GAAUxoB,IAAYjC,UAC3CzJ,EAAIiL,YAEX,GAAIjL,EAAIiL,OAAc,aAEbjL,EAAIiL,YACN,GAAI5S,EAAQ2H,EAAIiL,QAAS,CAC9B,IAAMA,EAAS08B,GAAuBp/B,EAAS0C,QAAU1C,EAASwC,QAAUyoB,EAAQvoB,SAAYipB,GAAUV,EAAQzoB,MAC9GE,IACFjL,EAAIiL,QAAUnP,MAAOmP,IAW7B,GALIjL,EAAIgL,MAA8B,gBAAtBhL,EAAIgL,KAAY,QAAwBhL,EAAIiL,SAE1DjL,EAAIiL,QAAUnP,MAAO,gBAGnB4P,IAAY9B,GAAO,CACrB,IAAMwB,EAAQu8B,GAAuBp/B,EAAS6C,QAAUooB,EAAQpoB,MAC5DA,IACFpL,EAAIoL,OAAStP,MAAOsP,IAIxB,GAAIM,IAAY5B,GAAS,CACvB,IAAMoB,EAAUs8B,GAAYj/B,EAAS2C,UAAYsoB,EAAQtoB,QACrDA,IACFlL,EAAIkL,SAAWpP,MAAOoP,IAM1B,OAFAlL,EAAG7E,KAAO6E,EAAQ6nC,GAEX1nC,GAAKH,GAAK/H,OAAS,EAAI+H,OAAMnB,aAGtC,SAAyBsT,EAA4B+1B,EAAmBvL,EAAkBjxB,EAAkBqD,GAC1G,IAAI/O,KAEJ,GAAa,aAAT+O,EAAqB,CACvB,IAAM7D,EAAUs8B,GAAY7K,EAAMp0B,SAAS2C,UAAYyxB,EAAMnJ,QAAQtoB,QACjEA,IACFlL,EAAIkL,SAAWpP,MAAOoP,IAK1B,OADAlL,EAAG7E,KAAO6E,EAAQkoC,GACX/nC,GAAKH,GAAK/H,OAAS,EAAI+H,OAAMnB,UAGtC,SAAuBsT,EAA4Bg2B,EAAiBxL,EAAkBjxB,EAAkCqD,GACtH,IAAMof,EAASwO,EAAMxO,OAAOziB,GACtB+V,EAASkb,EAAMlb,OAEjBzhB,KAEJ,GAAIgjB,GAAe7Q,GAAW,CAC5B,IAAMiM,EAAaue,EAAMoB,kBAAkBryB,GAASswB,IAAI,UAAY7U,GAAUpI,IACxEsC,EAAOgf,GAAqB,cAAeluB,EAASiF,SAAU+W,EAAOpmB,OAAQ0Z,EAAO0M,OAAOhQ,gBAAiBsD,EAAO6L,WAAYlP,GACrI+pB,EAAUhtC,KACJkmB,GAAQxlB,MAAOwnB,OAAQhC,OACxB8mB,GAMP,OAFAnoC,EAAG7E,KAAO6E,EAAQmoC,GAEXhoC,GAAKH,GAAK/H,OAAS,EAAI+H,OAAMnB,iBC7HV89B,GACtByL,GAAYzL,GACdA,EAAM0H,UAAUgE,QAMpB,SAAyB1L,GAChB,IAAAp0B,EAAAo0B,EAAAp0B,SACP,OAAQkB,GAAOC,GAAMC,GAAQE,GAAMD,GAAOE,IAAS2T,OAAO,SAAU6qB,EAAiB58B,GACnF,IAAMqY,EAAMxb,EAASmD,GAIrB,OAHIixB,EAAMxO,OAAOziB,KAAYixB,EAAMoB,kBAAkBryB,IAAc+U,GAAWsD,IAASrY,IAAY9B,IAASma,EAAIhV,OAAS2Q,KACvH4oB,EAAgB58B,GAqBtB,SAAsCixB,EAAkBjxB,GACtD,IAAMyG,EAAWwqB,EAAMxqB,SAASzG,GAC1ByiB,EAASwO,EAAMxO,OAAOziB,GAEtB68B,EAAa,IAAIhB,MAnBzB,SAA+B5K,EAAkBjxB,SAE/C,OAAQA,GACN,KAAKjC,GACH,IAAM9B,EAAQg1B,EAAMpB,UAAU9xB,IAC9B,OAAOkzB,EAAMnJ,QAAQU,QAAUlpB,KAAMrD,IAAUsD,OAAQtD,GACzD,KAAK+B,GACL,KAAKC,GACL,KAAKE,GACL,KAAKD,GACL,KAAKE,GACH,OAAAxH,MAASoJ,GAAUixB,EAAMpB,UAAU7vB,GAAQpJ,GAQJkmC,CAAsB7L,EAAOjxB,IAExEgc,GAAkB5D,QAAQ,SAAS5P,GACjC,IAAMpY,EAoCV,SAAqBoY,EAAqCu0B,EAAyB/8B,EAAkCixB,GACnH,IAAMxqB,EAAWwqB,EAAMxqB,SAASzG,GAEhC,OAAQwI,GACN,IAAK,SAEH,OAAOgsB,GAAa/tB,EAAUs2B,EAAgB1gC,OAAQ40B,EAAMlb,QAC9D,IAAK,QAGH,IAAMinB,OAAoC7pC,IAAnBsT,EAASzK,MAAsByK,EAASzK,MAC7D+gC,EAAgB/gC,aAAoC7I,IAA1B4pC,EAAgB/gC,WAAsB7I,EAAY,MAE9E,OAAOyhC,GACLoI,EACAzO,GAAc9nB,EAAUwqB,EAAMlb,eAC3B5iB,EACP,IAAK,SACH,gBCxGiBsvB,EAAgBhc,GACrC,IAAMhP,EAAOgrB,EAAOzrB,OAEpB,GAAIS,EACF,OAAOigB,GAAWjR,EAAUhP,GDoGnBwlC,CAAkBF,EAAiBt2B,GAC5C,IAAK,OACH,OAAOmuB,GAA2BmI,EAAgB15B,KCjGxD,SAAqB1T,EAASqQ,EAAkBiG,GAC9C,GACIlG,GAAeC,KACN,iBAANrQ,IAAyB2uB,GAAWrY,IAC9B,aAANtW,GAAoBqG,GAAqB,OAAQ,OAAQiQ,IAG9D,MAAO,WD0FmDi3B,CAAgBz2B,EAASpD,KAAMrD,EAASixB,EAAMoB,kBAAkBryB,GAASswB,IAAI,UAIzI,OAAOyM,EAAgBv0B,GA5DP20B,CAAY30B,EAAUia,EAAQziB,EAASixB,GACrD,QAAc99B,IAAV/C,EAAqB,CACvB,IAAM4gC,EAES,WAAbxoB,IAA0Bia,EAAOzrB,OAEpB,UAAbwR,GAAwBpY,IAAU6gC,EAAMxqB,SAASzG,GAAShE,OAE1D5L,IAAUqyB,EAAOja,IACfwoB,QAA8C79B,IAAlC89B,EAAMlb,OAAO0M,OAAOja,KAClCq0B,EAAW3B,IAAI1yB,EAAUpY,EAAO4gC,MAMtC,IAAMoM,EAAiB3a,EAAO5lB,aACxBwgC,GAAgB,SAAU,SAAU,QAAS,UAAW,YAAYtrB,OAAO,SAACjiB,EAAmBmiB,GACnG,IAAMqrB,EAAqBrH,GAAiBmH,EAAenrB,OAAagf,GAClE7gC,EAAQ+M,GAAO8U,GAEnB9U,GAAO8U,GAAMxL,EAAU62B,EAAoBrM,EAAOjxB,EAAS68B,EAAWvM,IAAI,SAC1EgN,EAIF,YAHcnqC,IAAV/C,GAAuBqE,GAAKrE,GAAO7D,OAAS,IAC9CuD,EAAEmiB,IAASunB,OAAQppC,IAEdN,OAGL2E,GAAK4oC,GAAc9wC,OAAS,GAC9BswC,EAAW3B,IAAI,SAAUmC,IAAgB5a,EAAO5lB,UAGlD,OAAOggC,EA7DwBU,CAAsBtM,EAAOjxB,IAEnD48B,OAbmBY,CAAgBvM,GAE1CA,EAAM0H,UAAUgE,QAoGpB,SAA4B1L,GAG1B,IAFM,IAAAr6B,EAAAq6B,EAAA0H,UAACgE,EAAA/lC,EAAA+lC,QAAS/Z,EAAAhsB,EAAAgsB,mBAELkG,GACT2U,GAAY3U,GAEZr0B,GAAKq0B,EAAM6P,UAAUgE,SAASvkB,QAAQ,SAACpY,GACrC4iB,EAAQH,OAAOziB,GAAW26B,GAAkB1J,EAAM0H,UAAU/V,QAAS5iB,GAErC,WAA5B4iB,EAAQH,OAAOziB,KAIjB28B,EAAQ38B,GAAW09B,GAAqBf,EAAQ38B,GAAU8oB,EAAM6P,UAAUgE,QAAQ38B,IAE7E28B,EAAQ38B,KAGX4iB,EAAQH,OAAOziB,GAAW,qBACnB28B,EAAQ38B,QAhBHxK,EAAA,EAAAme,EAAAsd,EAAM0M,SAANnoC,EAAAme,EAAApnB,OAAAiJ,IAAc,CAA7B,IAAMszB,EAAKnV,EAAAne,KAALszB,GAmCX,OAbAr0B,GAAKkoC,GAASvkB,QAAQ,SAACpY,GACrB,IAAoB,IAAAxK,EAAA,EAAAoB,EAAAq6B,EAAM0M,SAANnoC,EAAAoB,EAAArK,OAAAiJ,IAAgB,CAA/B,IAAMszB,EAAKlyB,EAAApB,GACTszB,EAAM6P,UAAUgE,QAAQ38B,IAKG,WAA5B4iB,EAAQH,OAAOziB,WAEV8oB,EAAM6P,UAAUgE,QAAQ38B,MAI9B28B,EA1IqBiB,CAAmB3M,GA6IjD,SAAAyM,GAAqCG,EAA+BC,GAClE,IAAKD,EACH,OAAOC,EAAYvH,QAErB,IAAMwH,EAAeF,EAAa7C,gBAAgB,UAC5CgD,EAAcF,EAAY9C,gBAAgB,UAGhD,IAAI+C,EAAa/M,WAAYgN,EAAYhN,UAAY+M,EAAa3tC,QAAU4tC,EAAY5tC,MAAxF,CAOA,IAFA,IAAI6tC,GAAa,aAENvoC,GACT,IAAMwoC,EAA0BvC,GAC9BkC,EAAa7C,gBAAgBtlC,GAC7BooC,EAAY9C,gBAAgBtlC,GAC5BA,EAAM,SAGN,SAACgT,EAAmBC,GAClB,OAAQjT,GACN,IAAK,QACH,OAAOsgC,GAAoBttB,EAAIC,GACjC,IAAK,OAGH,OADAs1B,GAAa,EACN3C,GAAa,UAExB,OAAOI,GAAiChzB,EAAIC,EAAIjT,EAAM,YAG1DmoC,EAAa5C,gBAAgBvlC,EAAMwoC,IAnBlB1oC,EAAA,EAAA2oC,EAAAliB,GAAAzmB,EAAA2oC,EAAA5xC,OAAAiJ,IAAoB,GAAxB2oC,EAAA3oC,IA+Bf,OAVIyoC,MACGJ,EAAa9C,cAAgB59B,YAAcihC,UAC9C/lC,GAAqBwlC,EAAa9C,UAAW,SAAU,eAEnD8C,EAAa7M,cAAgB7zB,YAAcihC,UAC/C/lC,GAAqBwlC,EAAa7M,UAAW,SAAU,cAKpD6M,eEzMuB5M,GAI9B,IAHA,IAAMoN,EAAuBpN,EAAM0H,UAAUgE,QACvC2B,KAEgB9oC,EAAA,EAAAoB,EAAAnC,GAAK4pC,GAAL7oC,EAAAoB,EAAArK,OAAAiJ,IAA4B,CAA7C,IAAMwK,EAAOpJ,EAAApB,GACV48B,EAAiBnB,EAAMoB,kBAAkBryB,GACzCu+B,EAAalxC,EAAU+kC,EAAetB,SAC5C,GAAIwN,EAAeC,GACjB,IAAoC,IAAA5qB,EAAA,EAAAyH,EAAAkjB,EAAeC,GAAf5qB,EAAAyH,EAAA7uB,OAAAonB,IAA4B,CAC/C+pB,GADetiB,EAAAzH,GAC6B0qB,EAAqBr+B,KAG9Es+B,EAAeC,GAAY9xC,KAAK4xC,EAAqBr+B,SAKzDs+B,EAAeC,IAAeF,EAAqBr+B,GAASu2B,SAIhE,OAAOhgC,EAAQkB,GAAK6mC,IAAiBnxC,IAAI,SAAC0vC,GAAgC,OAAAA,EAAW5O,wBCvBnDgD,GAClC,OAAIuN,GAAavN,IAAUwN,GAAcxN,IAAUyN,GAAczN,GAOnE,SAAuDA,GACrD,OAAOA,EAAM0M,SAAS5rB,OAAO,SAAC4sB,EAAa7V,GACzC,OAAO6V,EAAYzwC,OAAO46B,EAAM8V,wBAC/BC,GAA2B5N,IATrB6N,CAAuC7N,GAEvC4N,GAA2B5N,GAUtC,SAAA4N,GAA2C5N,GACzC,IAAM0H,EAAY1H,EAAM0H,UAAU9yB,WAClC,IAAK8yB,GAAaA,EAAUnR,OAC1B,SAGF,IAAM3hB,EAAa8yB,EAAU1K,UACtBxiC,EAAAoa,EAAApa,KAAM46B,EAAAx2B,EAAAgW,GAAA,SAEPpG,GACJkY,OAAQ,IAAIghB,EAAUl5B,KAAKtS,IAAI,SAAC6iC,GAAQ,OAAAA,EAAIrY,SAAQhqB,KAAK,MAAK,KAG1DoxC,EAAgBpG,EAAUxP,KAAKpX,OAAO,SAACitB,EAAS7V,GACpD,IAAMv2B,EAAiBqsC,GAAc9V,GAAQA,EAAKxR,OAAS,SAASsZ,EAAMiO,iBAAiB/V,GAAK,KAKhG,OAJKnzB,EAASgpC,EAASpsC,IAErBosC,EAAQvyC,KAAKmG,GAERosC,OAGT,GAAID,EAAIxyC,QAAU,EAChB,MAAM,IAAIV,MAAM,iDAGlB,OAAO4D,GACLhE,KAAIA,EACJgU,KAAIA,EACJs/B,KACEpnB,OAAQonB,EAAIxyC,OAAS,EAAI,IAAIwyC,EAAIpxC,KAAK,MAAK,IAAMoxC,EAAI,KAEpD1Y,ICSA,IAAM8Y,IACX,OACA,YACA,aACA,SACA,SACA,YACA,cACA,WACA,WACA,QACA,WACA,SACA,QACA,UACA,QCtEFC,GAAA,SAAAhI,GAGE,SAAAgI,EAAY3zC,EAAqB4zC,EAAwC5/B,EAA4B0pB,GAArG,IAAAmO,EACEF,EAAAhpC,KAAAiB,KAAAI,KACM4vC,IACH5zC,KAAIA,KACN4D,YAJ8BioC,EAAA+H,oBAAAA,EAAwC/H,EAAA73B,KAAAA,EAA4B63B,EAAAnO,KAAAA,EAF9FmO,EAAA9P,QAAS,IAQlB,OATyCiQ,EAAAA,EAAAA,GASzC2H,EATA,CAAyCtE,gBCMT7J,GAC1ByL,GAAYzL,GACdA,EAAM0H,UAAU9yB,WAUpB,SAA6BorB,GACpB,IAAAoO,EAAApO,EAAAoO,oBAAqBtpB,EAAAkb,EAAAlb,OAE5B,GAFoCkb,EAAAqO,cAEjB,CACjB,IAAMC,KAqBN,QAnBE3hC,GAAWD,KAAYG,GAAYD,KAAYua,QAAQ,SAAConB,IACpDvO,EAAMpZ,gBAAgB2nB,EAAc,KAAOvO,EAAMpZ,gBAAgB2nB,EAAc,MACjFD,EAAK9yC,MACHkrB,OAAQsZ,EAAM6C,QAAQ,WAAWyL,EAAKhzC,YAKxC0kC,EAAMpZ,gBAAgB3Z,KAAU+yB,EAAMxqB,SAASvI,IAAOmF,OAAS2Q,IACjEurB,EAAK9yC,MACHkrB,OAAQsZ,EAAM6C,QAAQ,WAAWyL,EAAKhzC,UAItB,IAAhBgzC,EAAKhzC,QAEPgzC,EAAK9yC,KAAKwkC,EAAMwO,gBAAgBlW,KAG3B,IAAI6V,GAAoBnO,EAAMyO,gBAAe,GAAKjwC,KACnDsmB,EAAOlQ,eACPw5B,QACFpO,EAAMqJ,iBAAiB,SAAUrJ,EAAMqJ,iBAAiB,WAAYiF,GAG1E,OAzC+BI,CAAoB1O,GAMjDA,EAAM0H,UAAU9yB,WAuEpB,SAAiCorB,GAC/B,GAA8B,IAA1BA,EAAM0M,SAASpxC,OACjB,OAGF,IAAIqzC,EACEC,EAAWvpC,EAAM26B,EAAM0M,SAAU,SAAC7U,GACtCgX,GAAgBhX,GAChB,IAAMjjB,EAAaijB,EAAM6P,UAAU9yB,WACnC,GAAKA,EAGE,CAAA,GAAK+5B,EAIL,CACL,IAAMG,EAjDZ,SAA2BC,EAA4BC,GACrD,IAAMC,EAAsB5pC,EAAM6oC,GAAuB,SAACzpC,GAExD,OAAKsqC,EAAMhP,SAAS9hC,eAAewG,KAChCuqC,EAAOjP,SAAS9hC,eAAewG,OAI9BsqC,EAAMhP,SAAS9hC,eAAewG,KAChCuqC,EAAOjP,SAAS9hC,eAAewG,IAE/BrI,EAAU2yC,EAAM1P,IAAI56B,MAAWrI,EAAU4yC,EAAO3P,IAAI56B,OAOxD,GADarI,EAAU2yC,EAAMvgC,QAAUpS,EAAU4yC,EAAOxgC,MAC9C,CACR,GAAIygC,EACF,OAAOF,EACF,GAAI3yC,EAAU2yC,EAAMhP,YAAc3jC,MACvC,OAAO4yC,EACF,GAAI5yC,EAAU4yC,EAAOjP,YAAc3jC,MACxC,OAAO2yC,EAKX,OAAO,KAoBWG,CAAkBP,EAAmB/5B,GAInD,OAHIk6B,IACFH,EAAoBG,KAEbA,EANT,OADAH,EAAoB/5B,GACb,EAJP,OAAO,IAeX,GAAI+5B,GAAqBC,EAAU,CAEjC,IAAMO,EAAOnP,EAAMyO,gBAAe,GAC5BW,EAAkB,IAAIjB,GAC1BgB,EACAR,EAAkBP,oBAClBO,EAAkBngC,KAClB7H,GAAUgoC,EAAkBzW,OAY9B,OARA8H,EAAM0M,SAASvlB,QAAQ,SAAC0Q,GAClBA,EAAM6P,UAAU9yB,aAClBw6B,EAAgBlX,KAAOkX,EAAgBlX,KAAKj7B,OAAO46B,EAAM6P,UAAU9yB,WAAWsjB,MAC9EL,EAAMwX,iBAAiBxX,EAAM6P,UAAU9yB,WAAWyqB,IAAI,QAAS8P,GAC/DtX,EAAM6P,UAAU9yB,WAAW2hB,QAAS,KAIjC6Y,EAGT,OAvH+BE,CAAwBtP,GC2BzD,IAAAuP,GAAA,SAAApJ,GASE,SAAAoJ,EAAYpsC,EAA8BqsC,EAA+BC,GAAzE,IAAApJ,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YAD2BioC,EAAAmJ,WAAAA,EAA+BnJ,EAAAoJ,SAAAA,IAqI3E,OA9ImCjJ,EAAAA,EAAAA,GAC1B+I,EAAAjxC,UAAAgnC,MAAP,WACE,OAAO,IAAIiK,EAAc,KAAI/wC,KAAMJ,KAAKoxC,YAAa7oC,GAAUvI,KAAKqxC,YAWxDF,EAAAG,iBAAd,SAA+BvsC,EAAsB68B,GACnD,IAAIrZ,GAAc,EAClBqZ,EAAM+G,gBAAgB,SAAA4I,GAChBA,EAAG5lC,YACL4c,GAAc,KAIlB,IAAMipB,KACAC,KAEN,OAAKlpB,GAKLqZ,EAAM+G,gBAAgB,SAACvxB,EAAUzG,GACxB,IAAAhF,EAAAyL,EAAAzL,UAAWxN,EAAAiZ,EAAAjZ,MACdwN,EACgB,UAAdA,GACF6lC,EAAK,KAAOA,EAAK,SACjBA,EAAK,KAAY,MAAIzrB,GAAQ3O,KAE7Bo6B,EAAKrzC,GAASqzC,EAAKrzC,OACnBqzC,EAAKrzC,GAAOwN,GAAaoa,GAAQ3O,GAG7BzF,GAAehB,IAA2C,iBAA/BixB,EAAM8P,YAAY/gC,KAC/C6gC,EAAKrzC,GAAY,IAAI4nB,IAAS5nB,MAAKA,EAAEwN,UAAW,QAChD6lC,EAAKrzC,GAAY,IAAI4nB,IAAS5nB,MAAKA,EAAEwN,UAAW,UA3E5D,SAAsB8lC,EAAkC9gC,EAAkByG,GACpEA,EAASzE,KACX8+B,EAAK1rB,GAAQ3O,QAAiB,EAC9Bq6B,EAAK1rB,GAAQ3O,GAAWiP,UAAW,UAAW,EAE1C2a,GAAiB5pB,EAAUzG,KAC7B8gC,EAAK1rB,GAAQ3O,GAAWiP,UAAW,YAAa,IAGlDorB,EAAK1rB,GAAQ3O,KAAa,EAsEtBu6B,CAAaF,EAAM9gC,EAASyG,KAI3BhS,GAAKqsC,GAAMv0C,OAASkI,GAAKosC,GAAMt0C,SAAY,EACvC,KAGF,IAAIi0C,EAAcpsC,EAAQ0sC,EAAMD,IA5B9B,MA+BGL,EAAAS,kBAAd,SAAgC7sC,EAAsBzE,GAIpD,IAHA,IAAMmxC,KACAD,KAEUrrC,EAAA,EAAAoB,EAAAjH,EAAEqL,UAAFxF,EAAAoB,EAAArK,OAAAiJ,IAAa,CAAxB,IACIT,GADEvI,EAACoK,EAAApB,IACHT,GAAIvH,EAAAhB,EAAAgB,MAAO2sB,EAAA3tB,EAAA2tB,GACdplB,IACS,UAAPA,GACF8rC,EAAK,KAAOA,EAAK,SACjBA,EAAK,KAAY,MAAI1mB,GAAM/E,GAAQ5oB,KAEnCq0C,EAAKrzC,GAASqzC,EAAKrzC,OACnBqzC,EAAKrzC,GAAOuH,GAAMolB,GAAM/E,GAAQ5oB,KAKtC,IAAgB,IAAAmnB,EAAA,EAAAyH,EAAAzrB,EAAE2qB,YAAF3G,EAAAyH,EAAA7uB,OAAAonB,IAAiB,CAA5B,IAAMnnB,EACTs0C,EADSt0C,EAAC4uB,EAAAzH,KACA,EAGZ,OAAKlf,GAAKqsC,GAAMv0C,OAASkI,GAAKosC,GAAMt0C,SAAY,EACvC,KAGF,IAAIi0C,EAAcpsC,EAAQ0sC,EAAMD,IAGlCL,EAAAjxC,UAAAwwC,MAAP,SAAaxoC,GACNF,GAAOhI,KAAKoxC,WAAYlpC,EAAMkpC,Y5CjDvC,eAIsB,IAAA3zC,KAAA0I,EAAA,EAAAA,EAAA5F,UAAArD,OAAAiJ,IAAA1I,EAAA0I,GAAA5F,UAAA4F,GACpB6O,GAAQD,MAAM9V,MAAM+V,GAASzU,W4CgDzBsxC,CAAU,wCA7GhB,SAAuBC,EAAoCC,GACzD,IAAK,IAAM3wC,KAAK2wC,EACd,GAAIA,EAAclyC,eAAeuB,GAAI,CAEnC,IAAM4wC,EAAMD,EAAc3wC,GAC1B,IAAK,IAAMsE,KAAMssC,EACXA,EAAInyC,eAAe6F,KACjBtE,KAAK0wC,EAEPA,EAAe1wC,GAAGsE,GAAMssC,EAAItsC,GAE5BosC,EAAe1wC,IAAMsE,GAAIssC,EAAItsC,MA+FnCusC,CAAcjyC,KAAKqxC,SAAUnpC,EAAMmpC,UACnCnpC,EAAMw/B,WAMHyJ,EAAAjxC,UAAAgyC,cAAP,SAAqB/1C,GAArB,IAAA8rC,EAAAjoC,KACE7D,EAAO4sB,QAAQ,SAAA3nB,GAAK,OAAA6mC,EAAKmJ,WAAWhwC,IAAK,KAGpC+vC,EAAAjxC,UAAAknC,gBAAP,WACE,IAAMniC,KAKN,OAHAG,GAAKpF,KAAKoxC,YAAYroB,QAAQ,SAAA3nB,GAAK,OAAA6D,EAAI7D,IAAK,IAC5CgE,GAAKpF,KAAKqxC,UAAUtoB,QAAQ,SAAAznB,GAAK,OAAA2D,EAAI3D,IAAK,IAEnC2D,GAGFksC,EAAAjxC,UAAAinC,eAAP,WAAA,IAAAc,EAAAjoC,KACQiF,KAQN,OANAG,GAAKpF,KAAKqxC,UAAUtoB,QAAQ,SAAA5qB,GAC1BiH,GAAK6iC,EAAKoJ,SAASlzC,IAAQ4qB,QAAQ,SAAArjB,GACjCT,EAAOS,EAAE,IAAIvH,IAAW,MAIrB8G,GAGFksC,EAAAjxC,UAAAgpC,SAAP,WAKE,IAJA,IAAM8I,KACA71C,KACA2uB,KAEc3kB,EAAA,EAAAoB,EAAAnC,GAAKpF,KAAKqxC,UAAVlrC,EAAAoB,EAAArK,OAAAiJ,IAClB,IADG,IAAMhI,EAAKoJ,EAAApB,GACGme,EAAA,EAAAyH,EAAA3mB,GAAKpF,KAAKqxC,SAASlzC,IAAnBmmB,EAAAyH,EAAA7uB,OAAAonB,IAA4B,CAAxC,IAAM5e,EAAEqmB,EAAAzH,GACXwG,EAAG1tB,KAAK4C,KAAKqxC,SAASlzC,GAAOuH,IAC7BssC,EAAI50C,KAAKsI,GACTvJ,EAAOiB,KAAKe,GAYhB,OAPE6V,KAAM,YACNiX,QAAS7lB,GAAKpF,KAAKoxC,YACnBY,IAAGA,EACH71C,OAAMA,EACN2uB,GAAEA,IAKRqmB,EA9IA,CAAmCrK,ICfnCqL,GAAA,SAAApK,GAYE,SAAAoK,EAAmBptC,EAAsC68B,EAAmCxlC,EAAqB09B,GAAjH,IAAAmO,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,KAD0CioC,EAAArG,MAAAA,EAAmCqG,EAAA7rC,KAAAA,EAAqB6rC,EAAAnO,KAAAA,EAG/G,IAAsB,IAAA3zB,EAAA,EAAAoB,GAAC0G,GAAQD,IAAT7H,EAAAoB,EAAArK,OAAAiJ,IAAe,CAAhC,IAAMwK,EAAOpJ,EAAApB,GACViR,EAAWwqB,EAAM5J,MAAMrnB,GAC7B,GAAIyG,EAAU,CACL,IAAAzE,EAAAyE,EAAAzE,IAAKrN,EAAA8R,EAAA9R,KACZ2iC,EAAKt3B,GAAQvQ,GACXhE,KAAMwlC,EAAM6C,QAAW9zB,EAAO,WAC9BxU,QACE4pB,GAAQ3O,WACJzE,GAAOoT,GAAQ3O,GAAWiP,UAAW,cAGzCkkB,GAAYjlC,IAAS8sC,UAAW9sC,GAChChI,EAAQgI,IAAS+sC,eAAgBpJ,GAAoB7xB,EAAUzG,gBAMvEs3B,EAAKqK,WAAa1Q,EAAMnI,QA4H5B,OA7J+B2O,EAAAA,EAAAA,GAoC7B1qC,OAAA2pC,eAAI8K,EAAAjyC,UAAA,cAAJ,WACE,OACMF,KAAK8Q,QAAU9Q,KAAK8Q,OAAO3U,YAAa0C,OACxCmB,KAAK6Q,KAAO7Q,KAAK6Q,IAAI1U,6CAOtBg2C,EAAAjyC,UAAAooC,UAAP,WACE,OAAOtoC,KAAK5D,MAGN+1C,EAAAjyC,UAAAqyC,kCAAR,WAGE,IAFA,IAAMC,KAEgBrsC,EAAA,EAAAoB,GAAC,IAAK,KAANpB,EAAAoB,EAAArK,OAAAiJ,IAA8B,CAA/C,IAAMwK,EAAOpJ,EAAApB,GACVssC,EAAsBzyC,KAAKsyC,WAAWhJ,UAAUoJ,OAAO/hC,GAC7D,GAAI8hC,IAAwBA,EAAoBta,OAAQ,CACtD,IAAMnkB,EAAOy+B,EAAoBxR,IAAI,QAC/B3Q,EAAQmiB,EAAoBxR,IAAI,SAEtC,GAAIjS,GAAkBhb,IAAS6oB,GAAcvM,GAAQ,CACnD,IACMnyB,EAAQw0C,GADCC,GAAe5yC,KAAKsyC,WAAY3hC,IAE3CxS,EACFq0C,EAA+B7hC,GAAWxS,EAE1Cod,GAAS,gEAMjB,OAAOi3B,GAGDL,EAAAjyC,UAAA2yC,sBAAR,SAA8BliC,EAA2BmiC,EAAyBN,GAChF,IAAMO,EAA2B,QAAZpiC,EAAoB,IAAM,IAEzCxU,KACA61C,KACAlnB,KAEF0nB,EAA+BO,KAC7BD,GAEF32C,EAAOiB,KAAK,YAAYo1C,EAA+BO,IAEvDf,EAAI50C,KAAK,SAGTjB,EAAOiB,KAAKo1C,EAA+BO,IAC3Cf,EAAI50C,KAAK,aAGX0tB,EAAG1tB,KAAK,YAAYo1C,EAA+BO,KAG/C,IAAAxrC,EAAAvH,KAAA2Q,GAACyhC,EAAA7qC,EAAA6qC,UAAWC,EAAA9qC,EAAA8qC,eAClB,GAAID,EAAW,CACN,IAAA1sC,EAAA0sC,EAAA1sC,GAAIvH,EAAAA,EAAAA,MACXhC,EAAOiB,KAAKe,GACZ6zC,EAAI50C,KAAKsI,GACTolB,EAAG1tB,KAAK2oB,GAAQqsB,SACPC,IACTl2C,EAAOiB,KAAKi1C,GACZL,EAAI50C,KAAK,OACT0tB,EAAG1tB,KAAKi1C,IAGV,OACEj2C,KAAM4D,KAAK2Q,GAASvU,KAEpBmH,OAAQuvC,GAAmB9yC,KAAK85B,KAChC7jB,WAAW7V,GACT4T,KAAM,YACNiX,QAASjrB,KAAK2Q,GAASxU,QACnBA,EAAOe,QACTf,OAAMA,EAAE61C,IAAGA,EAAElnB,GAAEA,UAMhBqnB,EAAAjyC,UAAAgpC,SAAP,WACE,IAAMpP,KACFgZ,EAAkB,KAChBN,EAAiCxyC,KAAKuyC,oCAE5C,GAAIvyC,KAAK8Q,QAAU9Q,KAAK6Q,MAAQ2hC,EAA+B30C,GAAK20C,EAA+B3iC,GAAI,CAErGijC,EAAkB,SAAS9yC,KAAK8Q,OAAO1U,KAAI,IAAI4D,KAAK6Q,IAAIzU,KAExD,IAAMD,KAAY0C,OAChB2zC,EAA+B30C,GAAK20C,EAA+B30C,MACnE20C,EAA+B3iC,GAAK2iC,EAA+B3iC,OAE/DmiC,EAAM71C,EAAO2B,IAAI,WAAmB,MAAA,aAE1Cg8B,EAAK18B,MACHhB,KAAM02C,EACNvvC,OAAQvD,KAAK85B,KACb7jB,YACEjC,KAAM,YACNiX,QAAajrB,KAAK8Q,OAAO3U,OAAM0C,OAAKmB,KAAK6Q,IAAI1U,QAC7CA,OAAMA,EACN61C,IAAGA,MAKT,IAAsB,IAAA7rC,EAAA,EAAAoB,GAAC0G,GAAQD,IAAT7H,EAAAoB,EAAArK,OAAAiJ,IAAe,CAAhC,IAAMwK,EAAOpJ,EAAApB,GACZnG,KAAK2Q,IACPmpB,EAAK18B,KAAK4C,KAAK6yC,sBAAsBliC,EAASmiC,EAAiBN,IAInE,OAAO1Y,GAEXqY,EA7JA,CAA+BrL,ICrB/BkM,GAAA,SAAAjL,GAKE,SAAAiL,EAAYjuC,EAA8B+jB,GAA1C,IAAAmf,EACCF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YAD4BioC,EAAAnf,UAAAA,IAwD5C,OA7DuCsf,EAAAA,EAAAA,GAC9B4K,EAAA9yC,UAAAgnC,MAAP,WACE,OAAO,IAAI8L,EAAkB,KAAI5yC,KAAMJ,KAAK8oB,aAOhCkqB,EAAAC,KAAd,SAAmBluC,EAAsB68B,GAChC,IAAAlb,EAAAkb,EAAAlb,OAAQ7U,EAAA+vB,EAAA/vB,KACf,GAA6B,WAAzB6U,EAAO8L,cACT,OAAO,KAGT,IAAM1rB,EAAS86B,EAAMsR,eAAe,SAACC,EAAoC/7B,EAAUzG,GACjF,IAAMoyB,EAAiBpxB,GAAehB,IAAYixB,EAAMoB,kBAAkBryB,GACtEoyB,KAOE7T,GANc6T,EAAe9B,IAAI,UAME7pB,EAASzL,WAAcgI,GAAW9B,KACvEshC,EAAW/7B,EAASjZ,OAASiZ,IAGjC,OAAO+7B,OAGT,OAAK/tC,GAAK0B,GAAQ5J,OAIX,IAAI81C,EAAkBjuC,EAAQ+B,GAH5B,MAMXpJ,OAAA2pC,eAAI2L,EAAA9yC,UAAA,cAAJ,WACE,OAAOF,KAAK8oB,2CAIPkqB,EAAA9yC,UAAAgpC,SAAP,WAAA,IAAAjB,EAAAjoC,KACQozC,EAAUhuC,GAAKpF,KAAK8G,QAAQ4b,OAAO,SAAC2wB,EAAal1C,GACrD,IAAMiZ,EAAW6wB,EAAKnf,UAAU3qB,GAC1BwiC,EAAM3d,GAAS5L,GAAWkP,KAAM,UAMtC,OAJiB,OAAblP,IACFi8B,EAAYj2C,KAAQujC,EAAG,aACvB0S,EAAYj2C,KAAK,UAAUujC,EAAG,MAEzB0S,OAGT,OAAOD,EAAQl2C,OAAS,GAEpB8W,KAAM,SACNsS,KAAM8sB,EAAQ90C,KAAK,SACnB,MAER00C,EA7DA,CAAuClM,ICoCvC,IAAAwM,GAAA,SAAAvL,GAOE,SAAAuL,EAAYvuC,EAAsByD,GAAlC,IAAAy/B,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YAEbioC,EAAKsL,OAAS/qC,IA6LlB,OAvM+B4/B,EAAAA,EAAAA,GAGtBkL,EAAApzC,UAAAgnC,MAAP,WACE,OAAO,IAAIoM,EAAU,KAAM/qC,GAAUvI,KAAKuzC,UAY9BD,EAAAE,aAAd,SAA2BzuC,EAAsB68B,EAAc6R,GAE7D,IAAI9R,KACE7H,EAAO8H,EAAM9H,KAKnB,OAJIA,GAAQA,EAAK9sB,QAAU8sB,EAAK9sB,OAAOxE,QACrCm5B,EAAW7H,EAAK9sB,OAAOxE,OAGlBxI,KAAK0zC,kBAAkB3uC,EAAQ48B,KAAc8R,IAGxCH,EAAAK,gCAAd,SAA8C5uC,EAAsBkR,EAA4Bw9B,GAC9F,IAAMjrC,KAgCN,OtD/EJ,SAAAorC,EAA+BluC,EAAuBxJ,GACpD,GAAI4J,EAAaJ,GACfkuC,EAAYluC,EAAGK,IAAK7J,QACf,GAAI0J,EAAaF,GACtB,IAAoB,IAAAS,EAAA,EAAAoB,EAAA7B,EAAGG,IAAHM,EAAAoB,EAAArK,OAAAiJ,IAClBytC,EADcrsC,EAAApB,GACKjK,QAEhB,GAAI6M,EAAYrD,GACrB,IAAoB,IAAA4e,EAAA,EAAAyH,EAAArmB,EAAGC,GAAH2e,EAAAyH,EAAA7uB,OAAAonB,IAClBsvB,EADc7nB,EAAAzH,GACKpoB,QAGrBA,EAAGwJ,GsDoCHkuC,CAAY39B,EAAUnP,OAAQ,SAAAA,GAC5B,GAAI+sC,GAAiB/sC,GAAS,CAE5B,IAAIiB,EAA4C,KAK5C+rC,GAAsBhtC,GACxBiB,EAAMjB,EAAOkiC,MACJ+K,GAAsBjtC,GAC/BiB,EAAMjB,EAAOwpB,MAAM,GACV0jB,GAAsBltC,KAC/BiB,GAAOjB,EAAOmtC,OAASntC,EAAW,IAAG,IAEnCiB,IACEsS,GAAWtS,GACbS,EAAM1B,EAAO3I,OAAS,OACboB,EAASwI,GAClBS,EAAM1B,EAAO3I,OAAS,SACbR,EAASoK,KAClBS,EAAM1B,EAAO3I,OAAS,WAItB2I,EAAOuV,WACT7T,EAAM1B,EAAO3I,OAAS,WAKD,IAAvBiH,GAAKoD,GAAOtL,OACP,KAGF8C,KAAK0zC,kBAAkB3uC,KAAYyD,EAAOirC,IAMrCH,EAAAY,yBAAd,SAAuCnvC,EAAsB68B,EAAc6R,GACzE,IAAM/H,KA0BN,OAxBI2B,GAAYzL,IAAUsJ,GAAatJ,KAErCA,EAAM+G,gBAAgB,SAAAvxB,GAChB6Q,GAAe7Q,GACjBs0B,EAASt0B,EAASjZ,OAAS,OAClB6pB,GAAiB5Q,GACrB1L,GAAsB0L,EAASzL,aAClC+/B,EAASt0B,EAASjZ,OAAS,UAEpB2L,GAAgBsN,EAASjZ,OAAS,EAGrCiZ,EAASjZ,SAASutC,IACtBA,EAASt0B,EAASjZ,OAAS,WAEpB2nB,GAAgB1O,IAAamzB,GAAYnzB,EAAS9R,OAASwE,GAAgBsN,EAAS9R,KAAKnH,OAAS,IAErGiZ,EAAS9R,KAAKnH,SAASutC,IAC3BA,EAASt0B,EAAS9R,KAAKnH,OAAS,cAMjC6B,KAAK0zC,kBAAkB3uC,KAAY2mC,EAAU+H,IAMvCH,EAAAI,kBAAf,SAAiC3uC,EAAsB48B,EAAwB+J,EAAwB+H,GAErG,IAAoB,IAAAttC,EAAA,EAAAoB,EAAAnC,GAAKsmC,GAALvlC,EAAAoB,EAAArK,OAAAiJ,IAAgB,CAA/B,IAAMhI,EAAKoJ,EAAApB,QAESrC,KADjBqwC,EAAWV,EAAc9H,gBAAgBxtC,IAClC4C,QAEPozC,EAASxS,UAAYwS,EAASpzC,QAAU2qC,EAASvtC,IAA6B,YAAnBg2C,EAASpzC,OAA2C,YAApB2qC,EAASvtC,UAC/FutC,EAASvtC,GAEhBod,GAASC,GAAY3F,eAAe1X,EAAOutC,EAASvtC,GAAQg2C,EAASpzC,SAK3E,IAAoB,IAAAujB,EAAA,EAAAyH,EAAA3mB,GAAKu8B,GAALrd,EAAAyH,EAAA7uB,OAAAonB,IAAgB,CAA/B,IACG6vB,EADGh2C,EAAK4tB,EAAAzH,QAEGxgB,KADXqwC,EAAWV,EAAcxS,IAAI9iC,MAG7Bg2C,IAAaxS,EAASxjC,UACjBwjC,EAASxjC,GAEhBod,GAASC,GAAY3F,eAAe1X,EAAOwjC,EAASxjC,GAAQg2C,KAKlE,IAAM3rC,EAAQ,IAAIijC,GAAM9J,EAAU+J,GAGlC+H,EAAczH,QAAQxjC,GAItB,IADA,IAAM9L,KACYsvB,EAAA,EAAAxB,EAAAplB,GAAKoD,EAAMo2B,WAAX5S,EAAAxB,EAAAttB,OAAA8uB,IAAuB,CAApC,IAAM9pB,EAAGsoB,EAAAwB,GACNjkB,EAAMS,EAAMy4B,IAAI/+B,GACV,OAAR6F,IACFrL,EAAEwF,GAAO6F,GAIb,OAAuB,IAAnB3C,GAAK1I,GAAGQ,QAAgBu2C,EAAcW,aACjC,KAGF,IAAId,EAAUvuC,EAAQrI,IAG/BgB,OAAA2pC,eAAWiM,EAAApzC,UAAA,aAAX,WACE,OAAOF,KAAKuzC,wCAGPD,EAAApzC,UAAAwwC,MAAP,SAAaxoC,GACXlI,KAAKuzC,OAAMnzC,KAAOJ,KAAKuzC,OAAWrrC,EAAMM,OACxCN,EAAMw/B,UAMD4L,EAAApzC,UAAAm0C,oBAAP,WAEE,IADA,IAAMC,KACcnuC,EAAA,EAAAoB,EAAAnC,GAAKpF,KAAKuzC,QAAVptC,EAAAoB,EAAArK,OAAAiJ,IAAmB,CAAlC,IAAMhI,EAAKoJ,EAAApB,GACRzJ,EAAIsD,KAAKuzC,OAAOp1C,GACS,IAA3B2L,GAAgB3L,KAClBm2C,EAAYn2C,GAASzB,GAGzB,OAAO43C,GAIFhB,EAAApzC,UAAAinC,eAAP,WACE,OAAO3nC,EAAM4F,GAAKpF,KAAKuzC,UAGlBD,EAAApzC,UAAAknC,gBAAP,WACE,OAAO5nC,EAAM4F,GAAKpF,KAAKuzC,UAGlBD,EAAApzC,UAAAq0C,mBAAP,SAA0BC,GAA1B,IAAAvM,EAAAjoC,KACE,YADwB,IAAAw0C,IAAAA,GAAA,GACjBpvC,GAAKpF,KAAKuzC,QACdzsC,OAAO,SAAA3I,GAAS,OAAAq2C,GAAa1qC,GAAgB3L,GAAS,IACtDL,IAAI,SAAAK,GACH,IAAMmoB,EAlNd,SAAyBnoB,EAAeqK,GACtC,IAAMpH,EAAIkI,GAAoBnL,GAC9B,MAAc,WAAVqK,EACK,YAAYpH,EAAC,IACD,YAAVoH,EACF,aAAapH,EAAC,IACF,WAAVoH,EACF,YAAYpH,EAAC,IACD,SAAVoH,EACF,UAAUpH,EAAC,IACC,YAAVoH,EACFpH,EAC6B,IAA3BoH,EAAM9H,QAAQ,SAEhB,aAAaU,EAAC,IADHoH,EAAM1J,MAAM,EAAG0J,EAAMtL,QACL,IACC,IAA1BsL,EAAM9H,QAAQ,QAEhB,YAAYU,EAAC,IADFoH,EAAM1J,MAAM,EAAG0J,EAAMtL,QACN,KAEjCqe,GAASC,GAAY5F,kBAAkBpN,IAChC,MA8LUisC,CAAgBt2C,EAAO8pC,EAAKsL,OAAOp1C,IAChD,OAAKmoB,GAKHtS,KAAM,UACNsS,KAAIA,EACJwE,GAAIjhB,GAAoB1L,IANjB,OASR2I,OAAO,SAAAxG,GAAK,OAAM,OAANA,KAErBgzC,EAvMA,CAA+BxM,ICxC/B4N,GAAA,SAAA3M,GAOE,SAAA2M,EAAY5a,GAAZ,IAAAmO,EACEF,EAAAhpC,KAAAiB,KAAM,OAAKA,KAIX,GAAI+5B,GAFJD,EAAOA,IAAS19B,KAAM,WAGpB6rC,EAAK0M,OAAShtC,OAAQmyB,EAAKnyB,aACtB,GAAIsyB,GAAUH,IAOnB,GANAmO,EAAK0M,OAASC,IAAK9a,EAAK8a,KAEnB9a,EAAK9sB,SACR8sB,EAAK9sB,YAGF8sB,EAAK9sB,SAAW8sB,EAAK9sB,OAAOgH,KAAM,CAGrC,IAAI6gC,EAAmB,kBAAkBC,KAAKhb,EAAK8a,KAAK,GACnDjuC,GAAU,OAAQ,MAAO,MAAO,MAAO,YAAakuC,KACvDA,EAAmB,QAIrB/a,EAAK9sB,OAAOgH,KAAO6gC,QAEZ7a,GAAYF,KACrBmO,EAAK0M,UAQP,GAJI7a,EAAK19B,OACP6rC,EAAKE,MAAQrO,EAAK19B,MAGhB09B,EAAK9sB,OAAQ,CACf,IAAMzF,EAAAuyB,EAAA9sB,OAACA,GAAAzF,EAAAiB,MAAAhI,EAAA+G,GAAA,WACP0gC,EAAK0M,MAAM3nC,OAASA,WAoD1B,OA/FgCo7B,EAAAA,EAAAA,GA+C9B1qC,OAAA2pC,eAAIqN,EAAAx0C,UAAA,YAAJ,WACE,OAAOF,KAAK20C,uCAGPD,EAAAx0C,UAAA60C,QAAP,WACE,QAAS/0C,KAAKmoC,OAGhBzqC,OAAA2pC,eAAIqN,EAAAx0C,UAAA,gBAAJ,WACE,OAAOF,KAAKmoC,WAGd,SAAa/rC,GACX4D,KAAKmoC,MAAQ/rC,mCAGfsB,OAAA2pC,eAAIqN,EAAAx0C,UAAA,cAAJ,SAAW6E,GACT,MAAM,IAAIvI,MAAM,mEAGXk4C,EAAAx0C,UAAAwnC,OAAP,WACE,MAAM,IAAIlrC,MAAM,kDAMXk4C,EAAAx0C,UAAAuG,KAAP,WACE,OAAIszB,GAAa/5B,KAAK20C,QACf30C,KAAKg1C,QAERh1C,KAAKg1C,MAAQvuC,EAAKzG,KAAK20C,QAElB30C,KAAKg1C,OACH/a,GAAUj6B,KAAK20C,OACjBluC,GAAMzG,KAAK20C,MAAMC,IAAK50C,KAAK20C,MAAM3nC,SAEjChN,KAAKmoC,OAITuM,EAAAx0C,UAAAgpC,SAAP,WACE,OAAA9oC,GACEhE,KAAM4D,KAAKmoC,OACRnoC,KAAK20C,OACR1+B,gBAGNy+B,EA/FA,CAAgC5N,ICUhCmO,GAAA,SAAAlN,GAKE,SAAAkN,EAAYlwC,EAA8BmwC,GAA1C,IAAAjN,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YAD2BioC,EAAAiN,QAAAA,IAoE5C,OAzEkC9M,EAAAA,EAAAA,GACzB6M,EAAA/0C,UAAAgnC,MAAP,WACE,OAAO,IAAI+N,EAAa,KAAM1sC,GAAUvI,KAAKk1C,WAOjCD,EAAA3D,iBAAd,SAA+BvsC,EAAsB68B,GACnD,IAAMsT,EAAUtT,EAAMsR,eAAe,SAACiC,EAAsC/9B,GAC1E,GAAIA,EAASiF,SAAU,CACrB,IAAMjb,EAAI2kB,GAAQ3O,GAClB+9B,EAAkB/zC,IAChB0pB,GAAI1pB,EACJib,SAAUjF,EAASiF,SACnBle,MAAOiZ,EAASjZ,OAGpB,OAAOg3C,OAGT,OAA6B,IAAzB/vC,GAAK8vC,GAASh4C,OACT,KAGF,IAAI+3C,EAAalwC,EAAQmwC,IAGpBD,EAAArD,kBAAd,SAAgC7sC,EAAsBzE,SACpD,OAAO,IAAI20C,EAAalwC,IAAMwC,MAC3BjH,EAAEnC,QACD2sB,GAAIxqB,EAAEwqB,GACNzO,SAAU/b,EAAE+b,SACZle,MAAOmC,EAAEnC,YAKR82C,EAAA/0C,UAAAwwC,MAAP,SAAaxoC,GACXlI,KAAKk1C,QAAO90C,KAAOJ,KAAKk1C,QAAYhtC,EAAMgtC,SAC1ChtC,EAAMw/B,UAGDuN,EAAA/0C,UAAAinC,eAAP,WACE,IAAMliC,KAMN,OAJAmD,GAAKpI,KAAKk1C,SAASnsB,QAAQ,SAAA3nB,GACzB6D,EAAI7D,EAAE0pB,KAAM,IAGP7lB,GAGFgwC,EAAA/0C,UAAAknC,gBAAP,WACE,IAAMniC,KAMN,OAJAmD,GAAKpI,KAAKk1C,SAASnsB,QAAQ,SAAA3nB,GACzB6D,EAAI7D,EAAEjD,QAAS,IAGV8G,GAGFgwC,EAAA/0C,UAAAgpC,SAAP,WACE,OAAO9gC,GAAKpI,KAAKk1C,SAASp3C,IAAI,SAAAjB,GAC5B,OACEmX,KAAM,UACN8W,GAAIjuB,EAAEiuB,GACNxE,KAAMvD,GAAUlmB,EAAEwf,SAAUxf,EAAEsB,WAItC82C,EAzEA,CAAkCnO,ICFlC,SAAAsO,GAAkCh0C,GAYhC,OAXA,SAAAi0C,EAAgC1wC,GAC9B,KAAIA,aAAgB+vC,IAApB,CAIA,IAAMnzC,EAAOoD,EAAKI,OACd3D,EAAEuD,IACJ0wC,EAAuB9zC,KAU7B,SAAA+zC,GAA4B3wC,GAC1B,IAAMI,EAASJ,EAAKI,OAGpB,GAAIJ,aAAgB2uC,GAAW,CAC7B,GAAIvuC,aAAkB2vC,GACpB,OAAO,EAGT,GAAI3vC,EAAOwiC,cAAgB,EAEzB,OAAO,EAGT,GAAIxiC,aAAkBuuC,GACpBvuC,EAAO2rC,MAAM/rC,OACR,CAEL,GAAIwD,GAAgBpD,EAAOoiC,iBAAkBxiC,EAAKyiC,mBAChD,OAAO,EAGTziC,EAAKijC,kBAIT,OAAO,EAQT,SAAA2N,GAAqC5wC,GACnC,QAAIA,aAAgBmjC,IAAcnjC,EAAK4iC,cAAgB,GAAK5iC,aAAgBwtC,MAI1ExtC,EAAK+iC,UAEA,GAQT,SAAA8N,GAAyCC,GACvC,IAAIt5C,KACJ,OAAOi5C,GAAkB,SAACzwC,GACxB,GAAIA,aAAgBswC,GAAc,CAChC,IAAMS,EAAU/wC,EAAKwiC,iBACR/hC,GAAKswC,GAASzuC,MAAM,SAACrD,GAAM,QAAEzH,EAAOyH,KAG/Ce,EAAK+iC,SAELvrC,EAAMiE,KAAOjE,EAAWu5C,GAI5B,OAAO,GAZFN,CAaJK,GCvBL,IAAAE,GAAA,SAAA5N,GAOE,SAAA4N,EAAY5wC,EAAsBwwB,GAAlC,IAAA0S,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YAEbioC,EAAK2N,OAASrgB,IA8KlB,OAxL+B6S,EAAAA,EAAAA,GAGtBuN,EAAAz1C,UAAAgnC,MAAP,WACE,OAAO,IAAIyO,EAAU,KAAMptC,GAAUvI,KAAK41C,UAS9BD,EAAA/D,kBAAd,SAAgC7sC,EAAsB8wC,GAE7C,IAAAtgB,EAAAsgB,EAAAtgB,MAAOtK,EAAA4qB,EAAA5qB,QAASH,EAAA+qB,EAAA/qB,GAAIvjB,EAAAsuC,EAAAppC,OAAAA,OAAA,IAAAlF,EAAA,OAAAA,EAErBuuC,KACAC,KACN,QAA4BjyC,IAAxB+xC,EAAevwC,KACjB,IAAwB,IAAAa,EAAA,EAAAme,EAAAuxB,EAAevwC,KAAfa,EAAAme,EAAApnB,OAAAiJ,IAAqB,CAAxC,IAAMisC,EAAS9tB,EAAAne,GAClB2vC,EAAW14C,KAAKg1C,EAAUj0C,OAC1B43C,EAAU34C,UAAyB0G,IAApBsuC,EAAU9hC,MAAsB,YAAc8hC,EAAU9hC,OAgB3E,OAAO,IAAIqlC,EAAW5wC,GACpBixC,WAAYzgB,EACZtK,QAAOA,EACPxe,OAAMA,EACNnH,MAhBAnH,MAAO23C,EACPxlC,MAAOylC,GAgBPE,WACAnrB,GAhDN,SAAwBA,GACtB,OAAOxtB,EAAQwtB,IAAOA,EAAG7jB,MAAM,SAAA9J,GAAK,OAAAQ,EAASR,MAAO2tB,EAAG5tB,OAAQ,EAiCzDg5C,CAAeprB,GACFA,EACPntB,EAASmtB,IACDA,EAAIA,EAAK,SAET+qB,EAAetgB,MAAQ,SAAUsgB,EAAetgB,MAAQ,WAa9DogB,EAAArE,iBAAd,SAA+BvsC,EAAsB68B,GAEnD,IAMIuU,EANEC,EAAkBxU,EAAMrM,MAE9B,IAAK6gB,EACH,OAAO,KAILA,EAAgB/f,iBAClB8f,EAAoBvU,EAAMxqB,SAASg/B,EAAgB/f,iBAGrD,IAGI/wB,EAHE+wC,EA3HV,SAA0BzU,GACxB,OAAOA,EAAMrM,MAAMW,QAAQxT,OAAO,SAACvmB,EAAQm6C,GACzC,IAEMC,EAASxwB,GAFEuwB,EAAGl/B,UAMpB,OAHIm/B,GACFp6C,EAAOiB,KAAKm5C,GAEPp6C,OAmHSq6C,CAAiB5U,GAC3BmE,EAAWnE,EAAMp0B,SAAS8C,MAI9BhL,EADEhI,EAAQyoC,IAAargB,GAAWqgB,GAC3BD,GAAWC,GAIXsQ,EAAQ3zB,OAAO,SAACvlB,EAAGgB,GAGxB,OAFAhB,EAAEgB,MAAMf,KAAKe,GACbhB,EAAEmT,MAAMlT,KAAK,cACND,IACLgB,SAAUmS,WAIhB,IAAMnS,EAAQyjC,EAAM7b,QAAQqwB,EAAgB3gB,cAE5C,OAAO,IAAIkgB,EAAU5wC,GACnBoxC,kBAAiBA,EACjBH,WAAW73C,EACX83C,WACAI,QAAOA,EACP/wC,KAAIA,EACJmH,OAAQ2pC,EAAgB3pC,OACxB6pB,OAAQ8f,EAAgB9f,OACxBxL,IAAK3sB,EAAQ,SAAUA,EAAQ,WAInCT,OAAA2pC,eAAIsO,EAAAz1C,UAAA,aAAJ,WACE,OAAOF,KAAK41C,wCAGPD,EAAAz1C,UAAAgyC,cAAP,SAAqB/1C,GACnB6D,KAAK41C,OAAOK,QAAUj2C,KAAK41C,OAAOK,QAAQp3C,OAAO1C,IAG5Cw5C,EAAAz1C,UAAAknC,gBAAP,WACE,IAAMniC,KAENA,EAAIjF,KAAK41C,OAAOI,aAAc,EAE9Bh2C,KAAKy2C,mBAAmB1tB,QAAQ,SAAA3nB,GAAK,OAAA6D,EAAI7D,IAAK,IAC9CpB,KAAK41C,OAAOK,QAAQltB,QAAQ,SAAA3nB,GAAK,OAAA6D,EAAI7D,IAAK,IAC1C,IAAMjD,EAAQ6B,KAAK41C,OAAOtwC,KAAKnH,MAG/B,OAFAb,EAAQa,GAASA,EAAM4qB,QAAQ,SAAA3nB,GAAK,OAAA6D,EAAI7D,IAAK,IAAQ6D,EAAI9G,IAAS,EAE3D8G,GAGF0wC,EAAAz1C,UAAAinC,eAAP,WACE,OAAOnnC,KAAK41C,OAAO9qB,GAAGpI,OAAO,SAACjf,EAAQyB,GAEpC,OADAzB,EAAOyB,IAAQ,EACRzB,QAIHkyC,EAAAz1C,UAAAu2C,iBAAR,WACQ,IAAAlvC,EAAAvH,KAAA41C,OAACO,EAAA5uC,EAAA4uC,kBAAmB7f,EAAA/uB,EAAA+uB,OAAQrL,EAAA1jB,EAAA0jB,QAClC,OAAIkrB,EACEA,EAAkBxjC,IAChB2jB,GAGMvQ,GAAQowB,GAAoB9vB,UAAW,UAI/CN,GAAQowB,MACRpwB,GAAQowB,GAAoB9vB,UAAW,UAGnCN,GAAQowB,IAEXlrB,OAGF0qB,EAAAz1C,UAAAgpC,SAAP,WACE,IAAMjzB,KACA1O,EAAAvH,KAAA41C,OAACK,EAAA1uC,EAAA0uC,QAASE,EAAA5uC,EAAA4uC,kBAAmBh4C,EAAAA,EAAAA,WAAmBk4C,EAAA9uC,EAAA8uC,QAAS/wC,EAAAiC,EAAAjC,KAAMmH,EAAAlF,EAAAkF,OAAQ6pB,EAAA/uB,EAAA+uB,OAAQxL,EAAAvjB,EAAAujB,GAGrF,GAAIwL,GAAU6f,EAAmB,CAC/B,IAAMlgB,EAAiBkgB,EAAoBpwB,GAAQowB,GAAoB9vB,UAAW,aAASviB,EAEvFqyC,EAAkBxjC,KAGpBsD,EAAU7Y,MACR4W,KAAM,UACNsS,KAAM,IACJP,GAAQowB,GAAoB7vB,KAAM,UAClC,IACAP,GAAQowB,GAAoB7vB,KAAM,QAASD,UAAW,QACtD,MACFyE,GAAImL,IAIRhgB,EAAU7Y,MACR4W,KAAM,SACN7V,MAAKknB,EACL4F,QAASorB,EACTn0C,IAAK+zB,EACLx3B,OAAQ,QACRsC,MAAO,IAcX,OATAkV,EAAU7Y,MACR4W,KAAM,QACNiX,QAASjrB,KAAKy2C,mBAAmB53C,OAAOo3C,GACxC93C,MAAKknB,EACL/f,KAAIA,EACJwlB,GAAEA,EACFre,OAAMA,IAGDwJ,GAEX0/B,EAxLA,CAA+B7O,IC7DlB4P,GAAqB,SAgClC,SAAAC,GAAuBhyC,GACrB,GAAIA,aAAgBwtC,GAClB,GAA2B,IAAvBxtC,EAAK4iC,eAAyB5iC,EAAK2pC,SAAS,aAAcxG,GAWvD,EAaX,SAAA8O,EAA6BjyC,GAC3B,GAAIA,aAAgBmjC,IAAcnjC,EAAKqP,OAASkmB,IACnB,IAAvBv1B,EAAK4iC,cAAqB,CAC5B,IAAM9N,EAAQ90B,EAAK2pC,SAAS,GAEtB7U,aAAiB0Y,KACrB1Y,EAAMmO,iBACNgP,EAAoBjyC,KAlBtBiyC,CAAoBjyC,EAAKi9B,MAAM0H,UAAUxP,KAAKllB,MAGjB1N,EAAQvC,EAAK2pC,SAASxwC,KA7CnCk6B,EA6CoDrzB,EA5CxE,SAAAuiC,EAAeviC,GACb,KAAMA,aAAgBwtC,IAAY,CAChC,IAAM0E,EAAOlyC,EAAKuiC,QAElB,GAAI2P,aAAgB/O,GAAY,CAC9B,IAAMgP,EAAUJ,GAAqBG,EAAKvO,YAC1CuO,EAAKrO,UAAUsO,GAEf9e,EAAM4J,MAAM0H,UAAUxP,KAAKid,YAAYD,GAAWD,OACzCA,aAAgB1F,IAAiB0F,aAAgBlB,KAC1DkB,EAAK3E,cAAcla,EAAM77B,QAI3B,OAFA+K,EAAQvC,EAAK2pC,SAASxwC,IAAIopC,IAAQne,QAAQ,SAAC9rB,GAAoB,OAAAA,EAAE8H,OAAS8xC,KAElEA,GAGV,OAAO3vC,EAAQvC,EAAK2pC,SAASxwC,IAAIopC,QA4B1Bne,QAAQ,SAAAlsB,GAAK,OAAAA,EAAEkI,OAASJ,EAAKi9B,MAAM0H,UAAUxP,KAAKllB,WAjBkB,CAGzE,IAAM6kB,EAAQ90B,EAAK2pC,SAAS,IAExB7U,aAAiB0X,IAAiB1X,aAAiBkc,KACrDlc,EAAMyY,cAAcvtC,EAAKxI,QAG3Bs9B,EAAMmO,iBACN+O,GAAchyC,QAUhBA,EAAK2pC,SAASvlB,QAAQ4tB,IAjD1B,IAAsB3e,EAqEtB,SAAAgf,GAAgCryC,GAG1BA,aAAgBquC,IAAqB/rC,EAAMmB,GAAKzD,EAAKmC,QAAS,SAAA1F,GAAK,OAAM,OAANA,KACrEuD,EAAK+iC,SAIH/iC,aAAgBmjC,KAAenjC,EAAK4jC,cACtC5jC,EAAK+iC,SAGP/iC,EAAK2pC,SAASvlB,QAAQiuB,IAMxB,SAAAC,GAAmBC,GACjB,IAAMC,KAUN,OADAD,EAAMnuB,QARN,SAAAquB,EAAgBzyC,GACa,IAAvBA,EAAK4iC,cACP4P,EAAO/5C,KAAKuH,GAEZA,EAAK2pC,SAASvlB,QAAQquB,KAKnBD,cC3FwBvV,GAC3ByL,GAAYzL,GAOlB,SAA8BA,GAC5B,IAAM8Q,EAAS9Q,EAAMyV,gBACfC,EAA4C1V,EAAM0H,UAAUoJ,OAElE6E,GAAUD,GAAsBvuB,QAAQ,SAACpY,GACvC,IAAM6mC,EAAiB9E,EAAO/hC,GACxB8mC,EAAkBD,EAAiBA,EAAerrC,YAASrI,EAE3D29B,EAiGV,SAAsCG,EAAkBjxB,GACtD,IAAMiG,EAAYgrB,EAAMoB,kBAAkBryB,GAASswB,IAAI,QAEjD90B,EArBR,SAAqCA,EAAgBiL,EAA4BR,EAAsB8gC,GACrG,GAAe,iBAAXvrC,EAA2B,CACvB,IAAA5E,EAAAowC,GAAAvgC,EAAAR,GAACxL,EAAA7D,EAAA6D,MAAOwsC,EAAArwC,EAAAqwC,OACd,IAAIxsC,EAEF,YADAmQ,GAASq8B,QAGN,QAAe9zC,IAAXqI,GAAwBurC,EAAYG,sBAAuB,CAE7D,IAAAzsC,EAAAusC,GAAAvgC,EAAAR,GAAAxL,MACP,GAAIA,EACF,MAAO,eAIX,OAAOe,EAMQ2rC,CAA4BlW,EAAM8P,YAAY/gC,GAAUixB,EAAMxqB,SAASzG,GAAUiG,EAAWgrB,EAAMlb,OAAO9Z,OACpHT,IAAWy1B,EAAM8P,YAAY/gC,KAC/BixB,EAAMyV,gBAAgB1mC,GAAQvQ,KACzBwhC,EAAMyV,gBAAgB1mC,IACzBxE,OAAMA,KAKV,GAAgB,MAAZwE,GAAmBixB,EAAMpZ,gBAAgB,MAC3C,OAAIoZ,EAAMpZ,gBAAgB,KACjBuvB,GAAyBnhC,EAAWzK,EAAQy1B,EAAO,KAAK/iC,OAAOk5C,GAAyBnhC,EAAWzK,EAAQy1B,EAAO,OAElHmW,GAAyBnhC,EAAWzK,EAAQy1B,EAAO,MAEvD,GAAgB,MAAZjxB,GAAmBixB,EAAMpZ,gBAAgB,MAClD,OAAIoZ,EAAMpZ,gBAAgB,KACjBuvB,GAAyBnhC,EAAWzK,EAAQy1B,EAAO,KAAK/iC,OAAOk5C,GAAyBnhC,EAAWzK,EAAQy1B,EAAO,OAElHmW,GAAyBnhC,EAAWzK,EAAQy1B,EAAO,MAG9D,OAAOmW,GAAyBnhC,EAAWzK,EAAQy1B,EAAOjxB,GA1HxCqnC,CAAsBpW,EAAOjxB,GACvCsnC,EAAiBX,EAAqB3mC,GAe5C,GAdAsnC,EAAexW,QAAUA,EAErBrR,GAAkBqnB,IAOpBQ,EAAepM,IAAI,aACjBvjB,OAAQ4vB,GAAmBC,EAAUV,KACpC,GAGD7V,EAAM0H,UAAUxP,KAAKse,UAAW,CAGlC,IADA,IAAIC,EAAqBzW,GACjBsJ,GAAamN,IAAgBA,EAAYtzC,QAC/CszC,EAAcA,EAAYtzC,OAG5B,IAAMwuB,EAAU8kB,EAAY/O,UAAU/V,QAAQ3mB,MAAM+D,GAEpD,GAAgB,WAAZ4iB,EACF,IAAqB,IAAAptB,EAAA,EAAAmyC,EAAA7W,EAAAt7B,EAAAmyC,EAAAp7C,OAAAiJ,IAAS,CAAzB,IAAMgG,EAAMmsC,EAAAnyC,GAEX22B,GAAgB3wB,KAElBA,EAAO2tB,KAAO4c,GAAqBvqC,EAAO2tB,KAAK77B,QAAQy4C,GAAoB,SA5CnF6B,CAAqB3W,GAoDzB,SAAiCA,GAC/B,IAAoB,IAAAz7B,EAAA,EAAAoB,EAAAq6B,EAAM0M,SAANnoC,EAAAoB,EAAArK,OAAAiJ,IAAgB,CAA/B,IAAMszB,EAAKlyB,EAAApB,GACdqyC,GAAiB/e,GAGnB,IAAM6d,EAA4C1V,EAAM0H,UAAUoJ,OAElE6E,GAAUD,GAAsBvuB,QAAQ,SAACpY,GAIvC,IAHA,IAAI8wB,EACAgX,EAAY,KAEItyC,EAAA,EAAAoB,EAAAq6B,EAAM0M,SAANnoC,EAAAoB,EAAArK,OAAAiJ,IAAgB,CAA/B,IAAMszB,EAAKlyB,EAAApB,GACRuyC,EAAiBjf,EAAM6P,UAAUoJ,OAAO/hC,GAC9C,GAAI+nC,EAAgB,CAEhBjX,OADc39B,IAAZ29B,EACQiX,EAAejX,QAEfA,EAAQ5iC,OAAO65C,EAAejX,SAG1C,IAAMkX,EAAKD,EAAezX,IAAI,aAC1BwX,GAAaE,GAAMF,EAAUnwB,SAAWqwB,EAAGrwB,QAC7C/M,GAAS,gFAEXk9B,EAAYE,GAIhBrB,EAAqB3mC,GAAS8wB,QAAUA,EAEpCgX,GACFnB,EAAqB3mC,GAASk7B,IAAI,YAAa4M,GAAW,KAjF5DG,CAAwBhX,GAgJ5B,SAAAmW,GAAkCnhC,EAAsBzK,EAAgBy1B,EAAkBjxB,GACxF,IAAMyG,EAAWwqB,EAAMxqB,SAASzG,GAEhC,GAAIxE,GAAqB,iBAAXA,IAA8BikB,GAAkBjkB,GAAS,CAC9D,IAAA6H,EAAAoD,EAAApD,KAAMqI,EAAAjF,EAAAiF,SACb,MAAa,aAATrI,GAAuBqI,EAZ/B,SAAkClQ,EAAa6H,EAAYqI,GACzD,OAAOlQ,EAAOrO,IAAI,SAAA+F,GAEhB,OAAQykB,OAAQ,UADHJ,GAAUrkB,GAAIwY,SAAQA,EAAErI,KAAIA,IACX,OAUrB6kC,CAAsD1sC,EAAQ6H,EAAMqI,IAGrElQ,GAGV,IAAMopB,EAAQqM,EAAMrM,MACpB,GAAIA,GAAS5kB,IAAY4kB,EAAME,aAC7B,MAAoB,cAAjBF,EAAM9oB,SACE,EAAG,MAKZqtB,KAFIA,EAAO8H,EAAMwO,gBAAgBlW,IAGjC/7B,MAAOyjC,EAAM7b,QAAQpV,GAAUqV,OAAQ,YAEvC8T,KAAIA,EACJ37B,MAAOyjC,EAAM7b,QAAQpV,GAAUqV,OAAQ,UAI3C,IAAM1gB,EAAOqM,GAAehB,GAwE9B,SAA2BixB,EAAkBjxB,EAAuBiG,GAClE,IAAKoY,GAAkBpY,GACrB,OAGF,IAAMQ,EAAkCwqB,EAAMxqB,SAASzG,GACjDrL,EAAO8R,EAAS9R,KAGtB,GAAI86B,GAAY96B,GACd,OACEI,GAAI,MACJvH,MAAO8qC,GAAoB7xB,EAAUzG,GACrCL,MAAO,aAKX,GAAIi6B,GAAYjlC,GAEd,OAAAlF,KACKkF,EACCA,EAAKnH,OAASA,MAAO26C,GAAwBxzC,EAAKnH,YAI1D,GAAa,eAATmH,EACF,OACEI,GAAI,MACJvH,MAAOyjC,EAAM7b,QAAQpV,GACrBL,MAAO,cAIX,GAAIyoC,GAAe,iBAAaj1C,GAAoCwB,GAClE,OAAO,EAIT,OA/GuC0zC,CAAWpX,EAAOjxB,EAASiG,QAAa9S,EAE/E,GAAe,iBAAXqI,EAA2B,CAC7B,IAAM2tB,EAAO8H,EAAMwO,gBAAgBlW,IAC5B/7B,EAAAA,EAAAA,MACP,QACE27B,KAAIA,EACJ37B,MAAO4nB,IAAS5nB,MAAKknB,EAAE1Z,UAAW,UAElCmuB,KAAIA,EACJ37B,MAAO4nB,IAAS5nB,MAAKknB,EAAE1Z,UAAW,UAE/B,IAAIyL,EAASzE,IA2Cb,OAAIrN,IAIPw0B,KAAMmf,GAAe3zC,GAAQs8B,EAAMwO,gBAAgBlW,IAAQ0H,EAAMwO,gBAAgBjW,IACjFh8B,MAAOyjC,EAAM7b,QAAQpV,GACrBrL,KAAMA,MAINw0B,KAAM8H,EAAMwO,gBAAgBlW,IAC5B/7B,MAAOyjC,EAAM7b,QAAQpV,KArDvB,GAAIse,GAAWrY,GAAY,CACzB,IAAM0R,EAASsZ,EAAM6C,QAAWre,GAAYhP,EAASzE,KAAI,IAAIyE,EAASjZ,MAAK,SAC3E,QAASmqB,OAAQ,YAAYA,EAAM,WAAWA,EAAM,WAAWA,EAAM,UAAUA,EAAM,WAGvF,OAAI0G,GAAkBpY,KAMlBkjB,KAAMmf,GAAe3zC,GAAQs8B,EAAMwO,gBAAgBlW,IAAQ0H,EAAMwO,gBAAgBjW,IAEjFh8B,MAAOyjC,EAAM7b,QAAQpV,EAASqwB,GAAiB5pB,EAAUzG,IAAY0V,UAAW,aAEhF/gB,MAAe,IAATA,GAAkBilC,GAAYjlC,GAGhCA,GAFFnH,MAAOyjC,EAAM7b,QAAQpV,MACrBjL,GAAI,SAIQ,MAAZiL,GAA+B,MAAZA,IAgBnBmpB,KAAM8H,EAAMwO,gBAAgBlW,IAC5B/7B,MAAOyjC,EAAM7b,QAAQpV,QAhBnBiC,GAAYwE,EAASzE,MAAQyE,EAASzE,IAAI4X,QACpCnT,EAASzE,IAAI4X,UAKrBuP,KAFIA,EAAO8H,EAAMwO,gBAAgBlW,IAGjC/7B,MAAOyjC,EAAM7b,QAAQpV,QAErBmpB,KAAIA,EACJ37B,MAAOyjC,EAAM7b,QAAQpV,GAAU0V,UAAW,UA8EpD,SAAAsxB,GAAyCvgC,EAA4BR,GACnE,OAAKQ,EAASzL,UAOTG,GAAuBsL,EAASzL,WAOf,iBAAlByL,EAASpD,MACO,QAAd4C,GAEAxL,OAAO,EACPwsC,OAAQp8B,GAAY/C,+BAA+BrB,KAKjDhM,OAAO,IAdXA,OAAO,EACPwsC,OAAQp8B,GAAYhD,uCAAuCpB,EAASzL,aARpEP,OAAO,EACPwsC,OAAQp8B,GAAYjD,wCAAwCnB,IAqHlE,SAAAu7B,GAAmCxmC,GACjC,GAAI2wB,GAAgB3wB,IAAWxO,EAASwO,EAAOhO,OAC7C,OAAOgO,EAAOhO,MACT,GhCnOT,SAAuCgO,GACrC,OAAK7O,EAAQ6O,IACJ,WAAYA,KAAY,SAAUA,GgCiOhC+sC,CAAuB/sC,GAAS,CAEzC,IADA,IAAIhO,OAAK,EACoBgI,EAAA,EAAAoB,EAAA4E,EAAOhQ,OAAPgK,EAAAoB,EAAArK,OAAAiJ,IAAe,CAAvC,IAAMgzC,EAAc5xC,EAAApB,GACvB,GAAI22B,GAAgBqc,IAAmBx7C,EAASw7C,EAAeh7C,OAC7D,GAAKA,GAEE,GAAIA,IAAUg7C,EAAeh7C,MAElC,OADAod,GAAS,+KACFpd,OAHPA,EAAQg7C,EAAeh7C,MAQ7B,OADAod,GAAS,6QACFpd,EACF,OhC1OT,SAAsCgO,GACpC,OAAK7O,EAAQ6O,IACJ,WAAYA,GAAU,SAAUA,EgCwO9BitC,CAAsBjtC,IAC/BoP,GAAS,6KAEF5d,EADDQ,EAAQgO,EAAOhQ,OAAO,IACHgC,OAAQ2F,QAH5B,EAST,SAAA8uC,GAA+BhR,EAAcjxB,GAc3C,OAnIF,SAA6B8wB,GAC3B,IAAM4X,EAAgBC,GAAY7X,EAAQ3jC,IAAI,SAAAqO,GAE5C,OAAI2wB,GAAgB3wB,IACXA,EAAA7G,KAAU9E,EAAA2L,GAAA,UAGZA,IACLgsC,GAEEoB,EAAuBD,GAAY7X,EAAQ3jC,IAAI,SAAA8B,GACnD,GAAIk9B,GAAgBl9B,GAAI,CACtB,IAAMzC,EAAIyC,EAAE0F,KAWZ,YAVUxB,IAAN3G,GAAoB87C,GAAe97C,KACxB,UAATA,EAAEuI,WAEGvI,EAAEgB,MAEK,cAAZhB,EAAEmT,cAEGnT,EAAEmT,OAGNnT,KAGR2J,OAAO,SAAA3J,GAAK,YAAM2G,IAAN3G,IAAkBg7C,GAEjC,GAA6B,IAAzBkB,EAAcn8C,OAAc,CAE9B,GAAI4/B,GADE3wB,EAASs1B,EAAQ,KACQ8X,EAAMr8C,OAAS,EAAG,CAC/C,IAAIs8C,EAAOD,EAAM,GAKjB,OAJIA,EAAMr8C,OAAS,IACjBqe,GAASC,GAAY9B,oBACrB8/B,GAAO,GAETp5C,KACK+L,GACH7G,KAAIk0C,IAGR,OAAOrtC,EAIT,IAAMstC,EAAcH,GAAYC,EAAMz7C,IAAI,SAAAX,GACxC,OAAU,IAANA,EACKA,EAEI,UAATA,EAAEuI,GACGvI,GAEToe,GAASC,GAAYhC,kBAAkBrc,KAChC,KACLg7C,GAEA7yC,OAAyBxB,EAEF,IAAvB21C,EAAYv8C,OACdoI,EAAOm0C,EAAY,GACVA,EAAYv8C,OAAS,IAC9Bqe,GAASC,GAAY9B,oBACrBpU,GAAO,GAGT,IASQ6G,EATFutC,EAAUJ,GAAY7X,EAAQ3jC,IAAI,SAAA8B,GACtC,OAAIk9B,GAAgBl9B,GACXA,EAAEk6B,KAEJ,OACL,SAAAj8B,GAAK,OAAAA,IAET,OAAuB,IAAnB67C,EAAQx8C,QAA+B,OAAfw8C,EAAQ,GAE5BvtC,EAAM/L,GACV05B,KAAM4f,EAAQ,GACdv9C,OAAQk9C,EAAcv7C,IAAI,SAAA8B,GAAK,OAACA,EAAgBzB,SAC5CmH,GAAQA,KAAIA,OAMpBlF,GAAQjE,OAAQk9C,GAAmB/zC,GAAQA,KAAIA,OAgDxCq0C,CAbgB/X,EAAM0H,UAAUoJ,OAAO/hC,GACf8wB,QAAQ3jC,IAAI,SAAAqO,GAQzC,OAHI2wB,GAAgB3wB,KAClBA,EAAO2tB,KAAO8H,EAAMiO,iBAAiB1jC,EAAO2tB,OAEvC3tB,KC1cX,SAAAytC,GAAuChY,GACnC,OAAOx8B,GAAKw8B,EAAM0H,UAAUoJ,QAAQhwB,OAAO,SAACgwB,EAAmB/hC,GAC7D,IAAMoyB,EAAiBnB,EAAM0H,UAAUoJ,OAAO/hC,GAC9C,GAAIoyB,EAAe5K,OAEjB,OAAOua,EAGT,IAAM9lC,EAAQm2B,EAAenE,UAGxB6Z,EAAA7rC,EAAA6rC,UAAWnoB,EAAA1jB,EAAA0jB,MACTl0B,EAAAwQ,EAAAxQ,KAAM4X,EAAApH,EAAAoH,KAAgC6lC,GAA1BjtC,EAAA6rC,UAAe7rC,EAAA0jB,MAAW9vB,EAAAoM,GAAA,OAAA,OAAA,YAAA,WAsB7C,OApBA0jB,EAwBN,SAAmCwpB,EAAqBtZ,EAAmBoB,EAAcjxB,GAEvF,GAAgB,MAAZA,GAA+B,MAAZA,EAAiB,CACtC,GAAIksB,GAAcid,GAEhB,OACEhyB,MAAOQ,OAAQkY,EAAY,UAExB,GAAIljC,EAAQw8C,IAAqC,IAAtBA,EAAW58C,OAAc,CACzD,IAAM68C,EAAKD,EAAW,GAChB1wB,EAAK0wB,EAAW,GACtB,GAAW,IAAPC,GAAYnK,GAAcxmB,GAE5B,OAAQ,GAAId,OAAQsZ,EAAMoY,YAAY5wB,EAAGd,UACpC,GAAIsnB,GAAcmK,IAAc,IAAP3wB,EAE9B,QAASd,OAAQsZ,EAAMoY,YAAYD,EAAGzxB,SAAU,IAItD,OAAOwxB,EA5CKG,CAAmB3pB,EAAOl0B,EAAMwlC,EAAOjxB,GAM3C8nC,GCsNV,SAAqCA,GACnC,OAAOA,EAAUnwB,OAAO5nB,QAAQw3C,KAAqB,EDvNhCgC,CAAqBzB,KACpCA,ECwNR,SAAqC7W,EAAc6W,GACjD,IAAM0B,EAAYp8C,KAAKyK,MAAMiwC,EAAUnwB,OAAOrqB,QAAQi6C,GAAkB,KAClE97C,EAAOsM,GAAQyxC,EAAU/vB,WAE3BgwB,EAAUxY,EAAM0H,UAAUlf,WAAawX,EAAM0H,UAAUlf,UAAUhuB,GACrE,IAAIg+C,EAWF,OARAA,EAAUxY,EAAMyY,sBAAsBj+C,EAAM+9C,EAAU/vB,WACjD+vB,EAAU3sC,UAAa2sC,EAAUh8C,QACpCg8C,EAAUh8C,MAAQi8C,EAAQE,QAAQ,GAAGn8C,MACjCi8C,EAAQE,QAAQp9C,OAAS,GAC3B2X,GAAK,sGACaxW,EAAY87C,EAAUh8C,OAAM,OAIhDmqB,OAAQiyB,GAASH,EAAQpmC,MAAM09B,YAC7B,IAAIrzC,EAAYjC,EAAOo+C,IAAM,KAAKn8C,EAAY87C,EAAU3sC,UAAY,MAAK,KACvEnP,EAAY87C,EAAUh8C,OAAS,OACV,WAApBi8C,EAAQ7mB,QAAuB,IAAM,KAAKl1B,EAAY+7C,EAAQ7mB,SAAQ,MAd7E1e,GAAK,2FAkBP,OAAQyT,OAAQ,QDhPEmyB,CAAqB7Y,EAAO6W,IAI1C/F,EAAOt1C,KAAIgD,GACThE,KAAIA,EACJ4X,KAAIA,EACJ7H,OAAQymC,GAAehR,EAAOjxB,IAC1B8nC,GAAaA,UAASA,OAC1BnoB,MAAOA,GACJupB,IAGEnH,OE1Cb,IAAAgI,GAAA,SAAA3S,GAKE,SAAA2S,EAAYt+C,EAAcu+C,GAA1B,IAAA1S,EACEF,EAAAhpC,KAAAiB,SAEG5D,KAAIA,KACN4D,YARIioC,EAAA9P,QAAS,EAET8P,EAAAxG,WAOLwG,EAAK2D,gBAAgB,OAAQ+O,KAEjC,OAZoCvS,EAAAA,EAAAA,GAYpCsS,EAZA,CAAoCjP,ICgBvBmP,IAAqC,QAAS,YAAa,UAGxE,SAAAC,GAAgCjZ,GAC1ByL,GAAYzL,GAOlB,SAA6BA,GAC3B,IAAM0V,EAA4C1V,EAAM0H,UAAUoJ,OAGlEhhC,GAAeqX,QAAQ,SAACpY,GACtB,IAAMsnC,EAAiBX,EAAqB3mC,GAC5C,GAAKsnC,EAAL,CAGA,IAAM6C,EAAkBlZ,EAAMoB,kBAAkBryB,GAG1C6mC,EAAiB5V,EAAMyV,gBAAgB1mC,GACvCyG,EAAWwqB,EAAMxqB,SAASzG,GAG1Bo6B,EAAuB,MAAZp6B,EAAkB,QAAsB,MAAZA,EAAkB,cAAW7M,EACtEi3C,EAAgBhQ,IAAanJ,EAAM0H,UAAU0B,WAAW/J,IAAI8J,QAAYjnC,EAEtE8S,EAAYkkC,EAAgB7Z,IAAI,QAGhC3R,EAAYypB,GAAe,QAAS,QAASniC,MAAgB4gC,EAAeloB,UAC9Eyb,GAAYnJ,EAAM8N,MAAQqL,GAAiBzrB,IAC7C/T,GAASC,GAAYrG,gCACrB4lC,GAAgB,GAGlB,IAAMC,EAWV,SAAwBpZ,GACtB,IAAMoZ,KAEAC,EAASrZ,EAAMoB,kBAAkB,KACjCkY,EAASD,GAAUA,EAAOha,IAAI,SAChCia,GAAUre,GAAcqe,IAAW37C,EAAS27C,EAAOpzB,OACrDkzB,EAAa59C,KAAK89C,EAAOpzB,MAG3B,IAAMqzB,EAASvZ,EAAMoB,kBAAkB,KACjCoY,EAASD,GAAUA,EAAOla,IAAI,SAChCma,GAAUve,GAAcue,IAAW77C,EAAS67C,EAAOtzB,OACrDkzB,EAAa59C,KAAKg+C,EAAOtzB,MAG3B,OAAOkzB,EA1BgBK,CAAezZ,GAE9B0Z,EA8BV,SACI3qC,EAAkBiG,EAAsB5C,EAAYwjC,EAAuB9wB,EAC3EoK,EAAejf,EAAYkpC,EAAwBrQ,EAAoBsQ,GAOzE,IAJA,IAAMO,EAAcR,GAA8C,OAA7BvD,EAAeloB,UAI7BnpB,EAAA,EAAAq1C,EAAAZ,GAAAz0C,EAAAq1C,EAAAt+C,OAAAiJ,IAAkB,CAApC,IAAMgT,EAAQqiC,EAAAr1C,GACjB,QAAiCrC,IAA7B0zC,EAAer+B,GAAyB,CAC1C,IAAMsiC,EAAuB9pB,GAAyB/a,EAAWuC,GAC3DuiC,EAAyB9pB,GAAoCjhB,EAASwI,GAC5E,GAAKsiC,EAEE,GAAIC,EACTngC,GAASmgC,QAET,OAAQviC,GACN,IAAK,QACH,OAAOq6B,GAAagE,EAAer+B,IACrC,IAAK,SACH,OAAOq6B,GAAamI,GAAYnE,EAAer+B,KACjD,IAAK,YACH,IAAMmW,EAAYkoB,EAAer+B,GACjC,GAAkB,OAAdmW,EAAoB,CACtB,IAAKyrB,EACH,OAAOvH,IAAc1rB,KAAMwH,IAG3B/T,GAASC,GAAY7C,iBAAiBhI,UAhB9C4K,GAASC,GAAYzC,kCAAkCnC,EAAWuC,EAAUxI,KAuBlF,OAAOs7B,GAsBT,SACEt7B,EAAkBiG,EAAsB5C,EAAY0S,EAAgBoK,EAAejf,EACnF64B,EAAoBsQ,EAAwBO,GAE5C,OAAQ5qC,GACN,KAAKzC,GACL,KAAKC,GACH,GAAI4qC,GAAe,QAAS,QAASniC,KAAe2kC,EAClD,GAAI5qC,IAAYzC,IAAc,SAAT2D,GACnB,GAAI6U,EAAO9Z,MAAMyiB,eACf,OAAQvH,KAAMpB,EAAO9Z,MAAMyiB,qBAG7B,GAAI3I,EAAO9Z,MAAM0iB,UACf,OAAQxH,KAAMpB,EAAO9Z,MAAM0iB,WAYjC,OAAI3e,IAAYxC,IAAK+gB,GAAoBtY,KAE9B0R,OAAQoiB,GAAa,IAEtB,GAAIpiB,OAAQoiB,IAExB,KAAK57B,GAEH,IAAM8sC,EAqBZ,SAAsB/pC,EAAYif,EAAepK,GAC/C,GAAIoK,EACF,OAAO,EAET,OAAQjf,GACN,IAAK,MACL,IAAK,OACH,OAAO6U,EAAO9Z,MAAM8iB,YACtB,IAAK,OACL,IAAK,QACL,IAAK,OACH,OAAOhJ,EAAO9Z,MAAMojB,eACtB,IAAK,OACH,OAAOtJ,EAAO9Z,MAAM+iB,YACtB,IAAK,QACL,IAAK,SACL,IAAK,SACH,OAAOjJ,EAAO9Z,MAAMmjB,QAIxB,MAAM,IAAIvzB,MAAMgf,GAAYhE,oBAAoB,OAAQ3F,IA1CnCgqC,CAAahqC,EAAMif,EAAMpK,GACpCo1B,EA4CZ,SAAsBjqC,EAAYmpC,EAAwBt0B,GACxD,IAAMgxB,EAAchxB,EAAO9Z,MAC3B,OAAQiF,GACN,IAAK,MACL,IAAK,OACH,YAAiC/N,IAA7B4iB,EAAO9Z,MAAMmvC,YACRr1B,EAAO9Z,MAAMmvC,YAEfC,GAAehB,EAAct0B,EAAO9Z,OAAS,EACtD,IAAK,OACL,IAAK,QACL,IAAK,OACH,OAAO8Z,EAAO9Z,MAAMqjB,eACtB,IAAK,OACH,OAAOvJ,EAAO9Z,MAAMgjB,YACtB,IAAK,QACL,IAAK,SACL,IAAK,SACH,GAAIlJ,EAAO9Z,MAAMqvC,QACf,OAAOv1B,EAAO9Z,MAAMqvC,QAItB,IAAMC,EAAYF,GAAehB,EAActD,GAC/C,OAAQwE,EAAY,IAAMA,EAAY,GAI1C,MAAM,IAAI1/C,MAAMgf,GAAYhE,oBAAoB,OAAQ3F,IAxEnCsqC,CAAatqC,EAAMmpC,EAAct0B,GAClD,OAAQk1B,EAAUE,GACpB,KAAKjtC,GACH,MAAO,SACT,KAAKH,GACL,KAAKC,GACL,KAAKC,GACH,MAAkB,YAAdgI,EAEc,YAAT5C,EAAqB,WAAa,UAE3B,SAATnC,GAA4B,aAATA,EAAsB,UAAY,OAC9D,KAAK9C,GAEH,OAAQ2X,EAAO9Z,MAAMijB,WAAYnJ,EAAO9Z,MAAMkjB,YAGlD,MAAM,IAAItzB,MAAM,qCAAqCmU,GAzEnDyrC,CACEzrC,EAASiG,EAAW5C,EAAM0S,EAC1BoK,EAAMjf,EAAM64B,EAAYsQ,EAAcO,IAtEdc,CACxB1rC,EAASiG,EAAWQ,EAASpD,KAAMwjC,EAAgB5V,EAAMlb,OACzDuxB,EAAehX,IAAI,QAASW,EAAM/vB,KAAMkpC,EAAenZ,EAAM6C,QAAQsG,GAAWiQ,GAGlF/C,EAAerM,gBAAgB,QAAS0P,MAzCxCgB,CAAoB1a,GAEpB2a,GAA0B3a,EAAO,SA6GrC,SAAA+Z,GAAqBxrB,GACnB,GAAID,GAAiBC,GAAS,CAC5B,IAAM9uB,GAAe8uB,OAAQA,EAAO/zB,MAOpC,OANI+zB,EAAO9lB,QACThJ,EAAEgJ,MAAQ8lB,EAAO9lB,OAEf8lB,EAAO5F,SACTlpB,EAAEkpB,OAAS4F,EAAO5F,QAEblpB,EAET,OAAQ8uB,OAAQA,GAoHlB,SAAA6rB,GAAwBhB,EAAwBtD,GAC9C,OAAIsD,EAAa99C,OAAS,EACjBknB,KAAK1Z,IAAIzL,MAAM,KAAM+7C,GAE1BtD,EAAYpoB,UACPooB,EAAYpoB,UAEd,eCvQ0BsS,EAAczoB,GAC3Ck0B,GAAYzL,GAOlB,SAAgCA,EAAkBzoB,GAChD,IAAMm+B,EAA4C1V,EAAM0H,UAAUoJ,OAElEttC,GAAKkyC,GAAsBvuB,QAAQ,SAACpY,GAClC,IAAM6mC,EAAiB5V,EAAMyV,gBAAgB1mC,GACvCsnC,EAAiBX,EAAqB3mC,GACtCmqC,EAAkBlZ,EAAMoB,kBAAkBryB,GAC1CyG,EAAWwqB,EAAMxqB,SAASzG,GAC1B+V,EAASkb,EAAMlb,OAEf8e,EAAiBgS,EAAer+B,GAChCqjC,EAAQ1B,EAAgB7Z,IAAI,QAE5Bwa,EAAuB9pB,GAAyB6qB,EAAOrjC,GACvDuiC,EAAyB9pB,GAAoCjhB,EAASwI,GAU5E,QARuBrV,IAAnB0hC,IAEGiW,EAEMC,GACTngC,GAASmgC,GAFTngC,GAASC,GAAYzC,kCAAkCyjC,EAAOrjC,EAAUxI,KAKxE8qC,QAAmD33C,IAA3B43C,EAC1B,QAAuB53C,IAAnB0hC,EAEFyS,EAAelM,kBAAkB5yB,EAAUq+B,OACtC,CACL,IAAMz2C,EAiBd,SACEoY,EAAuBxI,EAAkByG,EACzCR,EAAsB6lC,EAAsBC,EAC5CjF,EAAkChf,EAAkB/R,GACpD,IAAMgxB,EAAchxB,EAAO9Z,MAG3B,OAAQuM,GACN,IAAK,OACH,OAyDN,SAAqBvC,EAAsBjG,EAAkByG,GAC3D,GAAIA,EAASzE,KAAOomC,GAAe3sB,GAAUc,KAAMd,GAAUpI,KAAMpN,GACjE,OAEF,OAAOmiC,GAAe7qC,GAAGC,IAAIwC,GA7DlB+f,CAAK9Z,EAAWjG,EAASyG,GAClC,IAAK,UACH,OA8DN,SAAwBzG,EAAkBiG,EAAsB8gC,EAA0BtgC,EAA4BqhB,EAAkBkkB,GACtI,GAAI5D,GAAe7qC,GAAGC,IAAIwC,GAAU,CAClC,GAAIwe,GAAyBvY,GAAY,CACvC,QAAsC9S,IAAlC4zC,EAAYkF,kBACd,OAAOlF,EAAYkF,kBAGd,IAAA5oC,EAAAykB,EAAAzkB,KAAMjH,EAAA0rB,EAAA1rB,OACb,GAAa,QAATiH,IAAmBoD,EAASzE,MAEhB,aAAX5F,GAAqC,MAAZ4D,GACd,eAAX5D,GAAuC,MAAZ4D,GAE5B,OAAOgsC,EAAUloC,mBAKvB,GAAImC,IAAcwV,GAAUlZ,MAC1B,OAAOwkC,EAAYnoB,aAGvB,OApFW9C,CAAQ9b,EAASiG,EAAW8gC,EAAatgC,EAAUqhB,EAAS/R,EAAOtU,KAC5E,IAAK,eACH,OAqFN,SAA6ByqC,EAAsBlsC,EAAkB+mC,GACnE,QAAqB5zC,IAAjB+4C,EAEF,OAGF,GAAI9D,GAAe7qC,GAAGC,IAAIwC,GAKxB,OAAO+mC,EAAYloB,iBAErB,OAlGWuB,CAAa0rB,EAAc9rC,EAAS+mC,GAC7C,IAAK,eACH,OAmGN,SAA6BmF,EAAsBlsC,EAAkBiG,EAAsBkmC,EAA2BpF,GACpH,QAAqB5zC,IAAjB+4C,EAEF,OAGF,GAAI9D,GAAe7qC,GAAGC,IAAIwC,IAGpBiG,IAAcwV,GAAUoB,KAC1B,YAAqC1pB,IAAjC4zC,EAAYqF,iBACPrF,EAAYqF,iBAMdD,EAAoB,EAG/B,OAvHW9rB,CAAayrB,EAAc9rC,EAASiG,EAAW8lC,EAAmBhF,GAC3E,IAAK,UACH,OAwHN,SAAwB9gC,EAAsBtR,GAC5C,GAAI4pB,GAAoBtY,IAAuB,eAATtR,EAGpC,OAAO,EAET,OA9HWirB,CAAQ3Z,EAAWQ,EAAS9R,MACrC,IAAK,OACH,OA+HN,SAAqBqL,EAAkByG,EAA4BogC,EAAwB/e,GAIzF,GAD0B+e,GAAqC,iBAAnBA,EAE1C,OAAO,EAQT,GAAgB,SAAZ7mC,GAAwC,iBAAlByG,EAASpD,KACjC,OAAO,EAKT,IAAKoD,EAASzE,KAAOomC,GAAe7qC,GAAGC,IAAIwC,GAAU,CAC5C,IAAA5D,EAAA0rB,EAAA1rB,OAAQiH,EAAAykB,EAAAzkB,KACf,OAAIrN,GAAU,MAAO,OAAQ,OAAQ,SAAUqN,MAE/B,eAAXjH,GAAuC,MAAZ4D,GAChB,aAAX5D,GAAqC,MAAZ4D,GAQhC,OAAO,EA/JImgB,CAAKngB,EAASyG,EAAUqgC,EAAiBhf,GAGpD,OAAOif,EAAYv+B,GAvCC6jC,CACZ7jC,EAAUxI,EAASyG,EACnB0jC,EAAgB7Z,IAAI,QACpB6Z,EAAgB7Z,IAAI,WACpB6Z,EAAgB7Z,IAAI,gBACpBuW,EAAerrC,OACfy1B,EAAMnJ,QAAS/R,QAEH5iB,IAAV/C,GACFk3C,EAAepM,IAAI1yB,EAAUpY,GAAO,MA5C1Ck8C,CAAuBrb,EAAOzoB,GAE9BojC,GAA0B3a,EAAOzoB,GA2ErC,SAAAojC,GAA0C3a,EAAczoB,GAGtD,IAFA,IAAMm+B,EAA4C1V,EAAM0H,UAAUoJ,OAE9CvsC,EAAA,EAAAoB,EAAAq6B,EAAM0M,SAANnoC,EAAAoB,EAAArK,OAAAiJ,IAAgB,CAA/B,IAAMszB,EAAKlyB,EAAApB,GACG,UAAbgT,EACF0hC,GAAgBphB,GAEhByjB,GAAmBzjB,EAAOtgB,GAI9B/T,GAAKkyC,GAAsBvuB,QAAQ,SAACpY,GAGlC,IAFA,IAAIwsC,EAEgBh3C,EAAA,EAAAoB,EAAAq6B,EAAM0M,SAANnoC,EAAAoB,EAAArK,OAAAiJ,IAAgB,CAA/B,IACGuyC,EADQnxC,EAAApB,GACemjC,UAAUoJ,OAAO/hC,GAC9C,GAAI+nC,EAEFyE,EAAoB7Q,GAClB6Q,EAF6BzE,EAAe/M,gBAAgBxyB,GAG5DA,EACA,QACA+yB,GAAkC,SAAC7yB,EAAIC,GACrC,OAAQH,GACN,IAAK,QAEH,OAAIE,EAAGyO,MAAQxO,EAAGwO,KACTzO,EAAGyO,KAAOxO,EAAGwO,KAEf,EAGX,OAAO,KAKfwvB,EAAqB3mC,GAASi7B,gBAAgBzyB,EAAUgkC,KCtH5D,SAAAvmC,GACEib,EAA0BlhB,EAAkByG,EAC5CvF,EAAY6lC,GAGZ,IAAM7+B,EA6BR,SACElI,EAAkByG,EAA4BvF,EAAY6lC,GAE1D,OAAQtgC,EAASpD,MACf,IAAK,UACL,IAAK,UACH,GAAItD,GAAeC,IAAkC,aAAvB+B,GAAU/B,GAItC,MAHgB,UAAZA,GAAyC,YAAlByG,EAASpD,MAClCuH,GAASC,GAAY3D,4BAA4BlH,EAAS,YAErD,UAGT,GAAIooC,GAAe,IAAK,KAAMpoC,GAAU,CACtC,GAAIooC,GAAe,OAAQ,MAAO,QAASlnC,GAGzC,MAAO,OAET,GAAa,QAATA,EACF,MAAO,OAIX,MAAO,QAET,IAAK,WACH,OAAInB,GAAeC,GACV,aACyB,aAAvB+B,GAAU/B,IACnB4K,GAASC,GAAY3D,4BAA4BlH,EAAS,aAEnD,WAEF,OAET,IAAK,eACH,OAAID,GAAeC,GACbyG,EAASzE,IACJ,cAIF,aACyB,aAAvBD,GAAU/B,IACnB4K,GAASC,GAAY3D,4BAA4BlH,EAAS,iBAEnD,WAKLyG,EAASzE,KAAmB,MAAZhC,GAA+B,MAAZA,EAC9B,aAEF,SAET,IAAK,WACL,IAAK,YACL,IAAK,UACH,OAIJ,MAAM,IAAInU,MAAMgf,GAAY9E,iBAAiBU,EAASpD,OA7F7BmT,CAAYxW,EAASyG,EAAUvF,GAExD,OAAKF,GAAehB,QAIE7M,IAAlB+tB,EAEGL,GAAwB7gB,EAASkhB,GAMjCJ,GAAyBI,EAAeza,EAASpD,KAAMoD,EAASzE,KAK9Dkf,GAJLtW,GAASC,GAAY1C,6BAA6B+Y,EAAehZ,IAC1DA,IAPP0C,GAASC,GAAY5C,4BAA4BjI,EAASkhB,EAAehZ,IAClEA,GAYJA,EAlBE,KCUX,SAAAukC,GAA+Bxb,GACzByL,GAAYzL,GACdA,EAAM0H,UAAUoJ,OASpB,SAA4B9Q,GACnB,IAAAp0B,EAAAo0B,EAAAp0B,SAAUkZ,EAAAkb,EAAAlb,OAAQ7U,EAAA+vB,EAAA/vB,KAEzB,OAAOH,GAAegR,OAAO,SAAC26B,EAAsC1sC,GAClE,IAAIyG,EACAogC,OAA+B1zC,EAE7ByhB,EAAa/X,EAASmD,GAG5B,GACE+U,GAAWH,IAAe1T,IAAS4B,IACnC9C,IAAY9B,IAAS0W,EAAWvR,OAAS2Q,GAEzC,OAAO04B,EAeT,GAZI33B,GAAWH,IACbnO,EAAWmO,EACXiyB,EAAiBjyB,EAAW3Y,OACnB6Y,GAAuBF,IAChCnO,EAAWmO,EAAWC,UACtBgyB,EAAiBjyB,EAAWC,UAAiB,OACpC7U,IAAYzC,GACrBkJ,EAAWgQ,GAAY5Z,EAASsC,IACvBa,IAAYxC,KACrBiJ,EAAWgQ,GAAY5Z,EAASuC,KAG9BqH,GAA+B,OAAnBogC,IAA8C,IAAnBA,EAA0B,CAEnE,IAAM8F,GADN9F,EAAiBA,OACyBxjC,KACpCwoC,EAAQ5lC,GAAU4gC,EAAexjC,KAAMrD,EAASyG,EAAUvF,EAAM6U,EAAO9Z,OAC7EywC,EAAgB1sC,GAAW,IAAI+pC,GAC7B9Y,EAAMpB,UAAU7vB,EAAU,IAAI,IAC7B5P,MAAOy7C,EAAO7a,SAAU2b,IAAuBd,IAGpD,OAAOa,OA/CkBE,CAAmB3b,GAE5CA,EAAM0H,UAAUoJ,OAsDpB,SAA+B9Q,GAU7B,IATA,IAAMyb,EAAuCzb,EAAM0H,UAAUoJ,UAEvD8K,KAIAjqB,EAAUqO,EAAM0H,UAAU/V,mBAGrBkG,GACT2jB,GAAe3jB,GAGfr0B,GAAKq0B,EAAM6P,UAAUoJ,QAAQ3pB,QAAQ,SAACpY,GAIpC,GAFA4iB,EAAQ3mB,MAAM+D,GAAW4iB,EAAQ3mB,MAAM+D,a3BrGTA,EAAuBixB,GACzD,GAAIuN,GAAavN,IAAUsJ,GAAatJ,GACtC,MAAO,SACF,GAAIwN,GAAcxN,IAAUyN,GAAczN,GAC/C,OAAOj7B,EAAS2K,GAAyBX,GAAW,cAAgB,SAGtE,MAAM,IAAInU,MAAM,kC2B8FuCihD,CAAoB9sC,EAASixB,GAEjD,WAA3BrO,EAAQ3mB,MAAM+D,GAAuB,CACvC,IAAM+sC,EAAoBF,EAA2B7sC,GAC/CgtC,EAAiBlkB,EAAM6P,UAAUoJ,OAAO/hC,GAASg7B,gBAAgB,QAEnE+R,EACExvB,GAAgBwvB,EAAkB38C,MAAO48C,EAAe58C,OAE1Dy8C,EAA2B7sC,GAAW27B,GACpCoR,EAAmBC,EAAgB,OAAQ,QAASC,KAItDrqB,EAAQ3mB,MAAM+D,GAAW,qBAElB6sC,EAA2B7sC,IAGpC6sC,EAA2B7sC,GAAWgtC,MAzB1Bx3C,EAAA,EAAAoB,EAAAq6B,EAAM0M,SAANnoC,EAAAoB,EAAArK,OAAAiJ,IAAc,CAA7B,IAAMszB,EAAKlyB,EAAApB,KAALszB,GAgDX,OAhBAr0B,GAAKo4C,GAA4Bz0B,QAAQ,SAACpY,GAExC,IAAMvU,EAAOwlC,EAAMpB,UAAU7vB,GAAS,GAChCgqC,EAAmB6C,EAA2B7sC,GACpD0sC,EAAgB1sC,GAAW,IAAI+pC,GAAet+C,EAAMu+C,GAGpD,IAAoB,IAAAx0C,EAAA,EAAAoB,EAAAq6B,EAAM0M,SAANnoC,EAAAoB,EAAArK,OAAAiJ,IAAgB,CAA/B,IAAMszB,EAAKlyB,EAAApB,GACR03C,EAAapkB,EAAM6P,UAAUoJ,OAAO/hC,GACtCktC,IACFpkB,EAAMqkB,YAAYD,EAAW5c,IAAI,QAAS7kC,GAC1CyhD,EAAW1lB,QAAS,MAKnBklB,EAhHoBU,CAAsBnc,GAiDnD,IAAMgc,GAAsB1R,GAC1B,SAAC8R,EAAgBC,GAAmB,OAACzvB,GAAoBwvB,GAAOxvB,GAAoByvB,KCVtF,IAAAC,GAAA,WAGE,SAAAA,IACEl+C,KAAKm+C,WAqBT,OAlBSD,EAAAh+C,UAAAk+C,OAAP,SAAcC,EAAiBvH,GAC7B92C,KAAKm+C,QAAQE,GAAWvH,GAInBoH,EAAAh+C,UAAAuF,IAAP,SAAWrJ,GACT,YAA8B0H,IAAvB9D,KAAKm+C,QAAQ/hD,IAGf8hD,EAAAh+C,UAAA+gC,IAAP,SAAW7kC,GAGT,KAAO4D,KAAKm+C,QAAQ/hD,IAASA,IAAS4D,KAAKm+C,QAAQ/hD,IACjDA,EAAO4D,KAAKm+C,QAAQ/hD,GAGtB,OAAOA,GAEX8hD,EAzBA,GAqCA,SAAA7Q,GAA4BzL,GAC1B,OAAOA,GAAwB,SAAfA,EAAM5tB,KAGxB,SAAAk3B,GAA6BtJ,GAC3B,OAAOA,GAAwB,UAAfA,EAAM5tB,KAGxB,SAAAq7B,GAA8BzN,GAC5B,OAAOA,GAAwB,WAAfA,EAAM5tB,KAGxB,SAAAo7B,GAA8BxN,GAC5B,OAAOA,GAAwB,WAAfA,EAAM5tB,KAGxB,SAAAm7B,GAA6BvN,GAC3B,OAAOA,GAAwB,UAAfA,EAAM5tB,KAGxB,IAAAsqC,GAAA,WA6BE,SAAAA,EAAYp0B,EAAgBnlB,EAAew5C,EAAyB73B,EAAgB83B,EAAyBjrB,GAA7G,I3C5CMhsB,EAAC+c,EAAAkZ,EAAmBzR,EAAAoJ,EAAoBnJ,EAAAyyB,EAAoBj0B,E2C4ClEyd,EAAAjoC,KAFyBA,KAAAsuC,YA6YlBtuC,KAAA0+C,iBAAmB,SAAC7sC,GAazB,OATIA,EAAKy4B,MAAQz4B,EAAKy4B,KAAKxQ,OACzBjoB,EAAKy4B,KAAKxQ,KAAOmO,EAAK4H,iBAAiBh+B,EAAKy4B,KAAKxQ,OAI/CjoB,EAAKy4B,MAAQz4B,EAAKy4B,KAAKtS,OAASnmB,EAAKy4B,KAAKtS,MAAM8B,OAClDjoB,EAAKy4B,KAAKtS,MAAM8B,KAAOmO,EAAK4H,iBAAiBh+B,EAAKy4B,KAAKtS,MAAM8B,OAGxDjoB,GAvZP7R,KAAK+E,OAASA,EACd/E,KAAK0mB,OAASA,EACd1mB,KAAKw+C,SAAWA,EAGhBx+C,KAAK5D,KAAO8tB,EAAK9tB,MAAQmiD,EACzBv+C,KAAK2M,MAAQhP,EAASusB,EAAKvd,QAAU7L,KAAMopB,EAAKvd,OAASud,EAAKvd,MAG9D3M,KAAK2+C,aAAe55C,EAASA,EAAO45C,aAAe,IAAIT,GACvDl+C,KAAK4+C,kBAAoB75C,EAASA,EAAO65C,kBAAoB,IAAIV,GACjEl+C,KAAK6+C,kBAAoB95C,EAASA,EAAO85C,kBAAoB,IAAIX,GAEjEl+C,KAAK85B,KAAO5P,EAAK4P,KAEjB95B,KAAK8+C,YAAc50B,EAAK40B,YACxB9+C,KAAK++C,WAAaC,GAAmB90B,EAAKjU,eAC1CjW,KAAKi/C,OAASzoB,GAAWtM,IAASuM,GAAYvM,QAAQpmB,G3C9DjDwgB,GAAD/c,E2C8DuF2iB,O3C9DtFsT,MAAAA,OAAA,IAAAlZ,OAAAxgB,EAAAwgB,EAAmByH,EAAAxkB,EAAA4tB,OAAAA,OAAA,IAAApJ,OAAAjoB,EAAAioB,EAAoBC,EAAAzkB,EAAAk3C,OAAAA,OAAA,IAAAzyB,OAAAloB,EAAAkoB,EAAoBxB,EAAAjjB,EAAA68B,SAC1D5G,MAAKA,EAAEihB,OAAMA,EAAEtpB,OAAMA,EAAEiP,aADmC,IAAA5Z,OAAA1mB,EAAA0mB,I2CgEhExqB,KAAKspC,WACHxP,MACE6V,QAAS5qC,EAASA,EAAOukC,UAAUxP,KAAK6V,WACxCoH,YAAahyC,EAASA,EAAOukC,UAAUxP,KAAKid,eAC5CmI,oBAAqBn6C,EAASA,EAAOukC,UAAUxP,KAAKolB,uBAEpD9G,UAAW7hB,GAAYrM,IAAUnlB,GAAUA,EAAOukC,UAAUxP,KAAKse,YAAcluB,EAAK4P,MAEtFkR,WAAY,IAAIS,GAChBlC,eAAe14B,OAASC,WACxBe,KAAM,KACN0hB,QAAOnzB,GACLwM,SAAWgf,QAAUwH,WACjBG,OAENnJ,UAAW,KACXsoB,OAAQ,KACRl8B,WAAY,KACZ4zB,QACAkD,YAiZN,OA7YE5vC,OAAA2pC,eAAWiX,EAAAp+C,UAAA,aAAX,WACE,OAAOF,KAAKirC,iBAAiB,0CAI/BvtC,OAAA2pC,eAAWiX,EAAAp+C,UAAA,cAAX,WACE,OAAOF,KAAKirC,iBAAiB,2CAGrBqT,EAAAp+C,UAAAi/C,SAAV,SAAmB/uC,GACV,IAAAgiB,EAAAhiB,EAAAgiB,MAAOC,EAAAjiB,EAAAiiB,OACVD,GACFpyB,KAAKspC,UAAU0B,WAAWa,IAAI,QAASzZ,GAAO,GAG5CC,GACFryB,KAAKspC,UAAU0B,WAAWa,IAAI,SAAUxZ,GAAQ,IAI7CisB,EAAAp+C,UAAAsI,MAAP,WACExI,KAAKo/C,aAELp/C,KAAKq/C,kBACLr/C,KAAKs/C,2BAELt/C,KAAKu/C,iBACLv/C,KAAKywC,kBACLzwC,KAAKw/C,YACLx/C,KAAKy/C,qBACLz/C,KAAKouC,cACLpuC,KAAK0/C,kBAQApB,EAAAp+C,UAAAk/C,WAAP,qBD9NyBxd,GACzBwb,GAAexb,GACf4W,GAAiB5W,GACjB,IAAmB,IAAAz7B,EAAA,EAAAw5C,EAAAzuB,GAAA/qB,EAAAw5C,EAAAziD,OAAAiJ,IACjB+2C,GAAmBtb,EADN+d,EAAAx5C,IAIf00C,GAAgBjZ,GCwNdwd,CAAWp/C,OAGNs+C,EAAAp+C,UAAAuwC,gBAAP,WACEA,GAAgBzwC,OAUVs+C,EAAAp+C,UAAAo/C,yBAAR,WACgC,UAA1Bt/C,KAAKykC,QAAQ,UACfzkC,KAAK4/C,iBAAiB5/C,KAAKykC,QAAQ,SAAU,SAEhB,WAA3BzkC,KAAKykC,QAAQ,WACfzkC,KAAK4/C,iBAAiB5/C,KAAKykC,QAAQ,UAAW,WAQ3C6Z,EAAAp+C,UAAAkuC,YAAP,WACEA,GAAYpuC,OAQPs+C,EAAAp+C,UAAA2/C,mBAAP,WACE,GAAkB,SAAd7/C,KAAKgU,MAAiC,UAAdhU,KAAKgU,KAC/B,MAAO,QAKJsqC,EAAAp+C,UAAA4/C,mBAAP,WACE,GAAkB,SAAd9/C,KAAKgU,MAAiC,UAAdhU,KAAKgU,KAC/B,OACEoe,MAAOpyB,KAAKirC,iBAAiB,SAC7B5Y,OAAQryB,KAAKirC,iBAAiB,YAM7BqT,EAAAp+C,UAAA6/C,eAAP,WACE,GAAK//C,KAAKi/C,OAAV,CAIM,IAAA13C,EAAAvH,KAAAi/C,OAACzhB,EAAAj2B,EAAAi2B,MAAOihB,EAAAl3C,EAAAk3C,OAAQtpB,EAAA5tB,EAAA4tB,OAAQ7Q,EAAA/c,EAAA68B,QAAAA,OAAA,IAAA9f,KAAAA,EAE9B,OAAAlkB,GACEqsB,QAASltB,EAAS6kC,GAAWA,GAC3BvzB,IAAKuzB,EAAQvzB,KAAO,GACpBC,OAAQszB,EAAQtzB,QAAU,KAEzB9Q,KAAKggD,wBACJxiB,GAASA,MAAKA,MACdihB,GAAUA,OAAMA,MAChBtpB,GAAUA,OAAMA,SAIdmpB,EAAAp+C,UAAA8/C,sBAAV,WACE,UAKK1B,EAAAp+C,UAAA+/C,oBAAP,WAIE,IAHO,IAAA1W,EAAAvpC,KAAAspC,UAAAC,cACH2W,KAEkB/5C,EAAA,EAAAg6C,EAAAhX,GAAAhjC,EAAAg6C,EAAAjjD,OAAAiJ,IAAiB,CACjCojC,EADK54B,EAAOwvC,EAAAh6C,IACWwG,OACzBuzC,EAAY9iD,KAAKisC,GAAcrpC,KAAM2Q,IAIzC,IAAsB,IAAApJ,EAAA,EAAA64C,EAAAjX,GAAA5hC,EAAA64C,EAAAljD,OAAAqK,IAAiB,CAAlC,IAAMoJ,EAAOyvC,EAAA74C,GAChB24C,EAAcA,EAAYrhD,OAAO+qC,GAAgB5pC,KAAM2Q,IAEzD,OAAOuvC,GAKF5B,EAAAp+C,UAAAmgD,aAAP,WACE,OvCnPyBC,EuCmPLtgD,KAAKspC,UAAUc,KvCnP0B1jB,EuCmPpB1mB,KAAK0mB,OvClPzCnf,EAAA+4C,EAAAziD,EAAAA,OAAA,IAAA0J,KAAAA,EAAM+c,EAAAg8B,EAAAzwC,EAAAA,OAAA,IAAAyU,KAAAA,EAERzmB,EAAEC,IAAI,SAAAqF,GAAK,OAAAq7B,GAAar7B,EAAG,OAAQujB,KAAQ7nB,OAC3ChB,EAAEC,IAAI,SAAAqF,GAAK,OAAAq7B,GAAar7B,EAAG,OAAQujB,KACnC7W,EAAE/R,IAAI,SAAAqF,GAAK,OAAAq7B,GAAar7B,EAAG,OAAQujB,KACnC7W,EAAE/R,IAAI,SAAAqF,GAAK,OAAAq7B,GAAar7B,EAAG,OAAQujB,MACtC5f,OAAO,SAAA3D,GAAK,OAAAA,IAPhB,IAA6Bm9C,EAAoC55B,EACxDnf,EAAA1J,EAAMymB,EAAAzU,GuCqPNyuC,EAAAp+C,UAAAqgD,gBAAP,WACE,OAAOA,GAAgBvgD,OAGlBs+C,EAAAp+C,UAAAqvC,oBAAP,WACE,OAAOA,GAAoBvvC,OAGtBs+C,EAAAp+C,UAAAi/B,cAAP,WACE,IAAMxyB,EAAKvM,KACN60B,GAAmBj1B,KAAK0mB,OAAO/Z,OAAOulB,QACtClyB,KAAK2M,OAGV,GAAIA,EAAM7L,KAWR,OAVK6F,GAAU,OAAQ,SAAU3G,KAAKgU,QAIhCrH,EAAMqlB,QAA2B,UAAjBrlB,EAAMqlB,QACxBzW,GAASC,GAAY7F,qBAAqB3V,KAAKgU,OAEjDrH,EAAMqlB,OAAS,SAGV5sB,GAAKuH,GAAOzP,OAAS,EAAIyP,OAAQ7I,GAQrCw6C,EAAAp+C,UAAAsgD,cAAP,SAAqBC,QAAA,IAAAA,IAAAA,MACnB,IAAMjlB,MAENilB,EAAUA,EAAQ5hD,OAAOmB,KAAK0gD,6BAElBxjD,OAAS,IACnBs+B,EAAMilB,QAAUA,GAGlB,IAAMxB,EAASj/C,KAAK+/C,iBAChBd,IACFzjB,EAAMyjB,OAASA,GAGjBzjB,EAAMlB,SAAWz7B,OACfmB,KAAKigD,sBACLjgD,KAAK2gD,iBAKP,IAAMjO,GAAW1yC,KAAK+E,QAAUmmC,GAAalrC,KAAK+E,mBPxYvB68B,GAC7B,OAAIuN,GAAavN,IAAUwN,GAAcxN,IAAUyN,GAAczN,GAExDA,EAAM0M,SAAS5rB,OAAO,SAACgwB,EAAQjZ,GACpC,OAAOiZ,EAAO7zC,OAAO+hD,EAAennB,KACnCmgB,GAAuBhY,IAInBgY,GAAuBhY,GO+X+Bgf,CAAe5gD,SACxE0yC,EAAOx1C,OAAS,IAClBs+B,EAAMkX,OAASA,GAGjB,IAAMtI,EAAOpqC,KAAKqgD,eACdjW,EAAKltC,OAAS,IAChBs+B,EAAM4O,KAAOA,GAGf,IAAMkD,EAAUttC,KAAKugD,kBAKrB,OAJIjT,EAAQpwC,OAAS,IACnBs+B,EAAM8R,QAAUA,GAGX9R,GAGF8iB,EAAAp+C,UAAA2gD,gCAAP,SAAuClwC,GACrC,IAAoB,IAAAxK,EAAA,EAAAoB,EAAAvH,KAAKsuC,SAALnoC,EAAAoB,EAAArK,OAAAiJ,IAAe,CAA9B,IAAMszB,EAAKlyB,EAAApB,GACd,GAAIknC,GAAY5T,IACd,GAAIA,EAAMjR,gBAAgB7X,GACxB,OAAO,OAGT,GAAI8oB,EAAMonB,gCAAgClwC,GACxC,OAAO,EAIb,OAAO,GAGF2tC,EAAAp+C,UAAAukC,QAAP,SAAe3jC,GACb,OAAO4H,IAAS1I,KAAK5D,KAAO4D,KAAK5D,KAAO,IAAM,IAAM0E,IAM/Cw9C,EAAAp+C,UAAAkwC,gBAAP,SAAuBh0C,GACrB,IAAM0kD,EAAW9gD,KAAKykC,QAAQroC,GAIxB4rC,EAAYhoC,KAAKspC,UAAUxP,KAAKolB,oBAGtC,OAFAlX,EAAU8Y,IAAa9Y,EAAU8Y,IAAa,GAAK,EAE5CA,GAGFxC,EAAAp+C,UAAA+qC,iBAAP,SAAwBF,GACtB,GAAIG,GAAalrC,KAAK+E,QAAS,CAC7B,IAAM4L,EAAuB,UAAbo6B,EAAuB,IAAM,IACvChI,EAAiB/iC,KAAKspC,UAAUoJ,OAAO/hC,GAE7C,GAAIoyB,IAAmBA,EAAe5K,OAAQ,CAC5C,IAAMnkB,EAAO+uB,EAAe9B,IAAI,QAC1B3Q,EAAQyS,EAAe9B,IAAI,SAEjC,GAAIjS,GAAkBhb,IAAS6oB,GAAcvM,GAAQ,CACnD,IAAMkQ,EAAYuC,EAAe9B,IAAI,QAE/B9iC,EAAQw0C,GADCC,GAAe5yC,KAAM2Q,IAEpC,OAAIxS,GAGAmqB,OAAQ8iB,GAAS5K,EAAWuC,EAFbhd,IAASpa,UAAW,WAAYxN,MAAKknB,IAAIiB,KAAM,aAKhE/K,GAAS,8DACF,QAOf,OACE+M,OAAQtoB,KAAK6+C,kBAAkB5d,IAAIjhC,KAAKykC,QAAQsG,MAO7CuT,EAAAp+C,UAAA2vC,iBAAP,SAAwBzzC,GACtB,IAAMuI,EAAO3E,KAAKspC,UAAUxP,KAAKid,YAAY36C,GAE7C,OAAKuI,EAMEA,EAAK2jC,YAHHlsC,GAMJkiD,EAAAp+C,UAAA85C,YAAP,SAAmB+G,GAChB,OAAO/gD,KAAK6+C,kBAAkB5d,IAAI8f,IAG9BzC,EAAAp+C,UAAA0/C,iBAAP,SAAwBvB,EAAiBvH,GACvC92C,KAAK6+C,kBAAkBT,OAAOC,EAASvH,IAGlCwH,EAAAp+C,UAAA49C,YAAP,SAAmBO,EAAiBvH,GAClC92C,KAAK2+C,aAAaP,OAAOC,EAASvH,IAG7BwH,EAAAp+C,UAAA+wC,iBAAP,SAAwBoN,EAAiBvH,GACvC92C,KAAK4+C,kBAAkBR,OAAOC,EAASvH,IAMlCwH,EAAAp+C,UAAAsgC,UAAP,SAAiBwgB,EAAqCx4C,GACpD,OAAIA,EAIKxI,KAAKykC,QAAQuc,GAOjB/vC,GAAU+vC,IAAsBrvC,GAAeqvC,IAAsBhhD,KAAKspC,UAAUoJ,OAAOsO,IAE5FhhD,KAAK2+C,aAAal5C,IAAIzF,KAAKykC,QAAQuc,IAE9BhhD,KAAK2+C,aAAa1d,IAAIjhC,KAAKykC,QAAQuc,SAN5C,GAcK1C,EAAAp+C,UAAAmwC,eAAP,SAAsB7nC,GACpB,OAAIA,EAIKxI,KAAKykC,QAAQ,cAGjBzkC,KAAKspC,UAAU9yB,aAAexW,KAAKspC,UAAU9yB,WAAW2hB,QAAWn4B,KAAK4+C,kBAAkBn5C,IAAIzF,KAAKykC,QAAQ,eACvGzkC,KAAK4+C,kBAAkB3d,IAAIjhC,KAAKykC,QAAQ,oBADjD,GA4BK6Z,EAAAp+C,UAAA8iC,kBAAP,SAAyBryB,GAEvB,IAAK3Q,KAAKspC,UAAUoJ,OAClB,MAAM,IAAIl2C,MAAM,mIAGlB,IAAMykD,EAAsBjhD,KAAKspC,UAAUoJ,OAAO/hC,GAClD,OAAIswC,IAAwBA,EAAoB9oB,OACvC8oB,EAEDjhD,KAAK+E,OAAS/E,KAAK+E,OAAOi+B,kBAAkBryB,QAAW7M,GAM1Dw6C,EAAAp+C,UAAAm6C,sBAAP,SAA6B6G,EAAsBC,GACjD,IAAIC,EAAMphD,KAAKspC,UAAUlf,UAAU82B,GAInC,IAHKE,GAAOphD,KAAK+E,SACfq8C,EAAMphD,KAAK+E,OAAOs1C,sBAAsB6G,EAAcC,KAEnDC,EACH,MAAM,IAAI5kD,MAAMgf,GAAYlG,kBAAkB6rC,IAEhD,OAAOC,GAEX9C,EArdA,GAwdA+C,GAAA,SAAAtZ,GAAA,SAAAsZ,mDAmCA,OAnC6CjZ,EAAAA,EAAAA,GAIpCiZ,EAAAnhD,UAAA6lB,QAAP,SAAepV,EAA2B2F,QAAA,IAAAA,IAAAA,MACxC,IAAMc,EAAWpX,KAAKoX,SAASzG,GAE/B,GAAKyG,EAIL,OAAO2O,GAAQ3O,EAAUd,IAKpB+qC,EAAAnhD,UAAAgzC,eAAP,SAA4B9xC,EAAoD+nB,EAAS7oB,GACvF,OAAOoiB,GAAO1iB,KAAKshD,aAAc,SAACC,EAAQC,EAAwB3kD,GAChE,IAAMua,EAAWgQ,GAAYo6B,GAC7B,OAAIpqC,EACKhW,EAAEmgD,EAAKnqC,EAAUva,GAEnB0kD,GACNp4B,EAAM7oB,IAGJ+gD,EAAAnhD,UAAAyoC,gBAAP,SAAuBvnC,EAA+Cd,GACpEyoB,GAAQ/oB,KAAKshD,aAAc,SAACE,EAAwB3kD,GAClD,IAAMua,EAAWgQ,GAAYo6B,GACzBpqC,GACFhW,EAAEgW,EAAUva,IAEbyD,IAGP+gD,EAnCA,CAA6C/C,ICrlBvCmD,IACJh8C,IAAK,SAAS20C,GACZ,MAAwB,aAAjBA,EAAQpmC,MAA2C,WAApBomC,EAAQ7mB,SAC5C6mB,EAAQsH,MAAyB,WAAjBtH,EAAQsH,MAG5Bl5C,MAAO,SAASo5B,EAAO+f,EAAQvH,GAC7B,IAAMwH,EAAmBxH,EAAQ1H,UAEjC0H,EAAQE,QAAQvxB,QAAQ,SAASrsB,GAC/B,IAAMiU,EAAUjU,EAAEiU,QACZ/D,EAAQg1B,EAAMoB,kBAAkBryB,GAChCiG,EAAYhK,EAAQA,EAAMq0B,IAAI,aAAUn9B,EAEzC8I,GAAUsiB,GAAoBtY,KAAcqY,GAAWrY,IAK5DhK,EAAMi/B,IAAI,aAAcvjB,OAAQu5B,GAAkBzH,EAASzpC,EAAS,UAAU,GAC9EixC,EAAMxkD,KAAKuT,GAGPixB,EAAM4c,UAAY5c,EAAM4c,SAAS3tC,MAAQ+wB,EAAM4c,SAAS1tC,QAC3C8wB,EAAMoB,kBAAkBryB,IAAYzC,GAAIC,GAAID,IACpD29B,IAAI,aAAcvjB,OAAQu5B,GAAkBzH,EAASzpC,EAAS,UAAU,IAV/E4K,GAASC,GAAYjG,8BAe3BusC,gBAAiB,SAASlgB,EAAOwY,EAASqG,GAExC,IAAK7e,EAAM78B,OACT,OAAO07C,EAGT,IAAMrqC,EAAWgkC,EAAQ1H,OAAO5rC,OAAO,SAAC6J,GACtC,OAAS8vC,EAAQ35C,OAAO,SAAA3J,GAAK,OAAAA,EAAEf,OAASylD,GAAkBzH,EAASzpC,EAAS,UAAe,SAG7F,OAAO8vC,EAAQ5hD,OAAOuX,EAAStY,IAAI,SAAC6S,GAClC,OAAQvU,KAAMylD,GAAkBzH,EAASzpC,EAAS,aAItD8vC,QAAS,SAAS7e,EAAOwY,EAASqG,GAYhC,OAVI7e,EAAM78B,QACRq1C,EAAQ1H,OAAO3pB,QAAQ,SAAApY,GACrB,IAAM2X,EAASm4B,EAAQ35C,OAAO,SAAA3J,GAAK,OAAAA,EAAEf,OAASylD,GAAkBzH,EAASzpC,EAAS,UAAS,GAE3F2X,EAAOlrB,KAAO,eACPkrB,EAAOvnB,aACPunB,EAAO6hB,SAIXsW,IAIX,SAAAsB,GAEuBngB,EAAkBjxB,GAEvC,MAAO,UADOtS,EAAYujC,EAAMpB,UAAU7vB,IACpB,ICxDjB,IACMqxC,GAAgB,iBAEvBtuB,IACJuuB,UAAW,aACXvQ,YAAa,mBAEb+O,QAAS,SAAS7e,EAAOwY,GACvB,IAAMh+C,EAAOg+C,EAAQh+C,KACf8lD,EAAYxP,GAAOjtC,IAAI20C,GACvBqG,KACA0B,KACAC,KACAC,KAEN,GAAIjI,EAAQxmB,YAAcsuB,EAAW,CACnC,IAAMI,EAAa,2CAA2CjkD,EAAYjC,EAhB3D,UAiBfmmD,GAAOnI,EAAS,SAAS38C,EAAU+kD,GACjC,IAAMpP,EAAUoP,EAAItmB,QAAQ,GAAGp1B,SAAW07C,EAAItmB,QAAQ,GAAGp1B,WACrDssC,EAAQ1yC,QAAQ4hD,GAAc,GAChClP,EAAQh2C,KAAKklD,KA6CnB,OAxCAlI,EAAQE,QAAQvxB,QAAQ,SAASrsB,GAC/B,IAAMiU,EAAUjU,EAAEiU,QAClB,GAAIA,IAAYzC,IAAKyC,IAAYxC,GAAjC,CAKA,IAAMs0C,EA2HZ,SAAwB7gB,EAAkBwY,EAA6BzpC,GACrE,IAAM+xC,EAAQb,GAAkBzH,EAASzpC,EAAS,UAC5CgyC,EAAQd,GAAkBzH,EAASzpC,EAAS,QAC5CuxC,EAAYxP,GAAOjtC,IAAI20C,GAEvBwI,EAAWvkD,EADCujC,EAAMpB,UAAU7vB,IAE5B/D,EAAQg1B,EAAMoB,kBAAkBryB,GAChCiG,EAAYhK,EAAQA,EAAMq0B,IAAI,aAAUn9B,EACxCsM,EAAOwxB,EAAMqJ,iBAAiBt6B,IAAYzC,GAAI,QAAU,UAAUoa,OAClEu6B,EAAWlyC,EAAO,SAElB2iB,EAAKivB,GAAOnI,EAAS,SAASpxB,EAAYw5B,GAC9C,OAAOx5B,EAAInqB,QACR0jD,OAAQC,EAAItmB,QAAQ,GAAIiO,OAAQ,IAAI0Y,EAAK,KAAKA,EAAK,MACnDN,OAAQC,EAAKrY,OAAQ,IAAIuY,EAAK,cAAcG,EAAK,QAAQzyC,EAAI,SAalE,OANAkjB,EAAGl2B,MACDmlD,QAASj6B,OAAQ8xB,EAAQh+C,KAAO4lD,IAChC7X,OAAQjb,GAAoBtY,KAAeqY,GAAWrY,GACpD,UAAUgsC,EAAQ,KAAKD,EAAK,eAAeC,EAAQ,KAAKD,EAAK,QAAU,WAGpET,IAAc9lD,KAAMumD,EAAOrvB,UAChCl3B,KAAMsmD,EAAO3hD,SAAWuyB,GAAIA,IAE5Bl3B,KAAMumD,EACNrvB,KAAMivB,QAASj6B,OAAQo6B,GAAQvY,OAAWuY,EAAK,WAAWA,EAAK,uBAAuBE,EAAQ,KAAKF,EAAK,QA1J3FI,CAAelhB,EAAOwY,EAASzpC,GACpCgyC,EAAQd,GAAkBzH,EAASzpC,EAAS,QAC5C+xC,EAAQb,GAAkBzH,EAASzpC,EAAS,UAC5CiyC,EAAWvkD,EAAYujC,EAAMpB,UAAU7vB,IAEvCoyC,EAAQ7zB,GADI0S,EAAMoB,kBAAkBryB,GAASswB,IAAI,SACR,IAAM,GAErDwf,EAAQrjD,KAAK6B,MAAMwhD,EAASgC,GAC5BL,EAAchlD,KAAKulD,GACnBR,EAAU/kD,KAAK,cAAciB,EAAYsS,GAAQ,YACrCtS,EAAY3B,EAAEyB,OAAM,aAAawkD,EAAK,KAElDN,EAAcjlD,MACZojC,UAAWoB,EAAMpB,UAAU7vB,GAC3B2V,KAAM,aAAaq8B,EAAK,SAClBI,EAAK,UAAUH,EAAQ,KAAKF,EAAK,YAAYK,EAAQJ,EAAK,UACzDI,EAAK,UAAUH,EAAQ,KAAKF,EAAK,YAAYK,EAAQJ,EAAK,eApBjE9tC,GAAK,iEA0BJqtC,GACHzB,EAAQrjD,MACNhB,KAAMA,EAAO4lD,GACb7X,OAAQkY,EAAcvkD,IAAI,SAACwC,GAAM,OAAAA,EAAEgmB,OAAMhoB,KAAK,QAC5C,OAAMlC,EAAO4lD,IAAa,UAOzBvB,EAAQ5hD,QACbzC,KAAMA,EAAO4mD,GACb1vB,KACEivB,OAAQH,EAActkD,IAAI,SAACwC,GAAM,OAAEgoB,OAAQhoB,KAC3C6pC,OAAQiY,EAAc9jD,KAAK,QACzB,aAAa0b,GAAS4nB,GAAM,iBAAiBugB,EAAU7jD,KAAK,MAAK,iBAKzE2kD,WAAY,SAASrhB,EAAOwY,GAE1B,OADYA,EAAQh+C,KAAO4mD,GACd,MACU,WAApB5I,EAAQ7mB,QAAuB,OAAS,UAAUvZ,GAAS4nB,GAAM,MAGtEtH,MAAO,SAASsH,EAAOwY,EAAS9f,GAC9B,IAAMl+B,EAAOg+C,EAAQh+C,KACfmL,EAAA27C,GAAA9I,GAAC+I,EAAA57C,EAAA47C,GAAIC,EAAA77C,EAAA67C,GACLC,EAAQ,QAAQhlD,EAAY+7C,EAAQh+C,KAAOo+C,IAAM,IAGvD,GAAI9H,GAAOjtC,IAAI20C,GACb,OAAO9f,EAGT,IAAM6P,GACJtsC,EAAU,OAAPslD,GAAe76B,OAAWlsB,EAAI,UAAY2E,MAAO,GACpD8O,EAAU,OAAPuzC,GAAe96B,OAAWlsB,EAAI,UAAY2E,MAAO,GACpD+O,GAAW,OAAPqzC,GAAe76B,OAAWlsB,EAAI,UAAY+B,OAAQq9B,MAAO,UAC7DzrB,GAAW,OAAPqzC,GAAe96B,OAAWlsB,EAAI,UAAY+B,OAAQq9B,MAAO,YAO/D,GAAwB,WAApB4e,EAAQ7mB,QACV,IAAkB,IAAAptB,EAAA,EAAAme,EAAAlf,GAAK+kC,GAALhkC,EAAAme,EAAApnB,OAAAiJ,IAAc,CAA3B,IAAMjE,EAAGoiB,EAAAne,GACZgkC,EAAOjoC,IAAO9B,GACZ8C,KAASmgD,EAAK,cAAcA,EAAK,gBAAgBrpC,GAAS4nB,IACvDuI,EAAOjoC,KACRnB,MAAO,IAOf,IAAMgrB,EAAAquB,EAAAvoC,KAAC5B,EAAA8b,EAAA9b,KAAM6jB,EAAA/H,EAAA+H,YAAa5jB,EAAA1P,EAAAurB,GAAA,OAAA,gBACpBu3B,EAAWl+C,GAAK8K,GAAQwS,OAAO,SAACsG,EAAKplB,GAQzC,OAPAolB,EAAIplB,KACFV,MACS,OAAPigD,GAAkB/mD,EAAI,aAAaA,EAAI,QACjC,MAANgnD,GAAiBhnD,EAAI,aAAaA,EAAI,SACtC0K,OAAO,SAAAjJ,GAAK,OAAAA,IAAGS,KAAK,QACtByC,MAAOmP,EAAOtM,KACZ7C,MAAO,OACJioB,OAGT,QACE5sB,KAAMA,EA/HS,YAgIf4X,KAAM,OACNuvC,MAAM,EACNz1C,QACE01C,OACEvzC,MAAOlP,MAAOkP,GACd6jB,aAAc/yB,MAAO+yB,IAEvBqW,OAAQA,KAEFtrC,OAAOy7B,GACfl+B,KAAMA,EA1IS,SA2If4X,KAAM,OACNuvC,MAAM,EACNz1C,QACE01C,OACEvzC,MAAOlP,MAAO,gBAEhBopC,OAAM/pC,KAAM+pC,EAAWmZ,QA6C/B,SAAAf,GAAgBnI,EAA6BtxC,GAC3C,OAAOsxC,EAAQmI,OAAO7/B,OAAO,SAAS4Q,EAAWkvB,GAC/C,OAAKA,EAAItmB,QAIFpzB,EAAGwqB,EAAIkvB,IAHZ3tC,GAAQ2tC,EAAG,2DACJlvB,QC/Mb,IAEMmwB,IACJh+C,IAAK,SAAS20C,GACZ,MAAwB,aAAjBA,EAAQpmC,MAAuBomC,EAAQqJ,SAGhDnpB,MAAO,SAASsH,EAAOwY,EAAS9f,GACxB,IAAA/yB,EAAA27C,GAAA9I,GAACv8C,EAAA0J,EAAA1J,EAAGgS,EAAAtI,EAAAsI,EACJ4kB,EAAWmN,EAAM/vB,KACvB,GAAI8B,GAAW8gB,GAEb,OADAlZ,GAASC,GAAYnG,+BAA+Bof,IAC7C6F,EAGT,IAAMopB,GACJtnD,KAAMwlC,EAAM6C,QAhBF,WAiBVzwB,KAAM,OACNs2B,MAAOxQ,KAAM8H,EAAM6C,QAAQ,UAC3B32B,QACE01C,OACEvzC,MAAOlP,MAAO,eACdk8B,aAAcl8B,MAAO,KACrBmP,QAASnP,MAAO,eAChB4iD,WAAY5iD,OAAO,KAGvBkV,YACEjC,KAAM,UACNnW,GAAIyoB,KAAOzoB,IAAOA,IAAMgS,EAAM,qBAAuB,KACrDA,GAAIyW,KAAOzW,IAAOhS,IAAMgS,EAAM,qBAAuB,KACrDO,MAAOwxB,EAAMqJ,iBAAiB,SAAUrJ,EAAMqJ,iBAAiB,cAI/DnoB,EAAQ,EACR8gC,GAAS,EAcb,OAbAtpB,EAAMvR,QAAQ,SAAClX,EAAMlV,GACnB,IAAMP,EAAOyV,EAAKzV,MAAQ,GACtBA,IAASwlC,EAAM0H,UAAUz3B,KAAK,GAAGzV,KACnC0mB,EAAQnmB,EACCP,EAAKsE,QAzCN,YAyC0B,IAClCkjD,GAAS,KAIRA,GACHtpB,EAAM90B,OAAOsd,EAAQ,EAAG,EAAG4gC,GAGtBppB,gBChDasH,EAAkBwY,GACxC,IAAMyJ,EAAOzJ,EAAQE,QACf/wC,EAAQk6C,GAAQh+C,IAAI20C,GACxB,2CAA6C,QACzClvB,KACAyI,EAAYkwB,EAAK/lD,IAAI,SAACpB,GAAM,OAAA2B,EAAY3B,EAAEiU,WAAU7J,OAAO,SAACrG,GAAM,OAAAA,IAAGnC,KAAK,MAC1EnC,EAAS0nD,EAAK/lD,IAAI,SAACpB,GAAM,OAAA2B,EAAY3B,EAAEyB,SAAQG,KAAK,MACpDqJ,EAASk8C,EAAK/lD,IAAI,SAACpB,GACvB,IAAMiU,EAAUjU,EAAEiU,QACZyG,EAAWwqB,EAAMxqB,SAASzG,GAEhC,OAAQyG,GAAYA,EAASzE,KAAQuY,EAAK9tB,KAAKV,EAAEyB,OAC/C,IAAImL,GAAoBs4B,EAAM7b,QAAQpV,MAAcpH,GAAM,KACnDD,GAAoBs4B,EAAM7b,QAAQpV,GAAU0V,UAAW,QAAS9c,GAAM,KAC7E,GAAGD,GAAoB5M,EAAEyB,MAAOoL,KACjCjL,KAAK,MASR,QACElC,KAAMg+C,EAAQh+C,KAAO4mD,GACrBjiD,SACAuyB,KACEivB,OAAQnI,EAAQmI,OAChBpY,OAAQ,sDACInwB,GAAS4nB,GAAM,iBAAiBjO,EAAS,eACvCx3B,EAAM,eAAewL,EAAM,KACtCujB,EAAKhuB,OAAS,KAAOguB,EAAKptB,IAAI,SAACd,GAAM,OAAGqB,EAAY,OAASrB,GAAE,QAAOsB,KAAK,MAAQ,IACpF,WACFwlD,OAAO,MAKb,IAAMtwB,IACJyuB,UAAW,UACXvQ,YAAa,gBAEb+O,QAASA,GAETwC,WAAY,SAASrhB,EAAOwY,GAE1B,OADYA,EAAQh+C,KAAO4mD,GACd,MACU,WAApB5I,EAAQ7mB,QAAuB,OAAS,UAAUvZ,GAAS4nB,GAAM,OCjDlEvO,IACJ4uB,UAAW,WACXvQ,YAAa,iBAEb+O,QAASsD,GAETjC,gBAAiB,SAASlgB,EAAOwY,EAASqG,GACxC,IAAMuD,EAAYvD,EAAQ35C,OAAO,SAAC3J,GAAM,OAAAA,EAAEf,OAASg+C,EAAQh+C,OACrD09B,EAAO,QAAQz7B,EAAY+7C,EAAQh+C,KAAOo+C,IAAM,IAChD7yC,EAAYmyB,EAAI,aACtB,OAAOkqB,EAAU9mD,OAASujD,EAAUA,EAAQ5hD,QAC1CzC,KAAMg+C,EAAQh+C,KACd+tC,OAAWrQ,EAAI,eACbsgB,EAAQE,QAAQx8C,IAAI,SAACpB,EAAGC,GAAM,OAAGD,EAAEyB,MAAK,KAAKwJ,EAAM,IAAIhL,EAAC,MAAK2B,KAAK,MAAQ,OAIhF2kD,WAAY,SAASrhB,EAAOwY,GAE1B,OADYA,EAAQh+C,KAAO4mD,GACd,MACU,WAApB5I,EAAQ7mB,QAAuB,OAAS,UAAUvZ,GAAS4nB,GAAM,OCflEqiB,GAAS,oBACTC,GAAQ,mBAqDd,SAAAC,GAAiBviB,EAAkBwY,EAA6BzpC,EAAuBP,EAA0BqwC,GAC/G,IAAMrkD,EAAOg+C,EAAQh+C,KACf8lD,EAAYkC,GAAe3+C,IAAI20C,GAC/B9xB,EAASm4B,EAAQ35C,OAAO,SAAA3J,GAC5B,OAAOA,EAAEf,OAASylD,GAAkBzH,EAASzpC,EAASuxC,EAAY,OAAS,YAC1E,GACGlwB,EAAS51B,EAAO6nD,GAChBI,EAAQjoD,EAAO8nD,GACfI,EAAS1iB,EAAMqJ,iBAAiB76B,GAAMkY,OACtCi8B,EAAY3iB,EAAMoB,kBAAkBryB,GACpCiG,EAAY2tC,EAAUtjB,IAAI,QAE1B1W,EAAYyH,EAAM,WAAWrhB,EAK7Bw5B,GAHS+X,EACC,QAAdtrC,EAAsB,SACR,QAAdA,EAAsB,SAAW,YAFR,aAGJ,IAAI2T,EAAM,MAJlB,IAFF23B,GAAavxC,IAAYzC,GAAI,IAAM,IAEvBm2C,EAAK,IAAI1zC,EAAO,OAASuxC,EAAY,GAAGoC,EAAW,QAAQ/5B,EAAM,OAKvF23B,GAA2B,QAAdtrC,EAAsB,MAAK2tC,EAAUtjB,IAAI,aAAe,GAAM,IAAM,IAEpF3Y,EAAOgL,GAAGl2B,MACRmlD,QAASj6B,OAAQ+7B,GACjBla,OAAQ+X,EAAY/X,EAAS,cAAcA,EAAM,QAAQma,EAAM,MC5EnE,IAAML,GAAS,eACTC,GAAQ,cAqDd,SAAAM,GAAiB5iB,EAAkBwY,EAA6BzpC,EAAuBP,EAA0BqwC,GAC/G,IAAMrkD,EAAOg+C,EAAQh+C,KACf8lD,EAAYkC,GAAe3+C,IAAI20C,GAC/B9xB,EAASm4B,EAAQ35C,OAAO,SAAA3J,GAC5B,OAAOA,EAAEf,OAASylD,GAAkBzH,EAASzpC,EAASuxC,EAAY,OAAS,YAC1E,GACGoC,EAAS1iB,EAAMqJ,iBAAiB76B,GAAMkY,OACtCi8B,EAAY3iB,EAAMoB,kBAAkBryB,GACpCiG,EAAY2tC,EAAUtjB,IAAI,QAC1BtQ,EAAOuxB,EAAY/1C,GAAOy1B,EAAOjxB,GAAW2X,EAAOlsB,KACnDioD,EAAQjoD,EAAO8nD,GAKf/Z,GAHU+X,EACA,QAAdtrC,EAAsB,UACR,QAAdA,EAAsB,UAAY,aAFR,cAGJ,IAAI+Z,EAAI,MAJjB,GAAGv0B,EAAO6nD,GAAM,IAAItzC,GAIQ,KAAK0zC,GAC7CnC,GAA2B,QAAdtrC,EAAsB,MAAK2tC,EAAUtjB,IAAI,aAAe,GAAM,IAAM,IAEpF3Y,EAAOgL,GAAGl2B,MACRmlD,QAASj6B,OAAQ+7B,GACjBla,OAAQ+X,EAAY/X,EAAS,cAAcA,EAAM,QAAQma,EAAM,MC7DnE,IAAMG,IAAsCnK,SCf1C70C,IAAK,SAASk8C,GACZ,IAAM34B,EAAM24B,EACZ,YAAsB79C,IAAfklB,EAAI7sB,aAA0C2H,IAAlBklB,EAAI2K,WAGzCnrB,MAAO,SAASo5B,EAAO+f,EAAQvH,GAC7B,IAAMhkC,KACA+U,MAGLw2B,EAAOxlD,YAAc4sB,QAAQ,SAAC5qB,GAAU,OAAAiY,EAASjY,GAAS,QAE1DwjD,EAAOhuB,eAAiB5K,QAAQ,SAACpY,GAChC,IAAMyG,EAAWwqB,EAAMxqB,SAASzG,GAChC,GAAIyG,EACF,GAAIA,EAASiF,SAAU,CACrB,IAAMqoC,EAAU9iB,EAAM7b,QAAQpV,GAC9ByF,EAASsuC,GAAW/zC,EAMpBwa,EAAUu5B,IACR55B,GAAI45B,EACJvmD,MAAOiZ,EAASjZ,MAChBke,SAAUjF,EAASiF,eAGrBjG,EAASgB,EAASjZ,OAASwS,OAG7B4K,GAASC,GAAYpG,mCAAmCzE,MAI5D,IAAM6F,EAAa4jC,EAAQE,UAAYF,EAAQE,YAC/C,IAAK,IAAMn8C,KAASiY,EACdA,EAASvW,eAAe1B,IAC1BqY,EAAWpZ,MAAMe,MAAOA,EAAOwS,QAASyF,EAASjY,KAIrD,IAAMhC,EAASi+C,EAAQj+C,SAAWi+C,EAAQj+C,WAC1Cqa,EAAW1P,OAAO,SAACpK,GAAM,OAAAA,EAAEiU,UAASoY,QAAQ,SAACrsB,GAAM,OAAAP,EAAOO,EAAEiU,SAAWjU,EAAEyB,QAErEiH,GAAK+lB,GAAWjuB,SAClBk9C,EAAQ/9B,SAAW,IAAI44B,GAAa,KAAM9pB,MDhCKsI,QEhBnDhuB,IAAK,SAAS20C,GACZ,MAAwB,UAAjBA,EAAQpmC,MAAoBomC,EAAQ3mB,QAG7CgtB,QAAS,SAAS7e,EAAOwY,EAASqG,GAChC,OAAOA,EAAQ5hD,QACbzC,KAAMg+C,EAAQh+C,KATL,UAUT2E,OAAO,EACPuyB,KAAMivB,OAAQnI,EAAQmI,OAAQpY,OAAQiQ,EAAQ3mB,YAIlDwvB,WAAY,SAASrhB,EAAOwY,EAAS9zB,GACnC,IAAMq+B,EAAMvK,EAAQh+C,KAAO4mD,GACrB16B,EAAS8xB,EAAQh+C,KAjBZ,UAmBX,OAAUksB,EAAM,aAAaq8B,EAAG,MACT,WAApBvK,EAAQ7mB,QACJjL,EAAM,mBACNA,EAAM,oBAAoBtO,GAAS4nB,GAAM,OAC3CtZ,EAAM,MAAMq8B,EAAG,YFJqCjS,OAAM+O,GACjE7tB,WFVAnuB,IAAK,SAAS20C,GACZ,MAAwB,aAAjBA,EAAQpmC,MAAuBomC,EAAQxmB,WAGhD6sB,QAAS,SAAS7e,EAAOwY,EAASqG,GAChC,IAAMrkD,EAAOg+C,EAAQh+C,KACf8lD,EAAYkC,GAAe3+C,IAAI20C,GAC/BpoB,EAAS51B,EAAO6nD,GAChB18C,EAAA27C,GAAA9I,GAACv8C,EAAA0J,EAAA1J,EAAGgS,EAAAtI,EAAAsI,EACN0yC,EAASnoB,GAAcggB,EAAQxmB,UAAW,SAmC9C,OAjCKsuB,IACHK,EAASA,EAAOzkD,IAAI,SAAC2C,GAAM,OAACA,EAAEy7B,QAAQ,GAAGG,SAAWjgC,EJTrC,SIS4DqE,KAG7EggD,EAAQrjD,MACNhB,KAAM41B,EACNjxB,SACAuyB,KACEivB,OAAQA,EAAOzkD,IAAI,SAAC2C,GAAM,OAAAA,EAAEy7B,QAAQ,KACpCiO,OAAQ,2BACC,OAANtsC,EAAa,gBAAkBqkD,EAAY/1C,GAAOy1B,EAAO1zB,IACtD,SAAS2zC,GAAkBzH,EAAS,IAAK,UAAS,KAAO,KAEtD,OAANvqC,EAAa,gBAAkBqyC,EAAY/1C,GAAOy1B,EAAOzzB,IACtD,SAAS0zC,GAAkBzH,EAAS,IAAK,UAAS,KAAO,IAAM,QAGvEh+C,KAAMA,EAAO8nD,GACbnjD,SACAuyB,KACEivB,OAAQA,EACRpY,OAAQ,OAAOnY,EAAM,oBAAoBA,EAAM,oBAIzC,OAANn0B,GACFsmD,GAAQviB,EAAOwY,EAASlsC,GAAG,QAASuyC,GAG5B,OAAN5wC,GACFs0C,GAAQviB,EAAOwY,EAASjsC,GAAG,SAAUsyC,GAGhCA,IElCE5sB,MDVXpuB,IAAK,SAAS20C,GACZ,MAAwB,aAAjBA,EAAQpmC,MAAuBomC,EAAQvmB,MAGhD4sB,QAAS,SAAS7e,EAAOwY,EAASqG,GAChC,IAAMrkD,EAAOg+C,EAAQh+C,KACf8lD,EAAYkC,GAAe3+C,IAAI20C,GAC/BiK,EAAQjoD,EAAO8nD,GACf38C,EAAA27C,GAAA9I,GAACv8C,EAAA0J,EAAA1J,EAAGgS,EAAAtI,EAAAsI,EACJ+0C,EAAKvmD,EAAYujC,EAAMpB,UAAUtyB,KACjC22C,EAAKxmD,EAAYujC,EAAMpB,UAAUryB,KACnCo0C,EAASnoB,GAAcggB,EAAQvmB,KAAM,SAiCzC,OA/BKquB,IACHK,EAASA,EAAOzkD,IAAI,SAAC2C,GAAM,OAACA,EAAE47B,SAAWjgC,ELX1B,SKWiDqE,KAGlEggD,EAAQrjD,MACNhB,KAAMA,EAAO6nD,GACb3wB,KACEivB,OAAQA,EACRpY,OAAS+X,EACP,KACG0C,EAAK,aAAaA,EAAE,aAAe,GACnCC,EAAK,aAAaA,EAAE,aAAe,IACpC/9C,OAAO,SAACwf,GAAS,QAAEA,IAAMhoB,KAAK,MAAQ,IAJrB,+BAOvBlC,KAAMioD,EACN/wB,KACEivB,OAAQA,EACRuB,OAAO,EACP3Z,OAAQ,0DAIF,OAANtsC,GACFsmD,GAAQviB,EAAOwY,EAAS,IAAK,QAASqG,GAG9B,OAAN5wC,GACFs0C,GAAQviB,EAAOwY,EAAS,IAAK,SAAUqG,GAGlCA,IClCQqE,QGjBjBr/C,IAAK,SAAS20C,GACZ,MAAwB,WAAjBA,EAAQpmC,MAAyC,WAApBomC,EAAQ7mB,SAC1C6mB,EAAQsH,MAAyB,WAAjBtH,EAAQsH,MAG5BI,gBAAiB,SAASlgB,EAAOwY,EAASqG,GACxC,IAAMrkD,EAAOg+C,EAAQh+C,KACfynD,EAAOzJ,EAAQE,QACfoH,EAAOtH,EAAQsH,KACfn4C,EAAQk6C,GAAQh+C,IAAI20C,GACxB,2CAA6C,QAkB/C,OAhBAyJ,EAAK96B,QAAQ,SAASrsB,GACpB,IAAMqoD,EAASr8C,GAAWtM,EAAI,IAAIM,EAAEyB,OAClBsiD,EAAQ35C,OAAO,SAAC3J,GAAM,OAAAA,EAAEf,OAAS2oD,IACpC7nD,QACbujD,EAAQuE,SACN5oD,KAAM2oD,EACNhkD,MAAO,GACPuyB,KACEivB,OAAQnI,EAAQmI,OAChBpY,OAAQ,+CAA+C7gC,GAAoB5M,EAAEyB,MAAOoL,GAAM,YAE5Fm4C,KAAMA,EAAKhlD,EAAEyB,QAAUujD,EAAKhlD,EAAEiU,UAAY+wC,MAKzCjB,GAGTA,QAAS,SAAS7e,EAAOwY,EAASqG,GAChC,IAAMrkD,EAAOg+C,EAAQh+C,KACfynD,EAAOzJ,EAAQE,QACfhyB,EAASm4B,EAAQ35C,OAAO,SAAC3J,GAAM,OAAAA,EAAEf,OAASA,EAAO4mD,KAAO,GACxD7mD,EAAS0nD,EAAK/lD,IAAI,SAACpB,GAAM,OAAA2B,EAAY3B,EAAEyB,SAAQG,KAAK,MACpDqJ,EAASk8C,EAAK/lD,IAAI,SAACpB,GAAM,OAAAgM,GAAWtM,EAAI,IAAIM,EAAEyB,SASpD,OAPIwJ,EAAOzK,SACTorB,EAAO6hB,OAAYxiC,EAAOrJ,KAAK,QAAO,gBAAgBnC,EAAM,eAAewL,EAAOrJ,KAAK,MAAK,oBAGvFgqB,EAAOvnB,aACPunB,EAAOgL,GAEPmtB,IH5BgBgD,QAAOA,IAElC,SAAAwB,GAAiC7K,EAA6BtxC,GAC5D,IAAK,IAAMxI,KAAKmkD,GACVA,GAAUnkD,GAAGmF,IAAI20C,IACnBtxC,EAAG27C,GAAUnkD,IdTZ,IAAMk6C,GAAQ,SACRwI,GAAQ,SACRkC,GAAS,UACThN,GAAmB,qBA0KhC,SAAAiN,GAA2CvjB,EAAkBtH,GAU3D,OATA8qB,GAAiBxjB,EAAO,SAACwY,EAASiL,GAChC/qB,EAAQ+qB,EAAY/qB,MAAQ+qB,EAAY/qB,MAAMsH,EAAOwY,EAAS9f,GAASA,EACvE2qB,GAAiB7K,EAAS,SAACkL,GACrBA,EAAWhrB,QACbA,EAAQgrB,EAAWhrB,MAAMsH,EAAOwY,EAAS9f,QAKxCA,EAaT,SAAAkJ,GAAmC5B,EAAc2jB,EAAoCC,GACnF,IAAMC,KAwBN,IAAMC,EAAe78C,GAAY08C,EAvBjC,SAAcnpD,GACZ,IAAMsmD,EAAQh6C,GAAQtM,GAChBg+C,EAAUxY,EAAMyY,sBAAsBqI,EAAOtmD,GAC7CinD,EAAQhlD,EAAYqkD,EAAQlI,IAElC,GAAIJ,EAAQ/9B,SAAU,CACpB,IAAMod,EAAQ+rB,GAAU5jB,EAAM0H,UAAUxP,KAAK6rB,IACvCC,EAASxL,EAAQ/9B,SAAS6qB,QAC5BzN,EAAM10B,OACR6gD,EAAOje,iBAAiBlO,GAExBA,EAAM10B,OAAS6gD,EAQnB,MAJsB,SAAlBxL,EAAQl8C,OACVunD,EAAOroD,KAAKimD,GAGP9I,GAASH,EAAQpmC,MAAMiuC,UAAY,IAAIoB,EAAK,WAC5B,WAApBjJ,EAAQ7mB,QAAuB,IAAM,KAAKl1B,EAAY+7C,EAAQ7mB,SAAQ,OAI3E,OAAQkyB,EAAOvoD,OACX,KAAOuoD,EAAO3nD,IAAI,SAACX,GAAM,MAAA,eAAeA,EAAC,OAAMmB,KAAK,QAAU,QAC9D,IACA,IAAIonD,EAAY,IAyCtB,SAAAN,GAA0BxjB,EAAc94B,GACtC,IAAMy8C,EAAa3jB,EAAM0H,UAAUlf,UACnC,IAAK,IAAMy7B,KAAQN,EACjB,GAAIA,EAAW1lD,eAAegmD,GAAO,CACnC,IAAMzE,EAAMmE,EAAWM,GACvB/8C,EAAGs4C,EAAK7G,GAAS6G,EAAIptC,QAK3B,SAAAumC,GAAkBvmC,GAChB,OAAQA,GACN,IAAK,SACH,OAAO8xC,GACT,IAAK,QACH,OAAOC,GACT,IAAK,WACH,OAAOC,GAEX,OAAO,KAGT,SAAAC,GAAuBrkB,GAErB,IADA,IAAI78B,EAAS68B,EAAM78B,OACZA,IACDmmC,GAAanmC,IAGjBA,EAASA,EAAOA,OAGlB,OAAOA,EAGT,SAAAiV,GAAyB4nB,GACvB,IAAIxlC,EAAOiC,EAAYujC,EAAMxlC,MACvB47B,EAAQiuB,GAAcrkB,GAK5B,OAJI5J,IACF57B,IAAS47B,EAAMA,MAAMnnB,IAAM,aAAavH,GAAoB0uB,EAAMjS,QAAQ,OAAQ,SAAQ,IAAM,KAC3FiS,EAAMA,MAAMlnB,OAAS,aAAaxH,GAAoB0uB,EAAMjS,QAAQ,UAAW,SAAQ,IAAM,KAE7F3pB,EAGT,SAAA8pD,GAAoCtkB,GAClC,IAAIukB,GAAa,EAIjB,OAHAf,GAAiBxjB,EAAO,SAACwY,GACvB+L,EAAaA,GAAc/L,EAAQE,QAAQvzC,KAAK,SAAC88C,GAAS,OAAAA,EAAK1lD,QAAU2zB,OAEpEq0B,EAGT,SAAAtE,GAAkCzH,EAA6BzpC,EAAkB2f,GAC/E,IAAM81B,EAAUhM,EAAQiM,eAAiBjM,EAAQiM,iBACjD,GAAID,EAAQz1C,IAAYy1C,EAAQz1C,GAAS2f,GACvC,OAAO81B,EAAQz1C,GAAS2f,GAG1B81B,EAAQz1C,GAAWy1C,EAAQz1C,OAI3B,IAHA,IAAM21C,EAAW59C,GAAQ0xC,EAAQh+C,KAAO,KAAiB,WAAVk0B,EAAqB3f,EAAUypC,EAAQj+C,OAAOwU,KACzFvU,EAAOkqD,EACPC,EAAU,EACPH,EAAQhqD,IACbA,EAAUkqD,EAAQ,IAAIC,IAGxB,OAAQH,EAAQhqD,GAAQgqD,EAAQz1C,GAAS2f,GAASl0B,EAGpD,SAAA8mD,GAAsC9I,GACpC,IAAIv8C,EAAqB,KACrBslD,EAAY,KACZtzC,EAAqB,KACrBuzC,EAAa,KAWjB,OATAhJ,EAAQE,QAAQvxB,QAAQ,SAACrsB,EAAGC,GACtBD,EAAEiU,UAAYzC,IAChBrQ,EAAInB,EACJymD,EAAKxmD,GACID,EAAEiU,UAAYxC,KACvB0B,EAAInT,EACJ0mD,EAAKzmD,MAGDkB,EAACA,EAAEslD,GAAEA,EAAEtzC,EAACA,EAAEuzC,GAAEA,GkB3TtB,SAAAtP,GAAsCmO,GACpC,OAAOA,KAAeA,EAAU9jD,YAA6B2F,IAApBm+C,EAAUjZ,MAWrD,SAAAwd,GAAmCvE,GACjC,OAAOA,KAAeA,EAAU9jD,YAA0B2F,IAAjBm+C,EAAUwE,GAYrD,SAAAC,GAAoCzE,GAClC,OAAOA,KAAeA,EAAU9jD,YAA2B2F,IAAlBm+C,EAAU0E,IAYrD,SAAAC,GAAmC3E,GACjC,OAAOA,KAAeA,EAAU9jD,YAA0B2F,IAAjBm+C,EAAU4E,GAWrD,SAAAC,GAAoC7E,GAClC,OAAOA,KAAeA,EAAU9jD,YAA2B2F,IAAlBm+C,EAAU8E,IAarD,SAAAhT,GAAsCkO,GACpC,SAAIA,GAAaA,EAAU9jD,OACrBb,EAAQ2kD,EAAU3xB,QAAqC,IAA3B2xB,EAAU3xB,MAAMpzB,QAgBpD,SAAA82C,GAAsCiO,GACpC,OAAOA,KAAeA,EAAU9jD,QAC9Bb,EAAQ2kD,EAAUhO,QAClB32C,EAAQ2kD,EAAU+E,KAItB,SAAAnT,GAAiCoO,GAC/B,OAAOjO,GAAsBiO,IAAcnO,GAAsBmO,IAAclO,GAAsBkO,IAAcuE,GAAmBvE,IAAc2E,GAAmB3E,IAAcyE,GAAoBzE,IAAc6E,GAAoB7E,GAO7O,SAAA1+B,GAA2Bqe,EAAcqlB,EAAqCtiD,GAC5E,OAAOkE,GAAYo+C,EAAU,SAAChF,GAC5B,OAAItkD,EAASskD,GACJA,WA9HwBA,GACnC,OAAOA,GAAaA,EAAqB,UA8H5BiF,CAAqBjF,GACvBze,GAAmB5B,EAAOqgB,EAAU73B,UAAWzlB,GAE/CokC,GAAsBkZ,KAKnC,SAAAkF,GAA4BtjD,EAAyCwY,GACnE,OAAO6L,GAAUrkB,GAAIwY,SAAQA,EAAE8L,MAAM,IAQvC,SAAA4gB,GAAsCkZ,EAA2BmF,QAAA,IAAAA,IAAAA,GAAA,GACxD,IAAAjpD,EAAAA,EAAAA,MAAOke,EAAA4lC,EAAA5lC,SACR0G,EAAY1G,EAIf,QAAUgrC,GAAkBhrC,EAAUle,GAAS,IAChD4nB,GAAQk8B,GAAY37B,KAAM,UAE5B,GAAIwtB,GAAsBmO,GACxB,OAAOl/B,EAAY,MAAQokC,GAAmBlF,EAAUjZ,MAAO3sB,GAC1D,GAAImqC,GAAmBvE,GAE5B,OAAUl/B,EAAS,IAAIokC,GADjBG,EAAQrF,EAAUwE,GACyBpqC,GAC5C,GAAIuqC,GAAmB3E,GAE5B,OAAUl/B,EAAS,IAAIokC,GADjBI,EAAQtF,EAAU4E,GACyBxqC,GAC5C,GAAIqqC,GAAoBzE,GAE7B,OAAUl/B,EAAS,KAAKokC,GADlBG,EAAQrF,EAAU0E,IAC0BtqC,GAC7C,GAAIyqC,GAAoB7E,GAE7B,OAAUl/B,EAAS,KAAKokC,GADlBI,EAAQtF,EAAU8E,IAC0B1qC,GAC7C,GAAI23B,GAAsBiO,GAAY,CAE3C,IAAIhO,EAAQgO,EAAUhO,MAEtB,MAAO,YAhCX,SAA6B7rC,EAA8CiU,GACzE,OAAOjU,EAAKtK,IAAI,SAAC+F,GAAM,OAAAsjD,GAAmBtjD,EAAGwY,KAgCzCmrC,CAFFvT,EAAQA,GAASgO,EAAc,GAEF5lC,GAAU/d,KAAK,KAC5C,MAAQykB,EAAY,WACf,GAAIgxB,GAAsBkO,GAAY,CAC3C,IAAMsF,EAAQtF,EAAU3xB,MAAM,GACxBg3B,EAAQrF,EAAU3xB,MAAM,GAE9B,GAAc,OAAVi3B,GAA4B,OAAVD,GAAkBF,EACtC,MAAO,WAAarkC,EAAY,MAC9BokC,GAAmBI,EAAOlrC,GAAY,KACtC8qC,GAAmBG,EAAOjrC,GAAY,KAG1C,IAAMorC,KAQN,OAPc,OAAVF,GACFE,EAAMrqD,KAAQ2lB,EAAS,OAAOokC,GAAmBI,EAAOlrC,IAE5C,OAAVirC,GACFG,EAAMrqD,KAAQ2lB,EAAS,OAAOokC,GAAmBG,EAAOjrC,IAGnDorC,EAAMvqD,OAAS,EAAIuqD,EAAMnpD,KAAK,QAAU,OAIjD,MAAM,IAAI9B,MAAM,4BAA4BuB,KAAKC,UAAUikD,IAG7D,SAAAyF,GAAmCtmD,GACjC,OAAIyyC,GAAiBzyC,IAAMA,EAAEib,SAC3Bjc,KACKgB,GACHib,SAAUsH,GAAkBviB,EAAEib,YAG3Bjb,cC5MgBd,GACvB,YAAuBwD,IAAhBxD,EAAU,OAiOnB,SAAAqnD,GAAyBrnD,GACvB,YAAuBwD,IAAhBxD,EAAU,OAGnB,SAAAsnD,GAAyBtnD,GACvB,YAAuBwD,IAAhBxD,EAAU,OAGnB,SAAAunD,GAA4BvnD,GAC1B,YAA0BwD,IAAnBxD,EAAa,UAGtB,SAAAwnD,GAAsBxnD,GACpB,QAASA,EAAO,IAGlB,SAAAynD,GAA2BznD,GACzB,YAAyBwD,IAAlBxD,EAAY,SAGrB,SAAA0nD,GAA4B1nD,GAC1B,YAA0BwD,IAAnBxD,EAAa,UAGtB,SAAA2nD,GAAwB3nD,GACtB,YAAsBwD,IAAfxD,EAAS,MAKlB,SAAA0+C,GAAmC/oC,GACjC,OAAOA,EAAUnY,IAAI,SAAAwC,GACnB,OAAI4nD,GAAS5nD,IAETwG,OjF1PR,SAAAqhD,EAA2CziD,EAAuBikB,GAChE,OAAI7jB,EAAaJ,IACPK,IAAKoiD,EAAwBziD,EAAGK,IAAK4jB,IACpC/jB,EAAaF,IACdG,IAAKH,EAAGG,IAAI/H,IAAI,SAAAwc,GAAK,OAAA6tC,EAAwB7tC,EAAGqP,MAC/C5gB,EAAYrD,IACbC,GAAID,EAAGC,GAAG7H,IAAI,SAAAwc,GAAK,OAAA6tC,EAAwB7tC,EAAGqP,MAE/CA,EAAWjkB,GiFkPNyiD,CAAwB7nD,EAAEwG,OAAQ4gD,KAGvCpnD,sJC3PX,SAAA8nD,GAA4B9nD,EAAoCshC,GAC9D,IAAI9W,EAKFA,EAVJ,SAAwBxqB,GACtB,MAAO,OAAQA,EAMX+nD,CAAe/nD,GACZ3C,EAAS2C,EAAEwqB,KAAOxqB,EAAEwqB,GAAOxqB,EAAEwqB,GAAE,SAAWxqB,EAAEwqB,GAAG,GAAGxqB,EAAEwqB,GAAG,KAEtD/E,GAAQzlB,MAAQylB,GAAQzlB,GAAI+lB,UAAW,SAG/C,IAAM1T,EAAM6U,GAAalnB,EAAEqS,SAAK7O,OAC1B5B,EAzBR,SAAgByQ,EAAgBxU,GAC9B,OAAUioB,GAAYzT,GAAI,IAAIxU,EAwBlBmqD,CAAO31C,EAAKrS,EAAEnC,OACpBoJ,EAtBR,SAA6Bq6B,EAAc1/B,GACzC,OACEomB,OAAQsZ,EAAM6C,QAAWviC,EAAG,SAC5BqmD,aAAc3mB,EAAM6C,QAAWviC,EAAG,YAmB9BsmD,CAAA5mB,EAAA6mB,GAACngC,EAAA/gB,EAAA+gB,OAAQigC,EAAAhhD,EAAAghD,aAUf,OAAQrmD,IAAGumD,EAAEC,aARKtoD,GAChBuS,IAAKA,EACLxU,MAAOmC,EAAEnC,MACT2sB,GAAIA,GACDxC,GAAUA,OAAMA,MAChBigC,GAAgBA,aAAYA,QAmBnC,IAAAI,GAAA,SAAA5gB,GAKE,SAAA4gB,EAAY5jD,EAA8BmmB,GAA1C,IAAA+c,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YAD2BioC,EAAA/c,KAAAA,IA8F5C,OAnG6Bkd,EAAAA,EAAAA,GACpBugB,EAAAzoD,UAAAgnC,MAAP,WACE,OAAO,IAAIyhB,EAAQ,KAAMpgD,GAAUvI,KAAKkrB,QAO5By9B,EAAArX,iBAAd,SAA+BvsC,EAAsB68B,GACnD,IAAM1W,EAAO0W,EAAMsR,eAAe,SAAC0V,EAAuCxxC,EAAUzG,GAClF,GAAIyG,EAASzE,IAAK,CACV,IAAApL,EAAA6gD,GAAAhxC,EAAAwqB,GAAC1/B,EAAAA,EAAAA,IAAKwmD,EAAAnhD,EAAAmhD,aACZE,EAAkB1mD,GAAI9B,KACjBsoD,EACAE,EAAkB1mD,GApF/B,SAAsB0/B,EAAuBxqB,EAA4BzG,EAAkB+V,GACvF,GAAIsa,GAAiB5pB,EAAUzG,GAAU,CAGvC,IAAM66B,EAAQ6B,GAAYzL,KAAUA,EAAMhW,KAAKjb,IAAYixB,EAAMxO,OAAOziB,QAElE+0B,EAAa3f,GAAQ3O,GAAWkP,KAAM,UACtCqf,EAAW5f,GAAQ3O,GAAWkP,KAAM,QAASD,UAAW,QAE9D,OACEwiC,UAAW9iC,GAAQ3O,GAAWiP,UAAW,UACzC6uB,QAAS9P,GAAoBM,EAAYC,EAAU6F,EAAMx+B,OAAQ0Z,IAGrE,SAuESoiC,CAAalnB,EAAOxqB,EAAUzG,EAASixB,EAAMlb,SAGpD,OAAOkiC,OAGT,OAA0B,IAAtBxjD,GAAK8lB,GAAMhuB,OACN,KAGF,IAAIyrD,EAAQ5jD,EAAQmmB,IAOfy9B,EAAA/W,kBAAd,SAAgC7sC,EAAsBzE,EAAiBshC,SAC/Dtd,EAAA8jC,GAAA9nD,EAAAshC,GAAC1/B,EAAAA,EAAAA,IAAKwmD,EAAApkC,EAAAokC,aACZ,OAAO,IAAIC,EAAQ5jD,IAAMwC,MACtBrF,GAAMwmD,OAIJC,EAAAzoD,UAAAwwC,MAAP,SAAaxoC,GACXlI,KAAKkrB,KAAI9qB,KAAOJ,KAAKkrB,KAAShjB,EAAMgjB,MACpChjB,EAAMw/B,UAGDihB,EAAAzoD,UAAAinC,eAAP,WACE,IAAMliC,KAMN,OAJAmD,GAAKpI,KAAKkrB,MAAMnC,QAAQ,SAAAlsB,GACtBA,EAAEiuB,GAAG/B,QAAQ,SAAA3nB,GAAK,OAAA6D,EAAI7D,IAAK,MAGtB6D,GAGF0jD,EAAAzoD,UAAAknC,gBAAP,WACE,IAAMniC,KAMN,OAJAmD,GAAKpI,KAAKkrB,MAAMnC,QAAQ,SAAAlsB,GACtBoI,EAAIpI,EAAEsB,QAAS,IAGV8G,GAGF0jD,EAAAzoD,UAAAgpC,SAAP,WACE,OAAOhiC,EAAQkB,GAAKpI,KAAKkrB,MAAMptB,IAAI,SAAA6U,GACjC,IAAMsD,KAEA8yC,EAAQ3oD,GACV4T,KAAM,MACN7V,MAAOwU,EAAIxU,MACX2sB,GAAInY,EAAImY,GACRxC,OAAQ3V,EAAI2V,QACT3V,EAAIA,KAsBX,OAnBKA,EAAIA,IAAI4X,QAAU5X,EAAI41C,eACzBtyC,EAAU7Y,MACR4W,KAAM,SACN7V,MAAOwU,EAAIxU,MACXmqB,OAAQ3V,EAAI41C,eAEdQ,EAASx+B,QAAUjC,OAAQ3V,EAAI41C,eAGjCtyC,EAAU7Y,KAAK2rD,GAEXp2C,EAAIuiC,SACNj/B,EAAU7Y,MACR4W,KAAM,UACNsS,KAAM3T,EAAIuiC,QACVpqB,GAAInY,EAAIk2C,YAIL5yC,MAGb0yC,EAnGA,CAA6B7hB,IC1E7BkiB,GAAA,SAAAjhB,GAME,SAAAihB,EAAYjkD,EAAuC68B,EAAsB96B,GAAzE,IAAAmhC,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YADoCioC,EAAArG,MAAAA,EAAsBqG,EAAAnhC,OAAAA,EAEvEmhC,EAAK3hB,KAAO/C,GAAW0kB,EAAKrG,MAAOqG,EAAKnhC,OAAQmhC,KASpD,OAjBgCG,EAAAA,EAAAA,GAEvB4gB,EAAA9oD,UAAAgnC,MAAP,WACE,OAAO,IAAI8hB,EAAW,KAAMhpD,KAAK4hC,MAAOr5B,GAAUvI,KAAK8G,UAQlDkiD,EAAA9oD,UAAAgpC,SAAP,WACE,OACEl1B,KAAM,SACNsS,KAAMtmB,KAAKsmB,OAGjB0iC,EAjBA,CAAgCliB,ICAhCmiB,GAAA,SAAAlhB,GA4BE,SAAAkhB,EAAYlkD,EAA8B5I,EAA2B8oB,EAA0BqD,GAA/F,IAAA2f,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YAD2BioC,EAAA9rC,OAAAA,EAA2B8rC,EAAAhjB,QAAAA,EAA0BgjB,EAAA3f,OAAAA,IAYjG,OAxCiC8f,EAAAA,EAAAA,GACxB6gB,EAAA/oD,UAAAgnC,MAAP,WACE,OAAO,IAAI+hB,EAAY,KAAM1gD,GAAUvI,KAAK7D,QAAS6D,KAAKilB,QAASjlB,KAAKsoB,SAG5D2gC,EAAAC,SAAd,SAAuBnkD,EAAsB68B,GAC3C,IAAIunB,EAAiB,EAYrB,KAVE56C,GAAWD,KAAYG,GAAYD,KAAYua,QAAQ,SAACqgC,GACxD,IAAMC,EAAOD,EAAYtrD,IACvB,SAAA6S,GAAW,OAAAixB,EAAMpZ,gBAAgB7X,GAAWixB,EAAMxqB,SAASzG,GAASxS,WAAQ2F,KAG1EulD,EAAK,IAAMA,EAAK,MAClBtkD,EAAS,IAAIkkD,EAAYlkD,EAAQskD,EAAM,KAAMznB,EAAM6C,QAAQ,WAAW0kB,SAItEvnB,EAAMpZ,gBAAgB3Z,IAAQ,CAChC,IAAMuI,EAAWwqB,EAAMxqB,SAASvI,IAC5BuI,EAASpD,OAAS2Q,KACpB5f,EAAS,IAAIkkD,EAAYlkD,EAAQ,KAAMqS,EAASjZ,MAAOyjC,EAAM6C,QAAQ,WAAW0kB,OAIpF,OAAOpkD,GAOFkkD,EAAA/oD,UAAAgpC,SAAP,WACE,OAAA9oC,GACE4T,KAAM,WACFhU,KAAK7D,QAAUA,OAAQ6D,KAAK7D,WAC5B6D,KAAKilB,SAAWA,QAASjlB,KAAKilB,aAClCqD,OAAQtoB,KAAKsoB,UAGnB2gC,EAxCA,CAAiCniB,ICAjCwiB,GAAA,SAAAvhB,GAKE,SAAAuhB,EAAYvkD,EAA8ByR,EAA4Bra,EAA0B2uB,GAAhG,IAAAmd,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YAD2BioC,EAAAzxB,WAAAA,EAA4ByxB,EAAA9rC,OAAAA,EAA0B8rC,EAAAnd,GAAAA,IAqClG,OA1CkCsd,EAAAA,EAAAA,GACzBkhB,EAAAppD,UAAAgnC,MAAP,WACE,OAAO,IAAIoiB,EAAa,KAAMtpD,KAAKwW,WAAYjO,GAAUvI,KAAK7D,QAASoM,GAAUvI,KAAK8qB,MAO1Ew+B,EAAAJ,SAAd,SAAuBnkD,EAAsB68B,GAC3C,OAAKA,EAAMyO,oBAIT9hC,GAAWD,KAAYG,GAAYD,KAAYua,QAAQ,SAACqgC,GACxD,IAAMC,EAAOD,EAAYtrD,IACvB,SAAA6S,GAAW,OAAAixB,EAAMpZ,gBAAgB7X,GAAWixB,EAAMxqB,SAASzG,GAASxS,WAAQ2F,IAGxEkiB,EAASojC,EAAY,KAAO36C,GAAa,IAAM,IAEjD46C,EAAK,IAAMA,EAAK,MAClBtkD,EAAS,IAAIukD,EACXvkD,EACA68B,EAAMyO,iBACNgZ,GACCznB,EAAM6C,QAAQ,IAAMze,GAAS4b,EAAM6C,QAAQ,IAAMze,QAKjDjhB,GApBEA,GAuBJukD,EAAAppD,UAAAgpC,SAAP,WACE,OACEl1B,KAAM,WACNwC,WAAYxW,KAAKwW,WACjBra,OAAQ6D,KAAK7D,OACb2uB,GAAI9qB,KAAK8qB,KAGfw+B,EA1CA,CAAkCxiB,ICFlCyiB,GAAA,SAAAxhB,GAKE,SAAAwhB,EAAYxkD,UACVgjC,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,KAUjB,OAhBoCooC,EAAAA,EAAAA,GAC3BmhB,EAAArpD,UAAAgnC,MAAP,WACE,OAAO,IAAIqiB,EAAe,OAOrBA,EAAArpD,UAAAinC,eAAP,iBACE,OAAA5/B,MAASuqB,KAAe,EAAIvqB,GAGvBgiD,EAAArpD,UAAAgpC,SAAP,WACE,OAAQl1B,KAAM,aAAc8W,GAAIgH,KAEpCy3B,EAhBA,CAAoCziB,ICmDpC0iB,GAAA,SAAAzhB,GACE,SAAAyhB,EACkB7nB,EACA+J,EACT0I,QAFS,IAAAzS,IAAAA,WACA,IAAA+J,IAAAA,WACT,IAAA0I,IAAAA,GAAA,GAHT,IAAAnM,EAKEF,EAAAhpC,KAAAiB,KAAM2hC,EAAU+J,IAAS1rC,YAJTioC,EAAAtG,SAAAA,EACAsG,EAAAyD,SAAAA,EACTzD,EAAAmM,aAAAA,IAUX,OAdmChM,EAAAA,EAAAA,GAS1BohB,EAAAtpD,UAAAgnC,MAAP,WACE,IAAMA,EAAQa,EAAA7nC,UAAMgnC,MAAKnoC,KAAAiB,MAEzB,OADAknC,EAAMkN,aAAep0C,KAAKo0C,aACnBlN,GAEXsiB,EAdA,CAAmC/d,IC/CnCge,GAAA,SAAA1hB,GACE,SAAA0hB,EAAY1kD,EAAsCkR,EAA4CyzC,GAA9F,IAAAzhB,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YADmCioC,EAAAhyB,UAAAA,EAA4CgyB,EAAAyhB,UAAAA,IAwDhG,OAzDgCthB,EAAAA,EAAAA,GAKhBqhB,EAAAxW,KAAd,SAAmBluC,EAAsB68B,EAAc3rB,EAA4BswC,GACjF,IAAM5W,EAAU/N,EAAM0H,UAAUxP,KAAK6V,QAC/BxyC,EAAI,IAAIu3C,GAAWz+B,EAAUq0B,KAAKxQ,MACpC6vB,EAAaha,EAAQxyC,EAAEsJ,QACtBkjD,IACHha,EAAQxyC,EAAEsJ,QAAUtJ,EACpBwsD,EAAaxsD,GAGf,IAAMysD,EAAiBhoB,EAAM6C,QAAQ,UAAU8hB,GACzCsD,EAAiB,IAAI/hB,GAAW6hB,EAAYC,EAAgB,SAAUhoB,EAAM0H,UAAUxP,KAAKolB,qBAIjG,OAFAtd,EAAM0H,UAAUxP,KAAKid,YAAY6S,GAAkBC,EAE5C,IAAIJ,EAAW1kD,EAAQkR,EAAW4zC,EAAevhB,cAGnDmhB,EAAAvpD,UAAAinC,eAAP,WACE,OAAO3nC,EAAMQ,KAAKiW,UAAUq0B,KAAKnuC,SAAY6D,KAAKiW,UAAU6U,cAAcvtB,MAASyC,KAAKiW,UAAU6U,IAAM9qB,KAAKiW,UAAU6U,OAGlH2+B,EAAAvpD,UAAAgpC,SAAP,WACE,IAAI4gB,EAEJ,GAAI9pD,KAAKiW,UAAUq0B,KAAKnuC,OAEtB2tD,EAAO1pD,GACLuH,OAAQ3H,KAAKiW,UAAUq0B,KAAKnuC,QACxB6D,KAAKiW,UAAU6U,IAAMA,GAAM9qB,KAAKiW,UAAU6U,cAAcvtB,MAASyC,KAAKiW,UAAU6U,IAAM9qB,KAAKiW,UAAU6U,aAEtG,CAEL,IAAIi/B,EAAS/pD,KAAKiW,UAAU6U,GACvBntB,EAASosD,KACZxuC,GAASC,GAAYtF,oBACrB6zC,EAAS,WAGXD,GACEh/B,IAAKi/B,IAIT,OAAA3pD,GACE4T,KAAM,SACNs2B,KAAMtqC,KAAK0pD,UACXxnD,IAAKlC,KAAKiW,UAAUq0B,KAAKpoC,IACzB/F,QAAS6D,KAAKiW,UAAU+zC,SACrBF,EACC9pD,KAAKiW,UAAUg0C,SAAWA,QAASjqD,KAAKiW,UAAUg0C,cAG5DR,EAzDA,CAAgC3iB,IC0BhC,SAAAojB,GAAsBpwB,GAEpB,IAAIqwB,EAAe,EA8InB,OAzIA,SAAAC,EAAkBzlD,EAAoB0lD,GAChC1lD,aAAgB+vC,KAGbza,GAAUt1B,EAAKm1B,QAClBA,EAAK18B,KAAKitD,GAMVA,GAJEjuD,KAAM,KACNmH,OAAQ8mD,EAAWjuD,KACnB6Z,gBAsBN,GAhBItR,aAAgB2uC,KACd3uC,EAAKI,kBAAkB2vC,KAAe2V,EAAW9mD,QAEnD8mD,EAAWr9C,OAAM5M,KACZiqD,EAAWr9C,YACdxE,MAAO7D,EAAK0vC,wBAIdgW,EAAWp0C,UAAYo0C,EAAWp0C,UAAUpX,OAAO8F,EAAK4vC,oBAAmB,KAG3E8V,EAAWp0C,UAAYo0C,EAAWp0C,UAAUpX,OAAO8F,EAAK4vC,uBAIxD5vC,aAAgBwtC,GAelB,OAdKkY,EAAWjuD,OACdiuD,EAAWjuD,KAAO,QAAQ+tD,MAGvBE,EAAW9mD,QAAU8mD,EAAWp0C,UAAU/Y,OAAS,GACtD48B,EAAK18B,KAAKitD,GACV1lD,EAAKm1B,KAAOuwB,EAAWjuD,MAEvBuI,EAAKm1B,KAAOuwB,EAAW9mD,YAGzBoB,EAAKukC,WAAWngB,QAAQ,SAAAnpB,GAAK,OAAAk6B,EAAK18B,KAAKwC,MAMrC+E,aAAgBqkD,IAClBrkD,aAAgB8jC,IAChB9jC,aAAgB2kD,IAChB3kD,aAAgBskD,IAChBtkD,aAAgBwsC,IAChBxsC,aAAgB8kD,IAChB9kD,aAAgB2lD,IAChB3lD,aAAgB4kD,KAChBc,EAAWp0C,UAAU7Y,KAAKuH,EAAKukC,aAG7BvkC,aAAgBquC,IAClBruC,aAAgBgkD,IAChBhkD,aAAgBswC,IAChBtwC,aAAgBgxC,MAChB0U,EAAWp0C,UAAYo0C,EAAWp0C,UAAUpX,OAAO8F,EAAKukC,aAGtDvkC,aAAgBwsC,KACbkZ,EAAWjuD,OACdiuD,EAAWjuD,KAAO,QAAQ+tD,MAI1BxlD,aAAgBmjC,KACduiB,EAAW9mD,QAA0C,IAAhC8mD,EAAWp0C,UAAU/Y,OAC5CyH,EAAK6jC,UAAU6hB,EAAW9mD,QACjBoB,EAAKI,kBAAkB+iC,GAGhCnjC,EAAK6jC,UAAU6hB,EAAWjuD,OAErBiuD,EAAWjuD,OACdiuD,EAAWjuD,KAAO,QAAQ+tD,KAK5BxlD,EAAK6jC,UAAU6hB,EAAWjuD,MAGC,IAAvBuI,EAAK4iC,gBACPzN,EAAK18B,KAAKitD,GAMVA,GAJEjuD,KAAM,KACNmH,OAAQ8mD,EAAWjuD,KACnB6Z,iBAOR,OAAQtR,EAAK4iC,eACX,KAAK,EAEC5iC,aAAgBmjC,MAAgBuiB,EAAW9mD,QAAU8mD,EAAWp0C,UAAU/Y,OAAS,IAErF48B,EAAK18B,KAAKitD,GAEZ,MACF,KAAK,EACHD,EAASzlD,EAAK2pC,SAAS,GAAI+b,GAC3B,MACF,QACOA,EAAWjuD,OACdiuD,EAAWjuD,KAAO,QAAQ+tD,KAG5B,IAAII,EAASF,EAAWjuD,MACnBiuD,EAAW9mD,QAAU8mD,EAAWp0C,UAAU/Y,OAAS,EACtD48B,EAAK18B,KAAKitD,GAEVE,EAASF,EAAW9mD,OAGtBoB,EAAK2pC,SAASvlB,QAAQ,SAAA0Q,GAMpB2wB,EAAS3wB,GAJPr9B,KAAM,KACNmH,OAAQgnD,EACRt0C,+BCnKyB2rB,GACnC4oB,GAAwB5oB,GAExB,IAAM6oB,EAAiB7oB,EAAM0H,UAAU0B,WACvCyf,EAAe7e,gBAAgB,QAAS8e,GAAiC9oB,EAAO,UAChF6oB,EAAe7e,gBAAgB,SAAU8e,GAAiC9oB,EAAO,WAG5E,IAAM+oB,GAAwBC,GAUrC,SAAAJ,GAAwC5oB,GACtC,IAAoB,IAAAz7B,EAAA,EAAAoB,EAAAq6B,EAAM0M,SAANnoC,EAAAoB,EAAArK,OAAAiJ,IAAgB,CAApBoB,EAAApB,GACRk5C,mBAIV,SAAAqL,GAA0C9oB,EAAcmJ,GAMtD,IALA,IAGI8f,EAHEl6C,EAAuB,UAAbo6B,EAAuB,IAAM,IACvCxX,EAAUqO,EAAM0H,UAAU/V,QAIZptB,EAAA,EAAAoB,EAAAq6B,EAAM0M,SAANnoC,EAAAoB,EAAArK,OAAAiJ,IAAgB,CAA/B,IACG2kD,GADGrxB,EAAKlyB,EAAApB,IACUmjC,UAAU0B,WAAWW,gBAAgBZ,GACvDggB,EAAex3B,EAAQ3mB,MAAM+D,GACnC,GAAqB,gBAAjBo6C,GAAsD,eAApBD,EAAU/pD,MAAwB,CAGtE8pD,OAAa/mD,EACb,MAGF,GAAI+mD,EAAY,CACd,GAAqB,gBAAjBE,GAAkCF,EAAW9pD,QAAU+pD,EAAU/pD,MAAO,CAG1E8pD,OAAa/mD,EACb,MAEF+mD,EAAave,GACXue,EAAYC,EAAW/f,EAAU,SAGnC8f,EAAaC,EAIjB,GAAID,EAAY,CAEd,IAAoB,IAAAvmC,EAAA,EAAAyH,EAAA6V,EAAM0M,SAANhqB,EAAAyH,EAAA7uB,OAAAonB,IAAgB,CAA/B,IAAMmV,EAAK1N,EAAAzH,GACdsd,EAAMge,iBAAiBnmB,EAAMgL,QAAQsG,GAAWnJ,EAAM6C,QAAQsG,IAC9DtR,EAAM6P,UAAU0B,WAAWa,IAAId,EAAU,UAAU,GAErD,OAAO8f,EAGP,OACElpB,UAAU,EACV5gC,WAAO+C,GAkBb,SAAAknD,GAAyBppB,EAAkBmJ,GACzC,IAAMp6B,EAAuB,UAAbo6B,EAAuB,IAAM,IACvCrkB,EAASkb,EAAMlb,OACfqc,EAAiBnB,EAAMoB,kBAAkBryB,GAE/C,GAAIoyB,EAAgB,CAClB,IAAMnsB,EAAYmsB,EAAe9B,IAAI,QAC/B3Q,EAAQyS,EAAe9B,IAAI,SAEjC,OAAIjS,GAAkBpY,IAAcimB,GAAcvM,GAEzC,aAEA5J,EAAO+L,KAAKsY,GAEhB,OAAInJ,EAAMqO,cACRvpB,EAAO+L,KAAKsY,GAGF,UAAbA,GAAuC,SAAfnJ,EAAM/vB,KAEzB6U,EAAO9Z,MAAMyiB,eAIf3I,EAAO9Z,MAAM0iB,WAAaF,GAAmBE,UC7FxD,SAAA27B,GAAkD3wC,EAAMkkC,GACtD,OAAIr5B,GAAY7K,EAAEnc,OACZmc,EAAEnc,MAAM+sD,UAAU1M,EAEpBp+C,KAAWka,GAAUnc,MAAOqgD,EAASlkC,EAAEnc,MAAM+sD,eAE7C3vC,GAASC,GAAYhG,oBAAoB8E,EAAEnc,MAAM+sD,SAI9C5wC,EAMT,SAAA6wC,GAAmC/zC,EAAgConC,GAGjE,QAAiB16C,KAFjBsT,EAAW6zC,GAAc7zC,EAAUonC,IAEnC,CAKA,GAAIpnC,EAAS9R,MAAQilC,GAAYnzB,EAAS9R,MAAO,CAC/C,IAAMA,EAAO2lD,GAAc7zC,EAAS9R,KAAMk5C,GAC1CpnC,EAAQhX,KACHgX,EACC9R,GAAQA,KAAIA,OAIpB,OAAO8R,GAGT,SAAAg0C,GAAqC7lC,EAA+Bi5B,GAClE,IAAI94B,GAAWH,GAOR,CACL,GAAIE,GAAuBF,GAAa,CAEtC,GADMgsB,EAAK4Z,GAA0B5lC,EAAWC,UAAWg5B,GAEzD,OAAO6M,KACF9lC,GACHC,UAAW+rB,IAGNhsB,EAAAC,UACP,OADkBhlB,EAAA+kB,GAAA,cAItB,OAAOA,EAnBP,IAAMgsB,EACN,OADMA,EAAK4Z,GAA0B5lC,EAAYi5B,IAExCjN,EACEjsB,GAAiBC,IAClBC,UAAWD,EAAWC,gBADzB,EAuBX,SAAA8lC,GAAyBriC,EAAiCu1B,GACxD,IAAMv5C,KACN,IAAK,IAAM0L,KAAWsY,EACpB,GAAIA,EAAQppB,eAAe8Q,GAAU,CACnC,IAAM4U,EAAsD0D,EAAQtY,GAEpE,GAAIrT,EAAQioB,GAEVtgB,EAAI0L,GAAW4U,EAAWznB,IAAI,SAAA0jD,GAAM,OAAA4J,GAA4B5J,EAAIhD,KACjE13C,OAAO,SAAA06C,GAAM,OAAAA,QACX,CACL,IAAMA,EAAK4J,GAA4B7lC,EAAYi5B,GAC/CgD,IACFv8C,EAAI0L,GAAW6wC,IAKvB,OAAOv8C,cChF0BmS,EAAiC9R,EAAiCghB,GACnG,OAAOP,GAAQzgB,GAAOghB,KAAIA,EAAEN,OAAQ,MAAMD,GAAQ3O,KAGpD,IAAAm0C,GAAA,SAAAxjB,GAQE,SAAAwjB,EAAYrhC,EAA2BnlB,EAAew5C,EAAyBC,EAAyB93B,GAAxG,IAAAuhB,EACEF,EAAAhpC,KAAAiB,KAAMkqB,EAAMnlB,EAAQw5C,EAAiB73B,EAAQ83B,EAAUt0B,EAAKqJ,UAAQvzB,KARtDioC,EAAAj0B,KAAgB,QAW9Bi0B,EAAKxO,MAAQ+xB,GAAWthC,EAAKA,KAAM+d,EAAMA,EAAKxD,QAAQ,cAAU3gC,EAAW06C,EAAU93B,GAAQ,GAC7FuhB,EAAKqG,UAAYrG,EAAKxO,OAEtB,IAAMzB,WD/B6BA,EAA4BwmB,GACjE,OAAO8M,GAAgBtzB,EAAOwmB,GC8BQiN,CAAuBvhC,EAAK8N,MAAOwmB,UAEvEvW,EAAKjQ,MAAQiQ,EAAKyjB,UAAU1zB,KAuXhC,OAxYgCoQ,EAAAA,EAAAA,GAoBtBmjB,EAAArrD,UAAAwrD,UAAR,SAAkB1zB,GAEhB,OAAOtV,GAAOsV,EAAO,SAAS2zB,EAAiBv0C,EAA4BzG,GACzE,OAAKhK,GAAUqH,GAAKC,IAAS0C,QAMN7M,IAAnBsT,EAASjZ,OACXod,GAASC,GAAYrE,cAAcC,EAAUzG,IACtCg7C,IAITA,EAAgBh7C,GAAW0K,GAAUjE,EAAUzG,GACxCg7C,IAXLpwC,GAASC,GAAYhE,oBAAoB7G,EAAS,UAC3Cg7C,SAcNJ,EAAArrD,UAAAsoB,gBAAP,SAAuB7X,GACrB,QAAS3Q,KAAKg4B,MAAMrnB,IAGf46C,EAAArrD,UAAAkX,SAAP,SAAgBzG,GACd,OAAO3Q,KAAKg4B,MAAMrnB,IAGb46C,EAAArrD,UAAAs/C,UAAP,WACEx/C,KAAKspC,UAAUxP,KAAO0lB,GAAUx/C,MAChCA,KAAKy5B,MAAM+lB,aAGN+L,EAAArrD,UAAAm/C,gBAAP,WACEmL,GAAwBxqD,OAGnBurD,EAAArrD,UAAAq/C,eAAP,WAIEv/C,KAAKy5B,MAAM8lB,iBACXv/C,KAAKspC,UAAUlf,UAAYpqB,KAAKy5B,MAAM6P,UAAUlf,WAG3CmhC,EAAArrD,UAAAw/C,eAAP,WACE1/C,KAAKy5B,MAAMimB,kBAGN6L,EAAArrD,UAAAu/C,mBAAP,WACEz/C,KAAKy5B,MAAMgmB,qBAEXz/C,KAAK4rD,YAAY,UACjB5rD,KAAK4rD,YAAY,OAEjB5rD,KAAK6rD,eAAe,KACpB7rD,KAAK6rD,eAAe,MAGdN,EAAArrD,UAAA0rD,YAAR,SAAoBj7C,GAElB,GAAI3Q,KAAKwoB,gBAAgB7X,GAAU,CACjC,IAAMyG,EAAWpX,KAAKg4B,MAAMrnB,GACtBguB,EAASvnB,EAASunB,WACpBhyB,OAA2B7I,IAAnBsT,EAASzK,MAAsByK,EAASzK,WACjC7I,IAAjB66B,EAAOhyB,MAAsBgyB,EAAOhyB,MAAQuyB,GAAc9nB,EAAUpX,KAAK0mB,QAEvE1mB,KAAKy5B,MAAM6P,UAAUC,cAAc54B,GAAShE,QAE9CA,GAAS,MAAQ3M,KAAKy5B,MAAM6P,UAAUC,cAAc54B,GAAShE,MAC7D3M,KAAKy5B,MAAM6P,UAAUC,cAAc54B,GAAShE,MAAQ,MAGtD3M,KAAKspC,UAAUC,cAAc54B,IAC3BhE,MAAK89B,EACLhB,cAAeryB,EAEfunB,QAAS3+B,KAAK8rD,oBAAoBn7C,GAAS,OAKzC46C,EAAArrD,UAAA4rD,oBAAR,SAA4Bn7C,EAAwBvE,GAClD,IAAM2+B,EAAuB,QAAZp6B,EAAoB,SAAW,QAEhD,OACEvE,OAAMA,EACNs+B,WAAY1qC,KAAKy5B,MAAM6P,UAAU0B,WAAW/J,IAAI8J,GAAY/qC,KAAKy5B,MAAMwR,iBAAiBF,QAAYjnC,EACpGsmC,UAIImhB,EAAArrD,UAAA2rD,eAAR,SAAuBl7C,GACd,ItDlFmB5D,EsDkFnB0sB,EAAAz5B,KAAAy5B,MACP,GAAIA,EAAM6P,UAAUc,KAAKz5B,GAAU,CAC3B,IAAApJ,EAAAvH,KAAAspC,UAACC,EAAAhiC,EAAAgiC,cAAehW,EAAAhsB,EAAAgsB,QAGtB,GAFAA,EAAQ3H,KAAKjb,GAAW26B,GAAkB/X,EAAS5iB,GAErB,WAA1B4iB,EAAQ3H,KAAKjb,GAKf,IAHA,IAAMo7C,EAA4B,MAAZp7C,EAAkB,SAAW,MAE7Ck5B,EAAeN,EAAcwiB,GACP5lD,EAAA,EAAAme,EAAAmV,EAAM6P,UAAUc,KAAKz5B,GAArBxK,EAAAme,EAAApnB,OAAAiJ,IAA+B,CAAtD,IAAM6lD,EAAa1nC,EAAAne,GAChB6jC,EtD5FC,SADaj9B,EsD6Fai/C,EAAc/qB,IAAI,YtD5FxB,SAAXl0B,EACf,SAEF,SsD0FC88B,EAAaG,GAAcH,EAAaG,KACvChqC,KAAK8rD,oBAAoBC,GAAe,IAEzC,IAAME,EAAWztB,GAAawtB,EAAe,OAAQhsD,KAAK0mB,QAASiY,QAAQ,IAE3EkL,EAAaG,GAAY,GAAGI,KAAKhtC,KAAK6uD,GACtCD,EAAcltB,eAAgB,KAQ/BysB,EAAArrD,UAAAgsD,iCAAP,SAAwCzL,GACtC,OAAOzgD,KAAKy5B,MAAMyyB,iCAAiCzL,IAG9C8K,EAAArrD,UAAAwgD,yBAAP,WAEE,OADA1gD,KAAKy5B,MAAMinB,+BAIN6K,EAAArrD,UAAAisD,sBAAP,SAA6BryB,GAC3B,OAAO95B,KAAKy5B,MAAM0yB,sBAAsBryB,IAGlCyxB,EAAArrD,UAAAksD,sBAAR,WAAA,IAAAnkB,EAAAjoC,KACQqsD,KAuBN,OArBC,MAAO,UAAUtjC,QAAQ,SAACpY,IACxB,SAAU,UAAUoY,QAAQ,SAACihB,GAC5B,IAAMsiB,EAAwBrkB,EAAKqB,UAAUC,cAAc54B,GACrD47C,EAAkBD,EAAsBtiB,GAC9C,GAAIuiB,GAAmBA,EAAgB,GAAI,CAEzC,IAAMxhB,EAAuB,QAAZp6B,EAAoB,SAAW,QAC1C67C,EAA0B,WAAfxiB,EAA0B,aAAe,aACrD/B,EAAKxO,MAAM6P,UAAU0B,WAAW/J,IAAI8J,KAEvCshB,EAAaG,GAAYH,EAAaG,OACtCH,EAAaG,GAAU77C,GAAW,IAGhC27C,EAAsB3/C,QACxB0/C,EAAa5/C,OAAS4/C,EAAa5/C,WACnC4/C,EAAa5/C,OAAmB,QAAZkE,EAAoB,WAAa,eAAiB,SAKvE07C,GAGCd,EAAArrD,UAAA8/C,sBAAV,WACE,IAAMyM,EAAUzsD,KAAKwoB,gBAAgB,UAAYxoB,KAAK0sD,uBAAyB,EAI/E,OAAAtsD,KACKJ,KAAKosD,yBAERK,QAAOA,EACPhO,OAAQ,OACRjhB,MAAO,SAIJ+tB,EAAArrD,UAAAysD,sBAAP,WAEE,OAAO3sD,KAAKy5B,MAAMkzB,yBAGZpB,EAAArrD,UAAAwsD,qBAAR,WACE,KAAI1sD,KAAK+E,QAAW/E,KAAK+E,kBAAkBwmD,GAQzC,OAAQjjC,OAAQ,gBADYtoB,KAAKykC,QAAQ,iBACU,QAIhD8mB,EAAArrD,UAAAsgD,cAAP,SAAqBC,GACnB,OAAIzgD,KAAK+E,QAAW/E,KAAK+E,kBAAkBwmD,EAIzCnrD,KACMJ,KAAKwoB,gBAAgB,WACvB1a,QACEq8B,QAGEsiB,SAAUtuD,MAAO4nB,GAAQ/lB,KAAKg4B,MAAMlnB,QAASpH,OAAQ,oBAIxDq+B,EAAA7nC,UAAMsgD,cAAazhD,KAAAiB,KAACygD,IAGpB1Y,EAAA7nC,UAAMsgD,cAAazhD,KAAAiB,KAACygD,IAMrB8K,EAAArrD,UAAA0sD,gCAAR,WACE,IAAMzwD,KACA61C,KACAlnB,KAEN,GAAI9qB,KAAKy5B,iBAAiB8xB,GACxB,GAAIvrD,KAAKy5B,MAAMjR,gBAAgB,UAAW,CACxC,IAAMrqB,EAAQ4nB,GAAQ/lB,KAAKy5B,MAAMzB,MAAMlnB,QACvC3U,EAAOiB,KAAKe,GACZ6zC,EAAI50C,KAAK,YACT0tB,EAAG1tB,KAAK,YAAYe,SAGtB,IAAsB,IAAAgI,EAAA,EAAAoB,GAAC,IAAK,KAANpB,EAAAoB,EAAArK,OAAAiJ,IAA8B,CAA/C,IAAMwK,EAAOpJ,EAAApB,GACVssC,EAAsBzyC,KAAKy5B,MAAM6P,UAAUoJ,OAAO/hC,GACxD,GAAI8hC,IAAwBA,EAAoBta,OAAQ,CACtD,IAAMnkB,EAAOy+B,EAAoBxR,IAAI,QAC/B3Q,EAAQmiB,EAAoBxR,IAAI,SAEtC,GAAIjS,GAAkBhb,IAAS6oB,GAAcvM,IAErCnyB,EAAQw0C,GADCC,GAAe5yC,KAAKy5B,MAAO9oB,MAGxCxU,EAAOiB,KAAKe,GACZ6zC,EAAI50C,KAAK,YACT0tB,EAAG1tB,KAAK,YAAYe,IAEpBod,GAAS,+DAMnB,OAAQpf,OAAMA,EAAE61C,IAAGA,EAAElnB,GAAEA,IAIjBygC,EAAArrD,UAAA2sD,cAAR,WAAA,IAAA5kB,EAAAjoC,KACQuH,EAAAvH,KAAAspC,UAAAxP,KAAAgzB,UAAC1wD,EAAAmL,EAAAnL,KAAM09B,EAAAvyB,EAAAuyB,KACPxV,EAAAtkB,KAAAg4B,MAACnnB,EAAAyT,EAAAzT,IAAKC,EAAAwT,EAAAxT,OACNib,EAAA/rB,KAAA4sD,kCAACzwD,EAAA4vB,EAAA5vB,OAAQ61C,EAAAjmB,EAAAimB,IAAKlnB,EAAAiB,EAAAjB,GACdG,MAEL,MAAO,UAAUlC,QAAQ,SAACpY,GACzB,IAAMyG,EAAW6wB,EAAKjQ,MAAMrnB,GAC5B,GAAIyG,EAAU,CACZ6T,EAAQ7tB,KAAK2oB,GAAQ3O,IACd,IAAA9R,EAAA8R,EAAA9R,KACP,GAAIilC,GAAYjlC,GAAO,CACd,IAAAnH,EAAAA,EAAAA,MAAOuH,EAAAJ,EAAAI,GACRqnD,EAAaC,GAAmB51C,EAAU9R,GAC5CuL,GAAOC,GAIT3U,EAAOiB,KAAK2vD,GACZ/a,EAAI50C,KAAK,OACT0tB,EAAG1tB,KAAK2vD,KAER5wD,EAAOiB,KAAKe,GACZ6zC,EAAI50C,KAAKsI,GACTolB,EAAG1tB,KAAK2vD,SAEL,GAAIzvD,EAAQgI,GAAO,CAClBynD,EAAa9jB,GAAoB7xB,EAAUzG,GACjDxU,EAAOiB,KAAK2vD,GACZ/a,EAAI50C,KAAK,OACT0tB,EAAG1tB,KAAK2vD,OAKd,IAAME,IAAUp8C,KAASC,EAEzB,OAAA1Q,GACEhE,KAAIA,EACJ09B,KAAIA,EACJ7O,QAAOA,GACHgiC,GAAS9wD,EAAOe,QAClByO,UAASvL,KACH6sD,GAASA,MAAKA,MACd9wD,EAAOe,QAAUf,OAAMA,EAAE61C,IAAGA,EAAElnB,GAAEA,aAOpCygC,EAAArrD,UAAAgtD,iBAAR,SAAyBv8C,GAChB,IACDyG,EADCpX,KAAAg4B,MACgBrnB,GAEvB,OAAIyG,EACEmzB,GAAYnzB,EAAS9R,OACf0nD,GAAmB51C,EAAUA,EAAS9R,KAAM,UAC3ChI,EAAQ8Z,EAAS9R,OAClB2jC,GAAoB7xB,EAAUzG,EAAS,WAEzCoV,GAAQ3O,GAAWkP,KAAM,eAK7BilC,EAAArrD,UAAAitD,gBAAR,SAAwBx8C,GACf,IACDyG,EADCpX,KAAAg4B,MACgBrnB,GACvB,GAAIyG,EAAU,CACL,IAAA9R,EAAA8R,EAAA9R,KAEP,QADeilC,GAAYjlC,GAAQA,EAAKgL,OAAShT,EAAQgI,IAASA,IAAS,aAG7E,UAGKimD,EAAArrD,UAAAygD,cAAP,WACS,IAAAlnB,EAAAz5B,KAAAy5B,MAEDK,EHpMV,SAAkCszB,GAChC,IAAMtzB,KACAswB,EAAWF,GAAapwB,GAQ9B,OANAszB,EAAK9e,SAASvlB,QAAQ,SAAA0Q,GAAS,OAAA2wB,EAAS3wB,GACtCl2B,OAAQ6pD,EAAKhxD,KACbA,KAAM,KACN6Z,iBAGK6jB,EG0LQuzB,CADKrtD,KAAKspC,UAAUxP,KAAKgzB,WAKhCQ,EAAwB7zB,EAAMqmB,qBAE9BnzC,EAAQ8sB,EAAM0F,gBACdrT,EAAQ2N,EAAMomB,qBA0BpB,OAxBez/C,GACbhE,KAAM4D,KAAKykC,QAAQ,QACnBzwB,KAAM,SACFrH,GAAQA,MAAK89B,MACb3e,GAAQA,MAAKA,OACjBwe,MACEtS,MAAOh4B,KAAK6sD,iBAGdvnD,MACEnH,MACK6B,KAAKktD,iBAAiB,OAAMruD,OAC5BmB,KAAKktD,iBAAiB,WAE3B58C,MACKtQ,KAAKmtD,gBAAgB,OAAMtuD,OAC3BmB,KAAKmtD,gBAAgB,aAGxBrzB,EAAK58B,OAAS,GAAK48B,KAAMA,MACzBwzB,GAAyBx/C,QAASq8B,OAAQmjB,OAC3C7zB,EAAM+mB,mBAOH+K,EAAArrD,UAAAohD,WAAV,WACE,OAAOthD,KAAKg4B,OAEhBuzB,EAxYA,CAAgClK,IChBhCiJ,GAAA,SAAAviB,GA8BE,SAAAuiB,EAAYvlD,EAA8BkR,GAA1C,IAAAgyB,EACEF,EAAAhpC,KAAAiB,KAAM+E,IAAO/E,YAD2BioC,EAAAhyB,UAAAA,IAoE5C,OAlGyCmyB,EAAAA,EAAAA,GACzBkiB,EAAAiD,cAAd,SAA4BxoD,EAAsBizB,GACzC,IAAAnnB,EAAAmnB,EAAAnnB,IAAKC,EAAAknB,EAAAlnB,OACZ,GAAID,GAAOC,EAAQ,CAGjB,IAFA,IAAI+2B,EAAY,KAEO1hC,EAAA,EAAAoB,GAACsJ,EAAKC,GAAN3K,EAAAoB,EAAArK,OAAAiJ,IAAe,CAAjC,IAAMiR,EAAQ7P,EAAApB,GACjB,GAAIokC,GAAYnzB,EAAS9R,MAAO,CACxB,IAAAgf,EAAAlN,EAAA9R,KAACnH,EAAAmmB,EAAAnmB,MACP4G,EAAS8iC,EAAY,IAAIyiB,EAAoBvlD,GAC3CyoD,SACE9nD,GAHU4e,EAAA5e,GAIVvH,MAAKA,EACL2sB,GAAIkiC,GAAmB51C,EAAUA,EAAS9R,QAE5C2lB,SAAUlF,GAAQ3O,IAClBq2C,OAAQ,KAAM,SAIpB,OAAO5lB,EAET,OAAO,MAIFyiB,EAAApqD,UAAAgnC,MAAP,WACE,OAAO,IAAIojB,EAAoBtqD,KAAK+E,OAAQwD,GAAUvI,KAAKiW,aAOtDq0C,EAAApqD,UAAAinC,eAAP,WAAA,IAAAc,EAAAjoC,KACQiF,KAKN,OAJAjF,KAAKiW,UAAUu3C,OAAOzkC,QAAQ,SAAA2kC,GAC5BzoD,EAAIgjC,EAAK0lB,eAAeD,KAAmB,IAGtCzoD,GAGDqlD,EAAApqD,UAAAytD,eAAR,SAAuBD,GACrB,OAAOA,EAAe5iC,IAAM/E,GAAQ2nC,IAG/BpD,EAAApqD,UAAAgpC,SAAP,WAKE,IAJA,IAAM/sC,KACA61C,KACAlnB,KACA8iC,KACeznD,EAAA,EAAAoB,EAAAvH,KAAKiW,UAAUu3C,OAAfrnD,EAAAoB,EAAArK,OAAAiJ,IAAuB,CAAvC,IAAM0nD,EAAMtmD,EAAApB,GACf6rC,EAAI50C,KAAKywD,EAAOnoD,IAChBolB,EAAG1tB,KAAK4C,KAAK2tD,eAAeE,IAC5BD,EAAOxwD,UAAsB0G,IAAjB+pD,EAAOC,MAAsB,KAAOD,EAAOC,OACvD3xD,EAAOiB,UAAsB0G,IAAjB+pD,EAAO1vD,MAAsB,KAAO0vD,EAAO1vD,OAGzD,IAAMsvD,EAAQztD,KAAKiW,UAAUw3C,MACvBxiC,EAAUjrB,KAAKiW,UAAUgV,QACzB6qB,KACAC,KACN,QAA4BjyC,IAAxB9D,KAAKiW,UAAU3Q,KACjB,IAAwB,IAAAgf,EAAA,EAAAyH,EAAA/rB,KAAKiW,UAAU3Q,KAAfgf,EAAAyH,EAAA7uB,OAAAonB,IAAqB,CAAxC,IAAM8tB,EAASrmB,EAAAzH,GAClBwxB,EAAW14C,KAAKg1C,EAAUj0C,OAC1B43C,EAAU34C,KAAKg1C,EAAU9hC,OAAS,aAGtC,IAAMhL,GACJnH,MAAO23C,EACPxlC,MAAOylC,GAEHgY,EAAc/tD,KAAKiW,UAAU83C,YAE7BtqD,GACJuQ,KAAM,SACN45C,OAAMA,EACN9iC,GAAEA,EACFknB,IAAGA,EACH71C,OAAMA,EACNmJ,KAAIA,GAeN,YAZoBxB,IAAhBiqD,IACFtqD,EAAOsqD,YAAcA,QAGPjqD,IAAZmnB,IACFxnB,EAAOwnB,QAAUA,QAGLnnB,IAAV2pD,IACFhqD,EAAOgqD,MAAQA,GAGVhqD,GAEX6mD,EAlGA,CAAyCxjB,ICoJzC,SAAA0Y,GAA0B5d,GACxB,IAAIosB,EA1IN,SAAmBpsB,EAAc+N,GAC/B,GAAI/N,EAAM9H,OAAS8H,EAAM78B,OAAQ,CAE/B,IAAMxB,EAAS,IAAImxC,GAAW9S,EAAM9H,MAC9BrzB,EAAOlD,EAAOkD,OACpB,OAAIA,KAAQkpC,EAEHA,EAAQlpC,IAGfkpC,EAAQlpC,GAAQlD,EACTA,GAIT,OAAOq+B,EAAM78B,OAAOukC,UAAUxP,KAAKgzB,UAAYlrB,EAAM78B,OAAOukC,UAAUxP,KAAKgzB,UAAYlrB,EAAM78B,OAAOukC,UAAUxP,KAAKllB,KA2H1Gq5C,CAAUrsB,EAAOA,EAAM0H,UAAUxP,KAAK6V,SAE3CpoC,EAAAq6B,EAAA0H,UAAAxP,KAACid,EAAAxvC,EAAAwvC,YAAamI,EAAA33C,EAAA23C,oBACdzL,EAAgB7R,EAAM78B,OAAS68B,EAAM78B,OAAOukC,UAAUxP,KAAK2Z,cAAcvM,QAAU,IAAIsiB,GAGzF5nB,EAAM9H,MAAQ8H,EAAM9H,KAAK9sB,QAAsC,OAA5B40B,EAAM9H,KAAK9sB,OAAOxE,QACvDirC,EAAcW,cAAe,GAG/B4Z,EAAO1a,GAAUE,aAAawa,EAAMpsB,EAAO6R,IAAkBua,EAQzD9H,GAAoBtkB,KAAWyL,GAAYzL,IAAUuN,GAAavN,MACpEosB,EAAO,IAAIzE,GAAeyE,IAK5B,IAAME,EAAgBtsB,EAAM78B,QAAUoqC,GAAavN,EAAM78B,SACrDsoC,GAAYzL,IAAUsJ,GAAatJ,KACjCssB,IACFF,EAAOrF,GAAQrX,iBAAiB0c,EAAMpsB,IAAUosB,GAIhDpsB,EAAMmd,WAAW7hD,OAAS,IAC5B8wD,EAnJJ,SAAoCA,EAAoBpsB,EAAc6R,GACpE,IAAI0a,EAAgB,EAuDpB,OArDAvsB,EAAMmd,WAAWh2B,QAAQ,SAAAzoB,GACvB,GAAIunD,GAAYvnD,GACd0tD,EAAO,IAAIvlB,GAAculB,EAAM1tD,GAC/BmzC,EAAc5H,IAAIvrC,EAAEwqB,GAAI,WAAW,QAC9B,GAAIo9B,GAAS5nD,GAClB0tD,EAAO1a,GAAUK,gCAAgCqa,EAAM1tD,EAAGmzC,IAAkBua,EAE5EA,EAAO,IAAIhF,GAAWgF,EAAMpsB,EAAOthC,EAAEwG,aAChC,GAAIghD,GAAMxnD,GAGf,IAFA,IAAMqS,EAAMq7C,EAAOrF,GAAQ/W,kBAAkBoc,EAAM1tD,EAAGshC,GAElCz7B,EAAA,EAAAoB,EAAAnC,GAAKuN,EAAIw0B,kBAAThhC,EAAAoB,EAAArK,OAAAiJ,IAA4B,CAA3C,IAAMhI,EAAKoJ,EAAApB,GACdstC,EAAc5H,IAAI1tC,EAAO,UAAU,QAGhC,GAAIiwD,GAAW9tD,GACpB0tD,EAAO/Y,GAAarD,kBAAkBoc,EAAM1tD,GAE5CmzC,EAAc5H,IAAIvrC,EAAEwqB,GAAI,QAAQ,QAC3B,GAAIvC,GAAYjoB,GAAI,CACzB,IAAM+tD,EAAML,EAAO7c,GAAcS,kBAAkBoc,EAAM1tD,GAErD4lD,GAAoBtkB,KACtBosB,EAAO,IAAIzE,GAAeyE,IAG5B,IAAoB,IAAA1pC,EAAA,EAAAyH,EAAA3mB,GAAKipD,EAAIlnB,kBAAT7iB,EAAAyH,EAAA7uB,OAAAonB,IAATnmB,EAAK4tB,EAAAzH,GACdmvB,EAAc5H,IAAI1tC,EAAO,WAAW,QAEjC,GAAIwpD,GAASrnD,GAGlB,IAFA,IAAM0pD,EAASgE,EAAOvE,GAAWxW,KAAK+a,EAAMpsB,EAAOthC,EAAG6tD,KAElCniC,EAAA,EAAAxB,EAAAplB,GAAK4kD,EAAO7iB,kBAAZnb,EAAAxB,EAAAttB,OAAA8uB,IAAT7tB,EAAKqsB,EAAAwB,GACdynB,EAAc5H,IAAI1tC,EAAO,WAAW,QAEjC,GAAIypD,GAAStnD,GAGlB,IAFA,IAAMutD,EAASG,EAAO,IAAI1D,GAAoB0D,EAAM1tD,GAEhCs0B,EAAA,EAAA05B,EAAAlpD,GAAKyoD,EAAO1mB,kBAAZvS,EAAA05B,EAAApxD,OAAA03B,IAATz2B,EAAKmwD,EAAA15B,GACd6e,EAAc5H,IAAI1tC,EAAO,WAAW,OAEjC,CAAA,IAAI8pD,GAAQ3nD,GAQjB,YADAib,GAASC,GAAYxF,wBAAwB1V,IAJ7C,IAFA,IAAMi1B,EAAQy4B,EAAOrY,GAAU/D,kBAAkBoc,EAAM1tD,GAEnCiuD,EAAA,EAAAC,EAAAppD,GAAKmwB,EAAM4R,kBAAXonB,EAAAC,EAAAtxD,OAAAqxD,IAATpwD,EAAKqwD,EAAAD,GACd9a,EAAc5H,IAAI1tC,EAAO,WAAW,MAQnC6vD,EA2FES,CAAoBT,EAAMpsB,EAAO6R,IAG1Cua,EAAO1a,GAAUY,yBAAyB8Z,EAAMpsB,EAAO6R,IAAkBua,EAErE3gB,GAAYzL,KACdosB,EAAO/E,GAAYC,SAAS8E,EAAMpsB,GAClCosB,EAAO1E,GAAaJ,SAAS8E,EAAMpsB,KAGjCyL,GAAYzL,IAAUsJ,GAAatJ,MAEhCssB,IACHF,EAAOrF,GAAQrX,iBAAiB0c,EAAMpsB,IAAUosB,GAGlDA,EAAO/Y,GAAa3D,iBAAiB0c,EAAMpsB,IAAUosB,EACrDA,EAAOvlB,GAAcC,qBAAqBslB,EAAMpsB,IAIlD,IAAM8sB,EAAU9sB,EAAM6C,QAAQtK,IACxBwrB,EAAM,IAAI7d,GAAWkmB,EAAMU,EAASv0B,GAAK+kB,GAI/C,GAHAnI,EAAY2X,GAAW/I,EACvBqI,EAAOrI,EAEHtY,GAAYzL,GAAQ,CACtB,IAAMysB,EAAMld,GAAcG,iBAAiB0c,EAAMpsB,GAC7CysB,IACFL,EAAOK,EAEHnI,GAAoBtkB,KACtBosB,EAAO,IAAIzE,GAAeyE,KAI9BA,EAAOrY,GAAUrE,iBAAiB0c,EAAMpsB,IAAUosB,EAGhD3gB,GAAYzL,KACdosB,EAAOhb,GAAkBC,KAAK+a,EAAMpsB,IAAUosB,GAIhD,IAAMW,EAAW/sB,EAAM6C,QAAQvK,IACzBtlB,EAAO,IAAIkzB,GAAWkmB,EAAMW,EAAUz0B,GAAMglB,GAClDnI,EAAY4X,GAAY/5C,EACxBo5C,EAAOp5C,EAGP,IAAIk4C,EAAY,KAChB,GAAI5hB,GAAatJ,GAAQ,CACvB,IAAMgtB,EAAYhtB,EAAM6C,QAAQ,SAGhCupB,EAAOvlB,GAAcC,qBAAqBslB,EAAMpsB,GAKhDosB,EAAO1D,GAAoBiD,cAAcS,EAAMpsB,EAAM5J,QAAUg2B,EAE/DlB,EAAY,IAAI3a,GAAU6b,EAAMpsB,EAAOgtB,EAAWh6C,EAAK0zB,aACvDyO,EAAY6X,GAAa9B,EACzBkB,EAAOlB,EAGT,OAAA1sD,KACKwhC,EAAM0H,UAAUxP,MACnBid,YAAWA,EACXmI,oBAAmBA,EACnByG,IAAGA,EACH/wC,KAAIA,EACJk4C,UAASA,EACTrZ,cAAaA,IClQjB,IAAAob,GAAA,SAAA9mB,GACE,SAAA8mB,EAAY3kC,EAAgBnlB,EAAew5C,EAAyB73B,EAAgB83B,EAAyBjrB,UAC3GwU,EAAAhpC,KAAAiB,KAAMkqB,EAAMnlB,EAAQw5C,EAAiB73B,EAAQ83B,EAAUjrB,IAAQvzB,KA2EnE,OA7E8CooC,EAAAA,EAAAA,GAKrCymB,EAAA3uD,UAAAs/C,UAAP,WACEx/C,KAAKspC,UAAUxP,KAAO0lB,GAAUx/C,MAChCA,KAAKsuC,SAASvlB,QAAQ,SAAC0Q,GACrBA,EAAM+lB,eAGHqP,EAAA3uD,UAAAq/C,eAAP,WAAA,IAAAtX,EAAAjoC,KAIEA,KAAKspC,UAAUlf,aACf,mBAAWqP,GACTA,EAAM8lB,iBACNn6C,GAAKq0B,EAAM6P,UAAUlf,WAAWrB,QAAQ,SAAC7mB,GACvC+lC,EAAKqB,UAAUlf,UAAUloB,GAAOu3B,EAAM6P,UAAUlf,UAAUloB,MAH1CiE,EAAA,EAAAoB,EAAAvH,KAAKsuC,SAALnoC,EAAAoB,EAAArK,OAAAiJ,IAAa,GAAjBoB,EAAApB,MAQX0oD,EAAA3uD,UAAAw/C,eAAP,WACE,IAAoB,IAAAv5C,EAAA,EAAAoB,EAAAvH,KAAKsuC,SAALnoC,EAAAoB,EAAArK,OAAAiJ,IAAe,CAAnBoB,EAAApB,GACRu5C,mBAIHmP,EAAA3uD,UAAAu/C,mBAAP,WACE,IAAoB,IAAAt5C,EAAA,EAAAoB,EAAAvH,KAAKsuC,SAALnoC,EAAAoB,EAAArK,OAAAiJ,IAAe,CAAnBoB,EAAApB,GACRs5C,uBAMHoP,EAAA3uD,UAAAgsD,iCAAP,SAAwCzL,GACtC,OAAOzgD,KAAKsuC,SAAS5rB,OAAO,SAACosC,EAAIr1B,GAAU,OAAAA,EAAMyyB,iCAAiC4C,IAAKrO,IAGlFoO,EAAA3uD,UAAAwgD,yBAAP,WAEE,OADA1gD,KAAKsuC,SAASvlB,QAAQ,SAAC0Q,GAAU,OAAAA,EAAMinB,iCAIlCmO,EAAA3uD,UAAAysD,sBAAP,WACE,OAAO3sD,KAAKsuC,SAAS5rB,OAAO,SAAC+9B,EAAShnB,GACpC,OAAOgnB,EAAQ5hD,OAAO46B,EAAMkzB,0BAC3BA,GAAsB3sD,QAGpB6uD,EAAA3uD,UAAAisD,sBAAP,SAA6BryB,GAC3B,OAAO95B,KAAKsuC,SAAS5rB,OAAO,SAACqsC,EAAIt1B,GAAU,OAAAA,EAAM0yB,sBAAsB4C,IAAKj1B,IAGvE+0B,EAAA3uD,UAAAygD,cAAP,WAEE,OAAO3gD,KAAKsuC,SAASxwC,IAAI,SAAA27B,GACvB,IAAM9sB,EAAQ8sB,EAAM0F,gBACdrT,EAAQ2N,EAAMomB,qBACdyN,EAAwB7zB,EAAMqmB,qBACpC,OAAA1/C,GACE4T,KAAM,QACN5X,KAAMq9B,EAAMgL,QAAQ,UAChB93B,GAASA,MAAKA,MACdmf,GAASA,MAAKA,MACdwhC,GACFx/C,QACEq8B,OAAQmjB,OAGT7zB,EAAM+mB,oBAIjBqO,EA7EA,CAA8CvQ,ICA9C0Q,GAAA,SAAAjnB,GAOE,SAAAinB,EAAY9kC,EAA4BnlB,EAAew5C,EAAyBC,EAAyB93B,GAAzG,IAAAuhB,EACEF,EAAAhpC,KAAAiB,KAAMkqB,EAAMnlB,EAAQw5C,EAAiB73B,EAAQ83B,EAAUt0B,EAAKqJ,UAAQvzB,YAPtDioC,EAAAj0B,KAAiB,SAS3BkW,EAAKqJ,SAAWrJ,EAAKqJ,QAAQ3H,OAAiC,WAAxB1B,EAAKqJ,QAAQ3H,KAAK/tB,GAA0C,WAAxBqsB,EAAKqJ,QAAQ3H,KAAK/b,IAC9F0L,GAASC,GAAY/F,0BAGvBwyB,EAAKgnB,UAAYr4B,GAAc1M,GAE/B+d,EAAKqG,UAAY1X,GAAc1M,GAAQA,EAAKwN,QAAUxN,EAAK0N,SAAS95B,IAAI,SAAC27B,EAAO98B,GAC9E,OAAO6uD,GAAW/xB,EAAOwO,EAAMA,EAAKxD,QAAQ,UAAY9nC,QAAImH,EAAW06C,EAAU93B,GAAQ,OAqB/F,OAtCiC0hB,EAAAA,EAAAA,GAqBxB4mB,EAAA9uD,UAAAm/C,gBAAP,YNbF,SAAsCzd,GACpC4oB,GAAwB5oB,GACxB,IAAM6oB,EAAiB7oB,EAAM0H,UAAU0B,WAEjCkkB,EAAkBttB,EAAMqtB,UAAY,QAAU,SACpDxE,EAAe7e,gBAAgBsjB,EAAiBxE,GAAiC9oB,EAAOstB,IMStFC,CAAsBnvD,OAIjBgvD,EAAA9uD,UAAAkvD,eAAP,WACE,OAAO,MAGCJ,EAAA9uD,UAAA8/C,sBAAV,WACE,OAAA5/C,KACMJ,KAAKivD,WAAaxC,QAAS,OAC/BhO,OAAQ,OAERjhB,MAAO,UAGbwxB,EAtCA,CAAiCH,ICMjC,IAAAQ,GAAA,SAAAtnB,GACE,SAAAsnB,EACkB1tB,EACA+J,EACT5M,QAFS,IAAA6C,IAAAA,WACA,IAAA+J,IAAAA,WACT,IAAA5M,IAAAA,GAAA,GAHT,IAAAmJ,EAKEF,EAAAhpC,KAAAiB,OAAOA,YAJSioC,EAAAtG,SAAAA,EACAsG,EAAAyD,SAAAA,EACTzD,EAAAnJ,cAAAA,IAyBX,OA7BmCsJ,EAAAA,EAAAA,GAS1BinB,EAAAnvD,UAAAgnC,MAAP,WACE,OAAO,IAAImoB,EACT9mD,GAAUvI,KAAK2hC,UACfp5B,GAAUvI,KAAK0rC,UAAW1rC,KAAK8+B,gBAI5BuwB,EAAAnvD,UAAA8+B,YAAP,SAAmBpc,GAGjB,MAAa,SAATA,IAIS,SAATA,GAA4B,UAATA,IACZ5iB,KAAKihC,IAAIre,MAhCT,KADQ/e,EAoCG7D,KAAKihC,IAAIre,KAnCL,OAAN/e,IADxB,IAAuBA,GAsCvBwrD,EA7BA,CAAmC5jB,gBCZLtyB,EAAkBuN,EAAgB/V,EAA+B5D,EAAqB6J,QAArB,IAAA7J,IAAAA,EAAA,IAO7F,IALA,IAKyB5G,EAAA,EAAAmpD,GALU,SAAd14C,GAAwB,gBAAkB/X,QACjD,MAAZ8R,EAAkB,QAAU,QAC5B,OAAS5D,EAAO1D,OAAO,EAAE,GAAGD,cAAgB2D,EAAO1D,OAAO,GAC1D,SAEuBlD,EAAAmpD,EAAApyD,OAAAiJ,IAAa,CAAjC,IAAMopD,EAAUD,EAAAnpD,GACnB,GAAIugB,EAAO6oC,SAAgDzrD,IAAjC4iB,EAAO6oC,GAAYp2C,GAC3C,OAAOuN,EAAO6oC,GAAYp2C,gBCFTyoB,EAAkBjxB,EAA+B6+C,EAA0BziD,GAChG,IAAMqK,EAAWwqB,EAAMxqB,SAASzG,KAEhB,MAAZA,EAAkBixB,EAAMxqB,SAAS,MACrB,MAAZzG,EAAkBixB,EAAMxqB,SAAS,WACjCtT,GAEE8nB,EAAOgW,EAAMhW,KAAKjb,GAClB+V,EAASkb,EAAMlb,OAEjB0mB,KAGJ,GAAInlB,GAAe7Q,GAAW,CAC5B,IAAMiM,EAAaue,EAAMoB,kBAAkBryB,GAASswB,IAAI,UAAY7U,GAAUpI,IAExEsC,EAAOgf,GAAqB,cAAeluB,EAASiF,SAAUuP,EAAK5e,OAAQ0Z,EAAOkF,KAAKxI,gBAAiBsD,EAAO6L,WAAYlP,GAE7HiD,IACF8mB,EAAWtsC,MAAQwnB,OAAQhC,IAK/B,IAAI2X,EAAQwxB,GAAc,aAAc7tB,EAAMlb,OAAQ/V,EAAS5D,EAAQ60B,EAAMoB,kBAAkBryB,GAASswB,IAAI,SAQ5G,QAPcn9B,IAAVm6B,IACFA,EA2CJ,SAA2BrS,EAAYjb,EAAkByG,GACvD,QAAwBtT,IAApB8nB,EAAKne,WAEP,OAASme,EAAKne,WAAa,IAAO,KAAO,IAEzC,GAAIkD,IAAYzC,IAAKvH,GAAU+d,GAASF,IAAUpN,EAASpD,MACzD,OAAO,IAGX,OApDUvG,CAAWme,EAAMjb,EAASyG,MAEhCg2B,EAAWnP,OAASl9B,MAAOk9B,SAIjBn6B,IAAVm6B,EAAqB,CACvB,IAAMT,EAgDV,SAA2BS,EAAelxB,GAExC,OADAkxB,GAAUA,EAAQ,IAAO,KAAO,IACjB,QAAXlxB,GAA+B,WAAXA,EAClBkxB,EAAQ,KAAQ,EACX,SACE,EAAIA,GAASA,EAAQ,IACZ,QAAXlxB,EAAmB,QAAU,OAElB,QAAXA,EAAmB,OAAS,SAGhCkxB,EAAQ,IAAM,KAAQ,EAClB,SACE,IAAMA,GAASA,EAAQ,IACd,SAAXlxB,EAAoB,OAAS,QAElB,SAAXA,EAAoB,QAAU,OAhEzB2iD,CAAWzxB,EAAOlxB,GAC5BywB,IACF4P,EAAW5P,OAASz8B,MAAOy8B,IAG7B4P,EAAW3P,SAWf,SAA8BQ,EAAelxB,GAC3C,MAAe,QAAXA,GAA+B,WAAXA,EAClBkxB,GAAS,IAAM,KAAOA,GAChBl9B,MAAkB,QAAXgM,EAAmB,SAAW,OACpC,KAAOkxB,GAASA,GAAS,KAC1Bl9B,MAAkB,QAAXgM,EAAmB,MAAO,WAEjChM,MAAO,UAGZk9B,GAAS,IAAM,KAAOA,GAAW,KAAOA,GAASA,GAAS,KACrDl9B,MAAO,UACN,IAAMk9B,GAASA,GAAS,KACzBl9B,MAAkB,SAAXgM,EAAoB,MAAQ,WAEnChM,MAAkB,SAAXgM,EAAoB,SAAW,OA1B1B4iD,CAAc1xB,EAAOlxB,GAQ7C,OALAqgC,EAAUhtC,KACLgtC,EACAoiB,GAG8B,IAA5BpqD,GAAKgoC,GAAYlwC,YAAe4G,EAAYspC,cCzCvBxL,GAC5B,OAAOtwB,GAAwBoR,OAAO,SAASkJ,EAAMjb,GAInD,OAHIixB,EAAM0H,UAAUoJ,OAAO/hC,IAAYixB,EAAMhW,KAAKjb,KAChDib,EAAKjb,IA8JX,SAAmBA,EAA+BixB,GAChD,IAAMhW,EAAOgW,EAAMhW,KAAKjb,GAElBq7C,EAAgB,IAAIqD,GAG1BxhD,GAAmBkb,QAAQ,SAAS5P,GAClC,IAAMpY,EAqDV,SAAyDoY,EAAay2C,EAAqBj/C,EAA+BixB,GACxH,IAAMxqB,EAAWwqB,EAAMxqB,SAASzG,GAChC,OAAQwI,GACN,IAAK,QACH,OAAOyoB,EAAMpB,UAAU7vB,GACzB,IAAK,YACH,OC5NN,SAA0BixB,EAAkBjxB,GAC1C,IAAMk/C,EAAgD,MAAZl/C,EAAkB,IAAM,IAClE,GAAIixB,EAAMoB,kBAAkB6sB,GAC1B,OAAOjuB,EAAMpB,UAAUqvB,GDyNdC,CAAqBluB,EAAOjxB,GACrC,IAAK,SAEH,OAAOw0B,GAAa/tB,EAAUw4C,EAAc5iD,OAAQ40B,EAAMlb,QAC5D,IAAK,OACH,IAAM9P,EAAYgrB,EAAMoB,kBAAkBryB,GAASswB,IAAI,QACvD,OAAOsE,GAA2BqqB,EAAc3jD,KCtOtD,SAAqB2K,EAAsBQ,GACzC,OAAQ4X,GAAkBpY,KAAeQ,EAASzE,IDqOQo9C,CAAgBn5C,EAAWQ,IAEnF,IAAK,aACH,OC7NN,SAA2BA,EAA4BzG,EAA+Bi/C,GACpF,YAAiC9rD,IAA7B8rD,EAAcvjD,WACTujD,EAAcvjD,aAEP,MAAZsE,IAAmBhK,GAAU,eAAgB,YAAayQ,EAASpD,aAAvE,EDyNWg8C,CAAsB54C,EAAUzG,EAASi/C,GAClD,IAAK,eACH,IAAMh5C,EAAYgrB,EAAMoB,kBAAkBryB,GAASswB,IAAI,QACvD,OCtNN,SAA6B7pB,EAA4Bw4C,EAAqBj/C,EAA+BiG,GAC3G,YAAmC9S,IAA/B8rD,EAActjD,aACTsjD,EAActjD,aAID,YAAlB8K,EAASpD,KACO,QAAd4C,GACK,cAFX,EDgNWq5C,CAAwB74C,EAAUw4C,EAAej/C,EAASiG,GAEnE,IAAK,SACH,OAAO2uB,GAA2BqqB,EAAc7iD,OCzMtD,SAAuB4D,GACrB,OAAQA,GACN,KAAKzC,GACH,MAAO,SACT,KAAKC,GACH,MAAO,OAGX,MAAM,IAAI3R,MAAMgf,GAAY7B,0BDiMgCu2C,CAAkBv/C,IAC5E,IAAK,YACH,IAAMiG,EAAYgrB,EAAMoB,kBAAkBryB,GAASswB,IAAI,QACjD8J,EAAuB,MAAZp6B,EAAkB,QAAsB,MAAZA,EAAkB,cAAW7M,EACpEsM,EAAO26B,EAAWnJ,EAAMqJ,iBAAiBF,QAC5CjnC,EACH,OAAOyhC,GAA2BqqB,EAAcxiD,UCpMtD,SAA0BuD,EAA+ByG,EAA4BR,EAAsBxG,GACzG,IAAK4e,GAAkBpY,IAA4B,QAAdA,IAAwBjQ,GAAU,QAAS,QAAS,MAAO,WAAYyQ,EAASiF,UAEnH,OAAIjF,EAASzE,KAEH2V,OAAQ,QAAQlY,EAAKkY,OAAM,SAE7BA,OAAQ,QAAQlY,EAAKkY,OAAM,QD6L0B6nC,CAAqBx/C,EAASyG,EAAUR,EAAWxG,IAEhH,IAAK,QACH,IAAMggD,EAAuB,MAAZz/C,EAAkB,KAAO,KACpC0/C,EAAYzuB,EAAMxqB,SAASg5C,GAG3BlxB,EAAgBoxB,GAAiB1uB,EAAOjxB,GACxCg9B,OAAmC7pC,IAAlBo7B,EAA8BA,OAC3Bp7B,IAAxB8rD,EAAcjjD,WAAsB7I,EAAY8rD,EAAcjjD,MAEhE,OAAO44B,GACLoI,EAEAzH,IACG9gB,GAAehO,IAChBi5C,GAAajrC,GAAeirC,SAGlC,IAAK,SACH,OC3MN,SAMuBT,EAAqBhuB,EAAkBxqB,EAA4BzG,GACxF,IAAMvI,EAAOwnD,EAAcjoD,OAE3B,GAAIS,EACF,OAAOigB,GAAWjR,EAAUhP,GAG9B,GAAIgP,EAASzE,KAAOyE,EAASpD,OAASuQ,GAAc,CAClD,IAAMpY,EAASy1B,EAAM8P,YAAY/gC,GACjC,GAAIxE,GAAqB,iBAAXA,IAA8BikB,GAAkBjkB,GAC5D,OAGF,IAAMmc,EAASsZ,EAAM6C,QAAWre,GAAYhP,EAASzE,KAAI,IAAIyE,EAASjZ,MAAK,SAC3E,OAAQmqB,OAAQ,YAAYA,EAAM,WAAWA,EAAM,WAAWA,EAAM,UAAUA,EAAM,WDuL3EslB,CAAkBgiB,EAAehuB,EAAOxqB,EAAUzG,GAG7D,OAAOhD,GAAewL,GAAYy2C,EAAcz2C,QAAYrV,EAvG5CgqC,CAAY30B,EAAUyS,EAAMjb,EAASixB,GACnD,QAAc99B,IAAV/C,EAAqB,CACvB,IAAM4gC,EAES,WAAbxoB,IAA0ByS,EAAKjkB,OAElB,WAAbwR,IAA0ByS,EAAKpe,YAAcoe,EAAKne,WAEjC,UAAb0L,GAAwBpY,IAAUuvD,GAAiB1uB,EAAOjxB,IAE9D5P,IAAU6qB,EAAKzS,GAEX2oB,EAAc2tB,GAAct2C,EAAUyoB,EAAMlb,OAAQ/V,EAASq7C,EAAc/qB,IAAI,UAAWW,EAAMoB,kBAAkBryB,GAASswB,IAAI,SAGjIU,QAA4B79B,IAAhBg+B,EAEdkqB,EAAcngB,IAAI1yB,EAAUpY,EAAO4gC,GACb,SAAbxoB,GAAuB2oB,GAEhCkqB,EAAcngB,IAAI1yB,EAAU2oB,GAAa,MAM/C,IAAMyuB,EAAe3kC,EAAKpe,aACpBgjD,EAAazkD,GAAW2W,OAAO,SAACjiB,EAAiBmiB,GACrD,IAAKopC,EAAchtB,YAAYpc,GAE7B,OAAOniB,EAGT,IAAMgwD,EAAmB7pB,GAAiB2pB,EAAa3tC,OAAagf,GAE9D7gC,EAAiB,WAAT6hB,EACZ8tC,GAAc9uB,EAAOjxB,EAAS8/C,EAAkBzE,EAAc/qB,IAAI,WAClEwvB,EAKF,YAHc3sD,IAAV/C,GAAuBqE,GAAKrE,GAAO7D,OAAS,IAC9CuD,EAAEmiB,IAASunB,OAAQppC,IAEdN,OAIL2E,GAAKorD,GAAYtzD,OAAS,GAC5B8uD,EAAcngB,IAAI,SAAU2kB,IAAc5kC,EAAKpe,eAAgC1J,IAApB8nB,EAAKne,YAGlE,OAAOu+C,EAvNc2E,CAAUhgD,EAASixB,KAE/BhW,OAIX,IAAMglC,IACJC,OAAQ,MACRC,IAAK,SACLC,KAAM,QACNC,MAAO,QAiET,SAAAC,GAA6BC,EAAkCC,GAC7D,IAAID,EA4BF,OAAOC,EAAerzD,IAAI,SAAAkuD,GAAiB,OAAAA,EAAc9kB,UA1BzD,GAAIgqB,EAAgBh0D,SAAWi0D,EAAej0D,OAA9C,CAIA,IADA,IAAMk0D,EAASF,EAAgBh0D,OACtBP,EAAI,EAAGA,EAAIy0D,EAASz0D,IAAK,CAChC,IAAMw7B,EAAS+4B,EAAgBv0D,GACzB88B,EAAQ03B,EAAex0D,GAE7B,KAAOw7B,KAAesB,EACpB,OACK,GAAItB,GAAUsB,EAAO,CAC1B,IAAMiV,EAAevW,EAAOwT,gBAAgB,UACtCgD,EAAclV,EAAMkS,gBAAgB,UAE1C,GAAI+C,EAAa/M,UAAYgN,EAAYhN,UAAY+M,EAAa3tC,QAAU4tC,EAAY5tC,MAItF,OAEAmwD,EAAgBv0D,GAAK00D,GAAmBl5B,EAAQsB,IAQxD,OAAOy3B,GAGT,SAAAG,GAA4Bl5B,EAAuBsB,GACjD,mBAAWpzB,GACT,IAAMwoC,EAA0BvC,GAC9BnU,EAAOwT,gBAAgBtlC,GACvBozB,EAAMkS,gBAAgBtlC,GACtBA,EAAM,OAGN,SAACgT,EAAmBC,GAClB,OAAQjT,GACN,IAAK,QACH,OAAOsgC,GAAoBttB,EAAIC,GACjC,IAAK,YACH,OACEqoB,SAAUtoB,EAAGsoB,SACb5gC,MAAOsY,EAAGtY,OAASuY,EAAGvY,OAG5B,OAAOsrC,GAA+BhzB,EAAIC,EAAIjT,EAAM,UAGxD8xB,EAAOyT,gBAAgBvlC,EAAMwoC,IApBZ1oC,EAAA,EAAAmrD,EAAAzjD,GAAA1H,EAAAmrD,EAAAp0D,OAAAiJ,IAAkB,GAAtBmrD,EAAAnrD,IAsBf,OAAOgyB,EAGT,SAAAm4B,GAA0B1uB,EAAkBjxB,GAC1C,IAAMy/C,EAAuB,MAAZz/C,EAAkB,KAAO,KACpCyG,EAAWwqB,EAAMxqB,SAASzG,GAC1B0/C,EAAYzuB,EAAMxqB,SAASg5C,GAE3B3pB,EAASrvB,EAAWA,EAASzK,WAAQ7I,EACrC4iC,EAAS2pB,EAAYA,EAAU1jD,WAAQ7I,EAE7C,OAAI2iC,GAAUC,EACLF,GAAWC,EAAQC,GACjBD,IAEAC,SAEW5iC,IAAX2iC,EACFA,OACa3iC,IAAX4iC,EACFA,OADF,gBE9JwB70B,EAAsBrE,EAA4BkZ,GACjF,IAAM+R,EAAmB5kB,GAAUhC,GAAKzR,KAAOyR,IAASmC,KAAMnC,GAGxD0/C,EAAkB94B,EAAQ1rB,QAAUg1B,GAAc,SAAUtJ,EAAS/R,GAuB3E,OAtBA+R,EAAQ1rB,OAgDV,SAAgB8E,EAAYrE,EAA4B+jD,GACtD,OAAQ1/C,GACN,KAAKqB,GACL,KAAKK,GACL,KAAKC,GACL,KAAKxE,GACL,KAAKmE,GAEH,OAGJ,IAAMq+C,EAAWhkD,EAASuC,GACpB0hD,EAAWjkD,EAASsC,GAE1B,OAAQ+B,GACN,KAAKmB,GACH,GAAIw+C,GAAYC,EAAU,CAExB,GAAIF,EACF,OAAOA,EAIT,IAAM77B,EAAOloB,EAAS3P,EACtB,IAAK4zD,GAAY/rC,GAAWgQ,IAASA,EAAK1hB,OAASuQ,KAAiBmR,EAAK/iB,IACvE,MAAO,aAIT,IAAMgjB,EAAOnoB,EAASqC,EACtB,IAAK2hD,GAAY9rC,GAAWiQ,IAASA,EAAK3hB,OAASuQ,KAAiBoR,EAAKhjB,IACvE,MAAO,WAIb,KAAKS,GAEH,GAAIq+C,GAAYD,EACd,OAGJ,KAAKz+C,GAEH,GAAIy+C,EACF,MAAO,WACF,GAAIC,EACT,MAAO,aACF,GAAI5/C,IAASuB,GAAM,CACxB,GAAI5F,EAAS3P,IAAM2P,EAASqC,EAC1B,MAAO,WACF,GAAIrC,EAASqC,IAAMrC,EAAS3P,EACjC,MAAO,aAKb,KAAKoV,GACL,KAAKI,GAGH,IAAMq+C,EAAgBhsC,GAAWlY,EAAS3P,IAAM2oB,GAAahZ,EAAS3P,GAChE8zD,EAAgBjsC,GAAWlY,EAASqC,IAAM2W,GAAahZ,EAASqC,GACtE,GAAI6hD,IAAkBC,EACpB,MAAgB,SAAT9/C,EAAkB,aAAe,WACnC,IAAK6/C,GAAiBC,EAC3B,MAAgB,SAAT9/C,EAAkB,WAAa,aACjC,GAAI6/C,GAAiBC,EAAe,CACzC,IAAMj8B,EAAOloB,EAAS3P,EAChB83B,EAAOnoB,EAASqC,EAEhB+hD,EAAcl8B,EAAK1hB,OAASyQ,GAC5BotC,EAAcl8B,EAAK3hB,OAASyQ,GAGlC,OAAImtC,IAAgBC,EACF,SAAThgD,EAAkB,WAAa,cAC5B+/C,GAAeC,EACT,SAAThgD,EAAkB,aAAe,YAGrC6jB,EAAK/pB,WAAagqB,EAAKhqB,UACV,SAATkG,EAAkB,WAAa,aAC7B6jB,EAAK/pB,YAAcgqB,EAAKhqB,UACjB,SAATkG,EAAkB,aAAe,WAGtC0/C,GAKG,WAGP,OAAIA,QAKJ,EAGN,MAAO,WAtJUxkD,CAAO0rB,EAAQzkB,KAAMxG,EAAU+jD,QACxBztD,IAApBytD,GAAiCA,IAAoB94B,EAAQ1rB,QAC/DwO,GAASC,GAAYtD,iBAAiBugB,EAAQ1rB,OAAOwkD,SAK9BztD,UADoBA,IAApB20B,EAAQtoB,QAAwBsoB,EAAQtoB,QAAU4xB,GAAc,UAAWtJ,EAAS/R,MAE3G+R,EAAQtoB,QAwBZ,SAAiB0B,EAAYrE,GAC3B,GAAI7G,GAAUuM,GAAOG,GAAME,GAAQC,IAAS3B,KAErC0W,GAAY/a,GACf,MAAO,GAGX,OA/BoB2C,CAAQsoB,EAAQzkB,KAAMxG,SAIlB1J,IADA20B,EAAQU,SAE9BV,EAAQU,OA6BZ,SAAgBV,EAAkB/R,GAChC,IAAMorC,EAAe/vB,GAAc,SAAUtJ,EAAS/R,GAChD7U,EAAO4mB,EAAQzkB,KACrB,YAAwBlQ,IAAjBguD,EAA6BA,EAAejgD,IAASqB,IAASrB,IAASoB,IAAQpB,IAASuB,GAhC5E+lB,CAAOV,EAAS/R,SAKX5iB,KADA20B,EAAQ6F,QAAUyD,GAAc,SAAUtJ,EAAS/R,MAEzE+R,EAAQ6F,OAMZ,SAAgB7F,EAAkBjrB,EAA4BkZ,GAC5D,GAAIlZ,EAASiD,MAAQgoB,EAAQhoB,MAAQsxB,GAAc,OAAQtJ,EAAS/R,GAClE,MAAO,UAET,OAAO+R,EAAQ6F,OAVIA,CAAO7F,EAASjrB,EAAUkZ,IAGtC+R,EC6DT,SAAAwL,GAAwBxL,EAAkB+H,EAAmB5zB,EAAuB8Z,GAClF,QAAqB5iB,IAAjB20B,EAAQroB,KACV,OAAQrP,MAAO03B,EAAQroB,MAClB,GAAIsW,EAAOtU,IAAI2/C,iBACpB,OAAQhxD,MAAO2lB,EAAOtU,IAAI2/C,kBACrB,GAAInlD,EAAO,CAChB,IAAMgK,EAAYhK,EAAMq0B,IAAI,QAC5B,GAAIrqB,IAAcwV,GAAUlZ,MAMrB,OAAI0D,IAAcwV,GAAUoB,KAC1BsW,GAAYtD,IAEXz/B,MAAO2lB,EAAOtU,IAAIqC,oBAR1B,IAAMqlC,EAAaltC,EAAMq0B,IAAI,SAC7B,GAAIpE,GAAcid,IAAev6C,EAASu6C,EAAWhyB,MACnD,OAAQ/mB,MAAO+4C,EAAWhyB,KAAO,GAEnCvM,GAASC,GAAY1D,8CAMlB,GAAI4O,EAAO9Z,MAAM0iB,WAAwC,OAA3B5I,EAAO9Z,MAAM0iB,UAChD,OAAQvuB,MAAO2lB,EAAO9Z,MAAM0iB,UAAY,GAE1C,OAAQvuB,MAAO,IChHjB,SAAAixD,GAAqBpwB,EAAkBqwB,GAC9B,IAAAvrC,EAAAkb,EAAAlb,OAAQ0L,EAAAwP,EAAAxP,MAAOC,EAAAuP,EAAAvP,OAEtB,OAAAjyB,KACK8xD,GAAuBtwB,GAAQxxB,KAAM,UAAWrD,OAAQ,WACxDolD,GAAqB,IAAKvwB,EAAOwwB,GAAQhgC,IACzC+/B,GAAqB,IAAKvwB,EAAOwwB,GAAQ//B,IACzCggC,GAAmB,OAAQzwB,GAKlC,SAA4BA,EAAkBlb,EAAgBurC,GAC5D,GAAIA,EACF,OAAQ5hD,OAAQtP,MAAOkxD,IAEzB,OAAOI,GAAmB,QAASzwB,GAAQK,aAAcF,GAAc,QAASH,EAAMnJ,QAAS/R,KAR1F4rC,CAAY1wB,EAAOlb,EAAQurC,ICIlC,IAAMM,IACJ//C,MChBAggD,OAAQ,OACRR,YAAa,SAACpwB,GACZ,OAAAxhC,KACK8xD,GAAuBtwB,GAAQxxB,KAAM,SAAUrD,OAAQ,YACvDolD,GAAqB,IAAKvwB,EAAO,aACjCuwB,GAAqB,IAAKvwB,EAAO,aACjC6wB,GAAsB7wB,EAAO,YAAsC,eAAzBA,EAAMnJ,QAAQ1rB,OAA0B,KAAO,MACzF2lD,GAAe9wB,MDUtBxvB,KFNAogD,OAAQ,OACRR,YAAa,SAACpwB,GACZ,OAAAxhC,KACK8xD,GAAuBtwB,GAAQxxB,KAAM,SAAUrD,OAAQ,WAOhE,SAAW60B,GACF,IAAAlb,EAAAkb,EAAAlb,OAAQlZ,EAAAo0B,EAAAp0B,SAAUirB,EAAAmJ,EAAAnJ,QAASrG,EAAAwP,EAAAxP,MAC5BrlB,EAAS0rB,EAAQ1rB,OACjB4lD,EAAUnlD,EAAS4C,KAEnBslB,EAAOloB,EAAS3P,EAChB+0D,EAAQplD,EAASsC,GACjB+iD,EAAajxB,EAAMpB,UAAUtyB,IAC7B+sC,EAASrZ,EAAMoB,kBAAkB90B,IAEvC,GAAe,eAAXnB,GAA2B6lD,EAC7B,OAAAxyD,KACK+xD,GAAqB,IAAKvwB,EAAO,aACjC6wB,GAAsB7wB,EAAO,YAAa,OAG/C,GAAIlc,GAAWgQ,GAAO,CACpB,IAAMo9B,EAAa7X,EAAOha,IAAI,QAC9B,GAAIvL,EAAK/iB,MAAQggD,IAAY3jC,GAAkB8jC,GAC7C,OAAOC,GACLr9B,EAAM,IAAKkM,EAAMpB,UAAU,UAA6B18B,IAAvB20B,EAAQjkB,WAA2BkS,EAAOtU,IAAIoC,WAAaikB,EAAQjkB,WACpGymC,EAAOha,IAAI,YAGb,GAAI6xB,IAAe1mC,GAAUoB,KAC3B,OAAOwlC,GAAoBt9B,EAAM,IAAKkM,GAM5C,OAAOqxB,GAA4B,IAAKrxB,EAAKxhC,KACvCgyD,GAAQhgC,IACZ6R,GAAexL,EAASo6B,EAAY5X,EAAQv0B,IAvCzC7oB,CAAE+jC,GA4CX,SAAWA,GACF,IAAAlb,EAAAkb,EAAAlb,OAAQlZ,EAAAo0B,EAAAp0B,SAAU6kB,EAAAuP,EAAAvP,OAAQoG,EAAAmJ,EAAAnJ,QAC3B1rB,EAAS0rB,EAAQ1rB,OACjB4lD,EAAUnlD,EAAS4C,KAEnBulB,EAAOnoB,EAASqC,EAChBqjD,EAAQ1lD,EAASuC,GACjBojD,EAAavxB,EAAMpB,UAAUryB,IAC7BgtC,EAASvZ,EAAMoB,kBAAkB70B,IAGvC,GAAe,aAAXpB,GAAyBmmD,EAC3B,OAAA9yD,KACK+xD,GAAqB,IAAKvwB,EAAO,aACjC6wB,GAAsB7wB,EAAO,YAAa,OAG/C,GAAIlc,GAAWiQ,GAAO,CACpB,IAAMy9B,EAAajY,EAAOla,IAAI,QAC9B,GAAItL,EAAKhjB,MAAQggD,IAAY3jC,GAAkBokC,GAC7C,OAAOL,GACLp9B,EAAM,IAAKiM,EAAMpB,UAAU,UACJ18B,IAAvB20B,EAAQjkB,WAA2BkS,EAAOtU,IAAIoC,WAAaikB,EAAQjkB,WACnE2mC,EAAOla,IAAI,YAER,GAAImyB,IAAehnC,GAAUoB,KAClC,OAAOwlC,GAAoBr9B,EAAM,IAAKiM,GAG1C,OAAOqxB,GAA4B,IAAKrxB,EAAOwwB,GAAQ//B,GACrD4R,GAAexL,EAAS06B,EAAYhY,EAAQz0B,IAzEzC7W,CAAE+xB,MEET1vB,QDYAsgD,OAAQ,SACRR,YAAa,SAACpwB,GACZ,OAAOowB,GAAYpwB,EAAO,YCb5BnvB,UEhBA+/C,OAAQ,QACRR,YAAa,SAACpwB,GACZ,OAAAxhC,KACK8xD,GAAuBtwB,GAAQxxB,KAAM,SAAUrD,OAAQ,aAG9DsmD,sBAAuB,SAACzxB,GACf,IACD0xB,EADC1xB,EAAAp0B,SACmB6C,MAQ1B,OANejQ,GACb4T,KAAM,WACNwC,WAAYorB,EAAMyO,kBAEdijB,GAAY5tC,GAAW4tC,IAAaA,EAASt/C,OAAS2Q,IAAWxmB,MAAO4nB,GAAQutC,GAAWhtC,KAAM,kBFGzGhU,MGpBAkgD,OAAQ,OACRR,YAAa,SAACpwB,GACL,IAAAxP,EAAAwP,EAAAxP,MAAOC,EAAAuP,EAAAvP,OAEd,OAAAjyB,KACK8xD,GAAuBtwB,GAAQxxB,KAAM,SAAUrD,OAAQ,WACvDolD,GAAqB,IAAKvwB,EAAOwwB,GAAQhgC,IACzC+/B,GAAqB,IAAKvwB,EAAOwwB,GAAQ//B,IACzCggC,GAAmB,OAAQzwB,GAC5BS,UAAW,gBAEVqwB,GAAe9wB,MHUtB7vB,ODEAygD,OAAQ,SACRR,YAAa,SAACpwB,GACZ,OAAOowB,GAAYpwB,KCHrBvvB,MIjBAmgD,OAAQ,OACRR,YAAa,SAACpwB,GACZ,OAAAxhC,KACK8xD,GAAuBtwB,GAAQxxB,KAAM,SAAUrD,OAAQ,WAOhE,SAAkB60B,GAChB,IAAMlM,EAAOkM,EAAMp0B,SAAS3P,EACtB+0D,EAAQhxB,EAAMp0B,SAASsC,GACvBmrC,EAASrZ,EAAMoB,kBAAkB90B,IACjC4kD,EAAa7X,EAASA,EAAOha,IAAI,aAAUn9B,EAEjD,GAAI4hB,GAAWgQ,IAASA,EAAK/iB,MAAQigD,EACnC,OAAOG,GAAsBr9B,EAAM,IAAKkM,EAAMpB,UAAU,KAAM,EAAGya,EAAOha,IAAI,YACvE,GAAIvb,GAAWgQ,IAASulB,GAAUjsB,GAAkB8jC,GAAa,CAEtE,GAAIA,IAAe1mC,GAAUoB,KAC3B,OAAOwlC,GAAoBt9B,EAAM,IAAKkM,GAGtC,MAAM,IAAIplC,MAAMgf,GAAYvC,yBAAyB9F,GAAM2/C,IAG7D,OAAA1yD,KACK+xD,GAAqB,IAAKvwB,EAAO,aACjC6wB,GAAsB7wB,EAAO,YAAa,OAzB1C/jC,CAAE+jC,GA8BX,SAAkBA,GAChB,IAAMjM,EAAOiM,EAAMp0B,SAASqC,EACtBqjD,EAAQtxB,EAAMp0B,SAASuC,GACvBorC,EAASvZ,EAAMoB,kBAAkB70B,IACjCilD,EAAajY,EAASA,EAAOla,IAAI,aAAUn9B,EAEjD,GAAI4hB,GAAWiQ,IAASA,EAAKhjB,MAAQugD,EACnC,OAAOH,GAAsBp9B,EAAM,IAAKiM,EAAMpB,UAAU,KAAM,EAAG2a,EAAOla,IAAI,YACvE,GAAIvb,GAAWiQ,IAASwlB,GAAUnsB,GAAkBokC,GAAa,CAEtE,GAAIA,IAAehnC,GAAUoB,KAC3B,OAAOwlC,GAAoBr9B,EAAM,IAAKiM,GAGtC,MAAM,IAAIplC,MAAMgf,GAAYvC,yBAAyB9F,GAAMigD,IAG7D,OAAAhzD,KACK+xD,GAAqB,IAAKvwB,EAAO,aACjC6wB,GAAsB7wB,EAAO,YAAa,OAhD1C/xB,CAAE+xB,MJaT3vB,MKvBAugD,OAAQ,OACRR,YAAa,SAACpwB,GACLA,EAAAlb,OAAA,IAAiB+R,EAAAmJ,EAAAnJ,QAASrG,EAAAwP,EAAAxP,MAAOC,EAAAuP,EAAAvP,OAClCtlB,EAAS0rB,EAAQ1rB,OAEvB,OAAK60B,EAAMp0B,SAAS3P,GAAM+jC,EAAMp0B,SAASqC,GAAM+xB,EAAMp0B,SAASiC,UAAamyB,EAAMp0B,SAAS+B,UAK1FnP,KACK8xD,GAAuBtwB,GAAQxxB,KAAM,SAAUrD,OAAQ,WACvDolD,GAAqB,IAAKvwB,EAAkB,eAAX70B,EAA0B,YAAcqlD,GAAQhgC,IACjF+/B,GAAqB,IAAKvwB,EAAkB,aAAX70B,EAAwB,YAAcqlD,GAAQ//B,IAGnE,aAAXtlB,EAAwB0lD,GAAsB7wB,EAAO,YAAa,SAGvD,eAAX70B,EAA0B0lD,GAAsB7wB,EAAO,YAAa,SAErEywB,GAAmB,OAAQzwB,GAC5BS,UAAW,cACXJ,aAAcxJ,EAAQroB,aLC5B+B,QDaAqgD,OAAQ,SACRR,YAAa,SAACpwB,GACZ,OAAOowB,GAAYpwB,EAAO,YCd5B9gC,MMpBA0xD,OAAQ,OAERR,YAAa,SAACpwB,GACL,IAAAlb,EAAAkb,EAAAlb,OAAkB0L,GAAVwP,EAAAp0B,SAAUo0B,EAAAxP,OAAOC,EAAAuP,EAAAvP,OAAQoG,EAAAmJ,EAAAnJ,QAExC,OAAAr4B,KACK8xD,GAAuBtwB,GAAQxxB,KAAM,SAAUrD,OAAQ,WACvDolD,GAAqB,IAAKvwB,EAAOwwB,GAAQhgC,IACzC+/B,GAAqB,IAAKvwB,EAAOwwB,GAAQ//B,IACzCkhC,GAAY3xB,GACZywB,GAAmB,OAAQzwB,EAAKxhC,KAC7Bq4B,EAAQroB,MAAQ6xB,aAAcxJ,EAAQroB,UAC1CiyB,UAAW,c7EqGnB,SAA+Bh8B,EAActF,SAC3C,QAAc+C,IAAV/C,EACF,OAAAwG,MAASlB,IAAQtF,MAAOA,GAAMwG,E6ErGzBisD,CAAsB,QAI/B,SAAe/6B,EAAkBjrB,EAA4BkZ,GAE3D,QAAU5iB,KADA20B,EAAQ+E,OAASuE,GAAc,QAAStJ,EAAS/R,IAEzD,MAAO,SAGT,OAVsC8W,CAAMoE,EAAMnJ,QAASjrB,EAAUkZ,ONOrE1U,MOxBAwgD,OAAQ,OAERR,YAAa,SAACpwB,SACLlb,EAAAkb,EAAAlb,OAAQ+R,EAAAmJ,EAAAnJ,QAASrG,EAAAwP,EAAAxP,MAAOC,EAAAuP,EAAAvP,OACzBtlB,EAAS0rB,EAAQ1rB,OAEjB0mD,EAA2B,eAAX1mD,EAA0B,QAAU,SACpD2mD,EAAgC,eAAX3mD,EAA0B,SAAW,QAEhE,OAAA3M,KACK8xD,GAAuBtwB,GAAQxxB,KAAM,SAAUrD,OAAQ,WAEvDolD,GAAqB,IAAKvwB,EAAOwwB,GAAQhgC,GAAQ,MACjD+/B,GAAqB,IAAKvwB,EAAOwwB,GAAQ//B,GAAS,MAGlDggC,GAAmB,OAAQzwB,GAC5BK,aAQR,SAAqBL,GACZ,IAAAlb,EAAAkb,EAAAlb,OAAQ+R,EAAAmJ,EAAAnJ,QACT1rB,EAAS0rB,EAAQ1rB,OACjBH,EAAQg1B,EAAMoB,kBAA6B,eAAXj2B,EAA0B,IAAM,KAEtE,QAAqBjJ,IAAjB20B,EAAQroB,KACV,OAAOqoB,EAAQroB,KACV,QAA6BtM,IAAzB4iB,EAAO1U,KAAK2hD,SACrB,OAAOjtC,EAAO1U,KAAK2hD,SAEnB,IAAM7Z,EAAaltC,EAAQA,EAAMq0B,IAAI,cAAWn9B,EAC1CwrB,EAAYwqB,GAAcjd,GAAcid,GAC5CA,EAAWhyB,KACXpB,EAAO9Z,MAAM0iB,UACf,GAAyB,iBAAdA,EAET,MAAM,IAAI9yB,MAAM,kDAElB,OAAO8yB,EAAY,IA1BDskC,CAAYhyB,GAC1BS,UAAWoxB,MACXlsD,MACDmsD,IAAsB3yD,MAAO03B,EAAQ9jB,WAAa+R,EAAO1U,KAAK2C,WAAUpN,MPK7EgL,OGTAigD,OAAQ,QACRR,YAAa,SAACpwB,GACL,IAAAxP,EAAAwP,EAAAxP,MAAOC,EAAAuP,EAAAvP,OAEd,OAAAjyB,KACK8xD,GAAuBtwB,GAAQxxB,KAAM,UAAWrD,OAAQ,WACxDolD,GAAqB,IAAKvwB,EAAOwwB,GAAQhgC,IACzC+/B,GAAqB,IAAKvwB,EAAOwwB,GAAQ//B,IACzCggC,GAAmB,OAAQzwB,GAC3B8wB,GAAe9wB,OHGxB,SAAA8d,GAA+B9d,GAC7B,OAAIj7B,GAAUsM,GAAMF,GAAMO,IAAQsuB,EAAM/vB,MAS1C,SAAuB+vB,GACrB,IAAMiyB,GAwG2BhiD,EAxGE+vB,EAAM/vB,KAwGIrE,EAxGEo0B,EAAMp0B,SAyG9CpI,GAAKoI,GAAUkV,OAAO,SAACmxC,EAASljD,GACrC,OAAQA,GAEN,IAAK,IACL,IAAK,IACL,IAAK,QACL,IAAK,UACL,IAAK,OACL,IAAK,KACL,IAAK,KAEL,IAAK,WACL,IAAK,YACL,IAAK,YACL,IAAK,aAIL,IAAK,OACL,IAAK,QACH,OAAOkjD,EAET,IAAK,SACL,IAAK,MACH,IAAMtuC,EAAa/X,EAASmD,GAQ5B,OAPI4U,IACDjoB,EAAQioB,GAAcA,GAAcA,IAAawD,QAAQ,SAAC3R,GACpDA,EAASzL,WACZkoD,EAAQz2D,KAAK2oB,GAAQ3O,SAIpBy8C,EAET,IAAK,OACH,GAAa,UAAThiD,EAEF,OAAOgiD,EAOX,IAAK,QACL,IAAK,OACL,IAAK,SACL,IAAK,UAIH,IAAMz8C,EAAWgQ,GAAoB5Z,EAASmD,IAI9C,OAHIyG,IAAaA,EAASzL,WACxBkoD,EAAQz2D,KAAK2oB,GAAQ3O,OAEhBy8C,EACT,QACE,MAAM,IAAIr3D,MAAM,gBAAgBmU,EAAO,uCAhKvCmjD,EAAYC,GAAcnyB,GAE9BoyB,WAAaH,EAAQ32D,OAAS,EAAI+2D,GAAsB,KAoG5D,IAAmCpiD,EAAYrE,EAjG7C,OAAIqmD,EAAQ32D,OAAS,IAIjBd,KAAMwlC,EAAM6C,QAAQ,aACpBzwB,KAAM,QACNs2B,MACEtS,OACE57B,KAAM63D,GAAsBryB,EAAMwO,gBAAgBlW,IAClDJ,KAAM8H,EAAMwO,gBAAgBlW,IAC5BjP,QAAS4oC,IAGb/lD,QACEq8B,QACE/X,OAAQj0B,OAAQq9B,MAAO,UACvBnJ,QAASl0B,OAAQq9B,MAAO,aAG5BlB,MAAOw5B,IAGFA,EAtCAI,CAActyB,GAEdmyB,GAAcnyB,GAIzB,IAAMqyB,GAAsB,gBAwE5B,SAAAF,GAAuBnyB,EAAkBtrB,QAAA,IAAAA,IAAAA,GAEpC09C,WAAY,KACf,IAAMniD,EAAO+vB,EAAM/vB,KAEb0xC,OAA8Bz/C,IAAvB89B,EAAMnJ,QAAQ8qB,OACvB3hB,EAAMnJ,QAAQ8qB,KAiGpB,SAAmB3hB,GACjB,IAAMqZ,EAASrZ,EAAMoB,kBAAkB,KACjCmY,EAASvZ,EAAMoB,kBAAkB,KACvC,SAAQiY,GAAUA,EAAOha,IAAI,cAC1Bka,GAAUA,EAAOla,IAAI,cArGCkzB,CAAUvyB,GAC7B9V,EAAQiZ,GAAUnD,EAAMnJ,SACxBv2B,EAAM0/B,EAAMp0B,SAAStL,IACrBoD,EA7CR,SAAwBs8B,GACf,IAAAp0B,EAAAo0B,EAAAp0B,SAAU+nB,EAAAqM,EAAArM,MAAO1jB,EAAA+vB,EAAA/vB,KAAM4mB,EAAAmJ,EAAAnJ,QACxBnoB,EAAQ9C,EAAS8C,MACvB,GAAKhT,EAAQgT,KAAUsV,GAAWtV,GAAlC,CAEO,IAAKhT,EAAQgT,IAAUoV,GAAWpV,MAAYilB,EAEnD,OAAOuQ,GAAWx1B,GAAQgW,KAAM,UAC3B,GAAI3S,GAAW9B,GAAf,CAEL,IAAMuiD,EAAsB5mD,EAA4B,eAAnBirB,EAAQ1rB,OAA0B,IAAM,KAC7E,GAAI2Y,GAAW0uC,GAAsB,CACnC,IAAMj3D,EAAIi3D,EAAoB9uD,KAc9B,OACEnH,MAdgBosC,GAAYptC,GAC5B4oB,IAGEpa,UAAW4c,GAAYqZ,EAAMp0B,UAAYrQ,EAAEuI,QAAK5B,EAChD3F,MAAOhB,EAAEgB,QACPmoB,KAAM,UACVP,GAAQquC,GAEN/tC,UAAWub,EAAMrM,OAASqM,EAAMrM,MAAMe,OAAS,WAAQxyB,EACvDwiB,KAAM,UAKRhW,MAAO,iBAiBAk6B,CAAQ5I,GAEfyxB,EAAwBd,GAAa1gD,GAAMwhD,sBAAwBd,GAAa1gD,GAAMwhD,sBAAsBzxB,GAAS,KAE3H,OAAOxhC,GACLhE,KAAMwlC,EAAM6C,QAAQ,SACpBzwB,KAAMu+C,GAAa1gD,GAAM2gD,QACrBjP,GAAQA,MAAM,MACdz3B,GAASA,MAAKA,MACd5pB,GAAOA,KAAM/D,MAAO+D,EAAI/D,WACxBmH,GAAQA,KAAIA,OAChBglC,MAAOxQ,KAAMxjB,EAAI09C,WAAapyB,EAAMwO,gBAAgBlW,KACpDpsB,QACEq8B,OAAQooB,GAAa1gD,GAAMmgD,YAAYpwB,KAErCyxB,GACFp9C,UAAWo9C,QQ7GjB,IAAAgB,GAAA,SAAAtsB,GAkBE,SAAAssB,EAAYnqC,EAA0BnlB,EAAew5C,EACnD+V,EAAwC9V,EAAyB93B,EAAuBgpB,QAAxF,IAAA4kB,IAAAA,MADF,IAAArsB,EAGEF,EAAAhpC,KAAAiB,KAAMkqB,EAAMnlB,EAAQw5C,EAAiB73B,EAAQ83B,OAAU16C,IAAU9D,KAFuBioC,EAAAyH,IAAAA,EAlB1EzH,EAAAj0B,KAAe,OAIfi0B,EAAAoP,mBAINpP,EAAAssB,iBAEAtsB,EAAAusB,oBAEHvsB,EAAA+H,uBAES/H,EAAA7d,aACT6d,EAAAqG,YAMLrG,EAAKkX,SAAQ/+C,KACRk0D,EACCpqC,EAAKkI,OAASA,MAAOlI,EAAKkI,UAC1BlI,EAAKmI,QAAUA,OAAQnI,EAAKmI,aAElC,IAAMxgB,EAAOgC,GAAUqW,EAAKrY,MAAQqY,EAAKrY,KAAKmC,KAAOkW,EAAKrY,KAEpDrE,EAAWy6B,EAAKz6B,SAAWib,GtB5CrC,SAA0Cjb,EAA2BgxC,GACnE,OAAO8M,GAAgB99C,EAAUgxC,GsB2CoBiW,CAA0BvqC,EAAK1c,aAAgBgxC,GAAW3sC,UAE7Go2B,EAAKxP,QAAUi8B,GAAiBxqC,EAAKrY,KAAMrE,EAAUkZ,GAGrDuhB,EAAK1S,MAAQA,GAAM1jB,EAAMrE,EAAUy6B,EAAKvhB,OAAO6O,OAC/C0S,EAAKoP,gBAAkBpP,EAAK0sB,WAAW9iD,EAAMrE,GAE7Cy6B,EAAKssB,cAAgBtsB,EAAK2sB,SAASpnD,GACnCy6B,EAAKusB,iBAAmBvsB,EAAK4sB,WAAWrnD,GACxCy6B,EAAK+H,oBAAsB9lB,EAAK1T,WAGhCyxB,EAAK7d,UAAYF,EAAKE,YA+L1B,OAzO+Bge,EAAAA,EAAAA,GA6C7B1qC,OAAA2pC,eAAWgtB,EAAAn0D,UAAA,qBAAX,WACS,IAAAsN,EAAAxN,KAAAwN,SACDsnD,EAAiB90D,KAAK6R,OAAS4B,GAC/BshD,EAAiBvnD,GAAYmC,GAAqB5I,KACtD,SAAA4J,GAAW,OAAA+U,GAAWlY,EAASmD,MAEjC,OAAOmkD,GAAkBC,mCAOpBV,EAAAn0D,UAAAwxC,YAAP,SAAmB/gC,GACjB,IAAM/D,EAAQ5M,KAAKq3C,gBAAgB1mC,GACnC,OAAO/D,EAAQA,EAAMT,YAASrI,GAGzBuwD,EAAAn0D,UAAA0rB,KAAP,SAAYjb,GACV,OAAO3Q,KAAKu0D,cAAc5jD,IAGrB0jD,EAAAn0D,UAAAkzB,OAAP,SAAcziB,GACZ,OAAO3Q,KAAKw0D,iBAAiB7jD,IAGvB0jD,EAAAn0D,UAAAy0D,WAAR,SAAmB9iD,EAAYrE,GAC7B,OAAOkE,GAAegR,OAAO,SAACgwB,EAAQ/hC,GACpC,IAAIyG,EACAogC,EAEEjyB,EAAa/X,EAASmD,GAiB5B,OAfI+U,GAAWH,IACbnO,EAAWmO,EACXiyB,EAAiBjyB,EAAW3Y,OACnB6Y,GAAuBF,IAChCnO,EAAWmO,EAAWC,UACtBgyB,EAAiBjyB,EAAWC,UAAiB,OACxB,MAAZ7U,EACTyG,EAAWgQ,GAAY5Z,EAASsC,IACX,MAAZa,IACTyG,EAAWgQ,GAAY5Z,EAASuC,KAG9BqH,IACFs7B,EAAO/hC,GAAW6mC,OAEb9E,QAIH2hB,EAAAn0D,UAAA00D,SAAR,SAAiBpnD,GACf,OAAQU,GAAGC,IAAGuU,OAAO,SAASsyC,EAAOrkD,GAInC,IAAM4U,EAAa/X,EAASmD,GAC5B,GAAI+U,GAAWH,IACV5U,IAAYzC,IAAKwX,GAAWlY,EAASsC,KACrCa,IAAYxC,IAAKuX,GAAWlY,EAASuC,IAAM,CAE9C,IAAMklD,EAAWvvC,GAAWH,GAAcA,EAAWqG,KAAO,KAG3C,OAAbqpC,IAAkC,IAAbA,IACvBD,EAAMrkD,GAAQvQ,KACT60D,IAIT,OAAOD,QAIHX,EAAAn0D,UAAA20D,WAAR,SAAmBrnD,GACjB,OAAOgE,GAA2BkR,OAAO,SAASwyC,EAASvkD,GACzD,IAAM4U,EAAa/X,EAASmD,GAC5B,GAAI4U,EAAY,CACd,IAAM6N,EAAS1N,GAAWH,GAAcA,EAAW6N,OAChD3N,GAAuBF,GAAeA,EAAWC,UAAkB,OAAI,KAE3D,OAAX4N,IAA8B,IAAXA,IACrB8hC,EAAQvkD,GAAQvQ,KAAOgzB,IAI3B,OAAO8hC,QAIJb,EAAAn0D,UAAAs/C,UAAP,WACEx/C,KAAKspC,UAAUxP,KAAO0lB,GAAUx/C,OAG3Bq0D,EAAAn0D,UAAAm/C,gBAAP,YvB7FF,SAAoCzd,GAClC,IAAMuzB,EAAsBvzB,EAAM0H,UAAU0B,WAC5C,IAAKmqB,EAAoBxzB,SAASvP,MAAO,CACvC,IAAMA,EAAQ44B,GAAgBppB,EAAO,SACrCuzB,EAAoBtpB,IAAI,QAASzZ,GAAO,GAG1C,IAAK+iC,EAAoBxzB,SAAStP,OAAQ,CACxC,IAAMA,EAAS24B,GAAgBppB,EAAO,UACtCuzB,EAAoBtpB,IAAI,SAAUxZ,GAAQ,IuBqF1C+iC,CAAoBp1D,OAGfq0D,EAAAn0D,UAAAq/C,eAAP,WACEv/C,KAAKspC,UAAUlf,UnDlHnB,SAAmCwX,EAAkByzB,GACnD,IAAMC,KACAC,EAAkB3zB,EAAMlb,OAAO0D,qBAE5B2mB,GACP,IAAKskB,EAAQx1D,eAAekxC,oBAI5B,IAAM4Q,EAAS0T,EAAQtkB,GACjBykB,EAAMD,EAAgB5T,EAAO3tC,MAMnC,IAAK,IAAM9R,KAAOszD,EAGH,cAARtzD,GAAuBy/C,EAAOxlD,QAAoB,WAAR+F,GAAoBy/C,EAAOhuB,YAI9D,SAARzxB,IACFy/C,EAAOz/C,GAAI9B,KAAOo1D,EAAItzD,GAASy/C,EAAOz/C,UAGpB4B,IAAhB69C,EAAOz/C,KAAsC,IAAhBy/C,EAAOz/C,KACtCy/C,EAAOz/C,GAAOszD,EAAItzD,IAAQy/C,EAAOz/C,KAIrC6uC,EAAOroC,GAAQqoC,GACf,IAAMqJ,EAAUkb,EAASvkB,GAAQsa,KAC5B1J,GACHvlD,KAAM20C,EACNwR,OAAQ5kD,EAASgkD,EAAOruB,IAAM8G,GAAcunB,EAAOruB,GAAI,SAAWquB,EAAOruB,KAG3E2xB,GAAiB7K,EAAS,SAAAkL,GACpBA,EAAW98C,OACb88C,EAAW98C,MAAMo5B,EAAO+f,EAAQvH,MArCtC,IAAK,IAAIrJ,KAAQskB,IAARtkB,GA0CT,OAAOukB,EmDoEsBG,CAAmBz1D,KAAMA,KAAKoqB,YAGpDiqC,EAAAn0D,UAAAw/C,eAAP,WACE1/C,KAAKspC,UAAUz3B,KAAO6tC,GAAe1/C,OAGhCq0D,EAAAn0D,UAAAu/C,mBAAP,WACEz/C,KAAKspC,UAAUc,KAAOsrB,GAAc11D,OAG/Bq0D,EAAAn0D,UAAAgsD,iCAAP,SAAwCzL,GACtC,OnDpCsDA,EmDoCjBA,EnDnCnCkV,GAAY,EAChBvQ,GAFsCxjB,EmDoCL5hC,KnDlCT,SAACo6C,EAASiL,GAC5BA,EAAYvD,kBACdrB,EAAU4E,EAAYvD,gBAAgBlgB,EAAOwY,EAASqG,IAGxDwE,GAAiB7K,EAAS,SAAAkL,GACpBA,EAAWxD,kBACbrB,EAAU6E,EAAWxD,gBAAgBlgB,EAAOwY,EAASqG,MAIzDkV,GAAY,IAGVA,IACclV,EAAQ35C,OAAO,SAAC3J,GAAM,MAAW,SAAXA,EAAEf,OACpB,QAClBqkD,EAAQuE,SACN5oD,KAAM,OACN2E,SACAuyB,KAAMivB,OAAQ,YAAapY,OAAQ,yCAKlCsW,EA3BT,IAAwC7e,EAAkB6e,EACpDkV,GmDsCGtB,EAAAn0D,UAAAwgD,yBAAP,WACE,OnDjFJ,SAA6C9e,EAAkB6e,GAC7D2E,GAAiBxjB,EAAO,SAACwY,EAASiL,GAChC,IAAMjpD,EAAOg+C,EAAQh+C,KACjB6mD,EAAaoC,EAAYpC,WAAWrhB,EAAOwY,GAE/CqG,EAAQrjD,KAAK6B,MAAMwhD,EAAS4E,EAAY5E,QAAQ7e,EAAOwY,IAEvD6K,GAAiB7K,EAAS,SAAAkL,GACpBA,EAAW7E,UACbA,EAAU6E,EAAW7E,QAAQ7e,EAAOwY,EAASqG,IAE3C6E,EAAWrC,aACbA,EAAaqC,EAAWrC,WAAWrhB,EAAOwY,EAAS6I,MAIvDxC,EAAQrjD,MACNhB,KAAMA,EAAO8oD,GACb5xB,KACEivB,QAASj6B,OAAQlsB,EAAO4mD,IACxB7Y,OAAQ,UAAU9rC,EAAY+7C,EAAQh+C,KAAOo+C,IAAM,KAAKyI,EAAU,UAKxE,IAAM2S,EAAa3P,GAAcrkB,GACjC,GAAI6e,EAAQvjD,QAAU04D,EAAY,CAChC,IAAMC,EAAOx3D,EAAYu3D,EAAWnxB,QAAQ,SAC5Cgc,EAAQuE,SACN5oD,KAAM,QACN2E,SACAuyB,KACEivB,OAAQnoB,GAAc,YAAa,SACnC+P,OAAQ,kCAAkC0rB,EAAI,cAKpD,OAAOpV,EmD2CEqV,CAA6B91D,UAG/Bq0D,EAAAn0D,UAAAisD,sBAAP,SAA6BryB,GAC3B,OnDdJ,SAA0C8H,EAAkB9H,GAQ1D,OAPAsrB,GAAiBxjB,EAAO,SAAAwY,GACLtgB,EAAKhzB,OAAO,SAAClH,GAAM,OAAAA,EAAExD,OAASg+C,EAAQh+C,KAAOo+C,KAChDt9C,QACZ48B,EAAK18B,MAAMhB,KAAMg+C,EAAQh+C,KAAOo+C,OAI7B1gB,EmDMEi8B,CAA0B/1D,KAAM85B,IAGlCu6B,EAAAn0D,UAAA6/C,eAAP,WACE,OAAO,MAGFsU,EAAAn0D,UAAAysD,sBAAP,WACE,OAAOA,GAAsB3sD,OAGxBq0D,EAAAn0D,UAAAygD,cAAP,WACE,IAAIrmB,EAAQt6B,KAAKspC,UAAUz3B,SAS3B,OAJK7R,KAAK+E,QAAWoqC,GAAanvC,KAAK+E,UACrCu1B,EAAQ6qB,GAA2BnlD,KAAMs6B,IAGpCA,EAAMx8B,IAAIkC,KAAK0+C,mBAGjB2V,EAAAn0D,UAAA4/C,mBAAP,WACE,OACE1tB,MAAOpyB,KAAKirC,iBAAiB,SAC7B5Y,OAAQryB,KAAKirC,iBAAiB,YAIxBopB,EAAAn0D,UAAAohD,WAAV,WACE,OAAOthD,KAAKwN,UAGP6mD,EAAAn0D,UAAA81D,OAAP,SAAcC,EAAqBC,GACjC,IACIhsC,EADE1c,EAAWjF,GAAUvI,KAAKwN,UAiBhC,OAdA0c,GACErY,KAAM7R,KAAKy4B,QACXjrB,SAAUA,GAGPyoD,IACH/rC,EAAKxD,OAASne,GAAUvI,KAAK0mB,SAG1BwvC,IACHhsC,EAAK4P,KAAOvxB,GAAUvI,KAAK85B,OAItB5P,GAGTxsB,OAAA2pC,eAAWgtB,EAAAn0D,UAAA,YAAX,WACE,OAAOF,KAAKy4B,QAAQzkB,sCAGfqgD,EAAAn0D,UAAAsoB,gBAAP,SAAuB7X,GACrB,OAAOwlD,GAA2Bn2D,KAAKwN,SAAUmD,IAG5C0jD,EAAAn0D,UAAAkX,SAAP,SAAgBzG,GAEd,OAAOyW,GADYpnB,KAAKwN,SAASmD,KAGrC0jD,EAzOA,CAA+BhT,IChB/B+U,GAAA,SAAAruB,GASE,SAAAquB,EAAYlsC,EAA2BnlB,EAAew5C,EACpD+V,EAAmC9V,EAAyB93B,EAAgBgpB,GAD9E,IAAAzH,EAGEF,EAAAhpC,KAAAiB,KAAMkqB,EAAMnlB,EAAQw5C,EAAiB73B,EAAQ83B,EAAUt0B,EAAKqJ,UAAQvzB,KAXtDioC,EAAAj0B,KAAgB,QAa9B,IAAMg3B,EAAU5qC,KACXk0D,EACCpqC,EAAKkI,OAASA,MAAOlI,EAAKkI,UAC1BlI,EAAKmI,QAAUA,OAAQnI,EAAKmI,mBAGlC4V,EAAKkX,SAASnU,GAEd/C,EAAKqG,SAAWpkB,EAAK2B,MAAM/tB,IAAI,SAAC+tB,EAAOlvB,GACrC,GAAI85B,GAAY5K,GACd,OAAO,IAAIuqC,EAAWvqC,EAAOoc,EAAMA,EAAKxD,QAAQ,SAAS9nC,GAAIquC,EAAYwT,EAAU93B,EAAQgpB,GAG7F,GAAIlZ,GAAW3K,GACb,OAAO,IAAIwoC,GAAUxoC,EAAOoc,EAAMA,EAAKxD,QAAQ,SAAS9nC,GAAIquC,EAAYwT,EAAU93B,EAAQgpB,GAG5F,MAAM,IAAIlzC,MAAMgf,GAAYvG,kBA0FlC,OAzHgCmzB,EAAAA,EAAAA,GAmCvBguB,EAAAl2D,UAAAs/C,UAAP,WACEx/C,KAAKspC,UAAUxP,KAAO0lB,GAAUx/C,MAChC,IAAoB,IAAAmG,EAAA,EAAAoB,EAAAvH,KAAKsuC,SAALnoC,EAAAoB,EAAArK,OAAAiJ,IAAe,CAAnBoB,EAAApB,GACRq5C,cAIH4W,EAAAl2D,UAAAm/C,gBAAP,WACEuL,GAAqB5qD,OAGhBo2D,EAAAl2D,UAAAq/C,eAAP,WAAA,IAAAtX,EAAAjoC,KAIEA,KAAKspC,UAAUlf,aACf,mBAAWqP,GACTA,EAAM8lB,iBACNn6C,GAAKq0B,EAAM6P,UAAUlf,WAAWrB,QAAQ,SAAC7mB,GACvC+lC,EAAKqB,UAAUlf,UAAUloB,GAAOu3B,EAAM6P,UAAUlf,UAAUloB,MAH1CiE,EAAA,EAAAoB,EAAAvH,KAAKsuC,SAALnoC,EAAAoB,EAAArK,OAAAiJ,IAAa,GAAjBoB,EAAApB,MAQXiwD,EAAAl2D,UAAAw/C,eAAP,WACE,IAAoB,IAAAv5C,EAAA,EAAAoB,EAAAvH,KAAKsuC,SAALnoC,EAAAoB,EAAArK,OAAAiJ,IAAe,CAAnBoB,EAAApB,GACRu5C,mBAIH0W,EAAAl2D,UAAAu/C,mBAAP,YdjDF,SAA+B7d,GAO7B,IANM,IAAAr6B,EAAAq6B,EAAA0H,UAACc,EAAA7iC,EAAA6iC,KAAM7W,EAAAhsB,EAAAgsB,QACP8iC,GAGDvF,IAAK,EAAGD,OAAQ,EAAGG,MAAO,EAAGD,KAAM,GAEpB5qD,EAAA,EAAAme,EAAAsd,EAAM0M,SAANnoC,EAAAme,EAAApnB,OAAAiJ,IAAgB,EAAzBszB,EAAKnV,EAAAne,IACRs5C,qBAEN,IAAsB,IAAA1zB,EAAA,EAAAC,EAAA5mB,GAAKq0B,EAAM6P,UAAUc,MAArBre,EAAAC,EAAA9uB,OAAA6uB,IAA4B,CAA7C,IAAMpb,EAAOqb,EAAAD,GAChBwH,EAAQ3H,KAAKjb,GAAW26B,GAAkB1J,EAAM0H,UAAU/V,QAAS5iB,GACrC,WAA1B4iB,EAAQ3H,KAAKjb,KAIfy5B,EAAKz5B,GAAWsgD,GAAoB7mB,EAAKz5B,GAAU8oB,EAAM6P,UAAUc,KAAKz5B,IAEnEy5B,EAAKz5B,KAGR4iB,EAAQ3H,KAAKjb,GAAW,qBACjBy5B,EAAKz5B,MAOpB,IAAsB,IAAA6Z,EAAA,EAAAoK,GAAC1mB,GAAGC,IAAJqc,EAAAoK,EAAA13B,OAAAstB,IAAjB,CAAM7Z,EAAOikB,EAAApK,GAChB,IADG,IACiB8jC,EAAA,EAAAC,EAAA3sB,EAAM0M,SAANggB,EAAAC,EAAArxD,OAAAoxD,IAAgB,CAA/B,IAAM70B,EACT,IADSA,EAAK80B,EAAAD,IACHhlB,UAAUc,KAAKz5B,GAA1B,CAKA,GAA8B,gBAA1B4iB,EAAQ3H,KAAKjb,GAA4B,CAE3Cy5B,EAAKz5B,IAAYy5B,EAAKz5B,QAAgB9R,OAAO46B,EAAM6P,UAAUc,KAAKz5B,IAGlE,IAA4B,IAAA69C,EAAA,EAAA8H,EAAA78B,EAAM6P,UAAUc,KAAKz5B,GAArB69C,EAAA8H,EAAAp5D,OAAAsxD,IAA+B,CAAtD,IAAMxC,EAAasK,EAAA9H,GAChB+H,EAAAvK,EAAArgB,gBAAA,UAAC5+B,EAAAA,EAAAA,MAAe40B,EAAA40B,EAAA50B,SACtB,GAAI00B,EAAUtpD,GAAU,IAAM40B,EAAU,CAEtC,IAAM60B,EAAiB5F,GAAgB7jD,GACnCspD,EAAUtpD,GAAUspD,EAAUG,IAChCxK,EAAcngB,IAAI,SAAU2qB,GAAgB,GAGhDH,EAAUtpD,aAOP0sB,EAAM6P,UAAUc,KAAKz5B,McP9B8lD,CAAez2D,OAGVo2D,EAAAl2D,UAAAgsD,iCAAP,SAAwCzL,GACtC,OAAOzgD,KAAKsuC,SAAS5rB,OAAO,SAACosC,EAAIr1B,GAAU,OAAAA,EAAMyyB,iCAAiC4C,IAAKrO,IAIlF2V,EAAAl2D,UAAAwgD,yBAAP,WACE,OAAO1gD,KAAKsuC,SAAS5rB,OAAO,SAAC+9B,EAAShnB,GACpC,OAAOgnB,EAAQ5hD,OAAO46B,EAAMinB,kCAKzB0V,EAAAl2D,UAAAysD,sBAAP,WACE,OAAO3sD,KAAKsuC,SAAS5rB,OAAO,SAAC+9B,EAAShnB,GACpC,OAAOgnB,EAAQ5hD,OAAO46B,EAAMkzB,0BAC3BA,GAAsB3sD,QAGpBo2D,EAAAl2D,UAAAisD,sBAAP,SAA6BryB,GAC3B,OAAO95B,KAAKsuC,SAAS5rB,OAAO,SAACqsC,EAAIt1B,GAAU,OAAAA,EAAM0yB,sBAAsB4C,IAAKj1B,IAGvEs8B,EAAAl2D,UAAAi/B,cAAP,WACE,IAAIxyB,EAAQo7B,EAAA7nC,UAAMi/B,cAAapgC,KAAAiB,MAC/B,GAAI2M,EACF,OAAOA,EAGT,IAAoB,IAAAxG,EAAA,EAAAoB,EAAAvH,KAAKsuC,SAALnoC,EAAAoB,EAAArK,OAAAiJ,IAAe,CAEjC,GADAwG,EADcpF,EAAApB,GACAg5B,gBAEZ,OAAOxyB,IAMNypD,EAAAl2D,UAAA6/C,eAAP,WACE,OAAO,MAGFqW,EAAAl2D,UAAAygD,cAAP,WACE,OpDgFwC/e,EoDhFL5hC,KpDgFwBs6B,EoDhFlBpzB,EAAQlH,KAAKsuC,SAASxwC,IAAI,SAAC27B,GAClE,OAAOA,EAAMknB,mBpDgFjB/e,EAAM0M,SAASvlB,QAAQ,SAAA0Q,GACjB4T,GAAY5T,KACda,EAAQ6qB,GAA2B1rB,EAAOa,MAIvCA,EAPT,IAA4CsH,EAAmBtH,GoD3EtD87B,EAAAl2D,UAAAqgD,gBAAP,WACE,OAAOvgD,KAAKsuC,SAAS5rB,OAAO,SAAC4qB,EAAS7T,GACpC,OAAO6T,EAAQzuC,OAAO46B,EAAM8mB,oBAC3BA,GAAgBvgD,QAEvBo2D,EAzHA,CAAgC9X,ICJhCoY,GAAA,SAAA3uB,GAME,SAAA2uB,EAAYxsC,EAA4BnlB,EAAew5C,EAAyBoY,EAA6BjwC,GAA7G,IAAAuhB,EACEF,EAAAhpC,KAAAiB,KAAMkqB,EAAMnlB,EAAQw5C,EAAiB73B,EAAQiwC,EAAczsC,EAAKqJ,UAAQvzB,YAN1DioC,EAAAj0B,KAAiB,SAQ3BkW,EAAKqJ,SAAWrJ,EAAKqJ,QAAQ3H,OAAiC,WAAxB1B,EAAKqJ,QAAQ3H,KAAK/tB,GAA0C,WAAxBqsB,EAAKqJ,QAAQ3H,KAAK/b,IAC9F0L,GAASC,GAAY9F,0BAGvBuyB,EAAKijB,OAAShhC,EAAKghC,OACnBjjB,EAAKqG,SAAWrG,EAAK2uB,cAAc1sC,EAAM+d,EAAKijB,OAAQyL,EAAcjwC,KAoCxE,OAlDiC0hB,EAAAA,EAAAA,GAiBvBsuB,EAAAx2D,UAAA02D,cAAR,SAAsB1sC,EAA4BghC,EAAgB1M,EAAyB93B,GAMzF,IALA,IAAM4nB,KACAz9B,EAAMq6C,EAAOr6C,MAAQ2tC,EAAWA,EAAS3tC,IAAM,MAC/CC,EAASo6C,EAAOp6C,SAAW0tC,EAAWA,EAAS1tC,OAAS,MAGvC3K,EAAA,EAAA0wD,EAAAhmD,EAAA1K,EAAA0wD,EAAA35D,OAAAiJ,IACrB,IADG,IAAM2wD,EAAQD,EAAA1wD,GACSoB,EAAA,EAAAwvD,EAAAjmD,EAAAvJ,EAAAwvD,EAAA75D,OAAAqK,IAAQ,CAA7B,IAAMyvD,EAAWD,EAAAxvD,GACdwpC,GAAQ+lB,EAAW,IAAMA,EAAW,KAAOE,EAAc,IAAMA,EAAc,IAE7EC,GACJpmD,IAAKimD,EACLhmD,OAAQkmD,GAGV1oB,EAASlxC,KAAKouD,GAAWthC,EAAKA,KAAMlqB,KAAMA,KAAKykC,QAAQ,QAAUsM,QAAOjtC,EAAWmzD,EAAavwC,GAAQ,IAI5G,OAAO4nB,GAGFooB,EAAAx2D,UAAAm/C,gBAAP,WACEsL,GAAsB3qD,OAGd02D,EAAAx2D,UAAA8/C,sBAAV,WACE,OACEyM,QAASzsD,KAAKkrD,QAAUlrD,KAAKkrD,OAAOp6C,OAAS9Q,KAAKkrD,OAAOp6C,OAAO5T,OAAS,EACzEuhD,OAAQ,OACRjhB,MAAO,QAGbk5B,EAlDA,CAAiC7H,gBCDN3kC,EAAsBnlB,EAAew5C,EAC9D2Y,EAA4B1Y,EAAyB93B,EAAgBgpB,GACrE,GAAInZ,GAAYrM,GACd,OAAO,IAAIqhC,GAAWrhC,EAAMnlB,EAAQw5C,EAAiBC,EAAU93B,GAGjE,GAAI+P,GAAYvM,GACd,OAAO,IAAIksC,GAAWlsC,EAAMnlB,EAAQw5C,EAAiB2Y,EAAU1Y,EAAU93B,EAAQgpB,GAGnF,GAAIlZ,GAAWtM,GACb,OAAO,IAAImqC,GAAUnqC,EAAMnlB,EAAQw5C,EAAiB2Y,EAAU1Y,EAAU93B,EAAQgpB,GAGlF,GAAIhZ,GAAaxM,GACf,OAAO,IAAIwsC,GAAYxsC,EAAMnlB,EAAQw5C,EAAiBC,EAAU93B,GAGlE,GAAIiQ,GAAazM,GACf,OAAO,IAAI8kC,GAAY9kC,EAAMnlB,EAAQw5C,EAAiBC,EAAU93B,GAGlE,MAAM,IAAIlqB,MAAMgf,GAAYvG,uCClBjBkiD,IACXr2D,MAAO,QACPwR,MAAO,IAAK,KACZC,OAAQ,IAAK,KACbC,MAAO,IAAK,MAYD4kD,IACXhlD,IAAK5S,GAAO,MAAO,SAAU,IAAK,IAAK,OAAQ,QAAS,OAAQ,SAAU,WAC1E8S,KAAM9S,GAAO,MAAO,SAAU,IAAK,IAAK,QAAS,OAAQ,SAAU,QAAS,WAC5E+S,MAAO/S,GAAO,MAAO,SAAU,IAAK,IAAK,QAAS,OAAQ,SAAU,QAAS,SAAU,SACvFgT,KAAMhT,GAAO,MAAO,SAAU,IAAK,IAAK,QAAS,OAAQ,SAAU,WACnEwS,KAAMxS,GAAO,MAAO,SAAU,IAAK,IAAK,QAAS,OAAQ,SAAU,WACnE0S,OAAQ1S,GAAO,MAAO,SAAU,IAAK,IAAK,QAAS,OAAQ,SAAU,OAAQ,WAC7E2S,OAAQ3S,GAAO,MAAO,SAAU,IAAK,IAAK,QAAS,OAAQ,SAAU,OAAQ,WAC7EuS,MAAOvS,GAAO,MAAO,SAAU,IAAK,IAAK,QAAS,OAAQ,SAAU,OAAQ,SAAU,UACtFiT,SAAUjT,GAAO,MAAO,SAAU,QAAS,OAAQ,SAAU,SAAU,UACvEsB,KAAMtB,GAAO,MAAO,SAAU,OAAQ,QAAS,OAAQ,SAAU,0HAmBnE,SAAwC0qB,EACtCmtC,EACAC,QADA,IAAAD,IAAAA,EAAAF,SACA,IAAAG,IAAAA,EAAAF,IAEA,IAAMvlD,EAAOgC,GAAUqW,EAAKrY,MAAQqY,EAAKrY,KAAKmC,KAAOkW,EAAKrY,KACpDrE,EAAW0c,EAAK1c,SAChB+pD,EAAmBF,EAAmBxlD,GACtC2X,EAAoB8tC,EAAoBzlD,GAE9C,IAAK,IAAMlV,KAAK46D,EACd,KAAMA,EAAiB56D,KAAM6Q,GAC3B,MAAO,6BAAgC+pD,EAAiB56D,GACtD,eAAmBkV,EAAO,IAIhC,IAAK,IAAMlB,KAAWnD,EACpB,IAAKgc,EAAkB7Y,GACrB,MAAO,qBAAwBA,EAC7B,oCAAwCkB,EAAO,IAIrD,OAAIA,IAASmB,IAAQxF,EAAS3P,GAAM2P,EAASqC,EAItC,KAHE,kCCxDL2nD,0TCiBN,SAAwBC,EAAyBnhD,GhHoBjD,IAAoBohD,EoDuDaC,EAC3BzgB,O4D5E2C,IAAA5gC,IAAAA,MAE3CA,EAAIshD,ShHkBUF,EgHhBRphD,EAAIshD,OhHiBd5iD,GAAU0iD,GgHdNphD,EAAIwQ,YAEN+wC,GAA6BvhD,EAAIwQ,YAGnC,IAEE,IAAMJ,EAASqN,GAAW3sB,MAAckP,EAAIoQ,OAAQ+wC,EAAU/wC,SAKxDwD,EAAO7O,GAAUo8C,EAAW/wC,GAE5BiT,E9FsFV,SAAkCm+B,EAAiDC,EAA+CC,QAAA,IAAAA,IAAAA,GAAA,GAChI,IAAMr+B,EAAQv5B,GACZ4T,KAAM,OACH0lB,GAAmBq+B,GACnBr+B,GAAmBo+B,IAUxB,MAPsB,QAAlBn+B,EAAS3lB,OACNgkD,IACHz8C,GAASC,GAAYtG,gBACrBykB,EAAS3lB,KAAO,QAIb2lB,E8FpGYs+B,CAAkBR,EAAU99B,SAAUjT,EAAOiT,SAAUlD,GAAYvM,IAASsM,GAAWtM,IAMlG0X,EAAe4pB,GAAWthC,EAAM,KAAM,QAAIpmB,OAAWA,EAAW4iB,EAA0B,QAAlBiT,EAAS3lB,MAoBvF,OANA4tB,EAAMp5B,Q5DkCuBmvD,E4D/BZ/1B,EAAM0H,UAAUxP,M5DgC/Bod,EAAsB9uC,GAAKuvD,EAAchoB,UAEvC5mB,QAAQiuB,IAIdC,GADAC,EAAQA,EAAMpwC,OAAO,SAAAzF,GAAK,OAAAA,EAAEkmC,cAAgB,KAC3Bxe,QAAQmvC,GAA6BC,KAGtDlhB,GAFAC,EAAQA,EAAMpwC,OAAO,SAAAzF,GAAK,OAAAA,EAAEkmC,cAAgB,KAE3Bxe,QAAQmvC,GAA6BE,KACtDnhB,GAAUC,GAAOnuB,QAAQsvC,IAEzBnhB,EAAMnuB,QAAQ4tB,IAEdvxC,GAAKuyD,EAAchoB,SAAS5mB,QAAQ,SAAA5rB,GACa,IAA3Cw6D,EAAchoB,QAAQxyC,GAAGoqC,sBACpBowB,EAAchoB,QAAQxyC,K4DjBnC,SAA+BykC,EAAc02B,GAI3C,IAAMC,EAAW32B,EAAMlb,OAASyN,GAAuByN,EAAMlb,aAAU5iB,EAEjEg2B,KAAUj7B,OACd+iC,EAAMuqB,0B9B8EV,SAAiCwL,EAA8Ba,GAC7D,IAAMthB,EAAsB9uC,GAAKuvD,EAAchoB,SACzC7V,KAIAswB,EAAWF,GAAapwB,GAE1B2+B,EAAc,EAElBvhB,EAAMnuB,QAAQ,SAAAqkC,GAEPA,EAAKrY,YACRqY,EAAKsL,SAAW,UAAUD,KAG5B,IAAME,EAAkBvL,EAAKlkB,WAE7BkhB,EAASgD,EAAMuL,KAIjB7+B,EAAK/Q,QAAQ,SAAAnpB,GACgB,IAAvBA,EAAEqW,UAAU/Y,eACP0C,EAAEqW,YAMb,IADA,IAAI2iD,EAAU,EACLj8D,EAAI,EAAGA,EAAIm9B,EAAK58B,OAAQP,IAEI,MAD7BiD,EAAIk6B,EAAKn9B,IACRsZ,eAAiB/Y,QAAiB0C,EAAE2D,QACzCu2B,EAAKt0B,OAAOozD,IAAW,EAAG9+B,EAAKt0B,OAAO7I,EAAG,GAAG,IAKhD,IAAgB,IAAAwJ,EAAA,EAAA+pC,EAAApW,EAAA3zB,EAAA+pC,EAAAhzC,OAAAiJ,IACd,IADG,IACaoB,EAAA,EAAA+c,GADP1kB,EAACswC,EAAA/pC,IACQ8P,cAAF1O,EAAA+c,EAAApnB,OAAAqK,IAAmB,CAA9B,IAAMjH,EAACgkB,EAAA/c,GACK,WAAXjH,EAAE0T,OACJ1T,EAAEgqC,KAAOqtB,EAAc5gB,YAAYz2C,EAAEgqC,MAAMhC,aAMjD,IAAgB,IAAAvc,EAAA,EAAA8sC,EAAA/+B,EAAA/N,EAAA8sC,EAAA37D,OAAA6uB,IAAM,CAAjB,IAAMnsB,GAAAA,EAACi5D,EAAA9sC,IACJ3vB,QAAQo8D,IACZ54D,EAAE+H,OAAS6wD,EAAS54D,EAAExD,OAI1B,OAAO09B,E8BjILg/B,CAAiBl3B,EAAM0H,UAAUxP,KAAMw+B,EAAmBE,sBAGrDF,EAAmBE,SAE1B,IAAMlpB,EAAc1N,EAAM2N,sBACpB5iC,EAAQi1B,EAAMzC,gBACdrT,EAAQ8V,EAAMie,qBAEhBkZ,EAAgBn3B,EAAM+qB,wBA0B1B,OAvBAoM,EAAgBA,EAAcjyD,OAAO,SAAAwhB,GACnC,MAAqB,UAAhBA,EAAOlsB,MAAoC,WAAhBksB,EAAOlsB,WAAuC0H,IAAjBwkB,EAAOvnB,QAClEu3D,EAAmBhwC,EAAOlsB,OAASksB,EAAOvnB,OACnC,MAqBTmpB,KAhBU9pB,GACV44D,QAAS,8CACLp3B,EAAMkd,aAAeA,YAAald,EAAMkd,gBACzCwZ,EACC3rD,GAAQA,MAAK89B,MACb3e,GAAQA,MAAKA,OACjBgO,KAAMA,GACFwV,EAAYpyC,OAAS,GAAKoyC,YAAaA,MACxC1N,EAAM4e,cACJuY,EAAal6D,OACb+iC,EAAMsqB,uCAEPqM,GAAY7xC,OAAQ6xC,QArEjBU,CAAsBr3B,EAcjC,SAA+Bs3B,EAA6BxyC,EAAgBiT,GAC1E,OAAAv5B,GACEu5B,SAAoC,IAA1Bv0B,GAAKu0B,GAAUz8B,QAAgBy8B,EAAS3lB,KAAO2lB,EAAS3lB,KAAO2lB,GACtEE,GAA0BnT,GAC1BmT,GAA0Bq/B,IAlBOC,CAAsB1B,EAAW/wC,EAAQiT,YAGzErjB,EAAIshD,ShHrBV5iD,GAAUJ,IgHyBJ0B,EAAIwQ,YACNsyC","file":"build/vega-lite.min.js.map","sourcesContent":["export default function(fn, fields, name) {\n fn.fields = fields || [];\n fn.fname = name;\n return fn;\n}\n\nexport function accessorName(fn) {\n return fn == null ? null : fn.fname;\n}\n\nexport function accessorFields(fn) {\n return fn == null ? null : fn.fields;\n}\n","export default function(message) {\n throw Error(message);\n}\n","import error from './error';\n\nexport default function(p) {\n var path = [],\n q = null,\n b = 0,\n n = p.length,\n s = '',\n i, j, c;\n\n p = p + '';\n\n function push() {\n path.push(s + p.substring(i, j));\n s = '';\n i = j + 1;\n }\n\n for (i=j=0; j i) {\n push();\n } else {\n i = j + 1;\n }\n } else if (c === '[') {\n if (j > i) push();\n b = i = j + 1;\n } else if (c === ']') {\n if (!b) error('Access path missing open bracket: ' + p);\n if (b > 0) push();\n b = 0;\n i = j + 1;\n }\n }\n\n if (b) error('Access path missing closing bracket: ' + p);\n if (q) error('Access path missing closing quote: ' + p);\n\n if (j > i) {\n j++;\n push();\n }\n\n return path;\n}\n","export default Array.isArray;\n","export default function(_) {\n return _ === Object(_);\n}\n","export default function(_) {\n return typeof _ === 'string';\n}\n","import isArray from './isArray';\nimport isObject from './isObject';\nimport isString from './isString';\n\nexport default function $(x) {\n return isArray(x) ? '[' + x.map($) + ']'\n : isObject(x) || isString(x) ?\n // Output valid JSON and JS source strings.\n // See http://timelessrepo.com/json-isnt-a-javascript-subset\n JSON.stringify(x).replace('\\u2028','\\\\u2028').replace('\\u2029', '\\\\u2029')\n : x;\n}\n","import accessor from './accessor';\nimport field from './field';\n\nvar empty = [];\n\nexport var id = field('id');\n\nexport var identity = accessor(function(_) { return _; }, empty, 'identity');\n\nexport var zero = accessor(function() { return 0; }, empty, 'zero');\n\nexport var one = accessor(function() { return 1; }, empty, 'one');\n\nexport var truthy = accessor(function() { return true; }, empty, 'true');\n\nexport var falsy = accessor(function() { return false; }, empty, 'false');\n","import accessor from './accessor';\nimport splitAccessPath from './splitAccessPath';\nimport stringValue from './stringValue';\n\nexport default function(field, name) {\n var path = splitAccessPath(field),\n code = 'return _[' + path.map(stringValue).join('][') + '];';\n\n return accessor(\n Function('_', code),\n [(field = path.length===1 ? path[0] : field)],\n name || field\n );\n}\n","function log(method, level, input) {\n var args = [level].concat([].slice.call(input));\n console[method].apply(console, args); // eslint-disable-line no-console\n}\n\nexport var None = 0;\nexport var Error = 1;\nexport var Warn = 2;\nexport var Info = 3;\nexport var Debug = 4;\n\nexport default function(_) {\n var level = _ || None;\n return {\n level: function(_) {\n if (arguments.length) {\n level = +_;\n return this;\n } else {\n return level;\n }\n },\n error: function() {\n if (level >= Error) log('error', 'ERROR', arguments);\n return this;\n },\n warn: function() {\n if (level >= Warn) log('warn', 'WARN', arguments);\n return this;\n },\n info: function() {\n if (level >= Info) log('log', 'INFO', arguments);\n return this;\n },\n debug: function() {\n if (level >= Debug) log('log', 'DEBUG', arguments);\n return this;\n }\n }\n}\n","export default function(_) {\n return typeof _ === 'boolean';\n}\n","export default function(_) {\n return typeof _ === 'number';\n}\n","export default function(_) {\n for (var s={}, i=0, n=_.length; i= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n","var at, // The index of the current character\n ch, // The current character\n escapee = {\n '\"': '\"',\n '\\\\': '\\\\',\n '/': '/',\n b: '\\b',\n f: '\\f',\n n: '\\n',\n r: '\\r',\n t: '\\t'\n },\n text,\n\n error = function (m) {\n // Call error when something is wrong.\n throw {\n name: 'SyntaxError',\n message: m,\n at: at,\n text: text\n };\n },\n \n next = function (c) {\n // If a c parameter is provided, verify that it matches the current character.\n if (c && c !== ch) {\n error(\"Expected '\" + c + \"' instead of '\" + ch + \"'\");\n }\n \n // Get the next character. When there are no more characters,\n // return the empty string.\n \n ch = text.charAt(at);\n at += 1;\n return ch;\n },\n \n number = function () {\n // Parse a number value.\n var number,\n string = '';\n \n if (ch === '-') {\n string = '-';\n next('-');\n }\n while (ch >= '0' && ch <= '9') {\n string += ch;\n next();\n }\n if (ch === '.') {\n string += '.';\n while (next() && ch >= '0' && ch <= '9') {\n string += ch;\n }\n }\n if (ch === 'e' || ch === 'E') {\n string += ch;\n next();\n if (ch === '-' || ch === '+') {\n string += ch;\n next();\n }\n while (ch >= '0' && ch <= '9') {\n string += ch;\n next();\n }\n }\n number = +string;\n if (!isFinite(number)) {\n error(\"Bad number\");\n } else {\n return number;\n }\n },\n \n string = function () {\n // Parse a string value.\n var hex,\n i,\n string = '',\n uffff;\n \n // When parsing for string values, we must look for \" and \\ characters.\n if (ch === '\"') {\n while (next()) {\n if (ch === '\"') {\n next();\n return string;\n } else if (ch === '\\\\') {\n next();\n if (ch === 'u') {\n uffff = 0;\n for (i = 0; i < 4; i += 1) {\n hex = parseInt(next(), 16);\n if (!isFinite(hex)) {\n break;\n }\n uffff = uffff * 16 + hex;\n }\n string += String.fromCharCode(uffff);\n } else if (typeof escapee[ch] === 'string') {\n string += escapee[ch];\n } else {\n break;\n }\n } else {\n string += ch;\n }\n }\n }\n error(\"Bad string\");\n },\n\n white = function () {\n\n// Skip whitespace.\n\n while (ch && ch <= ' ') {\n next();\n }\n },\n\n word = function () {\n\n// true, false, or null.\n\n switch (ch) {\n case 't':\n next('t');\n next('r');\n next('u');\n next('e');\n return true;\n case 'f':\n next('f');\n next('a');\n next('l');\n next('s');\n next('e');\n return false;\n case 'n':\n next('n');\n next('u');\n next('l');\n next('l');\n return null;\n }\n error(\"Unexpected '\" + ch + \"'\");\n },\n\n value, // Place holder for the value function.\n\n array = function () {\n\n// Parse an array value.\n\n var array = [];\n\n if (ch === '[') {\n next('[');\n white();\n if (ch === ']') {\n next(']');\n return array; // empty array\n }\n while (ch) {\n array.push(value());\n white();\n if (ch === ']') {\n next(']');\n return array;\n }\n next(',');\n white();\n }\n }\n error(\"Bad array\");\n },\n\n object = function () {\n\n// Parse an object value.\n\n var key,\n object = {};\n\n if (ch === '{') {\n next('{');\n white();\n if (ch === '}') {\n next('}');\n return object; // empty object\n }\n while (ch) {\n key = string();\n white();\n next(':');\n if (Object.hasOwnProperty.call(object, key)) {\n error('Duplicate key \"' + key + '\"');\n }\n object[key] = value();\n white();\n if (ch === '}') {\n next('}');\n return object;\n }\n next(',');\n white();\n }\n }\n error(\"Bad object\");\n };\n\nvalue = function () {\n\n// Parse a JSON value. It could be an object, an array, a string, a number,\n// or a word.\n\n white();\n switch (ch) {\n case '{':\n return object();\n case '[':\n return array();\n case '\"':\n return string();\n case '-':\n return number();\n default:\n return ch >= '0' && ch <= '9' ? number() : word();\n }\n};\n\n// Return the json_parse function. It will have access to all of the above\n// functions and variables.\n\nmodule.exports = function (source, reviver) {\n var result;\n \n text = source;\n at = 0;\n ch = ' ';\n result = value();\n white();\n if (ch) {\n error(\"Syntax error\");\n }\n\n // If there is a reviver function, we recursively walk the new structure,\n // passing each name/value pair to the reviver function for possible\n // transformation, starting with a temporary root object that holds the result\n // in an empty key. If there is not a reviver function, we simply return the\n // result.\n\n return typeof reviver === 'function' ? (function walk(holder, key) {\n var k, v, value = holder[key];\n if (value && typeof value === 'object') {\n for (k in value) {\n if (Object.prototype.hasOwnProperty.call(value, k)) {\n v = walk(value, k);\n if (v !== undefined) {\n value[k] = v;\n } else {\n delete value[k];\n }\n }\n }\n }\n return reviver.call(holder, key, value);\n }({'': result}, '')) : result;\n};\n","var cx = /[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n escapable = /[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n gap,\n indent,\n meta = { // table of character substitutions\n '\\b': '\\\\b',\n '\\t': '\\\\t',\n '\\n': '\\\\n',\n '\\f': '\\\\f',\n '\\r': '\\\\r',\n '\"' : '\\\\\"',\n '\\\\': '\\\\\\\\'\n },\n rep;\n\nfunction quote(string) {\n // If the string contains no control characters, no quote characters, and no\n // backslash characters, then we can safely slap some quotes around it.\n // Otherwise we must also replace the offending characters with safe escape\n // sequences.\n \n escapable.lastIndex = 0;\n return escapable.test(string) ? '\"' + string.replace(escapable, function (a) {\n var c = meta[a];\n return typeof c === 'string' ? c :\n '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n }) + '\"' : '\"' + string + '\"';\n}\n\nfunction str(key, holder) {\n // Produce a string from holder[key].\n var i, // The loop counter.\n k, // The member key.\n v, // The member value.\n length,\n mind = gap,\n partial,\n value = holder[key];\n \n // If the value has a toJSON method, call it to obtain a replacement value.\n if (value && typeof value === 'object' &&\n typeof value.toJSON === 'function') {\n value = value.toJSON(key);\n }\n \n // If we were called with a replacer function, then call the replacer to\n // obtain a replacement value.\n if (typeof rep === 'function') {\n value = rep.call(holder, key, value);\n }\n \n // What happens next depends on the value's type.\n switch (typeof value) {\n case 'string':\n return quote(value);\n \n case 'number':\n // JSON numbers must be finite. Encode non-finite numbers as null.\n return isFinite(value) ? String(value) : 'null';\n \n case 'boolean':\n case 'null':\n // If the value is a boolean or null, convert it to a string. Note:\n // typeof null does not produce 'null'. The case is included here in\n // the remote chance that this gets fixed someday.\n return String(value);\n \n case 'object':\n if (!value) return 'null';\n gap += indent;\n partial = [];\n \n // Array.isArray\n if (Object.prototype.toString.apply(value) === '[object Array]') {\n length = value.length;\n for (i = 0; i < length; i += 1) {\n partial[i] = str(i, value) || 'null';\n }\n \n // Join all of the elements together, separated with commas, and\n // wrap them in brackets.\n v = partial.length === 0 ? '[]' : gap ?\n '[\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + ']' :\n '[' + partial.join(',') + ']';\n gap = mind;\n return v;\n }\n \n // If the replacer is an array, use it to select the members to be\n // stringified.\n if (rep && typeof rep === 'object') {\n length = rep.length;\n for (i = 0; i < length; i += 1) {\n k = rep[i];\n if (typeof k === 'string') {\n v = str(k, value);\n if (v) {\n partial.push(quote(k) + (gap ? ': ' : ':') + v);\n }\n }\n }\n }\n else {\n // Otherwise, iterate through all of the keys in the object.\n for (k in value) {\n if (Object.prototype.hasOwnProperty.call(value, k)) {\n v = str(k, value);\n if (v) {\n partial.push(quote(k) + (gap ? ': ' : ':') + v);\n }\n }\n }\n }\n \n // Join all of the member texts together, separated with commas,\n // and wrap them in braces.\n\n v = partial.length === 0 ? '{}' : gap ?\n '{\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + '}' :\n '{' + partial.join(',') + '}';\n gap = mind;\n return v;\n }\n}\n\nmodule.exports = function (value, replacer, space) {\n var i;\n gap = '';\n indent = '';\n \n // If the space parameter is a number, make an indent string containing that\n // many spaces.\n if (typeof space === 'number') {\n for (i = 0; i < space; i += 1) {\n indent += ' ';\n }\n }\n // If the space parameter is a string, it will be used as the indent string.\n else if (typeof space === 'string') {\n indent = space;\n }\n\n // If there is a replacer, it must be a function or an array.\n // Otherwise, throw an error.\n rep = replacer;\n if (replacer && typeof replacer !== 'function'\n && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) {\n throw new Error('JSON.stringify');\n }\n \n // Make a fake root object containing our value under the key of ''.\n // Return the result of stringifying the value.\n return str('', {'': value});\n};\n","var json = typeof JSON !== 'undefined' ? JSON : require('jsonify');\n\nmodule.exports = function (obj, opts) {\n if (!opts) opts = {};\n if (typeof opts === 'function') opts = { cmp: opts };\n var space = opts.space || '';\n if (typeof space === 'number') space = Array(space+1).join(' ');\n var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;\n var replacer = opts.replacer || function(key, value) { return value; };\n\n var cmp = opts.cmp && (function (f) {\n return function (node) {\n return function (a, b) {\n var aobj = { key: a, value: node[a] };\n var bobj = { key: b, value: node[b] };\n return f(aobj, bobj);\n };\n };\n })(opts.cmp);\n\n var seen = [];\n return (function stringify (parent, key, node, level) {\n var indent = space ? ('\\n' + new Array(level + 1).join(space)) : '';\n var colonSeparator = space ? ': ' : ':';\n\n if (node && node.toJSON && typeof node.toJSON === 'function') {\n node = node.toJSON();\n }\n\n node = replacer.call(parent, key, node);\n\n if (node === undefined) {\n return;\n }\n if (typeof node !== 'object' || node === null) {\n return json.stringify(node);\n }\n if (isArray(node)) {\n var out = [];\n for (var i = 0; i < node.length; i++) {\n var item = stringify(node, i, node[i], level+1) || json.stringify(null);\n out.push(indent + space + item);\n }\n return '[' + out.join(',') + indent + ']';\n }\n else {\n if (seen.indexOf(node) !== -1) {\n if (cycles) return json.stringify('__cycle__');\n throw new TypeError('Converting circular structure to JSON');\n }\n else seen.push(node);\n\n var keys = objectKeys(node).sort(cmp && cmp(node));\n var out = [];\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = stringify(node, key, node[key], level+1);\n\n if(!value) continue;\n\n var keyValue = json.stringify(key)\n + colonSeparator\n + value;\n ;\n out.push(indent + space + keyValue);\n }\n seen.splice(seen.indexOf(node), 1);\n return '{' + out.join(',') + indent + '}';\n }\n })({ '': obj }, '', obj, 0);\n};\n\nvar isArray = Array.isArray || function (x) {\n return {}.toString.call(x) === '[object Array]';\n};\n\nvar objectKeys = Object.keys || function (obj) {\n var has = Object.prototype.hasOwnProperty || function () { return true };\n var keys = [];\n for (var key in obj) {\n if (has.call(obj, key)) keys.push(key);\n }\n return keys;\n};\n","export type LogicalOperand = LogicalNot | LogicalAnd | LogicalOr | T;\n\nexport interface LogicalOr {\n or: LogicalOperand[];\n}\n\nexport interface LogicalAnd {\n and: LogicalOperand[];\n}\n\nexport interface LogicalNot {\n not: LogicalOperand;\n}\n\nexport function isLogicalOr(op: LogicalOperand): op is LogicalOr {\n return !!op.or;\n}\n\nexport function isLogicalAnd(op: LogicalOperand): op is LogicalAnd {\n return !!op.and;\n}\n\nexport function isLogicalNot(op: LogicalOperand): op is LogicalNot {\n return !!op.not;\n}\n\nexport function forEachLeaf(op: LogicalOperand, fn: (op: T) => void) {\n if (isLogicalNot(op)) {\n forEachLeaf(op.not, fn);\n } else if (isLogicalAnd(op)) {\n for (const subop of op.and) {\n forEachLeaf(subop, fn);\n }\n } else if (isLogicalOr(op)) {\n for (const subop of op.or) {\n forEachLeaf(subop, fn);\n }\n } else {\n fn(op);\n }\n}\n\nexport function normalizeLogicalOperand(op: LogicalOperand, normalizer: (o: T) => T): LogicalOperand {\n if (isLogicalNot(op)) {\n return {not: normalizeLogicalOperand(op.not, normalizer)};\n } else if (isLogicalAnd(op)) {\n return {and: op.and.map(o => normalizeLogicalOperand(o, normalizer))};\n } else if (isLogicalOr(op)) {\n return {or: op.or.map(o => normalizeLogicalOperand(o, normalizer))};\n } else {\n return normalizer(op);\n }\n}\n","import stableStringify from 'json-stable-stringify';\nimport {isArray, isNumber, isString, splitAccessPath, stringValue} from 'vega-util';\nimport {isLogicalAnd, isLogicalNot, isLogicalOr, LogicalOperand} from './logical';\n\n/**\n * Creates an object composed of the picked object properties.\n *\n * Example: (from lodash)\n *\n * var object = {'a': 1, 'b': '2', 'c': 3};\n * pick(object, ['a', 'c']);\n * // → {'a': 1, 'c': 3}\n *\n */\nexport function pick(obj: T, props: K[]): Pick {\n const copy: any = {};\n for (const prop of props) {\n if (obj.hasOwnProperty(prop)) {\n copy[prop] = obj[prop];\n }\n }\n return copy;\n}\n\n/**\n * The opposite of _.pick; this method creates an object composed of the own\n * and inherited enumerable string keyed properties of object that are not omitted.\n */\nexport function omit(obj: T, props: K[]): Omit {\n const copy = {...obj as any};\n for (const prop of props) {\n delete copy[prop];\n }\n return copy;\n}\n\n/**\n * Converts any object into a string representation that can be consumed by humans.\n */\nexport const stringify = stableStringify;\n\n/**\n * Converts any object into a string of limited size, or a number.\n */\nexport function hash(a: any) {\n if (isNumber(a)) {\n return a;\n }\n\n const str = isString(a) ? a : stableStringify(a);\n\n // short strings can be used as hash directly, longer strings are hashed to reduce memory usage\n if (str.length < 100) {\n return str;\n }\n\n // from http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/\n let h = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n h = ((h<<5)-h)+char;\n h = h & h; // Convert to 32bit integer\n }\n return h;\n}\n\nexport function contains(array: T[], item: T) {\n return array.indexOf(item) > -1;\n}\n\n/** Returns the array without the elements in item */\nexport function without(array: T[], excludedItems: T[]) {\n return array.filter(item => !contains(excludedItems, item));\n}\n\nexport function union(array: T[], other: T[]) {\n return array.concat(without(other, array));\n}\n\n/**\n * Returns true if any item returns true.\n */\nexport function some(arr: T[], f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (let k = 0; k(arr: T[], f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (let k = 0; k(dest: T, ...src: Partial[]): T {\n for (const s of src) {\n dest = deepMerge_(dest, s);\n }\n return dest;\n}\n\n// recursively merges src into dest\nfunction deepMerge_(dest: any, src: any) {\n if (typeof src !== 'object' || src === null) {\n return dest;\n }\n\n for (const p in src) {\n if (!src.hasOwnProperty(p)) {\n continue;\n }\n if (src[p] === undefined) {\n continue;\n }\n if (typeof src[p] !== 'object' || isArray(src[p]) || src[p] === null) {\n dest[p] = src[p];\n } else if (typeof dest[p] !== 'object' || dest[p] === null) {\n dest[p] = mergeDeep(isArray(src[p].constructor) ? [] : {}, src[p]);\n } else {\n mergeDeep(dest[p], src[p]);\n }\n }\n return dest;\n}\n\nexport function unique(values: T[], f: (item: T) => string | number): T[] {\n const results: any[] = [];\n const u = {};\n let v: string | number;\n for (const val of values) {\n v = f(val);\n if (v in u) {\n continue;\n }\n u[v] = 1;\n results.push(val);\n }\n return results;\n}\n\nexport interface Dict {\n [key: string]: T;\n}\n\nexport type StringSet = Dict;\n\n/**\n * Returns true if the two dictionaries disagree. Applies only to defined values.\n */\nexport function differ(dict: Dict, other: Dict) {\n for (const key in dict) {\n if (dict.hasOwnProperty(key)) {\n if (other[key] && dict[key] && other[key] !== dict[key]) {\n return true;\n }\n }\n }\n return false;\n}\n\nexport function hasIntersection(a: StringSet, b: StringSet) {\n for (const key in a) {\n if (key in b) {\n return true;\n }\n }\n return false;\n}\n\nexport function isNumeric(num: string | number) {\n return !isNaN(num as any);\n}\n\nexport function differArray(array: T[], other: T[]) {\n if (array.length !== other.length) {\n return true;\n }\n\n array.sort();\n other.sort();\n\n for (let i = 0; i < array.length; i++) {\n if (other[i] !== array[i]) {\n return true;\n }\n }\n\n return false;\n}\n\n// This is a stricter version of Object.keys but with better types. See https://github.com/Microsoft/TypeScript/pull/12253#issuecomment-263132208\nexport const keys = Object.keys as (o: T) => (Extract)[];\n\nexport function vals(x: {[key: string]: T}): T[] {\n const _vals: T[] = [];\n for (const k in x) {\n if (x.hasOwnProperty(k)) {\n _vals.push(x[k]);\n }\n }\n return _vals;\n}\n\n// Using mapped type to declare a collect of flags for a string literal type S\n// https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types\nexport type Flag = {\n [K in S]: 1\n};\n\nexport function flagKeys(f: Flag): S[] {\n return keys(f) as S[];\n}\n\nexport function duplicate(obj: T): T {\n return JSON.parse(JSON.stringify(obj));\n}\n\nexport function isBoolean(b: any): b is boolean {\n return b === true || b === false;\n}\n\n/**\n * Convert a string into a valid variable name\n */\nexport function varName(s: string): string {\n // Replace non-alphanumeric characters (anything besides a-zA-Z0-9_) with _\n const alphanumericS = s.replace(/\\W/g, '_');\n\n // Add _ if the string has leading numbers.\n return (s.match(/^\\d+/) ? '_' : '') + alphanumericS;\n}\n\nexport function logicalExpr(op: LogicalOperand, cb: Function): string {\n if (isLogicalNot(op)) {\n return '!(' + logicalExpr(op.not, cb) + ')';\n } else if (isLogicalAnd(op)) {\n return '(' + op.and.map((and: LogicalOperand) => logicalExpr(and, cb)).join(') && (') + ')';\n } else if (isLogicalOr(op)) {\n return '(' + op.or.map((or: LogicalOperand) => logicalExpr(or, cb)).join(') || (') + ')';\n } else {\n return cb(op);\n }\n}\n\nexport type Omit = Pick>;\n\n/**\n * Delete nested property of an object, and delete the ancestors of the property if they become empty.\n */\nexport function deleteNestedProperty(obj: any, orderedProps: string[]) {\n if (orderedProps.length === 0) {\n return true;\n }\n const prop = orderedProps.shift();\n if (deleteNestedProperty(obj[prop], orderedProps)) {\n delete obj[prop];\n }\n return Object.keys(obj).length === 0;\n}\n\nexport function titlecase(s: string) {\n return s.charAt(0).toUpperCase() + s.substr(1);\n}\n\n/**\n * Converts a path to an access path with datum.\n * @param path The field name.\n * @param datum The string to use for `datum`.\n */\nexport function accessPathWithDatum(path: string, datum='datum') {\n const pieces = splitAccessPath(path);\n const prefixes = [];\n for (let i = 1; i <= pieces.length; i++) {\n const prefix = `[${pieces.slice(0,i).map(stringValue).join('][')}]`;\n prefixes.push(`${datum}${prefix}`);\n }\n return prefixes.join(' && ');\n}\n\n/**\n * Return access with datum to the falttened field.\n * @param path The field name.\n * @param datum The string to use for `datum`.\n */\nexport function flatAccessWithDatum(path: string, datum='datum') {\n return `${datum}[${stringValue(splitAccessPath(path).join('.'))}]`;\n}\n\n/**\n * Replaces path accesses with access to non-nested field.\n * For example, `foo[\"bar\"].baz` becomes `foo\\\\.bar\\\\.baz`.\n */\nexport function replacePathInField(path: string) {\n return `${splitAccessPath(path).map(p => p.replace('.', '\\\\.')).join('\\\\.')}`;\n}\n\n/**\n * Remove path accesses with access from field.\n * For example, `foo[\"bar\"].baz` becomes `foo.bar.baz`.\n */\nexport function removePathFromField(path: string) {\n return `${splitAccessPath(path).join('.')}`;\n}\n\n/**\n * Count the depth of the path. Returns 1 for fields that are not nested.\n */\nexport function accessPathDepth(path: string) {\n if (!path) {\n return 0;\n }\n return splitAccessPath(path).length;\n}\n","import {AggregateOp} from 'vega';\nimport {toSet} from 'vega-util';\nimport {contains, Flag, flagKeys} from './util';\n\nconst AGGREGATE_OP_INDEX: Flag = {\n argmax: 1,\n argmin: 1,\n average: 1,\n count: 1,\n distinct: 1,\n max: 1,\n mean: 1,\n median: 1,\n min: 1,\n missing: 1,\n q1: 1,\n q3: 1,\n ci0: 1,\n ci1: 1,\n stderr: 1,\n stdev: 1,\n stdevp: 1,\n sum: 1,\n valid: 1,\n values: 1,\n variance: 1,\n variancep: 1,\n};\n\nexport const AGGREGATE_OPS = flagKeys(AGGREGATE_OP_INDEX);\n\nexport function isAggregateOp(a: string): a is AggregateOp {\n return !!AGGREGATE_OP_INDEX[a];\n}\n\nexport const COUNTING_OPS: AggregateOp[] = ['count', 'valid', 'missing', 'distinct'];\n\nexport function isCountingAggregateOp(aggregate: string): boolean {\n return aggregate && contains(COUNTING_OPS, aggregate);\n}\n\n/** Additive-based aggregation operations. These can be applied to stack. */\nexport const SUM_OPS: AggregateOp[] = [\n 'count',\n 'sum',\n 'distinct',\n 'valid',\n 'missing'\n];\n\n/**\n * Aggregation operators that always produce values within the range [domainMin, domainMax].\n */\nexport const SHARED_DOMAIN_OPS: AggregateOp[] = [\n 'mean',\n 'average',\n 'median',\n 'q1',\n 'q3',\n 'min',\n 'max',\n];\n\nexport const SHARED_DOMAIN_OP_INDEX = toSet(SHARED_DOMAIN_OPS);\n","import {DateTime} from './datetime';\nimport {Guide, GuideEncodingEntry, VlOnlyGuideConfig} from './guide';\nimport {Flag, flagKeys} from './util';\nimport {AxisOrient, VgAxis, VgAxisBase, VgAxisConfig} from './vega.schema';\n\n\n\nexport interface AxisConfig extends VgAxisConfig, VlOnlyGuideConfig {}\n\nexport interface Axis extends VgAxisBase, Guide {\n /**\n * The orientation of the axis. One of `\"top\"`, `\"bottom\"`, `\"left\"` or `\"right\"`. The orientation can be used to further specialize the axis type (e.g., a y axis oriented for the right edge of the chart).\n *\n * __Default value:__ `\"bottom\"` for x-axes and `\"left\"` for y-axes.\n */\n orient?: AxisOrient;\n\n /**\n * The offset, in pixels, by which to displace the axis from the edge of the enclosing group or data rectangle.\n *\n * __Default value:__ derived from the [axis config](https://vega.github.io/vega-lite/docs/config.html#facet-scale-config)'s `offset` (`0` by default)\n */\n offset?: number;\n\n /**\n * The anchor position of the axis in pixels. For x-axis with top or bottom orientation, this sets the axis group x coordinate. For y-axis with left or right orientation, this sets the axis group y coordinate.\n *\n * __Default value__: `0`\n */\n position?: number;\n\n\n /**\n * The rotation angle of the axis labels.\n *\n * __Default value:__ `-90` for nominal and ordinal fields; `0` otherwise.\n *\n * @minimum -360\n * @maximum 360\n */\n labelAngle?: number;\n\n /**\n * A desired number of ticks, for axes visualizing quantitative scales. The resulting number may be different so that values are \"nice\" (multiples of 2, 5, 10) and lie within the underlying scale's range.\n * @minimum 0\n *\n * __Default value__: Determine using a formula `ceil(width/40)` for x and `ceil(height/40)` for y.\n */\n tickCount?: number;\n\n /**\n * Explicitly set the visible axis tick values.\n */\n values?: number[] | string[] | boolean[] | DateTime[];\n\n /**\n * A non-positive integer indicating z-index of the axis.\n * If zindex is 0, axes should be drawn behind all chart elements.\n * To put them in front, use `\"zindex = 1\"`.\n *\n * __Default value:__ `1` (in front of the marks) for actual axis and `0` (behind the marks) for grids.\n *\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n\n /**\n * Mark definitions for custom axis encoding.\n *\n * @hide\n */\n encoding?: AxisEncoding;\n}\n\n\nexport type AxisPart = keyof AxisEncoding;\nexport const AXIS_PARTS: AxisPart[] = ['domain', 'grid', 'labels', 'ticks', 'title'];\n\n\n\n/**\n * A dictionary listing whether a certain axis property is applicable for only main axes or only grid axes.\n * (Properties not listed are applicable for both)\n */\nexport const AXIS_PROPERTY_TYPE: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in keyof VgAxis]: 'main' | 'grid' | 'both'\n} = {\n grid: 'grid',\n gridScale: 'grid',\n\n domain: 'main',\n labels: 'main',\n labelFlush: 'main',\n labelOverlap: 'main',\n minExtent: 'main',\n maxExtent: 'main',\n offset: 'main',\n ticks: 'main',\n title: 'main',\n values: 'both',\n\n scale: 'both',\n zindex: 'both' // this is actually set afterward, so it doesn't matter\n};\n\nexport interface AxisEncoding {\n /**\n * Custom encoding for the axis container.\n */\n axis?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the axis domain rule mark.\n */\n domain?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis gridline rule marks.\n */\n grid?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis label text marks.\n */\n labels?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis tick rule marks.\n */\n ticks?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the axis title text mark.\n */\n title?: GuideEncodingEntry;\n}\n\nconst COMMON_AXIS_PROPERTIES_INDEX: Flag = {\n orient: 1, // other things can depend on orient\n\n domain: 1,\n format: 1,\n grid: 1,\n labelBound: 1,\n labelFlush: 1,\n labelPadding: 1,\n labels: 1,\n labelOverlap: 1,\n maxExtent: 1,\n minExtent: 1,\n offset: 1,\n position: 1,\n tickCount: 1,\n ticks: 1,\n tickSize: 1,\n title: 1,\n titlePadding: 1,\n values: 1,\n zindex: 1,\n};\n\nconst AXIS_PROPERTIES_INDEX: Flag = {\n ...COMMON_AXIS_PROPERTIES_INDEX,\n encoding: 1,\n labelAngle: 1,\n titleMaxLength: 1\n};\n\nconst VG_AXIS_PROPERTIES_INDEX: Flag = {\n scale: 1,\n ...COMMON_AXIS_PROPERTIES_INDEX,\n gridScale: 1,\n encode: 1\n};\n\nexport function isAxisProperty(prop: string): prop is keyof Axis {\n return !!AXIS_PROPERTIES_INDEX[prop];\n}\n\nexport const VG_AXIS_PROPERTIES = flagKeys(VG_AXIS_PROPERTIES_INDEX);\n\n// Export for dependent projects\nexport const AXIS_PROPERTIES = flagKeys(AXIS_PROPERTIES_INDEX);\n\nexport interface AxisConfigMixins {\n /**\n * Axis configuration, which determines default properties for all `x` and `y` [axes](https://vega.github.io/vega-lite/docs/axis.html). For a full list of axis configuration options, please see the [corresponding section of the axis documentation](https://vega.github.io/vega-lite/docs/axis.html#config).\n */\n axis?: AxisConfig;\n\n /**\n * X-axis specific config.\n */\n axisX?: VgAxisConfig;\n\n /**\n * Y-axis specific config.\n */\n axisY?: VgAxisConfig;\n\n /**\n * Specific axis config for y-axis along the left edge of the chart.\n */\n axisLeft?: VgAxisConfig;\n\n /**\n * Specific axis config for y-axis along the right edge of the chart.\n */\n axisRight?: VgAxisConfig;\n\n /**\n * Specific axis config for x-axis along the top edge of the chart.\n */\n axisTop?: VgAxisConfig;\n\n /**\n * Specific axis config for x-axis along the bottom edge of the chart.\n */\n axisBottom?: VgAxisConfig;\n\n /**\n * Specific axis config for axes with \"band\" scales.\n */\n axisBand?: VgAxisConfig;\n}\n","/*\n * Constants and utilities for encoding channels (Visual variables)\n * such as 'x', 'y', 'color'.\n */\n\nimport {RangeType} from './compile/scale/type';\nimport {Encoding} from './encoding';\nimport {FacetMapping} from './facet';\nimport {Mark} from './mark';\nimport {Flag, flagKeys} from './util';\n\nexport namespace Channel {\n // Facet\n export const ROW: 'row' = 'row';\n export const COLUMN: 'column' = 'column';\n\n // Position\n export const X: 'x' = 'x';\n export const Y: 'y' = 'y';\n export const X2: 'x2' = 'x2';\n export const Y2: 'y2' = 'y2';\n\n // Geo Position\n export const LATITUDE: 'latitude' = 'latitude';\n export const LONGITUDE: 'longitude' = 'longitude';\n export const LATITUDE2: 'latitude2' = 'latitude2';\n export const LONGITUDE2: 'longitude2' = 'longitude2';\n\n // Mark property with scale\n export const COLOR: 'color' = 'color';\n\n export const FILL: 'fill' = 'fill';\n\n export const STROKE: 'stroke' = 'stroke';\n\n export const SHAPE: 'shape' = 'shape';\n export const SIZE: 'size' = 'size';\n export const OPACITY: 'opacity' = 'opacity';\n\n // Non-scale channel\n export const TEXT: 'text' = 'text';\n export const ORDER: 'order' = 'order';\n export const DETAIL: 'detail' = 'detail';\n export const KEY: 'key' = 'key';\n\n export const TOOLTIP: 'tooltip' = 'tooltip';\n export const HREF: 'href' = 'href';\n}\n\nexport type Channel = keyof Encoding | keyof FacetMapping;\n\nexport const X = Channel.X;\nexport const Y = Channel.Y;\nexport const X2 = Channel.X2;\nexport const Y2 = Channel.Y2;\n\nexport const LATITUDE = Channel.LATITUDE;\nexport const LATITUDE2 = Channel.LATITUDE2;\nexport const LONGITUDE = Channel.LONGITUDE;\nexport const LONGITUDE2 = Channel.LONGITUDE2;\n\nexport const ROW = Channel.ROW;\nexport const COLUMN = Channel.COLUMN;\nexport const SHAPE = Channel.SHAPE;\nexport const SIZE = Channel.SIZE;\nexport const COLOR = Channel.COLOR;\n\nexport const FILL = Channel.FILL;\nexport const STROKE = Channel.STROKE;\nexport const TEXT = Channel.TEXT;\nexport const DETAIL = Channel.DETAIL;\nexport const KEY = Channel.KEY;\nexport const ORDER = Channel.ORDER;\nexport const OPACITY = Channel.OPACITY;\nexport const TOOLTIP = Channel.TOOLTIP;\nexport const HREF = Channel.HREF;\n\nexport type GeoPositionChannel = 'longitude' | 'latitude' | 'longitude2' | 'latitude2';\n\nexport const GEOPOSITION_CHANNEL_INDEX: Flag = {\n longitude: 1,\n longitude2: 1,\n latitude: 1,\n latitude2: 1,\n};\n\nexport const GEOPOSITION_CHANNELS = flagKeys(GEOPOSITION_CHANNEL_INDEX);\n\nconst UNIT_CHANNEL_INDEX: Flag> = {\n // position\n x: 1,\n y: 1,\n x2: 1,\n y2: 1,\n\n ...GEOPOSITION_CHANNEL_INDEX,\n\n // color\n color: 1,\n fill: 1,\n stroke: 1,\n\n // other non-position with scale\n opacity: 1,\n size: 1,\n shape: 1,\n\n // channels without scales\n order: 1,\n text: 1,\n detail: 1,\n key: 1,\n tooltip: 1,\n href: 1,\n};\n\nexport type ColorChannel = 'color' | 'fill' | 'stroke';\n\nexport function isColorChannel(channel: Channel): channel is ColorChannel {\n return channel === 'color' || channel === 'fill' || channel === 'stroke';\n}\n\nconst FACET_CHANNEL_INDEX: Flag> = {\n row: 1,\n column: 1\n};\n\nconst CHANNEL_INDEX = {\n ...UNIT_CHANNEL_INDEX,\n ...FACET_CHANNEL_INDEX\n};\n\nexport const CHANNELS = flagKeys(CHANNEL_INDEX);\n\nconst {order: _o, detail: _d, ...SINGLE_DEF_CHANNEL_INDEX} = CHANNEL_INDEX;\n/**\n * Channels that cannot have an array of channelDef.\n * model.fieldDef, getFieldDef only work for these channels.\n *\n * (The only two channels that can have an array of channelDefs are \"detail\" and \"order\".\n * Since there can be multiple fieldDefs for detail and order, getFieldDef/model.fieldDef\n * are not applicable for them. Similarly, selection projection won't work with \"detail\" and \"order\".)\n */\n\nexport const SINGLE_DEF_CHANNELS: SingleDefChannel[] = flagKeys(SINGLE_DEF_CHANNEL_INDEX);\n\n// Using the following line leads to TypeError: Cannot read property 'elementTypes' of undefined\n// when running the schema generator\n// export type SingleDefChannel = typeof SINGLE_DEF_CHANNELS[0];\nexport type SingleDefChannel = 'x' | 'y' | 'x2' | 'y2' |\n 'longitude' | 'latitude' | 'longitude2' | 'latitude2' |\n 'row' | 'column' |\n 'color' | 'fill' | 'stroke' |\n 'size' | 'shape' | 'opacity' |\n 'text' | 'tooltip' | 'href' | 'key';\n\nexport function isChannel(str: string): str is Channel {\n return !!CHANNEL_INDEX[str];\n}\n\n// CHANNELS without COLUMN, ROW\nexport const UNIT_CHANNELS = flagKeys(UNIT_CHANNEL_INDEX);\n\n\n// NONPOSITION_CHANNELS = UNIT_CHANNELS without X, Y, X2, Y2;\nconst {\n x: _x, y: _y,\n // x2 and y2 share the same scale as x and y\n x2: _x2, y2: _y2,\n latitude: _latitude, longitude: _longitude,\n latitude2: _latitude2, longitude2: _longitude2,\n // The rest of unit channels then have scale\n ...NONPOSITION_CHANNEL_INDEX\n} = UNIT_CHANNEL_INDEX;\n\nexport const NONPOSITION_CHANNELS = flagKeys(NONPOSITION_CHANNEL_INDEX);\nexport type NonPositionChannel = typeof NONPOSITION_CHANNELS[0];\n\n// POSITION_SCALE_CHANNELS = X and Y;\nconst POSITION_SCALE_CHANNEL_INDEX: {x:1, y:1} = {x:1, y:1};\nexport const POSITION_SCALE_CHANNELS = flagKeys(POSITION_SCALE_CHANNEL_INDEX);\nexport type PositionScaleChannel = typeof POSITION_SCALE_CHANNELS[0];\n\n// NON_POSITION_SCALE_CHANNEL = SCALE_CHANNELS without X, Y\nconst {\n // x2 and y2 share the same scale as x and y\n // text and tooltip have format instead of scale,\n // href has neither format, nor scale\n text: _t, tooltip: _tt, href: _hr,\n // detail and order have no scale\n detail: _dd, key: _k, order: _oo,\n ...NONPOSITION_SCALE_CHANNEL_INDEX\n} = NONPOSITION_CHANNEL_INDEX;\nexport const NONPOSITION_SCALE_CHANNELS = flagKeys(NONPOSITION_SCALE_CHANNEL_INDEX);\nexport type NonPositionScaleChannel = typeof NONPOSITION_SCALE_CHANNELS[0];\n\n// Declare SCALE_CHANNEL_INDEX\nconst SCALE_CHANNEL_INDEX = {\n ...POSITION_SCALE_CHANNEL_INDEX,\n ...NONPOSITION_SCALE_CHANNEL_INDEX\n};\n\n/** List of channels with scales */\nexport const SCALE_CHANNELS = flagKeys(SCALE_CHANNEL_INDEX);\nexport type ScaleChannel = typeof SCALE_CHANNELS[0];\n\nexport function isScaleChannel(channel: Channel): channel is ScaleChannel {\n return !!SCALE_CHANNEL_INDEX[channel];\n}\n\nexport type SupportedMark = {\n [mark in Mark]?: boolean\n};\n\n/**\n * Return whether a channel supports a particular mark type.\n * @param channel channel name\n * @param mark the mark type\n * @return whether the mark supports the channel\n */\nexport function supportMark(channel: Channel, mark: Mark) {\n return mark in getSupportedMark(channel);\n}\n\n/**\n * Return a dictionary showing whether a channel supports mark type.\n * @param channel\n * @return A dictionary mapping mark types to boolean values.\n */\nexport function getSupportedMark(channel: Channel): SupportedMark {\n switch (channel) {\n case COLOR:\n case FILL:\n case STROKE:\n\n case DETAIL:\n case KEY:\n case TOOLTIP:\n case HREF:\n case ORDER: // TODO: revise (order might not support rect, which is not stackable?)\n case OPACITY:\n case ROW:\n case COLUMN:\n return { // all marks\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, rect: true, line: true, trail: true, area: true, text: true, geoshape: true\n };\n case X:\n case Y:\n case LATITUDE:\n case LONGITUDE:\n return { // all marks except geoshape. geoshape does not use X, Y -- it uses a projection\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, rect: true, line: true, trail: true, area: true, text: true\n };\n case X2:\n case Y2:\n case LATITUDE2:\n case LONGITUDE2:\n return {\n rule: true, bar: true, rect: true, area: true\n };\n case SIZE:\n return {\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, text: true, line: true, trail: true\n };\n case SHAPE:\n return {point: true, geoshape: true};\n case TEXT:\n return {text: true};\n }\n}\n\nexport function rangeType(channel: Channel): RangeType {\n switch (channel) {\n case X:\n case Y:\n case SIZE:\n case OPACITY:\n // X2 and Y2 use X and Y scales, so they similarly have continuous range.\n case X2:\n case Y2:\n return 'continuous';\n\n case ROW:\n case COLUMN:\n case SHAPE:\n // TEXT, TOOLTIP, and HREF have no scale but have discrete output\n case TEXT:\n case TOOLTIP:\n case HREF:\n return 'discrete';\n\n // Color can be either continuous or discrete, depending on scale type.\n case COLOR:\n case FILL:\n case STROKE:\n return 'flexible';\n\n // No scale, no range type.\n\n case LATITUDE:\n case LONGITUDE:\n case LATITUDE2:\n case LONGITUDE2:\n case DETAIL:\n case KEY:\n case ORDER:\n return undefined;\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('rangeType not implemented for ' + channel);\n}\n","import {isBoolean} from 'vega-util';\nimport {Channel, COLOR, COLUMN, FILL, OPACITY, ROW, SHAPE, SIZE, STROKE} from './channel';\nimport {keys, varName} from './util';\n\n\nexport interface BaseBin {\n /**\n * The number base to use for automatic bin determination (default is base 10).\n *\n * __Default value:__ `10`\n *\n */\n base?: number;\n /**\n * An exact step size to use between bins.\n *\n * __Note:__ If provided, options such as maxbins will be ignored.\n */\n step?: number;\n /**\n * An array of allowable step sizes to choose from.\n * @minItems 1\n */\n steps?: number[];\n /**\n * A minimum allowable step size (particularly useful for integer values).\n */\n minstep?: number;\n /**\n * Scale factors indicating allowable subdivisions. The default value is [5, 2], which indicates that for base 10 numbers (the default base), the method may consider dividing bin sizes by 5 and/or 2. For example, for an initial step size of 10, the method can check if bin sizes of 2 (= 10/5), 5 (= 10/2), or 1 (= 10/(5*2)) might also satisfy the given constraints.\n *\n * __Default value:__ `[5, 2]`\n *\n * @minItems 1\n */\n divide?: number[];\n /**\n * Maximum number of bins.\n *\n * __Default value:__ `6` for `row`, `column` and `shape` channels; `10` for other channels\n *\n * @minimum 2\n */\n maxbins?: number;\n /**\n * A value in the binned domain at which to anchor the bins, shifting the bin boundaries if necessary to ensure that a boundary aligns with the anchor value.\n *\n * __Default Value:__ the minimum bin extent value\n */\n anchor?: number;\n /**\n * If true (the default), attempts to make the bin boundaries use human-friendly boundaries, such as multiples of ten.\n */\n nice?: boolean;\n}\n\n\n/**\n * Binning properties or boolean flag for determining whether to bin data or not.\n */\nexport interface BinParams extends BaseBin {\n /**\n * A two-element (`[min, max]`) array indicating the range of desired bin values.\n * @minItems 2\n * @maxItems 2\n */\n extent?: number[]; // VgBinTransform uses a different extent so we need to pull this out.\n}\n\nexport function binToString(bin: BinParams | boolean) {\n if (isBoolean(bin)) {\n return 'bin';\n }\n return 'bin' + keys(bin).map(p => varName(`_${p}_${bin[p]}`)).join('');\n}\n\nexport function isBinParams(bin: BinParams | boolean): bin is BinParams {\n return bin && !isBoolean(bin);\n}\n\nexport function autoMaxBins(channel: Channel): number {\n switch (channel) {\n case ROW:\n case COLUMN:\n case SIZE:\n case COLOR:\n case FILL:\n case STROKE:\n case OPACITY:\n // Facets and Size shouldn't have too many bins\n // We choose 6 like shape to simplify the rule\n case SHAPE:\n return 6; // Vega's \"shape\" has 6 distinct values\n default:\n return 10;\n }\n}\n","import {toSet} from 'vega-util';\nimport {CompositeMark, CompositeMarkDef} from './compositemark/index';\nimport {contains, flagKeys} from './util';\nimport {VgMarkConfig} from './vega.schema';\n\nexport namespace Mark {\n export const AREA: 'area' = 'area';\n export const BAR: 'bar' = 'bar';\n export const LINE: 'line' = 'line';\n export const POINT: 'point' = 'point';\n export const RECT: 'rect' = 'rect';\n export const RULE: 'rule' = 'rule';\n export const TEXT: 'text' = 'text';\n export const TICK: 'tick' = 'tick';\n export const TRAIL: 'trail' = 'trail';\n export const CIRCLE: 'circle' = 'circle';\n export const SQUARE: 'square' = 'square';\n export const GEOSHAPE: 'geoshape' = 'geoshape';\n}\n\n/**\n * All types of primitive marks.\n */\nexport type Mark = typeof Mark.AREA | typeof Mark.BAR | typeof Mark.LINE | typeof Mark.TRAIL | typeof Mark.POINT | typeof Mark.TEXT | typeof Mark.TICK | typeof Mark.RECT | typeof Mark.RULE | typeof Mark.CIRCLE | typeof Mark.SQUARE | typeof Mark.GEOSHAPE;\n\n\nexport const AREA = Mark.AREA;\nexport const BAR = Mark.BAR;\nexport const LINE = Mark.LINE;\nexport const POINT = Mark.POINT;\nexport const TEXT = Mark.TEXT;\nexport const TICK = Mark.TICK;\nexport const TRAIL = Mark.TRAIL;\nexport const RECT = Mark.RECT;\nexport const RULE = Mark.RULE;\nexport const GEOSHAPE = Mark.GEOSHAPE;\n\nexport const CIRCLE = Mark.CIRCLE;\nexport const SQUARE = Mark.SQUARE;\n\n// Using mapped type to declare index, ensuring we always have all marks when we add more.\nconst MARK_INDEX: {[M in Mark]: 1} = {\n area: 1,\n bar: 1,\n line: 1,\n point: 1,\n text: 1,\n tick: 1,\n trail: 1,\n rect: 1,\n geoshape: 1,\n rule: 1,\n circle: 1,\n square: 1\n};\n\nexport function isMark(m: string): m is Mark {\n return !!MARK_INDEX[m];\n}\n\nexport function isPathMark(m: Mark | CompositeMark): m is 'line' | 'area' | 'trail' {\n return contains(['line', 'area', 'trail'], m);\n}\n\nexport const PRIMITIVE_MARKS = flagKeys(MARK_INDEX);\n\n\nexport interface MarkConfig extends VgMarkConfig {\n // ---------- Color ----------\n /**\n * Whether the mark's color should be used as fill color instead of stroke color.\n *\n * __Default value:__ `true` for all marks except `point` and `false` for `point`.\n *\n * __Applicable for:__ `bar`, `point`, `circle`, `square`, and `area` marks.\n *\n * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n *\n */\n filled?: boolean;\n\n /**\n * Default color. Note that `fill` and `stroke` have higher precedence than `color` and will override `color`.\n *\n * __Default value:__ `\"#4682b4\"`\n *\n * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n */\n color?: string;\n}\n\nexport interface BarBinSpacingMixins {\n /**\n * Offset between bars for binned field. Ideal value for this is either 0 (Preferred by statisticians) or 1 (Vega-Lite Default, D3 example style).\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n binSpacing?: number;\n}\n\n\n/** @hide */\nexport type HiddenComposite = CompositeMark | CompositeMarkDef;\n\nexport type AnyMark =\n HiddenComposite |\n Mark |\n MarkDef;\n\nexport function isMarkDef(mark: AnyMark): mark is (MarkDef | CompositeMarkDef) {\n return mark['type'];\n}\n\nconst PRIMITIVE_MARK_INDEX = toSet(PRIMITIVE_MARKS);\n\nexport function isPrimitiveMark(mark: CompositeMark | CompositeMarkDef | Mark | MarkDef): mark is Mark {\n const markType = isMarkDef(mark) ? mark.type : mark;\n return markType in PRIMITIVE_MARK_INDEX;\n}\n\nexport const STROKE_CONFIG = ['stroke', 'strokeWidth',\n 'strokeDash', 'strokeDashOffset', 'strokeOpacity', 'strokeJoin', 'strokeMiterLimit'];\n\nexport const FILL_CONFIG = ['fill', 'fillOpacity'];\n\nexport const FILL_STROKE_CONFIG = [].concat(STROKE_CONFIG, FILL_CONFIG);\n\nexport const VL_ONLY_MARK_CONFIG_PROPERTIES: (keyof MarkConfig)[] = ['filled', 'color'];\n\nexport const VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX: {\n [k in (typeof PRIMITIVE_MARKS[0])]?: (keyof MarkConfigMixins[k])[]\n} = {\n area: ['line', 'point'],\n bar: ['binSpacing', 'continuousBandSize', 'discreteBandSize'],\n line: ['point'],\n text: ['shortTimeLabels'],\n tick: ['bandSize', 'thickness']\n};\n\nexport const defaultMarkConfig: MarkConfig = {\n color: '#4c78a8',\n};\n\nexport interface MarkConfigMixins {\n /** Mark Config */\n mark?: MarkConfig;\n\n // MARK-SPECIFIC CONFIGS\n /** Area-Specific Config */\n area?: AreaConfig;\n\n /** Bar-Specific Config */\n bar?: BarConfig;\n\n /** Circle-Specific Config */\n circle?: MarkConfig;\n\n /** Line-Specific Config */\n line?: LineConfig;\n\n /** Point-Specific Config */\n point?: MarkConfig;\n\n /** Rect-Specific Config */\n rect?: MarkConfig;\n\n /** Rule-Specific Config */\n rule?: MarkConfig;\n\n /** Square-Specific Config */\n square?: MarkConfig;\n\n /** Text-Specific Config */\n text?: TextConfig;\n\n /** Tick-Specific Config */\n tick?: TickConfig;\n\n /** Trail-Specific Config */\n trail?: LineConfig;\n\n /** Geoshape-Specific Config */\n geoshape?: MarkConfig;\n}\n\n\nexport interface BarConfig extends BarBinSpacingMixins, MarkConfig {\n\n /**\n * The default size of the bars on continuous scales.\n *\n * __Default value:__ `5`\n *\n * @minimum 0\n */\n continuousBandSize?: number;\n\n /**\n * The size of the bars. If unspecified, the default size is `bandSize-1`,\n * which provides 1 pixel offset between bars.\n * @minimum 0\n */\n discreteBandSize?: number;\n}\n\nexport type OverlayMarkDef = MarkConfig & MarkDefMixins;\n\nexport interface PointOverlayMixins {\n /**\n * A flag for overlaying points on top of line or area marks, or an object defining the properties of the overlayed points.\n *\n * - If this property is `\"transparent\"`, transparent points will be used (for enhancing tooltips and selections).\n *\n * - If this property is an empty object (`{}`) or `true`, filled points with default properties will be used.\n *\n * - If this property is `false`, no points would be automatically added to line or area marks.\n *\n * __Default value:__ `false`.\n */\n point?: boolean | OverlayMarkDef | 'transparent';\n}\n\nexport interface LineConfig extends MarkConfig, PointOverlayMixins {}\n\nexport interface LineOverlayMixins {\n /**\n * A flag for overlaying line on top of area marks, or an object defining the properties of the overlayed lines.\n *\n * - If this value is an empty object (`{}`) or `true`, lines with default properties will be used.\n *\n * - If this value is `false`, no lines would be automatically added to area marks.\n *\n * __Default value:__ `false`.\n */\n line?: boolean | OverlayMarkDef;\n}\n\nexport interface AreaConfig extends MarkConfig, PointOverlayMixins, LineOverlayMixins {}\n\nexport interface TickThicknessMixins {\n /**\n * Thickness of the tick mark.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n thickness?: number;\n}\n\nexport interface MarkDefMixins {\n /**\n * A string or array of strings indicating the name of custom styles to apply to the mark. A style is a named collection of mark property defaults defined within the [style configuration](https://vega.github.io/vega-lite/docs/mark.html#style-config). If style is an array, later styles will override earlier styles. Any [mark properties](https://vega.github.io/vega-lite/docs/encoding.html#mark-prop) explicitly defined within the `encoding` will override a style default.\n *\n * __Default value:__ The mark's name. For example, a bar mark will have style `\"bar\"` by default.\n * __Note:__ Any specified style will augment the default style. For example, a bar mark with `\"style\": \"foo\"` will receive from `config.style.bar` and `config.style.foo` (the specified style `\"foo\"` has higher precedence).\n */\n style?: string | string[];\n\n /**\n * Whether a mark be clipped to the enclosing group’s width and height.\n */\n clip?: boolean;\n\n // Offset properties should not be a part of config\n\n /**\n * Offset for x-position.\n */\n xOffset?: number;\n\n /**\n * Offset for y-position.\n */\n yOffset?: number;\n\n /**\n * Offset for x2-position.\n */\n x2Offset?: number;\n\n /**\n * Offset for y2-position.\n */\n y2Offset?: number;\n}\n\n// Point/Line OverlayMixins are only for area, line, and trail but we don't want to declare multiple types of MarkDef\nexport interface MarkDef extends BarBinSpacingMixins, MarkConfig, PointOverlayMixins, LineOverlayMixins, TickThicknessMixins, MarkDefMixins {\n /**\n * The mark type.\n * One of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"geoshape\"`, `\"rule\"`, and `\"text\"`.\n */\n type: Mark;\n}\n\nexport const defaultBarConfig: BarConfig = {\n binSpacing: 1,\n continuousBandSize: 5\n};\n\nexport interface TextConfig extends MarkConfig {\n /**\n * Whether month names and weekday names should be abbreviated.\n */\n shortTimeLabels?: boolean;\n}\n\nexport interface TickConfig extends MarkConfig, TickThicknessMixins {\n /**\n * The width of the ticks.\n *\n * __Default value:__ 2/3 of rangeStep.\n * @minimum 0\n */\n bandSize?: number;\n}\n\nexport const defaultTickConfig: TickConfig = {\n thickness: 1\n};\n","/**\n * Vega-Lite's singleton logger utility.\n */\n\nimport {AggregateOp} from 'vega';\nimport {logger, LoggerInterface, Warn} from 'vega-util';\nimport {Channel, GeoPositionChannel} from './channel';\nimport {CompositeMark} from './compositemark';\nimport {DateTime, DateTimeExpr} from './datetime';\nimport {FieldDef} from './fielddef';\nimport {Mark} from './mark';\nimport {Projection} from './projection';\nimport {ScaleType} from './scale';\nimport {Type} from './type';\nimport {stringify} from './util';\nimport {VgSortField} from './vega.schema';\n\n\nexport {LoggerInterface} from 'vega-util';\n\n/**\n * Main (default) Vega Logger instance for Vega-Lite\n */\nconst main = logger(Warn);\nlet current: LoggerInterface = main;\n\n/**\n * Logger tool for checking if the code throws correct warning\n */\nexport class LocalLogger implements LoggerInterface {\n public warns: any[] = [];\n public infos: any[] = [];\n public debugs: any[] = [];\n\n public level() {\n return this;\n }\n\n public warn(...args: any[]) {\n this.warns.push(...args);\n return this;\n }\n\n public info(...args: any[]) {\n this.infos.push(...args);\n return this;\n }\n\n public debug(...args: any[]) {\n this.debugs.push(...args);\n return this;\n }\n}\n\nexport function wrap(f: (logger: LocalLogger) => void) {\n return () => {\n current = new LocalLogger();\n f(current as LocalLogger);\n reset();\n };\n}\n\n/**\n * Set the singleton logger to be a custom logger\n */\nexport function set(newLogger: LoggerInterface) {\n current = newLogger;\n return current;\n}\n\n/**\n * Reset the main logger to use the default Vega Logger\n */\nexport function reset() {\n current = main;\n return current;\n}\n\nexport function warn(..._: any[]) {\n current.warn.apply(current, arguments);\n}\n\nexport function info(..._: any[]) {\n current.info.apply(current, arguments);\n}\n\nexport function debug(..._: any[]) {\n current.debug.apply(current, arguments);\n}\n\n/**\n * Collection of all Vega-Lite Error Messages\n */\nexport namespace message {\n export const INVALID_SPEC = 'Invalid spec';\n\n // FIT\n export const FIT_NON_SINGLE = 'Autosize \"fit\" only works for single views and layered views.';\n\n export const CANNOT_FIX_RANGE_STEP_WITH_FIT = 'Cannot use a fixed value of \"rangeStep\" when \"autosize\" is \"fit\".';\n\n // SELECTION\n export function cannotProjectOnChannelWithoutField(channel: Channel) {\n return `Cannot project a selection on encoding channel \"${channel}\", which has no field.`;\n }\n\n export function nearestNotSupportForContinuous(mark: string) {\n return `The \"nearest\" transform is not supported for ${mark} marks.`;\n }\n\n export function selectionNotFound(name: string) {\n return `Cannot find a selection named \"${name}\"`;\n }\n\n export const SCALE_BINDINGS_CONTINUOUS = 'Scale bindings are currently only supported for scales with unbinned, continuous domains.';\n\n // REPEAT\n export function noSuchRepeatedValue(field: string) {\n return `Unknown repeated value \"${field}\".`;\n }\n\n // CONCAT\n export const CONCAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in concatenated views.';\n\n // REPEAT\n export const REPEAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in repeated views.';\n\n // TITLE\n export function cannotSetTitleAnchor(type: string) {\n return `Cannot set title \"anchor\" for a ${type} spec`;\n }\n\n // DATA\n export function unrecognizedParse(p: string) {\n return `Unrecognized parse \"${p}\".`;\n }\n\n export function differentParse(field: string, local: string, ancestor: string) {\n return `An ancestor parsed field \"${field}\" as ${ancestor} but a child wants to parse the field as ${local}.`;\n }\n\n // TRANSFORMS\n export function invalidTransformIgnored(transform: any) {\n return `Ignoring an invalid transform: ${stringify(transform)}.`;\n }\n\n export const NO_FIELDS_NEEDS_AS = 'If \"from.fields\" is not specified, \"as\" has to be a string that specifies the key to be used for the data from the secondary source.';\n\n // ENCODING & FACET\n\n export function encodingOverridden(channels: Channel[]) {\n return `Layer's shared ${channels.join(',')} channel ${channels.length === 1 ? 'is' : 'are'} overriden`;\n }\n export function projectionOverridden(opt: {parentProjection: Projection, projection: Projection}) {\n const {parentProjection, projection} = opt;\n return `Layer's shared projection ${stringify(parentProjection)} is overridden by a child projection ${stringify(projection)}.`;\n }\n\n export function primitiveChannelDef(channel: Channel, type: 'string' | 'number' | 'boolean', value: string | number | boolean) {\n return `Channel ${channel} is a ${type}. Converted to {value: ${stringify(value)}}.`;\n }\n\n export function invalidFieldType(type: Type) {\n return `Invalid field type \"${type}\"`;\n }\n\n export function nonZeroScaleUsedWithLengthMark(\n mark: 'bar' | 'area', channel: Channel,\n opt: {scaleType?: ScaleType, zeroFalse?: boolean}\n ) {\n const scaleText = opt.scaleType ? `${opt.scaleType} scale` :\n opt.zeroFalse ? 'scale with zero=false' :\n 'scale with custom domain that excludes zero';\n\n return `A ${scaleText} is used to encode ${mark}'s ${channel}. This can be misleading as the ${channel === 'x' ? 'width' : 'height'} of the ${mark} can be arbitrary based on the scale domain. You may want to use point mark instead.`;\n }\n\n export function invalidFieldTypeForCountAggregate(type: Type, aggregate: string) {\n return `Invalid field type \"${type}\" for aggregate: \"${aggregate}\", using \"quantitative\" instead.`;\n }\n\n export function invalidAggregate(aggregate: AggregateOp | string) {\n return `Invalid aggregation operator \"${aggregate}\"`;\n }\n\n export function emptyOrInvalidFieldType(type: Type | string, channel: Channel, newType: Type) {\n return `Invalid field type \"${type}\" for channel \"${channel}\", using \"${newType}\" instead.`;\n }\n export function droppingColor(type: 'encoding' | 'property', opt: {fill?: boolean, stroke?: boolean}) {\n const {fill, stroke} = opt;\n return `Dropping color ${type} as the plot also has ` + (\n fill && stroke ? 'fill and stroke' : fill ? 'fill' : 'stroke'\n );\n }\n\n export function emptyFieldDef(fieldDef: FieldDef, channel: Channel) {\n return `Dropping ${stringify(fieldDef)} from channel \"${channel}\" since it does not contain data field or value.`;\n }\n export function latLongDeprecated(channel: Channel, type: Type, newChannel: GeoPositionChannel) {\n return `${channel}-encoding with type ${type} is deprecated. Replacing with ${newChannel}-encoding.`;\n }\n\n export const LINE_WITH_VARYING_SIZE = 'Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.';\n\n export function incompatibleChannel(channel: Channel, markOrFacet: Mark | 'facet' | CompositeMark, when?: string) {\n return `${channel} dropped as it is incompatible with \"${markOrFacet}\"${when ? ` when ${when}` : ''}.`;\n }\n\n export function invalidEncodingChannel(channel: string) {\n return `${channel}-encoding is dropped as ${channel} is not a valid encoding channel.`;\n }\n\n export function facetChannelShouldBeDiscrete(channel: string) {\n return `${channel} encoding should be discrete (ordinal / nominal / binned).`;\n }\n\n export function discreteChannelCannotEncode(channel: Channel, type: Type) {\n return `Using discrete channel \"${channel}\" to encode \"${type}\" field can be misleading as it does not encode ${type === 'ordinal' ? 'order' : 'magnitude'}.`;\n }\n\n // Mark\n export const BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.';\n\n export function lineWithRange(hasX2: boolean, hasY2: boolean) {\n const channels = hasX2 && hasY2 ? 'x2 and y2' : hasX2 ? 'x2' : 'y2';\n return `Line mark is for continuous lines and thus cannot be used with ${channels}. We will use the rule mark (line segments) instead.`;\n }\n\n export function orientOverridden(original: string, actual: string) {\n return `Specified orient \"${original}\" overridden with \"${actual}\"`;\n }\n\n // SCALE\n export const CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = 'custom domain scale cannot be unioned with default field-based domain';\n\n export function cannotUseScalePropertyWithNonColor(prop: string) {\n return `Cannot use the scale property \"${prop}\" with non-color channel.`;\n }\n\n export function unaggregateDomainHasNoEffectForRawField(fieldDef: FieldDef) {\n return `Using unaggregated domain with raw field has no effect (${stringify(fieldDef)}).`;\n }\n\n export function unaggregateDomainWithNonSharedDomainOp(aggregate: string) {\n return `Unaggregated domain not applicable for \"${aggregate}\" since it produces values outside the origin domain of the source data.`;\n }\n\n export function unaggregatedDomainWithLogScale(fieldDef: FieldDef) {\n return `Unaggregated domain is currently unsupported for log scale (${stringify(fieldDef)}).`;\n }\n\n export function cannotApplySizeToNonOrientedMark(mark: Mark) {\n return `Cannot apply size to non-oriented mark \"${mark}\".`;\n }\n\n export function rangeStepDropped(channel: Channel) {\n return `rangeStep for \"${channel}\" is dropped as top-level ${\n channel === 'x' ? 'width' : 'height'} is provided.`;\n }\n\n export function scaleTypeNotWorkWithChannel(channel: Channel, scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `Channel \"${channel}\" does not work with \"${scaleType}\" scale. We are using \"${defaultScaleType}\" scale instead.`;\n }\n\n export function scaleTypeNotWorkWithFieldDef(scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `FieldDef does not work with \"${scaleType}\" scale. We are using \"${defaultScaleType}\" scale instead.`;\n }\n\n export function scalePropertyNotWorkWithScaleType(scaleType: ScaleType, propName: string, channel: Channel) {\n return `${channel}-scale's \"${propName}\" is dropped as it does not work with ${scaleType} scale.`;\n }\n\n export function scaleTypeNotWorkWithMark(mark: Mark, scaleType: ScaleType) {\n return `Scale type \"${scaleType}\" does not work with mark \"${mark}\".`;\n }\n\n export function mergeConflictingProperty(property: string | number | symbol, propertyOf: string | number | symbol, v1: T, v2: T) {\n return `Conflicting ${propertyOf.toString()} property \"${property.toString()}\" (${stringify(v1)} and ${stringify(v2)}). Using ${stringify(v1)}.`;\n }\n\n export function independentScaleMeansIndependentGuide(channel: Channel) {\n return `Setting the scale to be independent for \"${channel}\" means we also have to set the guide (axis or legend) to be independent.`;\n }\n\n export function domainSortDropped(sort: VgSortField) {\n return `Dropping sort property ${stringify(sort)} as unioned domains only support boolean or op 'count'.`;\n }\n\n export const UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains';\n\n export const MORE_THAN_ONE_SORT = 'Domains that should be unioned has conflicting sort properties. Sort will be set to true.';\n\n // AXIS\n export const INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.';\n\n // STACK\n export function cannotStackRangedMark(channel: Channel) {\n return `Cannot stack \"${channel}\" if there is already \"${channel}2\"`;\n }\n\n export function cannotStackNonLinearScale(scaleType: ScaleType) {\n return `Cannot stack non-linear scale (${scaleType})`;\n }\n\n export function stackNonSummativeAggregate(aggregate: string) {\n return `Stacking is applied even though the aggregate function is non-summative (\"${aggregate}\")`;\n }\n\n // TIMEUNIT\n export function invalidTimeUnit(unitName: string, value: string | number) {\n return `Invalid ${unitName}: ${stringify(value)}`;\n }\n\n export function dayReplacedWithDate(fullTimeUnit: string) {\n return `Time unit \"${fullTimeUnit}\" is not supported. We are replacing it with ${\n fullTimeUnit.replace('day', 'date')}.`;\n }\n\n export function droppedDay(d: DateTime | DateTimeExpr) {\n return `Dropping day from datetime ${stringify(d)} as day cannot be combined with other units.`;\n }\n}\n\n","// DateTime definition object\n\nimport {isNumber} from 'vega-util';\nimport * as log from './log';\nimport {duplicate, keys} from './util';\n\n\n/*\n * A designated year that starts on Sunday.\n */\nconst SUNDAY_YEAR = 2006;\n\n/**\n * @minimum 1\n * @maximum 12\n * @TJS-type integer\n */\nexport type Month = number;\n\n/**\n * @minimum 1\n * @maximum 7\n */\nexport type Day = number;\n\n/**\n * Object for defining datetime in Vega-Lite Filter.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n * We accept string for month and day names.\n */\nexport interface DateTime {\n /**\n * Integer value representing the year.\n * @TJS-type integer\n */\n year?: number;\n\n /**\n * Integer value representing the quarter of the year (from 1-4).\n * @minimum 1\n * @maximum 4\n * @TJS-type integer\n */\n quarter?: number;\n\n /** One of: (1) integer value representing the month from `1`-`12`. `1` represents January; (2) case-insensitive month name (e.g., `\"January\"`); (3) case-insensitive, 3-character short month name (e.g., `\"Jan\"`). */\n month?: Month | string;\n\n /**\n * Integer value representing the date from 1-31.\n * @minimum 1\n * @maximum 31\n * @TJS-type integer\n */\n date?: number;\n\n /**\n * Value representing the day of a week. This can be one of: (1) integer value -- `1` represents Monday; (2) case-insensitive day name (e.g., `\"Monday\"`); (3) case-insensitive, 3-character short day name (e.g., `\"Mon\"`).
**Warning:** A DateTime definition object with `day`** should not be combined with `year`, `quarter`, `month`, or `date`.\n */\n day?: Day | string;\n\n /**\n * Integer value representing the hour of a day from 0-23.\n * @minimum 0\n * @maximum 23\n * @TJS-type integer\n */\n hours?: number;\n\n /**\n * Integer value representing the minute segment of time from 0-59.\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n minutes?: number;\n\n /**\n * Integer value representing the second segment (0-59) of a time value\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n seconds?: number;\n\n /**\n * Integer value representing the millisecond segment of time.\n * @minimum 0\n * @maximum 999\n * @TJS-type integer\n */\n milliseconds?: number;\n\n /**\n * A boolean flag indicating if date time is in utc time. If false, the date time is in local time\n */\n utc?: boolean;\n}\n\n\n/**\n * Internal Object for defining datetime expressions.\n * This is an expression version of DateTime.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n */\nexport interface DateTimeExpr {\n year?: string;\n quarter?: string;\n month?: string;\n date?: string;\n day?: string;\n hours?: string;\n minutes?: string;\n seconds?: string;\n milliseconds?: string;\n utc?: boolean;\n}\n\nexport function isDateTime(o: any): o is DateTime {\n return !!o && (!!o.year || !!o.quarter || !!o.month || !!o.date || !!o.day ||\n !!o.hours || !!o.minutes || !!o.seconds || !!o.milliseconds);\n}\n\nexport const MONTHS = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];\nexport const SHORT_MONTHS = MONTHS.map((m) => m.substr(0, 3));\n\nexport const DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];\nexport const SHORT_DAYS = DAYS.map((d) => d.substr(0,3));\n\nfunction normalizeQuarter(q: number | string) {\n if (isNumber(q)) {\n if (q > 4) {\n log.warn(log.message.invalidTimeUnit('quarter', q));\n }\n // We accept 1-based quarter, so need to readjust to 0-based quarter\n return (q - 1) + '';\n } else {\n // Invalid quarter\n throw new Error(log.message.invalidTimeUnit('quarter', q));\n }\n}\n\nfunction normalizeMonth(m: string | number) {\n if (isNumber(m)) {\n // We accept 1-based month, so need to readjust to 0-based month\n return (m - 1) + '';\n } else {\n const lowerM = m.toLowerCase();\n const monthIndex = MONTHS.indexOf(lowerM);\n if (monthIndex !== -1) {\n return monthIndex + ''; // 0 for january, ...\n }\n const shortM = lowerM.substr(0, 3);\n const shortMonthIndex = SHORT_MONTHS.indexOf(shortM);\n if (shortMonthIndex !== -1) {\n return shortMonthIndex + '';\n }\n // Invalid month\n throw new Error(log.message.invalidTimeUnit('month', m));\n }\n}\n\nfunction normalizeDay(d: string | number) {\n if (isNumber(d)) {\n // mod so that this can be both 0-based where 0 = sunday\n // and 1-based where 7=sunday\n return (d % 7) + '';\n } else {\n const lowerD = d.toLowerCase();\n const dayIndex = DAYS.indexOf(lowerD);\n if (dayIndex !== -1) {\n return dayIndex + ''; // 0 for january, ...\n }\n const shortD = lowerD.substr(0, 3);\n const shortDayIndex = SHORT_DAYS.indexOf(shortD);\n if (shortDayIndex !== -1) {\n return shortDayIndex + '';\n }\n // Invalid day\n throw new Error(log.message.invalidTimeUnit('day', d));\n }\n}\n\n/**\n * Return Vega Expression for a particular date time.\n * @param d\n * @param normalize whether to normalize quarter, month, day.\n */\nexport function dateTimeExpr(d: DateTime | DateTimeExpr, normalize = false) {\n const units: (string | number)[] = [];\n\n if (normalize && d.day !== undefined) {\n if (keys(d).length > 1) {\n log.warn(log.message.droppedDay(d));\n d = duplicate(d);\n delete d.day;\n }\n }\n\n if (d.year !== undefined) {\n units.push(d.year);\n } else if (d.day !== undefined) {\n // Set year to 2006 for working with day since January 1 2006 is a Sunday\n units.push(SUNDAY_YEAR);\n } else {\n units.push(0);\n }\n\n if (d.month !== undefined) {\n const month = normalize ? normalizeMonth(d.month) : d.month;\n units.push(month);\n } else if (d.quarter !== undefined) {\n const quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter;\n units.push(quarter + '*3');\n } else {\n units.push(0); // months start at zero in JS\n }\n\n if (d.date !== undefined) {\n units.push(d.date);\n } else if (d.day !== undefined) {\n // HACK: Day only works as a standalone unit\n // This is only correct because we always set year to 2006 for day\n const day = normalize ? normalizeDay(d.day) : d.day;\n units.push(day + '+1');\n } else {\n units.push(1); // Date starts at 1 in JS\n }\n\n // Note: can't use TimeUnit enum here as importing it will create\n // circular dependency problem!\n for (const timeUnit of ['hours', 'minutes', 'seconds', 'milliseconds']) {\n if (d[timeUnit] !== undefined) {\n units.push(d[timeUnit]);\n } else {\n units.push(0);\n }\n }\n\n if (d.utc) {\n return `utc(${units.join(', ')})`;\n } else {\n return `datetime(${units.join(', ')})`;\n }\n}\n","import {DateTimeExpr, dateTimeExpr} from './datetime';\nimport * as log from './log';\nimport {accessPathWithDatum, Flag, flagKeys} from './util';\n\nexport namespace TimeUnit {\n export const YEAR: 'year' = 'year';\n export const MONTH: 'month' = 'month';\n export const DAY: 'day' = 'day';\n export const DATE: 'date' = 'date';\n export const HOURS: 'hours' = 'hours';\n export const MINUTES: 'minutes' = 'minutes';\n export const SECONDS: 'seconds' = 'seconds';\n export const MILLISECONDS: 'milliseconds' = 'milliseconds';\n export const YEARMONTH: 'yearmonth' = 'yearmonth';\n export const YEARMONTHDATE: 'yearmonthdate' = 'yearmonthdate';\n export const YEARMONTHDATEHOURS: 'yearmonthdatehours' = 'yearmonthdatehours';\n export const YEARMONTHDATEHOURSMINUTES: 'yearmonthdatehoursminutes' = 'yearmonthdatehoursminutes';\n export const YEARMONTHDATEHOURSMINUTESSECONDS: 'yearmonthdatehoursminutesseconds' = 'yearmonthdatehoursminutesseconds';\n\n // MONTHDATE always include 29 February since we use year 0th (which is a leap year);\n export const MONTHDATE: 'monthdate' = 'monthdate';\n export const HOURSMINUTES: 'hoursminutes' = 'hoursminutes';\n export const HOURSMINUTESSECONDS: 'hoursminutesseconds' = 'hoursminutesseconds';\n export const MINUTESSECONDS: 'minutesseconds' = 'minutesseconds';\n export const SECONDSMILLISECONDS: 'secondsmilliseconds' = 'secondsmilliseconds';\n export const QUARTER: 'quarter' = 'quarter';\n export const YEARQUARTER: 'yearquarter' = 'yearquarter';\n export const QUARTERMONTH: 'quartermonth' = 'quartermonth';\n export const YEARQUARTERMONTH: 'yearquartermonth' = 'yearquartermonth';\n export const UTCYEAR: 'utcyear' = 'utcyear';\n export const UTCMONTH: 'utcmonth' = 'utcmonth';\n export const UTCDAY: 'utcday' = 'utcday';\n export const UTCDATE: 'utcdate' = 'utcdate';\n export const UTCHOURS: 'utchours' = 'utchours';\n export const UTCMINUTES: 'utcminutes' = 'utcminutes';\n export const UTCSECONDS: 'utcseconds' = 'utcseconds';\n export const UTCMILLISECONDS: 'utcmilliseconds' = 'utcmilliseconds';\n export const UTCYEARMONTH: 'utcyearmonth' = 'utcyearmonth';\n export const UTCYEARMONTHDATE: 'utcyearmonthdate' = 'utcyearmonthdate';\n export const UTCYEARMONTHDATEHOURS: 'utcyearmonthdatehours' = 'utcyearmonthdatehours';\n export const UTCYEARMONTHDATEHOURSMINUTES: 'utcyearmonthdatehoursminutes' = 'utcyearmonthdatehoursminutes';\n export const UTCYEARMONTHDATEHOURSMINUTESSECONDS: 'utcyearmonthdatehoursminutesseconds' = 'utcyearmonthdatehoursminutesseconds';\n\n // MONTHDATE always include 29 February since we use year 0th (which is a leap year);\n export const UTCMONTHDATE: 'utcmonthdate' = 'utcmonthdate';\n export const UTCHOURSMINUTES: 'utchoursminutes' = 'utchoursminutes';\n export const UTCHOURSMINUTESSECONDS: 'utchoursminutesseconds' = 'utchoursminutesseconds';\n export const UTCMINUTESSECONDS: 'utcminutesseconds' = 'utcminutesseconds';\n export const UTCSECONDSMILLISECONDS: 'utcsecondsmilliseconds' = 'utcsecondsmilliseconds';\n export const UTCQUARTER: 'utcquarter' = 'utcquarter';\n export const UTCYEARQUARTER: 'utcyearquarter' = 'utcyearquarter';\n export const UTCQUARTERMONTH: 'utcquartermonth' = 'utcquartermonth';\n export const UTCYEARQUARTERMONTH: 'utcyearquartermonth' = 'utcyearquartermonth';\n}\n\nexport type LocalSingleTimeUnit =\n typeof TimeUnit.YEAR |\n typeof TimeUnit.QUARTER |\n typeof TimeUnit.MONTH |\n typeof TimeUnit.DAY |\n typeof TimeUnit.DATE |\n typeof TimeUnit.HOURS |\n typeof TimeUnit.MINUTES |\n typeof TimeUnit.SECONDS |\n typeof TimeUnit.MILLISECONDS;\n\n/** Time Unit that only corresponds to only one part of Date objects. */\nconst LOCAL_SINGLE_TIMEUNIT_INDEX: Flag = {\n year: 1,\n quarter: 1,\n month: 1,\n day: 1,\n date: 1,\n hours: 1,\n minutes: 1,\n seconds: 1,\n milliseconds: 1\n};\n\nexport const TIMEUNIT_PARTS = flagKeys(LOCAL_SINGLE_TIMEUNIT_INDEX);\n\nexport function isLocalSingleTimeUnit(timeUnit: string): timeUnit is LocalSingleTimeUnit {\n return !!LOCAL_SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport type UtcSingleTimeUnit =\n typeof TimeUnit.UTCYEAR |\n typeof TimeUnit.UTCQUARTER |\n typeof TimeUnit.UTCMONTH |\n typeof TimeUnit.UTCDAY |\n typeof TimeUnit.UTCDATE |\n typeof TimeUnit.UTCHOURS |\n typeof TimeUnit.UTCMINUTES |\n typeof TimeUnit.UTCSECONDS |\n typeof TimeUnit.UTCMILLISECONDS;\n\nconst UTC_SINGLE_TIMEUNIT_INDEX: Flag = {\n utcyear: 1,\n utcquarter: 1,\n utcmonth: 1,\n utcday: 1,\n utcdate: 1,\n utchours: 1,\n utcminutes: 1,\n utcseconds: 1,\n utcmilliseconds: 1\n};\n\nexport function isUtcSingleTimeUnit(timeUnit: string): timeUnit is UtcSingleTimeUnit {\n return !!UTC_SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport type SingleTimeUnit = LocalSingleTimeUnit | UtcSingleTimeUnit;\n\nexport type LocalMultiTimeUnit =\n // Local Time\n typeof TimeUnit.YEARQUARTER | typeof TimeUnit.YEARQUARTERMONTH |\n typeof TimeUnit.YEARMONTH | typeof TimeUnit.YEARMONTHDATE | typeof TimeUnit.YEARMONTHDATEHOURS | typeof TimeUnit.YEARMONTHDATEHOURSMINUTES| typeof TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS |\n typeof TimeUnit.QUARTERMONTH |\n typeof TimeUnit.MONTHDATE |\n typeof TimeUnit.HOURSMINUTES | typeof TimeUnit.HOURSMINUTESSECONDS |\n typeof TimeUnit.MINUTESSECONDS |\n typeof TimeUnit.SECONDSMILLISECONDS;\n\nconst LOCAL_MULTI_TIMEUNIT_INDEX: Flag = {\n yearquarter: 1,\n yearquartermonth: 1,\n\n yearmonth: 1,\n yearmonthdate: 1,\n yearmonthdatehours: 1,\n yearmonthdatehoursminutes: 1,\n yearmonthdatehoursminutesseconds: 1,\n\n quartermonth: 1,\n\n monthdate: 1,\n\n hoursminutes: 1,\n hoursminutesseconds: 1,\n\n minutesseconds: 1,\n\n secondsmilliseconds: 1\n};\n\nexport type UtcMultiTimeUnit =\n typeof TimeUnit.UTCYEARQUARTER | typeof TimeUnit.UTCYEARQUARTERMONTH |\n typeof TimeUnit.UTCYEARMONTH | typeof TimeUnit.UTCYEARMONTHDATE | typeof TimeUnit.UTCYEARMONTHDATEHOURS | typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTES| typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTESSECONDS |\n typeof TimeUnit.UTCQUARTERMONTH |\n typeof TimeUnit.UTCMONTHDATE |\n typeof TimeUnit.UTCHOURSMINUTES | typeof TimeUnit.UTCHOURSMINUTESSECONDS |\n typeof TimeUnit.UTCMINUTESSECONDS |\n typeof TimeUnit.UTCSECONDSMILLISECONDS;\n\nconst UTC_MULTI_TIMEUNIT_INDEX: Flag = {\n utcyearquarter: 1,\n utcyearquartermonth: 1,\n\n utcyearmonth: 1,\n utcyearmonthdate: 1,\n utcyearmonthdatehours: 1,\n utcyearmonthdatehoursminutes: 1,\n utcyearmonthdatehoursminutesseconds: 1,\n\n utcquartermonth: 1,\n\n utcmonthdate: 1,\n\n utchoursminutes: 1,\n utchoursminutesseconds: 1,\n\n utcminutesseconds: 1,\n\n utcsecondsmilliseconds: 1\n};\n\nexport type MultiTimeUnit = LocalMultiTimeUnit | UtcMultiTimeUnit;\n\n\nexport type LocalTimeUnit = LocalSingleTimeUnit | LocalMultiTimeUnit;\nexport type UtcTimeUnit = UtcSingleTimeUnit | UtcMultiTimeUnit;\n\nconst UTC_TIMEUNIT_INDEX: Flag = {\n ...UTC_SINGLE_TIMEUNIT_INDEX,\n ...UTC_MULTI_TIMEUNIT_INDEX\n};\n\nexport function isUTCTimeUnit(t: string): t is UtcTimeUnit {\n return !!UTC_TIMEUNIT_INDEX[t];\n}\n\nexport function getLocalTimeUnit(t: UtcTimeUnit): LocalTimeUnit {\n return t.substr(3) as LocalTimeUnit;\n}\n\nexport type TimeUnit = SingleTimeUnit | MultiTimeUnit;\n\nconst TIMEUNIT_INDEX: Flag = {\n ...LOCAL_SINGLE_TIMEUNIT_INDEX,\n ...UTC_SINGLE_TIMEUNIT_INDEX,\n ...LOCAL_MULTI_TIMEUNIT_INDEX,\n ...UTC_MULTI_TIMEUNIT_INDEX\n};\n\nexport const TIMEUNITS = flagKeys(TIMEUNIT_INDEX);\n\nexport function isTimeUnit(t: string): t is TimeUnit {\n return !!TIMEUNIT_INDEX[t];\n}\n\ntype DateMethodName = keyof Date;\n\nconst SET_DATE_METHOD: Record = {\n year: 'setFullYear',\n month: 'setMonth',\n date: 'setDate',\n hours: 'setHours',\n minutes: 'setMinutes',\n seconds: 'setSeconds',\n milliseconds: 'setMilliseconds',\n // Day and quarter have their own special cases\n quarter: null,\n day: null,\n};\n\n/**\n * Converts a date to only have the measurements relevant to the specified unit\n * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00'\n * Note: the base date is Jan 01 1900 00:00:00\n */\nexport function convert(unit: TimeUnit, date: Date): Date {\n const isUTC = isUTCTimeUnit(unit);\n const result: Date = isUTC ?\n // start with uniform date\n new Date(Date.UTC(0, 0, 1, 0, 0, 0, 0)) :\n new Date(0, 0, 1, 0, 0, 0, 0);\n for (const timeUnitPart of TIMEUNIT_PARTS) {\n if (containsTimeUnit(unit, timeUnitPart)) {\n switch (timeUnitPart) {\n case TimeUnit.DAY:\n throw new Error('Cannot convert to TimeUnits containing \\'day\\'');\n case TimeUnit.QUARTER: {\n const {getDateMethod, setDateMethod} = dateMethods('month', isUTC);\n // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3)\n result[setDateMethod]((Math.floor(date[getDateMethod]() / 3)) * 3);\n break;\n }\n default:\n const {getDateMethod, setDateMethod} = dateMethods(timeUnitPart, isUTC);\n result[setDateMethod](date[getDateMethod]());\n }\n }\n }\n return result;\n}\n\nfunction dateMethods(singleUnit: SingleTimeUnit, isUtc: boolean) {\n const rawSetDateMethod = SET_DATE_METHOD[singleUnit];\n const setDateMethod = isUtc ? 'setUTC' + rawSetDateMethod.substr(3) : rawSetDateMethod;\n const getDateMethod = 'get' + (isUtc ? 'UTC' : '') + rawSetDateMethod.substr(3);\n return {setDateMethod, getDateMethod};\n}\n\nexport function getTimeUnitParts(timeUnit: TimeUnit) {\n return TIMEUNIT_PARTS.reduce((parts, part) => {\n if (containsTimeUnit(timeUnit, part)) {\n return parts.concat(part);\n }\n return parts;\n }, []);\n}\n\n/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */\nexport function containsTimeUnit(fullTimeUnit: TimeUnit, timeUnit: TimeUnit) {\n const index = fullTimeUnit.indexOf(timeUnit);\n return index > -1 &&\n (\n timeUnit !== TimeUnit.SECONDS ||\n index === 0 ||\n fullTimeUnit.charAt(index-1) !== 'i' // exclude milliseconds\n );\n}\n\n/**\n * Returns Vega expresssion for a given timeUnit and fieldRef\n */\nexport function fieldExpr(fullTimeUnit: TimeUnit, field: string): string {\n const fieldRef = accessPathWithDatum(field);\n\n const utc = isUTCTimeUnit(fullTimeUnit) ? 'utc' : '';\n function func(timeUnit: TimeUnit) {\n if (timeUnit === TimeUnit.QUARTER) {\n // quarter starting at 0 (0,3,6,9).\n return `(${utc}quarter(${fieldRef})-1)`;\n } else {\n return `${utc}${timeUnit}(${fieldRef})`;\n }\n }\n\n const d = TIMEUNIT_PARTS.reduce((dateExpr: DateTimeExpr, tu: TimeUnit) => {\n if (containsTimeUnit(fullTimeUnit, tu)) {\n dateExpr[tu] = func(tu);\n }\n return dateExpr;\n }, {} as {[key in SingleTimeUnit]: string});\n\n return dateTimeExpr(d);\n}\n\n/**\n * returns the signal expression used for axis labels for a time unit\n */\nexport function formatExpression(timeUnit: TimeUnit, field: string, shortTimeLabels: boolean, isUTCScale: boolean): string {\n if (!timeUnit) {\n return undefined;\n }\n\n const dateComponents: string[] = [];\n let expression = '';\n const hasYear = containsTimeUnit(timeUnit, TimeUnit.YEAR);\n\n if (containsTimeUnit(timeUnit, TimeUnit.QUARTER)) {\n // special expression for quarter as prefix\n expression = `'Q' + quarter(${field})`;\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) {\n // By default use short month name\n dateComponents.push(shortTimeLabels !== false ? '%b' : '%B');\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.DAY)) {\n dateComponents.push(shortTimeLabels ? '%a' : '%A');\n } else if (containsTimeUnit(timeUnit, TimeUnit.DATE)) {\n dateComponents.push('%d' + (hasYear ? ',' : '')); // add comma if there is year\n }\n\n if (hasYear) {\n dateComponents.push(shortTimeLabels ? '%y' : '%Y');\n }\n\n const timeComponents: string[] = [];\n\n if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) {\n timeComponents.push('%H');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) {\n timeComponents.push('%M');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) {\n timeComponents.push('%S');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MILLISECONDS)) {\n timeComponents.push('%L');\n }\n\n const dateTimeComponents: string[] = [];\n if (dateComponents.length > 0) {\n dateTimeComponents.push(dateComponents.join(' '));\n }\n if (timeComponents.length > 0) {\n dateTimeComponents.push(timeComponents.join(':'));\n }\n\n if (dateTimeComponents.length > 0) {\n if (expression) {\n // Add space between quarter and main time format\n expression += ` + ' ' + `;\n }\n\n // We only use utcFormat for utc scale\n // For utc time units, the data is already converted as a part of timeUnit transform.\n // Thus, utc time units should use timeFormat to avoid shifting the time twice.\n if (isUTCScale) {\n expression += `utcFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n } else {\n expression += `timeFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n }\n }\n\n // If expression is still an empty string, return undefined instead.\n return expression || undefined;\n}\n\nexport function normalizeTimeUnit(timeUnit: TimeUnit): TimeUnit {\n if (timeUnit !== 'day' && timeUnit.indexOf('day') >= 0) {\n log.warn(log.message.dayReplacedWithDate(timeUnit));\n return timeUnit.replace('day', 'date') as TimeUnit;\n }\n return timeUnit;\n}\n","import {Flag} from './util';\n/** Constants and utilities for data type */\n/** Data type based on level of measurement */\n\nexport namespace Type {\n export const QUANTITATIVE: 'quantitative' = 'quantitative';\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const TEMPORAL: 'temporal' = 'temporal';\n export const NOMINAL: 'nominal' = 'nominal';\n\n export const LATITUDE: 'latitude' = 'latitude';\n export const LONGITUDE: 'longitude' = 'longitude';\n export const GEOJSON: 'geojson' = 'geojson';\n}\nexport type BasicType = typeof Type.QUANTITATIVE | typeof Type.ORDINAL | typeof Type.TEMPORAL | typeof Type.NOMINAL;\nexport type GeoType = typeof Type.LATITUDE | typeof Type.LONGITUDE | typeof Type.GEOJSON;\n\nexport type Type = BasicType | GeoType;\n\nexport const TYPE_INDEX: Flag = {\n quantitative: 1,\n ordinal: 1,\n temporal: 1,\n nominal: 1,\n latitude: 1,\n longitude: 1,\n geojson: 1\n};\n\nexport function isType(t: any): t is Type {\n return !!TYPE_INDEX[t];\n}\n\nexport const QUANTITATIVE = Type.QUANTITATIVE;\nexport const ORDINAL = Type.ORDINAL;\nexport const TEMPORAL = Type.TEMPORAL;\nexport const NOMINAL = Type.NOMINAL;\n\nexport const GEOJSON = Type.GEOJSON;\n\n/**\n * Get full, lowercase type name for a given type.\n * @param type\n * @return Full type name.\n */\nexport function getFullName(type: Type|string): Type {\n if (type) {\n type = type.toLowerCase();\n switch (type) {\n case 'q':\n case QUANTITATIVE:\n return 'quantitative';\n case 't':\n case TEMPORAL:\n return 'temporal';\n case 'o':\n case ORDINAL:\n return 'ordinal';\n case 'n':\n case NOMINAL:\n return 'nominal';\n case Type.LATITUDE:\n return 'latitude';\n case Type.LONGITUDE:\n return 'longitude';\n case GEOJSON:\n return 'geojson';\n }\n }\n // If we get invalid input, return undefined type.\n return undefined;\n}\n","// Declaration and utility for variants of a field definition object\nimport {AggregateOp} from 'vega';\nimport {isArray, isBoolean, isNumber, isString} from 'vega-util';\nimport {isAggregateOp, isCountingAggregateOp} from './aggregate';\nimport {Axis} from './axis';\nimport {autoMaxBins, BinParams, binToString} from './bin';\nimport {Channel, rangeType} from './channel';\nimport {CompositeAggregate} from './compositemark';\nimport {Config} from './config';\nimport {DateTime, dateTimeExpr, isDateTime} from './datetime';\nimport {TitleMixins} from './guide';\nimport {Legend} from './legend';\nimport * as log from './log';\nimport {LogicalOperand} from './logical';\nimport {Predicate} from './predicate';\nimport {Scale} from './scale';\nimport {Sort, SortOrder} from './sort';\nimport {StackOffset} from './stack';\nimport {getLocalTimeUnit, getTimeUnitParts, isLocalSingleTimeUnit, isUtcSingleTimeUnit, normalizeTimeUnit, TimeUnit} from './timeunit';\nimport {AggregatedFieldDef, WindowFieldDef} from './transform';\nimport {getFullName, QUANTITATIVE, Type} from './type';\nimport {flatAccessWithDatum, replacePathInField, titlecase} from './util';\n\n\n/**\n * Definition object for a constant value of an encoding channel.\n */\nexport interface ValueDef {\n /**\n * A constant value in visual domain (e.g., `\"red\"` / \"#0099ff\" for color, values between `0` to `1` for opacity).\n */\n value: number | string | boolean;\n}\n\n/**\n * Generic type for conditional channelDef.\n * F defines the underlying FieldDef type.\n */\nexport type ChannelDefWithCondition> = FieldDefWithCondition | ValueDefWithCondition;\n\nexport type Conditional = ConditionalPredicate | ConditionalSelection;\n\nexport type ConditionalPredicate = {\n test: LogicalOperand;\n} & T;\n\nexport type ConditionalSelection = {\n /**\n * A [selection name](https://vega.github.io/vega-lite/docs/selection.html), or a series of [composed selections](https://vega.github.io/vega-lite/docs/selection.html#compose).\n */\n selection: LogicalOperand;\n} & T;\n\nexport function isConditionalSelection(c: Conditional): c is ConditionalSelection {\n return c['selection'];\n}\n\nexport interface ConditionValueDefMixins {\n /**\n * One or more value definition(s) with a selection predicate.\n *\n * __Note:__ A field definition's `condition` property can only contain [value definitions](https://vega.github.io/vega-lite/docs/encoding.html#value-def)\n * since Vega-Lite only allows at most one encoded field per encoding channel.\n */\n condition?: Conditional | Conditional[];\n}\n\n/**\n * A FieldDef with Condition\n * {\n * condition: {value: ...},\n * field: ...,\n * ...\n * }\n */\n\nexport type FieldDefWithCondition> = F & ConditionValueDefMixins;\n\n/**\n * A ValueDef with Condition\n * {\n * condition: {field: ...} | {value: ...},\n * value: ...,\n * }\n */\nexport interface ValueDefWithCondition> {\n /**\n * A field definition or one or more value definition(s) with a selection predicate.\n */\n condition?: Conditional | Conditional | Conditional[];\n\n /**\n * A constant value in visual domain.\n */\n value?: number | string | boolean;\n}\n\n/**\n * Reference to a repeated value.\n */\nexport type RepeatRef = {\n repeat: 'row' | 'column'\n};\n\nexport type Field = string | RepeatRef;\n\nexport function isRepeatRef(field: Field): field is RepeatRef {\n return field && !isString(field) && 'repeat' in field;\n}\n\n/** @hide */\nexport type HiddenCompositeAggregate = CompositeAggregate;\n\nexport type Aggregate = AggregateOp | HiddenCompositeAggregate;\n\nexport interface FieldDefBase {\n\n /**\n * __Required.__ A string defining the name of the field from which to pull a data value\n * or an object defining iterated values from the [`repeat`](https://vega.github.io/vega-lite/docs/repeat.html) operator.\n *\n * __Note:__ Dots (`.`) and brackets (`[` and `]`) can be used to access nested objects (e.g., `\"field\": \"foo.bar\"` and `\"field\": \"foo['bar']\"`).\n * If field names contain dots or brackets but are not nested, you can use `\\\\` to escape dots and brackets (e.g., `\"a\\\\.b\"` and `\"a\\\\[0\\\\]\"`).\n * See more details about escaping in the [field documentation](https://vega.github.io/vega-lite/docs/field.html).\n *\n * __Note:__ `field` is not required if `aggregate` is `count`.\n */\n field?: F;\n\n // function\n\n /**\n * Time unit (e.g., `year`, `yearmonth`, `month`, `hours`) for a temporal field.\n * or [a temporal field that gets casted as ordinal](https://vega.github.io/vega-lite/docs/type.html#cast).\n *\n * __Default value:__ `undefined` (None)\n */\n timeUnit?: TimeUnit;\n\n /**\n * A flag for binning a `quantitative` field, or [an object defining binning parameters](https://vega.github.io/vega-lite/docs/bin.html#params).\n * If `true`, default [binning parameters](https://vega.github.io/vega-lite/docs/bin.html) will be applied.\n *\n * __Default value:__ `false`\n */\n bin?: boolean | BinParams;\n\n /**\n * Aggregation function for the field\n * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).\n *\n * __Default value:__ `undefined` (None)\n */\n aggregate?: Aggregate;\n}\n\nexport function toFieldDefBase(fieldDef: FieldDef): FieldDefBase {\n const {field, timeUnit, bin, aggregate} = fieldDef;\n return {\n ...(timeUnit ? {timeUnit} : {}),\n ...(bin ? {bin} : {}),\n ...(aggregate ? {aggregate} : {}),\n field\n };\n}\n\n/**\n * Definition object for a data field, its type and transformation of an encoding channel.\n */\nexport interface FieldDef extends FieldDefBase, TitleMixins {\n /**\n * The encoded field's type of measurement (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, or `\"nominal\"`).\n * It can also be a `\"geojson\"` type for encoding ['geoshape'](https://vega.github.io/vega-lite/docs/geoshape.html).\n */\n // * or an initial character of the type name (`\"Q\"`, `\"T\"`, `\"O\"`, `\"N\"`).\n // * This property is case-insensitive.\n type: Type;\n}\n\nexport interface SortableFieldDef extends FieldDef {\n /**\n * Sort order for the encoded field.\n *\n * For continuous fields (quantitative or temporal), `sort` can be either `\"ascending\"` or `\"descending\"`.\n *\n * For discrete fields, `sort` can be one of the following:\n * - `\"ascending\"` or `\"descending\"` -- for sorting by the values' natural order in Javascript.\n * - [A sort field definition](https://vega.github.io/vega-lite/docs/sort.html#sort-field) for sorting by another field.\n * - [An array specifying the field values in preferred order](https://vega.github.io/vega-lite/docs/sort.html#sort-array). In this case, the sort order will obey the values in the array, followed by any unspecified values in their original order. For discrete time field, values in the sort array can be [date-time definition objects](types#datetime). In addition, for time units `\"month\"` and `\"day\"`, the values can be the month or day names (case insensitive) or their 3-letter initials (e.g., `\"Mon\"`, `\"Tue\"`).\n * - `null` indicating no sort.\n *\n * __Default value:__ `\"ascending\"`\n *\n * __Note:__ `null` is not supported for `row` and `column`.\n */\n sort?: Sort;\n}\n\nexport interface ScaleFieldDef extends SortableFieldDef {\n /**\n * An object defining properties of the channel's scale, which is the function that transforms values in the data domain (numbers, dates, strings, etc) to visual values (pixels, colors, sizes) of the encoding channels.\n *\n * If `null`, the scale will be [disabled and the data value will be directly encoded](https://vega.github.io/vega-lite/docs/scale.html#disable).\n *\n * __Default value:__ If undefined, default [scale properties](https://vega.github.io/vega-lite/docs/scale.html) are applied.\n */\n scale?: Scale | null;\n}\n\nexport interface PositionFieldDef extends ScaleFieldDef {\n /**\n * An object defining properties of axis's gridlines, ticks and labels.\n * If `null`, the axis for the encoding channel will be removed.\n *\n * __Default value:__ If undefined, default [axis properties](https://vega.github.io/vega-lite/docs/axis.html) are applied.\n */\n axis?: Axis | null;\n\n /**\n * Type of stacking offset if the field should be stacked.\n * `stack` is only applicable for `x` and `y` channels with continuous domains.\n * For example, `stack` of `y` can be used to customize stacking for a vertical bar chart.\n *\n * `stack` can be one of the following values:\n * - `\"zero\"`: stacking with baseline offset at zero value of the scale (for creating typical stacked [bar](https://vega.github.io/vega-lite/docs/stack.html#bar) and [area](https://vega.github.io/vega-lite/docs/stack.html#area) chart).\n * - `\"normalize\"` - stacking with normalized domain (for creating [normalized stacked bar and area charts](https://vega.github.io/vega-lite/docs/stack.html#normalized).
\n * -`\"center\"` - stacking with center baseline (for [streamgraph](https://vega.github.io/vega-lite/docs/stack.html#streamgraph)).\n * - `null` - No-stacking. This will produce layered [bar](https://vega.github.io/vega-lite/docs/stack.html#layered-bar-chart) and area chart.\n *\n * __Default value:__ `zero` for plots with all of the following conditions are true:\n * (1) the mark is `bar` or `area`;\n * (2) the stacked measure channel (x or y) has a linear scale;\n * (3) At least one of non-position channels mapped to an unaggregated field that is different from x and y. Otherwise, `null` by default.\n */\n stack?: StackOffset | null;\n}\n\n/**\n * Field definition of a mark property, which can contain a legend.\n */\nexport interface MarkPropFieldDef extends ScaleFieldDef {\n /**\n * An object defining properties of the legend.\n * If `null`, the legend for the encoding channel will be removed.\n *\n * __Default value:__ If undefined, default [legend properties](https://vega.github.io/vega-lite/docs/legend.html) are applied.\n */\n legend?: Legend | null;\n}\n\n// Detail\n\n// Order Path have no scale\n\nexport interface OrderFieldDef extends FieldDef {\n /**\n * The sort order. One of `\"ascending\"` (default) or `\"descending\"`.\n */\n sort?: SortOrder;\n}\n\nexport interface TextFieldDef extends FieldDef {\n /**\n * The [formatting pattern](https://vega.github.io/vega-lite/docs/format.html) for a text field. If not defined, this will be determined automatically.\n */\n format?: string;\n}\n\nexport type ChannelDef = ChannelDefWithCondition>;\n\nexport function isConditionalDef(channelDef: ChannelDef): channelDef is ChannelDefWithCondition> {\n return !!channelDef && !!channelDef.condition;\n}\n\n/**\n * Return if a channelDef is a ConditionalValueDef with ConditionFieldDef\n */\nexport function hasConditionalFieldDef(channelDef: ChannelDef): channelDef is (ValueDef & {condition: Conditional>}) {\n return !!channelDef && !!channelDef.condition && !isArray(channelDef.condition) && isFieldDef(channelDef.condition);\n}\n\nexport function hasConditionalValueDef(channelDef: ChannelDef): channelDef is (ValueDef & {condition: Conditional | Conditional[]}) {\n return !!channelDef && !!channelDef.condition && (\n isArray(channelDef.condition) || isValueDef(channelDef.condition)\n );\n}\n\nexport function isFieldDef(channelDef: ChannelDef): channelDef is FieldDef | PositionFieldDef | ScaleFieldDef | MarkPropFieldDef | OrderFieldDef | TextFieldDef {\n return !!channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count');\n}\n\nexport function isStringFieldDef(fieldDef: ChannelDef): fieldDef is FieldDef {\n return isFieldDef(fieldDef) && isString(fieldDef.field);\n}\n\nexport function isValueDef(channelDef: ChannelDef): channelDef is ValueDef {\n return channelDef && 'value' in channelDef && channelDef['value'] !== undefined;\n}\n\nexport function isScaleFieldDef(channelDef: ChannelDef): channelDef is ScaleFieldDef {\n return !!channelDef && (!!channelDef['scale'] || !!channelDef['sort']);\n}\n\nexport interface FieldRefOption {\n /** exclude bin, aggregate, timeUnit */\n nofn?: boolean;\n /** Wrap the field with datum or parent (e.g., datum['...'] for Vega Expression */\n expr?: 'datum' | 'parent';\n /** prepend fn with custom function prefix */\n prefix?: string;\n /** append suffix to the field ref for bin (default='start') */\n binSuffix?: 'end' | 'range' | 'mid';\n /** append suffix to the field ref (general) */\n suffix?: string;\n}\n\nfunction isOpFieldDef(fieldDef: FieldDefBase | WindowFieldDef | AggregatedFieldDef): fieldDef is WindowFieldDef | AggregatedFieldDef {\n return !!fieldDef['op'];\n}\n\nexport function vgField(fieldDef: FieldDefBase | WindowFieldDef | AggregatedFieldDef, opt: FieldRefOption = {}): string {\n let field = fieldDef.field;\n const prefix = opt.prefix;\n let suffix = opt.suffix;\n\n if (isCount(fieldDef)) {\n field = 'count_*';\n } else {\n let fn: string = undefined;\n\n if (!opt.nofn) {\n if (isOpFieldDef(fieldDef)) {\n fn = fieldDef.op;\n } else if (fieldDef.bin) {\n fn = binToString(fieldDef.bin);\n suffix = opt.binSuffix || '';\n } else if (fieldDef.aggregate) {\n fn = String(fieldDef.aggregate);\n } else if (fieldDef.timeUnit) {\n fn = String(fieldDef.timeUnit);\n }\n }\n\n if (fn) {\n field = field ? `${fn}_${field}` : fn;\n }\n }\n\n if (suffix) {\n field = `${field}_${suffix}`;\n }\n\n if (prefix) {\n field = `${prefix}_${field}`;\n }\n\n if (opt.expr) {\n // Expression to access flattened field. No need to escape dots.\n return flatAccessWithDatum(field, opt.expr);\n } else {\n // We flattened all fields so paths should have become dot.\n return replacePathInField(field);\n }\n}\n\nexport function isDiscrete(fieldDef: FieldDef) {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n case 'geojson':\n return true;\n case 'quantitative':\n return !!fieldDef.bin;\n case 'latitude':\n case 'longitude':\n case 'temporal':\n return false;\n }\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n\nexport function isContinuous(fieldDef: FieldDef) {\n return !isDiscrete(fieldDef);\n}\n\nexport function isCount(fieldDef: FieldDefBase) {\n return fieldDef.aggregate === 'count';\n}\n\nexport type FieldTitleFormatter = (fieldDef: FieldDefBase, config: Config) => string;\n\nexport function verbalTitleFormatter(fieldDef: FieldDefBase, config: Config) {\n const {field: field, bin, timeUnit, aggregate} = fieldDef;\n if (aggregate === 'count') {\n return config.countTitle;\n } else if (bin) {\n return `${field} (binned)`;\n } else if (timeUnit) {\n const units = getTimeUnitParts(timeUnit).join('-');\n return `${field} (${units})`;\n } else if (aggregate) {\n return `${titlecase(aggregate)} of ${field}`;\n }\n return field;\n}\n\nexport function functionalTitleFormatter(fieldDef: FieldDefBase, config: Config) {\n const fn = fieldDef.aggregate || fieldDef.timeUnit || (fieldDef.bin && 'bin');\n if (fn) {\n return fn.toUpperCase() + '(' + fieldDef.field + ')';\n } else {\n return fieldDef.field;\n }\n}\n\nexport const defaultTitleFormatter: FieldTitleFormatter = (fieldDef: FieldDefBase, config: Config) => {\n switch (config.fieldTitle) {\n case 'plain':\n return fieldDef.field;\n case 'functional':\n return functionalTitleFormatter(fieldDef, config);\n default:\n return verbalTitleFormatter(fieldDef, config);\n }\n};\n\nlet titleFormatter = defaultTitleFormatter;\n\nexport function setTitleFormatter(formatter: FieldTitleFormatter) {\n titleFormatter = formatter;\n}\n\nexport function resetTitleFormatter() {\n setTitleFormatter(defaultTitleFormatter);\n}\n\nexport function title(fieldDef: FieldDefBase, config: Config) {\n return titleFormatter(fieldDef, config);\n}\n\nexport function defaultType(fieldDef: FieldDef, channel: Channel): Type {\n if (fieldDef.timeUnit) {\n return 'temporal';\n }\n if (fieldDef.bin) {\n return 'quantitative';\n }\n switch (rangeType(channel)) {\n case 'continuous':\n return 'quantitative';\n case 'discrete':\n return 'nominal';\n case 'flexible': // color\n return 'nominal';\n default:\n return 'quantitative';\n }\n}\n\n/**\n * Returns the fieldDef -- either from the outer channelDef or from the condition of channelDef.\n * @param channelDef\n */\nexport function getFieldDef(channelDef: ChannelDef): FieldDef {\n if (isFieldDef(channelDef)) {\n return channelDef;\n } else if (hasConditionalFieldDef(channelDef)) {\n return channelDef.condition;\n }\n return undefined;\n}\n\n/**\n * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n */\nexport function normalize(channelDef: ChannelDef, channel: Channel): ChannelDef {\n if (isString(channelDef) || isNumber(channelDef) || isBoolean(channelDef)) {\n const primitiveType = isString(channelDef) ? 'string' :\n isNumber(channelDef) ? 'number' : 'boolean';\n log.warn(log.message.primitiveChannelDef(channel, primitiveType, channelDef));\n return {value: channelDef};\n }\n\n // If a fieldDef contains a field, we need type.\n if (isFieldDef(channelDef)) {\n return normalizeFieldDef(channelDef, channel);\n } else if (hasConditionalFieldDef(channelDef)) {\n return {\n ...channelDef,\n // Need to cast as normalizeFieldDef normally return FieldDef, but here we know that it is definitely Condition\n condition: normalizeFieldDef(channelDef.condition, channel) as Conditional>\n };\n }\n return channelDef;\n}\nexport function normalizeFieldDef(fieldDef: FieldDef, channel: Channel) {\n // Drop invalid aggregate\n if (fieldDef.aggregate && !isAggregateOp(fieldDef.aggregate)) {\n const {aggregate, ...fieldDefWithoutAggregate} = fieldDef;\n log.warn(log.message.invalidAggregate(fieldDef.aggregate));\n fieldDef = fieldDefWithoutAggregate;\n }\n\n // Normalize Time Unit\n if (fieldDef.timeUnit) {\n fieldDef = {\n ...fieldDef,\n timeUnit: normalizeTimeUnit(fieldDef.timeUnit)\n };\n }\n\n // Normalize bin\n if (fieldDef.bin) {\n fieldDef = {\n ...fieldDef,\n bin: normalizeBin(fieldDef.bin, channel)\n };\n }\n\n // Normalize Type\n if (fieldDef.type) {\n const fullType = getFullName(fieldDef.type);\n if (fieldDef.type !== fullType) {\n // convert short type to full type\n fieldDef = {\n ...fieldDef,\n type: fullType\n };\n }\n if (fieldDef.type !== 'quantitative') {\n if (isCountingAggregateOp(fieldDef.aggregate)) {\n log.warn(log.message.invalidFieldTypeForCountAggregate(fieldDef.type, fieldDef.aggregate));\n fieldDef = {\n ...fieldDef,\n type: 'quantitative'\n };\n }\n }\n } else {\n // If type is empty / invalid, then augment with default type\n const newType = defaultType(fieldDef, channel);\n log.warn(log.message.emptyOrInvalidFieldType(fieldDef.type, channel, newType));\n fieldDef = {\n ...fieldDef,\n type: newType\n };\n }\n\n const {compatible, warning} = channelCompatibility(fieldDef, channel);\n if (!compatible) {\n log.warn(warning);\n }\n return fieldDef;\n}\n\nexport function normalizeBin(bin: BinParams|boolean, channel: Channel) {\n if (isBoolean(bin)) {\n return {maxbins: autoMaxBins(channel)};\n } else if (!bin.maxbins && !bin.step) {\n return {...bin, maxbins: autoMaxBins(channel)};\n } else {\n return bin;\n }\n}\n\nconst COMPATIBLE = {compatible: true};\nexport function channelCompatibility(fieldDef: FieldDef, channel: Channel): {compatible: boolean; warning?: string;} {\n const type = fieldDef.type;\n\n switch (channel) {\n case 'row':\n case 'column':\n if (isContinuous(fieldDef)) {\n return {\n compatible: false,\n warning: log.message.facetChannelShouldBeDiscrete(channel)\n };\n }\n return COMPATIBLE;\n\n case 'x':\n case 'y':\n case 'color':\n case 'fill':\n case 'stroke':\n case 'text':\n case 'detail':\n case 'key':\n case 'tooltip':\n case 'href':\n return COMPATIBLE;\n\n case 'longitude':\n case 'longitude2':\n case 'latitude':\n case 'latitude2':\n if (type !== QUANTITATIVE) {\n return {\n compatible: false,\n warning: `Channel ${channel} should be used with a quantitative field only, not ${fieldDef.type} field.`\n };\n }\n return COMPATIBLE;\n\n case 'opacity':\n case 'size':\n case 'x2':\n case 'y2':\n if ((type === 'nominal' && !fieldDef['sort']) || type === 'geojson') {\n return {\n compatible: false,\n warning: `Channel ${channel} should not be used with an unsorted discrete field.`\n };\n }\n return COMPATIBLE;\n\n case 'shape':\n if (fieldDef.type !== 'nominal' && fieldDef.type !== 'geojson') {\n return {\n compatible: false,\n warning: 'Shape channel should be used with only either nominal or geojson data'\n };\n }\n return COMPATIBLE;\n\n case 'order':\n if (fieldDef.type === 'nominal' && !('sort' in fieldDef)) {\n return {\n compatible: false,\n warning: `Channel order is inappropriate for nominal field, which has no inherent order.`\n };\n }\n return COMPATIBLE;\n }\n throw new Error('channelCompatability not implemented for channel ' + channel);\n}\n\nexport function isNumberFieldDef(fieldDef: FieldDef) {\n return fieldDef.type === 'quantitative' || !!fieldDef.bin;\n}\n\nexport function isTimeFieldDef(fieldDef: FieldDef) {\n return fieldDef.type === 'temporal' || !!fieldDef.timeUnit;\n}\n\n\n/**\n * Getting a value associated with a fielddef.\n * Convert the value to Vega expression if applicable (for datetime object, or string if the field def is temporal or has timeUnit)\n */\nexport function valueExpr(\n v: number | string | boolean | DateTime,\n {timeUnit, type, time, undefinedIfExprNotRequired}: {\n timeUnit: TimeUnit,\n type?: Type,\n time?: boolean\n undefinedIfExprNotRequired?: boolean\n }\n): string {\n\n let expr = undefined;\n if (isDateTime(v)) {\n expr = dateTimeExpr(v, true);\n } else if (isString(v) || isNumber(v)) {\n if (timeUnit || type === 'temporal') {\n if (isLocalSingleTimeUnit(timeUnit)) {\n expr = dateTimeExpr({[timeUnit]: v}, true);\n } else if (isUtcSingleTimeUnit(timeUnit)) {\n // FIXME is this really correct?\n expr = valueExpr(v, {timeUnit: getLocalTimeUnit(timeUnit)});\n } else {\n // just pass the string to date function (which will call JS Date.parse())\n expr = `datetime(${JSON.stringify(v)})`;\n }\n }\n }\n if (expr) {\n return time ? `time(${expr})` : expr;\n }\n // number or boolean or normal string\n return undefinedIfExprNotRequired ? undefined : JSON.stringify(v);\n}\n\n/**\n * Standardize value array -- convert each value to Vega expression if applicable\n */\nexport function valueArray(\n fieldDef: FieldDef,\n values: (number | string | boolean | DateTime)[]\n) {\n const {timeUnit, type} = fieldDef;\n return values.map(v => {\n const expr = valueExpr(v, {timeUnit, type, undefinedIfExprNotRequired: true});\n // return signal for the expression if we need an expression\n if (expr !== undefined) {\n return {signal: expr};\n }\n // otherwise just return the original value\n return v;\n });\n}\n","\nimport {isArray} from 'vega-util';\nimport {Channel, CHANNELS, isChannel, supportMark} from './channel';\nimport {FacetMapping} from './facet';\nimport {\n ChannelDef,\n Field,\n FieldDef,\n FieldDefWithCondition,\n getFieldDef,\n hasConditionalFieldDef,\n isConditionalDef,\n isFieldDef,\n isValueDef,\n MarkPropFieldDef,\n normalize,\n normalizeFieldDef,\n OrderFieldDef,\n PositionFieldDef,\n TextFieldDef,\n ValueDef,\n ValueDefWithCondition\n} from './fielddef';\nimport * as log from './log';\nimport {Mark} from './mark';\nimport {Type} from './type';\nimport {contains, keys, some} from './util';\n\nexport interface Encoding {\n /**\n * X coordinates of the marks, or width of horizontal `\"bar\"` and `\"area\"`.\n */\n x?: PositionFieldDef | ValueDef;\n\n /**\n * Y coordinates of the marks, or height of vertical `\"bar\"` and `\"area\"`.\n */\n y?: PositionFieldDef | ValueDef;\n\n /**\n * X2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n // TODO: Ham need to add default behavior\n x2?: FieldDef | ValueDef;\n\n /**\n * Y2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n // TODO: Ham need to add default behavior\n y2?: FieldDef | ValueDef;\n\n\n /**\n * Longitude position of geographically projected marks.\n */\n longitude?: FieldDef;\n\n /**\n * Latitude position of geographically projected marks.\n */\n latitude?: FieldDef;\n\n /**\n * Longitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n longitude2?: FieldDef;\n\n /**\n * Latitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n latitude2?: FieldDef;\n\n /**\n * Color of the marks – either fill or stroke color based on the `filled` property of mark definition.\n * By default, `color` represents fill color for `\"area\"`, `\"bar\"`, `\"tick\"`,\n * `\"text\"`, `\"trail\"`, `\"circle\"`, and `\"square\"` / stroke color for `\"line\"` and `\"point\"`.\n *\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_\n * 1) For fine-grained control over both fill and stroke colors of the marks, please use the `fill` and `stroke` channels. If either `fill` or `stroke` channel is specified, `color` channel will be ignored.\n * 2) See the scale documentation for more information about customizing [color scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme).\n */\n color?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * Fill color of the marks.\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_ When using `fill` channel, `color ` channel will be ignored. To customize both fill and stroke, please use `fill` and `stroke` channels (not `fill` and `color`).\n */\n fill?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n\n /**\n * Stroke color of the marks.\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_ When using `stroke` channel, `color ` channel will be ignored. To customize both stroke and fill, please use `stroke` and `fill` channels (not `stroke` and `color`).\n */\n stroke?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n\n /**\n * Opacity of the marks – either can be a value or a range.\n *\n * __Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `opacity` property.\n */\n opacity?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * Size of the mark.\n * - For `\"point\"`, `\"square\"` and `\"circle\"`, – the symbol size, or pixel area of the mark.\n * - For `\"bar\"` and `\"tick\"` – the bar and tick's size.\n * - For `\"text\"` – the text's font size.\n * - Size is unsupported for `\"line\"`, `\"area\"`, and `\"rect\"`. (Use `\"trail\"` instead of line with varying size)\n */\n size?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * For `point` marks the supported values are\n * `\"circle\"` (default), `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`,\n * or `\"triangle-down\"`, or else a custom SVG path string.\n * For `geoshape` marks it should be a field definition of the geojson data\n *\n * __Default value:__ If undefined, the default shape depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#point-config)'s `shape` property.\n */\n shape?: FieldDefWithCondition> | ValueDefWithCondition>; // TODO: maybe distinguish ordinal-only\n\n /**\n * Additional levels of detail for grouping data in aggregate views and\n * in line, trail, and area marks without mapping data to a specific visual channel.\n */\n detail?: FieldDef | FieldDef[];\n\n /**\n * A data field to use as a unique key for data binding. When a visualization’s data is updated, the key value will be used to match data elements to existing mark instances. Use a key channel to enable object constancy for transitions over dynamic data.\n */\n key?: FieldDef;\n\n /**\n * Text of the `text` mark.\n */\n text?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * The tooltip text to show upon mouse hover.\n */\n tooltip?: FieldDefWithCondition> | ValueDefWithCondition> | TextFieldDef[];\n\n /**\n * A URL to load upon mouse click.\n */\n href?: FieldDefWithCondition> | ValueDefWithCondition>;\n\n /**\n * Order of the marks.\n * - For stacked marks, this `order` channel encodes [stack order](https://vega.github.io/vega-lite/docs/stack.html#order).\n * - For line and trail marks, this `order` channel encodes order of data points in the lines. This can be useful for creating [a connected scatterplot](https://vega.github.io/vega-lite/examples/connected_scatterplot.html). Setting `order` to `{\"value\": null}` makes the line marks use the original order in the data sources.\n * - Otherwise, this `order` channel encodes layer order of the marks.\n *\n * __Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping.\n */\n order?: OrderFieldDef | OrderFieldDef[] | ValueDef;\n}\n\nexport interface EncodingWithFacet extends Encoding, FacetMapping {}\n\nexport function channelHasField(encoding: EncodingWithFacet, channel: Channel): boolean {\n const channelDef = encoding && encoding[channel];\n if (channelDef) {\n if (isArray(channelDef)) {\n return some(channelDef, (fieldDef) => !!fieldDef.field);\n } else {\n return isFieldDef(channelDef) || hasConditionalFieldDef(channelDef);\n }\n }\n return false;\n}\n\n\nexport function isAggregate(encoding: EncodingWithFacet) {\n return some(CHANNELS, (channel) => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n if (isArray(channelDef)) {\n return some(channelDef, (fieldDef) => !!fieldDef.aggregate);\n } else {\n const fieldDef = getFieldDef(channelDef);\n return fieldDef && !!fieldDef.aggregate;\n }\n }\n return false;\n });\n}\n\nexport function normalizeEncoding(encoding: Encoding, mark: Mark): Encoding {\n return keys(encoding).reduce((normalizedEncoding: Encoding, channel: Channel | string) => {\n if (!isChannel(channel)) {\n // Drop invalid channel\n log.warn(log.message.invalidEncodingChannel(channel));\n return normalizedEncoding;\n }\n\n if (!supportMark(channel, mark)) {\n // Drop unsupported channel\n\n log.warn(log.message.incompatibleChannel(channel, mark));\n return normalizedEncoding;\n }\n\n // Drop line's size if the field is aggregated.\n if (channel === 'size' && mark === 'line') {\n const fieldDef = getFieldDef(encoding[channel]);\n if (fieldDef && fieldDef.aggregate) {\n log.warn(log.message.LINE_WITH_VARYING_SIZE);\n return normalizedEncoding;\n }\n }\n\n // Drop color if either fill or stroke is specified\n if (channel === 'color' && ('fill' in encoding || 'stroke' in encoding) ) {\n log.warn(log.message.droppingColor('encoding', {fill: 'fill' in encoding, stroke: 'stroke' in encoding}));\n return normalizedEncoding;\n }\n\n const channelDef = encoding[channel];\n if (\n channel === 'detail' ||\n (channel === 'order' && !isArray(channelDef) && !isValueDef(channelDef)) ||\n (channel === 'tooltip' && isArray(channelDef))\n ) {\n if (channelDef) {\n // Array of fieldDefs for detail channel (or production rule)\n normalizedEncoding[channel] = (isArray(channelDef) ? channelDef : [channelDef])\n .reduce((defs: FieldDef[], fieldDef: FieldDef) => {\n if (!isFieldDef(fieldDef)) {\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n } else {\n defs.push(normalizeFieldDef(fieldDef, channel));\n }\n return defs;\n }, []);\n }\n } else {\n\n const fieldDef = getFieldDef(encoding[channel]);\n if (fieldDef && contains([Type.LATITUDE, Type.LONGITUDE], fieldDef.type)) {\n const {[channel]: _, ...newEncoding} = normalizedEncoding;\n const newChannel = channel === 'x' ? 'longitude' :\n channel === 'y' ? 'latitude' :\n channel === 'x2' ? 'longitude2' :\n channel === 'y2' ? 'latitude2' : undefined;\n log.warn(log.message.latLongDeprecated(channel, fieldDef.type, newChannel));\n return {\n ...newEncoding,\n [newChannel]: {\n ...normalize(fieldDef as any, channel),\n type: 'quantitative'\n }\n };\n }\n\n if (!isFieldDef(channelDef) && !isValueDef(channelDef) && !isConditionalDef(channelDef)) {\n log.warn(log.message.emptyFieldDef(channelDef, channel));\n return normalizedEncoding;\n }\n normalizedEncoding[channel] = normalize(channelDef as ChannelDef, channel);\n }\n return normalizedEncoding;\n }, {});\n}\n\n\nexport function isRanged(encoding: EncodingWithFacet) {\n return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2));\n}\n\nexport function fieldDefs(encoding: EncodingWithFacet): FieldDef[] {\n const arr: FieldDef[] = [];\n CHANNELS.forEach(function(channel) {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((def) => {\n if (isFieldDef(def)) {\n arr.push(def);\n } else if (hasConditionalFieldDef(def)) {\n arr.push(def.condition);\n }\n });\n }\n });\n return arr;\n}\n\nexport function forEach(mapping: any,\n f: (fd: FieldDef, c: Channel) => void,\n thisArg?: any) {\n if (!mapping) {\n return;\n }\n\n for (const channel of keys(mapping)) {\n if (isArray(mapping[channel])) {\n mapping[channel].forEach(function(channelDef: ChannelDef) {\n f.call(thisArg, channelDef, channel);\n });\n } else {\n f.call(thisArg, mapping[channel], channel);\n }\n }\n}\n\nexport function reduce(mapping: U,\n f: (acc: any, fd: FieldDef, c: Channel) => U,\n init: T, thisArg?: any) {\n if (!mapping) {\n return init;\n }\n\n return keys(mapping).reduce((r, channel) => {\n const map = mapping[channel];\n if (isArray(map)) {\n return map.reduce((r1: T, channelDef: ChannelDef) => {\n return f.call(thisArg, r1, channelDef, channel);\n }, r);\n } else {\n return f.call(thisArg, r, map, channel);\n }\n }, init);\n}\n","import {NonPositionChannel} from '../channel';\nimport {MarkConfig} from '../mark';\n\nexport function getMarkSpecificConfigMixins(markSpecificConfig: MarkConfig, channel: NonPositionChannel) {\n const value = markSpecificConfig[channel];\n return value !== undefined ? {[channel]: {value}} : {};\n}\n","import {isNumber} from 'vega-util';\nimport {Channel} from '../channel';\nimport {Config} from '../config';\nimport {reduce} from '../encoding';\nimport {AggregatedFieldDef, BinTransform, CalculateTransform, TimeUnitTransform} from '../transform';\nimport {Encoding, forEach} from './../encoding';\nimport {Field, FieldDef, isContinuous, isFieldDef, PositionFieldDef, vgField} from './../fielddef';\nimport * as log from './../log';\nimport {MarkConfig} from './../mark';\nimport {GenericUnitSpec, NormalizedLayerSpec} from './../spec';\nimport {Orient} from './../vega.schema';\nimport {getMarkSpecificConfigMixins} from './common';\n\n\nexport const BOXPLOT: 'box-plot' = 'box-plot';\nexport type BOXPLOT = typeof BOXPLOT;\nexport type BoxPlotStyle = 'boxWhisker' | 'box' | 'boxMid';\n\n\nexport interface BoxPlotDef {\n /**\n * Type of the mark. For box plots, this should always be `\"box-plot\"`.\n * [boxplot](https://vega.github.io/vega-lite/docs/compositemark.html#boxplot)\n */\n type: BOXPLOT;\n\n /**\n * Orientation of the box plot. This is normally automatically determined, but can be specified when the orientation is ambiguous and cannot be automatically determined.\n */\n orient?: Orient;\n\n /**\n * Extent is used to determine where the whiskers extend to. The options are\n * - `\"min-max\": min and max are the lower and upper whiskers respectively.\n * - A scalar (integer or floating point number) that will be multiplied by the IQR and the product will be added to the third quartile to get the upper whisker and subtracted from the first quartile to get the lower whisker.\n * __Default value:__ `\"1.5\"`.\n */\n extent?: 'min-max' | number;\n}\n\nexport function isBoxPlotDef(mark: BOXPLOT | BoxPlotDef): mark is BoxPlotDef {\n return !!mark['type'];\n}\n\nexport const BOXPLOT_STYLES: BoxPlotStyle[] = ['boxWhisker', 'box', 'boxMid'];\n\nexport interface BoxPlotConfig extends MarkConfig {\n /** Size of the box and mid tick of a box plot */\n size?: number;\n /** The default extent, which is used to determine where the whiskers extend to. The options are\n * - `\"min-max\": min and max are the lower and upper whiskers respectively.\n * - `\"number\": A scalar (integer or floating point number) that will be multiplied by the IQR and the product will be added to the third quartile to get the upper whisker and subtracted from the first quartile to get the lower whisker.\n */\n extent?: 'min-max' | number;\n}\n\nexport interface BoxPlotConfigMixins {\n /**\n * Box Config\n * @hide\n */\n box?: BoxPlotConfig;\n\n /**\n * @hide\n */\n boxWhisker?: MarkConfig;\n\n /**\n * @hide\n */\n boxMid?: MarkConfig;\n}\n\nexport const VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX: {\n [k in keyof BoxPlotConfigMixins]?: (keyof BoxPlotConfigMixins[k])[]\n} = {\n box: ['size', 'color', 'extent'],\n boxWhisker: ['color'],\n boxMid: ['color']\n};\n\nconst supportedChannels: Channel[] = ['x', 'y', 'color', 'detail', 'opacity', 'size'];\nexport function filterUnsupportedChannels(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>): GenericUnitSpec, BOXPLOT | BoxPlotDef> {\n return {\n ...spec,\n encoding: reduce(spec.encoding, (newEncoding, fieldDef, channel) => {\n if (supportedChannels.indexOf(channel) > -1) {\n newEncoding[channel] = fieldDef;\n } else {\n log.warn(log.message.incompatibleChannel(channel, BOXPLOT));\n }\n return newEncoding;\n }, {}),\n };\n}\n\nexport function normalizeBoxPlot(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>, config: Config): NormalizedLayerSpec {\n spec = filterUnsupportedChannels(spec);\n // TODO: use selection\n const {mark, encoding, selection, projection: _p, ...outerSpec} = spec;\n\n let kIQRScalar: number = undefined;\n if (isNumber(config.box.extent)) {\n kIQRScalar = config.box.extent;\n }\n\n if (isBoxPlotDef(mark)) {\n if (mark.extent) {\n if(mark.extent === 'min-max') {\n kIQRScalar = undefined;\n }\n }\n }\n\n const orient: Orient = boxOrient(spec);\n const {transform, continuousAxisChannelDef, continuousAxis, encodingWithoutContinuousAxis} = boxParams(spec, orient, kIQRScalar);\n\n const {color, size, ...encodingWithoutSizeColorAndContinuousAxis} = encodingWithoutContinuousAxis;\n\n // Size encoding or the default config.box.size is applied to box and boxMid\n const sizeMixins = size ? {size} : getMarkSpecificConfigMixins(config.box, 'size');\n\n const continuousAxisScaleAndAxis = {};\n if (continuousAxisChannelDef.scale) {\n continuousAxisScaleAndAxis['scale'] = continuousAxisChannelDef.scale;\n }\n if (continuousAxisChannelDef.axis) {\n continuousAxisScaleAndAxis['axis'] = continuousAxisChannelDef.axis;\n }\n\n return {\n ...outerSpec,\n transform,\n layer: [\n { // lower whisker\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n encoding: {\n [continuousAxis]: {\n field: 'lower_whisker_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type,\n ...continuousAxisScaleAndAxis\n },\n [continuousAxis + '2']: {\n field: 'lower_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutSizeColorAndContinuousAxis,\n ...getMarkSpecificConfigMixins(config.boxWhisker, 'color')\n }\n }, { // upper whisker\n mark: {\n type: 'rule',\n style: 'boxWhisker'\n },\n encoding: {\n [continuousAxis]: {\n field: 'upper_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n [continuousAxis + '2']: {\n field: 'upper_whisker_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutSizeColorAndContinuousAxis,\n ...getMarkSpecificConfigMixins(config.boxWhisker, 'color')\n }\n }, { // box (q1 to q3)\n ...(selection ? {selection} : {}),\n mark: {\n type: 'bar',\n style: 'box'\n },\n encoding: {\n [continuousAxis]: {\n field: 'lower_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n [continuousAxis + '2']: {\n field: 'upper_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutContinuousAxis,\n ...(encodingWithoutContinuousAxis.color ? {} : getMarkSpecificConfigMixins(config.box, 'color')),\n ...sizeMixins,\n }\n }, { // mid tick\n mark: {\n type: 'tick',\n style: 'boxMid'\n },\n encoding: {\n [continuousAxis]: {\n field: 'mid_box_' + continuousAxisChannelDef.field,\n type: continuousAxisChannelDef.type\n },\n ...encodingWithoutSizeColorAndContinuousAxis,\n ...getMarkSpecificConfigMixins(config.boxMid, 'color'),\n ...sizeMixins,\n }\n }\n ]\n };\n}\n\nfunction boxOrient(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>): Orient {\n const {mark: mark, encoding: encoding, projection: _p, ..._outerSpec} = spec;\n\n if (isFieldDef(encoding.x) && isContinuous(encoding.x)) {\n // x is continuous\n if (isFieldDef(encoding.y) && isContinuous(encoding.y)) {\n // both x and y are continuous\n if (encoding.x.aggregate === undefined && encoding.y.aggregate === BOXPLOT) {\n return 'vertical';\n } else if (encoding.y.aggregate === undefined && encoding.x.aggregate === BOXPLOT) {\n return 'horizontal';\n } else if (encoding.x.aggregate === BOXPLOT && encoding.y.aggregate === BOXPLOT) {\n throw new Error('Both x and y cannot have aggregate');\n } else {\n if (isBoxPlotDef(mark) && mark.orient) {\n return mark.orient;\n }\n\n // default orientation = vertical\n return 'vertical';\n }\n }\n\n // x is continuous but y is not\n return 'horizontal';\n } else if (isFieldDef(encoding.y) && isContinuous(encoding.y)) {\n // y is continuous but x is not\n return 'vertical';\n } else {\n // Neither x nor y is continuous.\n throw new Error('Need a valid continuous axis for boxplots');\n }\n}\n\n\nfunction boxContinousAxis(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>, orient: Orient) {\n const {mark: mark, encoding: encoding, projection: _p, ..._outerSpec} = spec;\n\n let continuousAxisChannelDef: PositionFieldDef;\n let continuousAxis: 'x' | 'y';\n\n if (orient === 'vertical') {\n continuousAxis = 'y';\n continuousAxisChannelDef = encoding.y as FieldDef; // Safe to cast because if y is not continuous fielddef, the orient would not be vertical.\n } else {\n continuousAxis = 'x';\n continuousAxisChannelDef = encoding.x as FieldDef; // Safe to cast because if x is not continuous fielddef, the orient would not be horizontal.\n }\n\n if (continuousAxisChannelDef && continuousAxisChannelDef.aggregate) {\n const {aggregate, ...continuousAxisWithoutAggregate} = continuousAxisChannelDef;\n if (aggregate !== BOXPLOT) {\n log.warn(`Continuous axis should not have customized aggregation function ${aggregate}`);\n }\n continuousAxisChannelDef = continuousAxisWithoutAggregate;\n }\n\n return {\n continuousAxisChannelDef,\n continuousAxis\n };\n}\n\nfunction boxParams(spec: GenericUnitSpec, BOXPLOT | BoxPlotDef>, orient: Orient, kIQRScalar: 'min-max' | number) {\n\n const {continuousAxisChannelDef, continuousAxis} = boxContinousAxis(spec, orient);\n const encoding = spec.encoding;\n\n const isMinMax = kIQRScalar === undefined;\n const aggregate: AggregatedFieldDef[] = [\n {\n op: 'q1',\n field: continuousAxisChannelDef.field,\n as: 'lower_box_' + continuousAxisChannelDef.field\n },\n {\n op: 'q3',\n field: continuousAxisChannelDef.field,\n as: 'upper_box_' + continuousAxisChannelDef.field\n },\n {\n op: 'median',\n field: continuousAxisChannelDef.field,\n as: 'mid_box_' + continuousAxisChannelDef.field\n }\n ];\n let postAggregateCalculates: CalculateTransform[] = [];\n\n aggregate.push({\n op: 'min',\n field: continuousAxisChannelDef.field,\n as: (isMinMax ? 'lower_whisker_' : 'min_') + continuousAxisChannelDef.field\n });\n aggregate.push({\n op: 'max',\n field: continuousAxisChannelDef.field,\n as: (isMinMax ? 'upper_whisker_' : 'max_') + continuousAxisChannelDef.field\n });\n\n if (!isMinMax) {\n postAggregateCalculates = [\n {\n calculate: `datum.upper_box_${continuousAxisChannelDef.field} - datum.lower_box_${continuousAxisChannelDef.field}`,\n as: 'iqr_' + continuousAxisChannelDef.field\n },\n {\n calculate: `min(datum.upper_box_${continuousAxisChannelDef.field} + datum.iqr_${continuousAxisChannelDef.field} * ${kIQRScalar}, datum.max_${continuousAxisChannelDef.field})`,\n as: 'upper_whisker_' + continuousAxisChannelDef.field\n },\n {\n calculate: `max(datum.lower_box_${continuousAxisChannelDef.field} - datum.iqr_${continuousAxisChannelDef.field} * ${kIQRScalar}, datum.min_${continuousAxisChannelDef.field})`,\n as: 'lower_whisker_' + continuousAxisChannelDef.field\n }\n ];\n }\n\n const groupby: string[] = [];\n const bins: BinTransform[] = [];\n const timeUnits: TimeUnitTransform[] = [];\n\n const encodingWithoutContinuousAxis: Encoding = {};\n forEach(encoding, (channelDef, channel) => {\n if (channel === continuousAxis) {\n // Skip continuous axis as we already handle it separately\n return;\n }\n if (isFieldDef(channelDef)) {\n if (channelDef.aggregate && channelDef.aggregate !== BOXPLOT) {\n aggregate.push({\n op: channelDef.aggregate,\n field: channelDef.field,\n as: vgField(channelDef)\n });\n } else if (channelDef.aggregate === undefined) {\n const transformedField = vgField(channelDef);\n\n // Add bin or timeUnit transform if applicable\n const bin = channelDef.bin;\n if (bin) {\n const {field} = channelDef;\n bins.push({bin, field, as: transformedField});\n } else if (channelDef.timeUnit) {\n const {timeUnit, field} = channelDef;\n timeUnits.push({timeUnit, field, as: transformedField});\n }\n\n groupby.push(transformedField);\n }\n // now the field should refer to post-transformed field instead\n encodingWithoutContinuousAxis[channel] = {\n field: vgField(channelDef),\n type: channelDef.type\n };\n } else {\n // For value def, just copy\n encodingWithoutContinuousAxis[channel] = encoding[channel];\n }\n });\n\n return {\n transform: [].concat(\n bins,\n timeUnits,\n [{aggregate, groupby}],\n postAggregateCalculates\n ),\n continuousAxisChannelDef,\n continuousAxis,\n encodingWithoutContinuousAxis\n };\n}\n","import {Config} from './../config';\nimport {AnyMark, isMarkDef} from './../mark';\nimport {GenericUnitSpec, NormalizedLayerSpec} from './../spec';\nimport {BOXPLOT, BoxPlotConfigMixins, BoxPlotDef, normalizeBoxPlot, VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX} from './boxplot';\nimport {ERRORBAR, normalizeErrorBar} from './errorbar';\n\n// This package import below makes the generated .d.ts file compatible with\n// Typescript 2.7 so that libraries requiring us can use Typedoc (which\n// currently is limited to Typescript 2.7). This comment and import can be\n// removed when Typedoc is updated to Typescript 2.9 or later. See\n// https://github.com/vega/vega-lite/issues/3862 for more details.\nimport * as boxplot from './boxplot';\n\nexport {BoxPlotConfig} from './boxplot';\nexport type UnitNormalizer = (spec: GenericUnitSpec, config: Config)=> NormalizedLayerSpec;\n\n/**\n * Registry index for all composite mark's normalizer\n */\nconst normalizerRegistry: {[mark: string]: UnitNormalizer} = {};\n\nexport function add(mark: string, normalizer: UnitNormalizer) {\n normalizerRegistry[mark] = normalizer;\n}\n\nexport function remove(mark: string) {\n delete normalizerRegistry[mark];\n}\n\nexport type CompositeMark = BOXPLOT | ERRORBAR;\n\nexport type CompositeMarkDef = BoxPlotDef;\n\nexport type CompositeAggregate = BOXPLOT;\n\nexport const COMPOSITE_MARK_STYLES = boxplot.BOXPLOT_STYLES;\nexport type CompositeMarkStyle = typeof COMPOSITE_MARK_STYLES[0];\n\nexport interface CompositeMarkConfigMixins extends BoxPlotConfigMixins {}\n\nexport const VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = {\n ...VL_ONLY_BOXPLOT_CONFIG_PROPERTY_INDEX\n};\n\nadd(BOXPLOT, normalizeBoxPlot);\nadd(ERRORBAR, normalizeErrorBar);\n\n/**\n * Transform a unit spec with composite mark into a normal layer spec.\n */\nexport function normalize(\n // This GenericUnitSpec has any as Encoding because unit specs with composite mark can have additional encoding channels.\n spec: GenericUnitSpec,\n config: Config\n ): NormalizedLayerSpec {\n\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n const normalizer = normalizerRegistry[mark];\n if (normalizer) {\n return normalizer(spec, config);\n }\n\n throw new Error(`Invalid mark type \"${mark}\"`);\n}\n","import {Field} from '../fielddef';\nimport {Encoding} from './../encoding';\nimport {GenericUnitSpec, NormalizedLayerSpec} from './../spec';\n\n\nexport const ERRORBAR: 'error-bar' = 'error-bar';\nexport type ERRORBAR = typeof ERRORBAR;\n\nexport function normalizeErrorBar(spec: GenericUnitSpec, ERRORBAR>): NormalizedLayerSpec {\n // TODO: use selection\n const {mark: _m, selection: _sel, projection: _p, encoding, ...outerSpec} = spec;\n const {size: _s, ...encodingWithoutSize} = encoding;\n const {x2: _x2, y2: _y2, ...encodingWithoutX2Y2} = encoding;\n const {x: _x, y: _y, ...encodingWithoutX_X2_Y_Y2} = encodingWithoutX2Y2;\n\n if (!encoding.x2 && !encoding.y2) {\n throw new Error('Neither x2 or y2 provided');\n }\n\n return {\n ...outerSpec,\n layer: [\n {\n mark: 'rule',\n encoding: encodingWithoutSize\n },{ // Lower tick\n mark: 'tick',\n encoding: encodingWithoutX2Y2\n }, { // Upper tick\n mark: 'tick',\n encoding: encoding.x2 ? {\n x: encoding.x2,\n y: encoding.y,\n ...encodingWithoutX_X2_Y_Y2\n } : {\n x: encoding.x,\n y: encoding.y2,\n ...encodingWithoutX_X2_Y_Y2\n }\n }\n ]\n };\n}\n","import {toSet} from 'vega-util';\nimport {BinParams} from './bin';\nimport {Channel, CHANNELS, isColorChannel} from './channel';\nimport {DateTime} from './datetime';\nimport * as log from './log';\nimport {Type, TYPE_INDEX} from './type';\nimport {contains, Flag, flagKeys, keys} from './util';\nimport {ScaleInterpolate, ScaleInterpolateParams} from './vega.schema';\n\nexport namespace ScaleType {\n // Continuous - Quantitative\n export const LINEAR: 'linear' = 'linear';\n export const BIN_LINEAR: 'bin-linear' = 'bin-linear';\n export const LOG: 'log' = 'log';\n export const POW: 'pow' = 'pow';\n export const SQRT: 'sqrt' = 'sqrt';\n // Continuous - Time\n export const TIME: 'time' = 'time';\n export const UTC: 'utc' = 'utc';\n // sequential\n export const SEQUENTIAL: 'sequential' = 'sequential';\n\n // Quantile, Quantize, threshold\n export const QUANTILE: 'quantile' = 'quantile';\n export const QUANTIZE: 'quantize' = 'quantize';\n export const THRESHOLD: 'threshold' = 'threshold';\n\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const BIN_ORDINAL: 'bin-ordinal' = 'bin-ordinal';\n export const POINT: 'point' = 'point';\n export const BAND: 'band' = 'band';\n}\n\nexport type ScaleType = typeof ScaleType.LINEAR | typeof ScaleType.BIN_LINEAR |\n typeof ScaleType.LOG | typeof ScaleType.POW | typeof ScaleType.SQRT |\n typeof ScaleType.TIME | typeof ScaleType.UTC |\n // TODO: add 'quantize', 'quantile', 'threshold' back when we really support them\n typeof ScaleType.SEQUENTIAL | // typeof ScaleType.QUANTILE | typeof ScaleType.QUANTIZE | typeof ScaleType.THRESHOLD |\n typeof ScaleType.ORDINAL | typeof ScaleType.BIN_ORDINAL | typeof ScaleType.POINT | typeof ScaleType.BAND;\n\n\n/**\n * Index for scale categories -- only scale of the same categories can be merged together.\n * Current implementation is trying to be conservative and avoid merging scale type that might not work together\n */\nconst SCALE_CATEGORY_INDEX: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleType]: ScaleType | 'numeric' | 'ordinal-position'\n} = {\n linear: 'numeric',\n log: 'numeric',\n pow: 'numeric',\n sqrt: 'numeric',\n 'bin-linear': 'bin-linear', // TODO: should bin-linear support merging with other\n time: 'time',\n utc: 'time',\n sequential: 'sequential',\n ordinal: 'ordinal',\n 'bin-ordinal': 'bin-ordinal', // TODO: should bin-ordinal support merging with other\n point: 'ordinal-position',\n band: 'ordinal-position'\n};\n\nexport const SCALE_TYPES = keys(SCALE_CATEGORY_INDEX) as ScaleType[];\n\n/**\n * Whether the two given scale types can be merged together.\n */\nexport function scaleCompatible(scaleType1: ScaleType, scaleType2: ScaleType) {\n const scaleCategory1 = SCALE_CATEGORY_INDEX[scaleType1];\n const scaleCategory2 = SCALE_CATEGORY_INDEX[scaleType2];\n return scaleCategory1 === scaleCategory2 ||\n (scaleCategory1 === 'ordinal-position' && scaleCategory2 === 'time') ||\n (scaleCategory2 === 'ordinal-position' && scaleCategory1 === 'time');\n}\n\n/**\n * Index for scale precedence -- high score = higher priority for merging.\n */\nconst SCALE_PRECEDENCE_INDEX: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleType]: number\n} = {\n // numeric\n linear: 0,\n log: 1,\n pow: 1,\n sqrt: 1,\n // time\n time: 0,\n utc: 0,\n // ordinal-position -- these have higher precedence than continuous scales as they support more types of data\n point: 10,\n band: 11, // band has higher precedence as it is better for interaction\n // non grouped types\n 'bin-linear': 0,\n sequential: 0,\n ordinal: 0,\n 'bin-ordinal': 0,\n};\n\n/**\n * Return scale categories -- only scale of the same categories can be merged together.\n */\nexport function scaleTypePrecedence(scaleType: ScaleType): number {\n return SCALE_PRECEDENCE_INDEX[scaleType];\n}\n\nexport const CONTINUOUS_TO_CONTINUOUS_SCALES: ScaleType[] = ['linear', 'bin-linear', 'log', 'pow', 'sqrt', 'time', 'utc'];\nconst CONTINUOUS_TO_CONTINUOUS_INDEX = toSet(CONTINUOUS_TO_CONTINUOUS_SCALES);\n\nexport const CONTINUOUS_DOMAIN_SCALES: ScaleType[] = CONTINUOUS_TO_CONTINUOUS_SCALES.concat(['sequential' /* TODO add 'quantile', 'quantize', 'threshold'*/]);\nconst CONTINUOUS_DOMAIN_INDEX = toSet(CONTINUOUS_DOMAIN_SCALES);\n\nexport const DISCRETE_DOMAIN_SCALES: ScaleType[] = ['ordinal', 'bin-ordinal', 'point', 'band'];\nconst DISCRETE_DOMAIN_INDEX = toSet(DISCRETE_DOMAIN_SCALES);\n\nconst BIN_SCALES_INDEX = toSet(['bin-linear', 'bin-ordinal']);\n\nexport const TIME_SCALE_TYPES: ScaleType[] = ['time', 'utc'];\n\nexport function hasDiscreteDomain(type: ScaleType): type is 'ordinal' | 'bin-ordinal' | 'point' | 'band' {\n return type in DISCRETE_DOMAIN_INDEX;\n}\n\nexport function isBinScale(type: ScaleType): type is 'bin-linear' | 'bin-ordinal' {\n return type in BIN_SCALES_INDEX;\n}\n\nexport function hasContinuousDomain(type: ScaleType):\n type is 'linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc'|\n 'sequential' /* TODO add | 'quantile' | 'quantize' | 'threshold' */ {\n return type in CONTINUOUS_DOMAIN_INDEX;\n}\n\nexport function isContinuousToContinuous(type: ScaleType): type is 'linear' | 'bin-linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc' {\n return type in CONTINUOUS_TO_CONTINUOUS_INDEX;\n}\n\nexport type NiceTime = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year';\n\nexport interface ScaleConfig {\n /**\n * If true, rounds numeric output values to integers.\n * This can be helpful for snapping to the pixel grid.\n * (Only available for `x`, `y`, and `size` scales.)\n */\n round?: boolean;\n\n /**\n * If true, values that exceed the data domain are clamped to either the minimum or maximum range value\n */\n clamp?: boolean;\n /**\n * Default range step for `x` band and point scales of text marks.\n *\n * __Default value:__ `90`\n *\n * @minimum 0\n */\n textXRangeStep?: number; // FIXME: consider if we will rename this \"tableColumnWidth\"\n\n /**\n * Default range step for band and point scales of (1) the `y` channel\n * and (2) the `x` channel when the mark is not `text`.\n *\n * __Default value:__ `21`\n *\n * @minimum 0\n */\n rangeStep?: number | null;\n\n /**\n * Default inner padding for `x` and `y` band-ordinal scales.\n *\n * __Default value:__ `0.1`\n *\n * @minimum 0\n * @maximum 1\n */\n bandPaddingInner?: number;\n\n /**\n * Default outer padding for `x` and `y` band-ordinal scales.\n * If not specified, by default, band scale's paddingOuter is paddingInner/2.\n * @minimum 0\n * @maximum 1\n */\n bandPaddingOuter?: number;\n\n /**\n * Default padding for continuous scales.\n *\n * __Default:__ `5` for continuous x-scale of a vertical bar and continuous y-scale of a horizontal bar.; `0` otherwise.\n *\n * @minimum 0\n */\n continuousPadding?: number;\n\n /**\n * Default outer padding for `x` and `y` point-ordinal scales.\n *\n * __Default value:__ `0.5`\n *\n * @minimum 0\n * @maximum 1\n */\n pointPadding?: number;\n\n /**\n * Use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis.\n *\n * This is equivalent to setting `domain` to `\"unaggregate\"` for aggregated _quantitative_ fields by default.\n *\n * This property only works with aggregate functions that produce values within the raw data domain (`\"mean\"`, `\"average\"`, `\"median\"`, `\"q1\"`, `\"q3\"`, `\"min\"`, `\"max\"`). For other aggregations that produce values outside of the raw data domain (e.g. `\"count\"`, `\"sum\"`), this property is ignored.\n *\n * __Default value:__ `false`\n */\n useUnaggregatedDomain?: boolean;\n\n // nice should depends on type (quantitative or temporal), so\n // let's not make a config.\n\n // Configs for Range\n\n /**\n * The default max value for mapping quantitative fields to bar's size/bandSize.\n *\n * If undefined (default), we will use the scale's `rangeStep` - 1.\n * @minimum 0\n */\n maxBandSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to bar and tick's size/bandSize scale with zero=false.\n *\n * __Default value:__ `2`\n *\n * @minimum 0\n */\n minBandSize?: number;\n\n /**\n * The default max value for mapping quantitative fields to text's size/fontSize.\n *\n * __Default value:__ `40`\n *\n * @minimum 0\n */\n maxFontSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to tick's size/fontSize scale with zero=false\n *\n * __Default value:__ `8`\n *\n * @minimum 0\n */\n minFontSize?: number;\n\n /**\n * Default minimum opacity for mapping a field to opacity.\n *\n * __Default value:__ `0.3`\n *\n * @minimum 0\n * @maximum 1\n */\n minOpacity?: number;\n\n /**\n * Default max opacity for mapping a field to opacity.\n *\n * __Default value:__ `0.8`\n *\n * @minimum 0\n * @maximum 1\n */\n maxOpacity?: number;\n\n\n /**\n * Default minimum value for point size scale with zero=false.\n *\n * __Default value:__ `9`\n *\n * @minimum 0\n */\n minSize?: number;\n\n /**\n * Default max value for point size scale.\n * @minimum 0\n */\n maxSize?: number;\n\n /**\n * Default minimum strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks with zero=false.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n minStrokeWidth?: number;\n\n /**\n * Default max strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks.\n *\n * __Default value:__ `4`\n *\n * @minimum 0\n */\n maxStrokeWidth?: number;\n}\n\nexport const defaultScaleConfig = {\n textXRangeStep: 90,\n rangeStep: 21,\n pointPadding: 0.5,\n bandPaddingInner: 0.1,\n facetSpacing: 16,\n\n minBandSize: 2,\n\n minFontSize: 8,\n maxFontSize: 40,\n\n minOpacity: 0.3,\n maxOpacity: 0.8,\n\n // FIXME: revise if these *can* become ratios of rangeStep\n minSize: 9, // Point size is area. For square point, 9 = 3 pixel ^ 2, not too small!\n\n minStrokeWidth: 1,\n maxStrokeWidth: 4\n};\n\nexport interface SchemeParams {\n /**\n * A color scheme name for sequential/ordinal scales (e.g., `\"category10\"` or `\"viridis\"`).\n *\n * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference.\n */\n name: string;\n\n /**\n * For sequential and diverging schemes only, determines the extent of the color range to use. For example `[0.2, 1]` will rescale the color scheme such that color values in the range _[0, 0.2)_ are excluded from the scheme.\n */\n extent?: number[];\n\n /**\n * The number of colors to use in the scheme. This can be useful for scale types such as `\"quantize\"`, which use the length of the scale range to determine the number of discrete bins for the scale domain.\n *\n * @hide\n */\n count?: number;\n}\n\nexport type SelectionDomain = {\n /**\n * The name of a selection.\n */\n selection: string,\n /**\n * The field name to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html)\n * over multiple fields or encodings.\n */\n field?: string\n} | {\n /**\n * The name of a selection.\n */\n selection: string,\n /**\n * The encoding channel to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html)\n * over multiple fields or encodings.\n */\n encoding?: string\n};\n\nexport type Domain = number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain;\nexport type Scheme = string | SchemeParams;\n\nexport type Range = number[] | string[] | string;\n\nexport function isExtendedScheme(scheme: string | SchemeParams): scheme is SchemeParams {\n return scheme && !!scheme['name'];\n}\n\nexport function isSelectionDomain(domain: Domain): domain is SelectionDomain {\n return domain && domain['selection'];\n}\n\nexport interface Scale {\n /**\n * The type of scale. Vega-Lite supports the following categories of scale types:\n *\n * 1) [**Continuous Scales**](https://vega.github.io/vega-lite/docs/scale.html#continuous) -- mapping continuous domains to continuous output ranges ([`\"linear\"`](https://vega.github.io/vega-lite/docs/scale.html#linear), [`\"pow\"`](https://vega.github.io/vega-lite/docs/scale.html#pow), [`\"sqrt\"`](https://vega.github.io/vega-lite/docs/scale.html#sqrt), [`\"log\"`](https://vega.github.io/vega-lite/docs/scale.html#log), [`\"time\"`](https://vega.github.io/vega-lite/docs/scale.html#time), [`\"utc\"`](https://vega.github.io/vega-lite/docs/scale.html#utc), [`\"sequential\"`](https://vega.github.io/vega-lite/docs/scale.html#sequential)).\n *\n * 2) [**Discrete Scales**](https://vega.github.io/vega-lite/docs/scale.html#discrete) -- mapping discrete domains to discrete ([`\"ordinal\"`](https://vega.github.io/vega-lite/docs/scale.html#ordinal)) or continuous ([`\"band\"`](https://vega.github.io/vega-lite/docs/scale.html#band) and [`\"point\"`](https://vega.github.io/vega-lite/docs/scale.html#point)) output ranges.\n *\n * 3) [**Discretizing Scales**](https://vega.github.io/vega-lite/docs/scale.html#discretizing) -- mapping continuous domains to discrete output ranges ([`\"bin-linear\"`](https://vega.github.io/vega-lite/docs/scale.html#bin-linear) and [`\"bin-ordinal\"`](https://vega.github.io/vega-lite/docs/scale.html#bin-ordinal)).\n *\n * __Default value:__ please see the [scale type table](https://vega.github.io/vega-lite/docs/scale.html#type).\n */\n type?: ScaleType;\n\n /**\n * Customized domain values.\n *\n * For _quantitative_ fields, `domain` can take the form of a two-element array with minimum and maximum values. [Piecewise scales](https://vega.github.io/vega-lite/docs/scale.html#piecewise) can be created by providing a `domain` with more than two entries.\n * If the input field is aggregated, `domain` can also be a string value `\"unaggregated\"`, indicating that the domain should include the raw data values prior to the aggregation.\n *\n * For _temporal_ fields, `domain` can be a two-element array minimum and maximum values, in the form of either timestamps or the [DateTime definition objects](https://vega.github.io/vega-lite/docs/types.html#datetime).\n *\n * For _ordinal_ and _nominal_ fields, `domain` can be an array that lists valid input values.\n *\n * The `selection` property can be used to [interactively determine](https://vega.github.io/vega-lite/docs/selection.html#scale-domains) the scale domain.\n */\n domain?: number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain;\n\n\n // Hide because we might not really need this.\n /**\n * If true, reverses the order of the scale range.\n * __Default value:__ `false`.\n *\n * @hide\n */\n reverse?: boolean;\n\n /**\n * The range of the scale. One of:\n *\n * - A string indicating a [pre-defined named scale range](https://vega.github.io/vega-lite/docs/scale.html#range-config) (e.g., example, `\"symbol\"`, or `\"diverging\"`).\n *\n * - For [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous), two-element array indicating minimum and maximum values, or an array with more than two entries for specifying a [piecewise scale](https://vega.github.io/vega-lite/docs/scale.html#piecewise).\n *\n * - For [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) and [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales, an array of desired output values.\n *\n * __Notes:__\n *\n * 1) For [sequential](https://vega.github.io/vega-lite/docs/scale.html#sequential), [ordinal](https://vega.github.io/vega-lite/docs/scale.html#ordinal), and discretizing color scales, you can also specify a color [`scheme`](https://vega.github.io/vega-lite/docs/scale.html#scheme) instead of `range`.\n *\n * 2) Any directly specified `range` for `x` and `y` channels will be ignored. Range can be customized via the view's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` and `height`) or via [range steps and paddings properties](#range-step) for [band](#band) and [point](#point) scales.\n */\n range?: number[] | string[] | string;\n\n // ordinal\n /**\n * The distance between the starts of adjacent bands or points in [band](https://vega.github.io/vega-lite/docs/scale.html#band) and [point](https://vega.github.io/vega-lite/docs/scale.html#point) scales.\n *\n * If `rangeStep` is `null` or if the view contains the scale's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` for `x` scales and `height` for `y` scales), `rangeStep` will be automatically determined to fit the size of the view.\n *\n * __Default value:__ derived the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `textXRangeStep` (`90` by default) for x-scales of `text` marks and `rangeStep` (`21` by default) for x-scales of other marks and y-scales.\n *\n * __Warning__: If `rangeStep` is `null` and the cardinality of the scale's domain is higher than `width` or `height`, the rangeStep might become less than one pixel and the mark might not appear correctly.\n *\n * @minimum 0\n */\n rangeStep?: number | null;\n\n /**\n * A string indicating a color [scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme) name (e.g., `\"category10\"` or `\"viridis\"`) or a [scheme parameter object](https://vega.github.io/vega-lite/docs/scale.html#scheme-params).\n *\n * Discrete color schemes may be used with [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) or [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales. Continuous color schemes are intended for use with [sequential](https://vega.github.io/vega-lite/docs/scales.html#sequential) scales.\n *\n * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference.\n */\n scheme?: string | SchemeParams;\n\n /**\n * If `true`, rounds numeric output values to integers. This can be helpful for snapping to the pixel grid.\n *\n * __Default value:__ `false`.\n */\n round?: boolean;\n\n /**\n * For _[continuous](https://vega.github.io/vega-lite/docs/scale.html#continuous)_ scales, expands the scale domain to accommodate the specified number of pixels on each of the scale range. The scale range must represent pixels for this parameter to function as intended. Padding adjustment is performed prior to all other adjustments, including the effects of the zero, nice, domainMin, and domainMax properties.\n *\n * For _[band](https://vega.github.io/vega-lite/docs/scale.html#band)_ scales, shortcut for setting `paddingInner` and `paddingOuter` to the same value.\n *\n * For _[point](https://vega.github.io/vega-lite/docs/scale.html#point)_ scales, alias for `paddingOuter`.\n *\n * __Default value:__ For _continuous_ scales, derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `continuousPadding`.\n * For _band and point_ scales, see `paddingInner` and `paddingOuter`.\n *\n * @minimum 0\n */\n padding?: number;\n\n /**\n * The inner padding (spacing) within each band step of band scales, as a fraction of the step size. This value must lie in the range [0,1].\n *\n * For point scale, this property is invalid as point scales do not have internal band widths (only step sizes between bands).\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingInner`.\n *\n * @minimum 0\n * @maximum 1\n */\n paddingInner?: number;\n\n /**\n * The outer padding (spacing) at the ends of the range of band and point scales,\n * as a fraction of the step size. This value must lie in the range [0,1].\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingOuter` for band scales and `pointPadding` for point scales.\n *\n * @minimum 0\n * @maximum 1\n */\n paddingOuter?: number;\n\n // typical\n /**\n * If `true`, values that exceed the data domain are clamped to either the minimum or maximum range value\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `clamp` (`true` by default).\n */\n clamp?: boolean;\n\n /**\n * Extending the domain so that it starts and ends on nice round values. This method typically modifies the scale’s domain, and may only extend the bounds to the nearest round value. Nicing is useful if the domain is computed from data and may be irregular. For example, for a domain of _[0.201479…, 0.996679…]_, a nice domain might be _[0.2, 1.0]_.\n *\n * For quantitative scales such as linear, `nice` can be either a boolean flag or a number. If `nice` is a number, it will represent a desired tick count. This allows greater control over the step size used to extend the bounds, guaranteeing that the returned ticks will exactly cover the domain.\n *\n * For temporal fields with time and utc scales, the `nice` value can be a string indicating the desired time interval. Legal values are `\"millisecond\"`, `\"second\"`, `\"minute\"`, `\"hour\"`, `\"day\"`, `\"week\"`, `\"month\"`, and `\"year\"`. Alternatively, `time` and `utc` scales can accept an object-valued interval specifier of the form `{\"interval\": \"month\", \"step\": 3}`, which includes a desired number of interval steps. Here, the domain would snap to quarter (Jan, Apr, Jul, Oct) boundaries.\n *\n * __Default value:__ `true` for unbinned _quantitative_ fields; `false` otherwise.\n *\n */\n nice?: boolean | number | NiceTime | {interval: string, step: number};\n\n /**\n * The logarithm base of the `log` scale (default `10`).\n */\n base?: number;\n\n /**\n * The exponent of the `pow` scale.\n */\n exponent?: number;\n\n /**\n * If `true`, ensures that a zero baseline value is included in the scale domain.\n *\n * __Default value:__ `true` for x and y channels if the quantitative field is not binned and no custom `domain` is provided; `false` otherwise.\n *\n * __Note:__ Log, time, and utc scales do not support `zero`.\n */\n zero?: boolean;\n\n /**\n * The interpolation method for range values. By default, a general interpolator for numbers, dates, strings and colors (in RGB space) is used. For color ranges, this property allows interpolation in alternative color spaces. Legal values include `rgb`, `hsl`, `hsl-long`, `lab`, `hcl`, `hcl-long`, `cubehelix` and `cubehelix-long` ('-long' variants use longer paths in polar coordinate spaces). If object-valued, this property accepts an object with a string-valued _type_ property and an optional numeric _gamma_ property applicable to rgb and cubehelix interpolators. For more, see the [d3-interpolate documentation](https://github.com/d3/d3-interpolate).\n *\n * __Note:__ Sequential scales do not support `interpolate` as they have a fixed interpolator. Since Vega-Lite uses sequential scales for quantitative fields by default, you have to set the scale `type` to other quantitative scale type such as `\"linear\"` to customize `interpolate`.\n */\n interpolate?: ScaleInterpolate | ScaleInterpolateParams;\n}\n\nconst SCALE_PROPERTY_INDEX: Flag = {\n type: 1,\n domain: 1,\n range: 1,\n rangeStep: 1,\n scheme: 1,\n // Other properties\n reverse: 1,\n round: 1,\n // quantitative / time\n clamp: 1,\n nice: 1,\n // quantitative\n base: 1,\n exponent: 1,\n interpolate: 1,\n zero: 1, // zero depends on domain\n // band/point\n padding: 1,\n paddingInner: 1,\n paddingOuter: 1\n};\n\nexport const SCALE_PROPERTIES = flagKeys(SCALE_PROPERTY_INDEX);\n\nconst {type, domain, range, rangeStep, scheme, ...NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX} = SCALE_PROPERTY_INDEX;\n\nexport const NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES = flagKeys(NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX);\n\nexport const SCALE_TYPE_INDEX = generateScaleTypeIndex();\n\nexport function scaleTypeSupportProperty(scaleType: ScaleType, propName: keyof Scale) {\n switch (propName) {\n case 'type':\n case 'domain':\n case 'reverse':\n case 'range':\n return true;\n case 'scheme':\n return contains(['sequential', 'ordinal', 'bin-ordinal', 'quantile', 'quantize'], scaleType);\n case 'interpolate':\n // FIXME(https://github.com/vega/vega-lite/issues/2902) how about ordinal?\n return contains(['linear', 'bin-linear', 'pow', 'log', 'sqrt', 'utc', 'time'], scaleType);\n case 'round':\n return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point';\n case 'padding':\n return isContinuousToContinuous(scaleType) || contains(['point', 'band'], scaleType);\n case 'paddingOuter':\n case 'rangeStep':\n return contains(['point', 'band'], scaleType);\n case 'paddingInner':\n return scaleType === 'band';\n case 'clamp':\n return isContinuousToContinuous(scaleType) || scaleType === 'sequential';\n case 'nice':\n return isContinuousToContinuous(scaleType) || scaleType === 'sequential' || scaleType as any === 'quantize';\n case 'exponent':\n return scaleType === 'pow';\n case 'base':\n return scaleType === 'log';\n case 'zero':\n return hasContinuousDomain(scaleType) && !contains([\n 'log', // log scale cannot have zero value\n 'time', 'utc', // zero is not meaningful for time\n 'bin-linear', // binning should not automatically add zero\n 'threshold', // threshold requires custom domain so zero does not matter\n 'quantile' // quantile depends on distribution so zero does not matter\n ], scaleType);\n }\n /* istanbul ignore next: should never reach here*/\n throw new Error(`Invalid scale property ${propName}.`);\n}\n\n/**\n * Returns undefined if the input channel supports the input scale property name\n */\nexport function channelScalePropertyIncompatability(channel: Channel, propName: keyof Scale): string {\n switch (propName) {\n case 'interpolate':\n case 'scheme':\n if (!isColorChannel(channel)) {\n return log.message.cannotUseScalePropertyWithNonColor(channel);\n }\n return undefined;\n case 'type':\n case 'domain':\n case 'range':\n case 'base':\n case 'exponent':\n case 'nice':\n case 'padding':\n case 'paddingInner':\n case 'paddingOuter':\n case 'rangeStep':\n case 'reverse':\n case 'round':\n case 'clamp':\n case 'zero':\n return undefined; // GOOD!\n }\n /* istanbul ignore next: it should never reach here */\n throw new Error(`Invalid scale property \"${propName}\".`);\n}\n\nexport function scaleTypeSupportDataType(specifiedType: ScaleType, fieldDefType: Type, bin: boolean|BinParams):boolean {\n if (contains([Type.ORDINAL, Type.NOMINAL], fieldDefType)) {\n return specifiedType === undefined || hasDiscreteDomain(specifiedType);\n } else if (fieldDefType === Type.TEMPORAL) {\n return contains([ScaleType.TIME, ScaleType.UTC, ScaleType.SEQUENTIAL, undefined], specifiedType);\n } else if (fieldDefType === Type.QUANTITATIVE) {\n if (bin) {\n return contains([ScaleType.BIN_LINEAR, ScaleType.BIN_ORDINAL, ScaleType.LINEAR], specifiedType);\n }\n return contains([ScaleType.LOG, ScaleType.POW, ScaleType.SQRT, ScaleType.QUANTILE, ScaleType.QUANTIZE, ScaleType.LINEAR, ScaleType.SEQUENTIAL, undefined], specifiedType);\n }\n\n return true;\n}\n\nexport function channelSupportScaleType(channel: Channel, scaleType: ScaleType): boolean {\n switch (channel) {\n case Channel.X:\n case Channel.Y:\n case Channel.SIZE: // TODO: size and opacity can support ordinal with more modification\n case Channel.OPACITY:\n // Although it generally doesn't make sense to use band with size and opacity,\n // it can also work since we use band: 0.5 to get midpoint.\n return isContinuousToContinuous(scaleType) || contains(['band', 'point'], scaleType);\n\n case Channel.COLOR:\n case Channel.FILL:\n case Channel.STROKE:\n return scaleType !== 'band'; // band does not make sense with color\n\n case Channel.SHAPE:\n return scaleType === 'ordinal'; // shape = lookup only\n }\n /* istanbul ignore next: it should never reach here */\n return false;\n}\n\nexport function getSupportedScaleType(channel: Channel, fieldDefType: Type, bin?: boolean) {\n return SCALE_TYPE_INDEX[generateScaleTypeIndexKey(channel, fieldDefType, bin)];\n}\n\nexport interface ScaleTypeIndex {\n [channel: string]: ScaleType[];\n}\n\n// generates ScaleTypeIndex where keys are encoding channels and values are list of valid ScaleTypes\nfunction generateScaleTypeIndex() {\n const index: ScaleTypeIndex = {};\n for (const channel of CHANNELS) {\n for (const fieldDefType of keys(TYPE_INDEX)) {\n for (const scaleType of SCALE_TYPES) {\n for (const bin of [false, true]) {\n const key = generateScaleTypeIndexKey(channel, fieldDefType, bin);\n if (channelSupportScaleType(channel, scaleType) && scaleTypeSupportDataType(scaleType, fieldDefType, bin)) {\n index[key] = index[key] || [];\n index[key].push(scaleType);\n }\n }\n }\n }\n }\n return index;\n}\n\nfunction generateScaleTypeIndexKey(channel: Channel, fieldDefType: Type, bin: boolean) {\n const key = channel + '_' + fieldDefType;\n return bin ? key + '_bin' : key;\n}\n","import {ConditionValueDefMixins, ValueDef} from './fielddef';\nimport {VgEncodeChannel} from './vega.schema';\n\nexport interface TitleMixins {\n /**\n * A title for the field. If `null`, the title will be removed.\n *\n * __Default value:__ derived from the field's name and transformation function (`aggregate`, `bin` and `timeUnit`). If the field has an aggregate function, the function is displayed as part of the title (e.g., `\"Sum of Profit\"`). If the field is binned or has a time unit applied, the applied function is shown in parentheses (e.g., `\"Profit (binned)\"`, `\"Transaction Date (year-month)\"`). Otherwise, the title is simply the field name.\n *\n * __Notes__:\n *\n * 1) You can customize the default field title format by providing the [`fieldTitle` property in the [config](https://vega.github.io/vega-lite/docs/config.html) or [`fieldTitle` function via the `compile` function's options](https://vega.github.io/vega-lite/docs/compile.html#field-title).\n *\n * 2) If both field definition's `title` and axis, header, or legend `title` are defined, axis/header/legend title will be used.\n */\n title?: string | null;\n}\n\nexport interface Guide extends TitleMixins {\n /**\n * The formatting pattern for labels. This is D3's [number format pattern](https://github.com/d3/d3-format#locale_format) for quantitative fields and D3's [time format pattern](https://github.com/d3/d3-time-format#locale_format) for time field.\n *\n * See the [format documentation](https://vega.github.io/vega-lite/docs/format.html) for more information.\n *\n * __Default value:__ derived from [numberFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for quantitative fields and from [timeFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for temporal fields.\n */\n format?: string;\n}\nexport interface VlOnlyGuideConfig {\n\n /**\n * Whether month names and weekday names should be abbreviated.\n *\n * __Default value:__ `false`\n */\n shortTimeLabels?: boolean;\n}\n\n\nexport type GuideEncodingEntry = {\n [k in VgEncodeChannel]?: ValueDef & ConditionValueDefMixins;\n};\n\nexport const VL_ONLY_GUIDE_CONFIG: (keyof VlOnlyGuideConfig)[] = ['shortTimeLabels'];\n","import {DateTime} from './datetime';\nimport {Guide, GuideEncodingEntry, VlOnlyGuideConfig} from './guide';\nimport {Flag, flagKeys} from './util';\nimport {VgLegend, VgLegendBase, VgLegendConfig} from './vega.schema';\n\n\nexport interface LegendConfig extends VgLegendConfig, VlOnlyGuideConfig {}\n\n/**\n * Properties of a legend or boolean flag for determining whether to show it.\n */\nexport interface Legend extends VgLegendBase, Guide {\n /**\n * Mark definitions for custom legend encoding.\n *\n * @hide\n */\n encoding?: LegendEncoding;\n\n /**\n * The desired number of tick values for quantitative legends.\n */\n tickCount?: number;\n\n /**\n * Explicitly set the visible legend values.\n */\n values?: number[] | string[] | boolean[] | DateTime[];\n\n /**\n * The type of the legend. Use `\"symbol\"` to create a discrete legend and `\"gradient\"` for a continuous color gradient.\n *\n * __Default value:__ `\"gradient\"` for non-binned quantitative fields and temporal fields; `\"symbol\"` otherwise.\n */\n type?: 'symbol' | 'gradient';\n\n /**\n * A non-positive integer indicating z-index of the legend.\n * If zindex is 0, legend should be drawn behind all chart elements.\n * To put them in front, use zindex = 1.\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n}\n\nexport type LegendEncoding = {\n /**\n * Custom encoding for the legend container.\n * This can be useful for creating legend with custom x, y position.\n */\n legend?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the legend title text mark.\n */\n title?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend label text marks.\n */\n labels?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend symbol marks.\n */\n symbols?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend gradient filled rect marks.\n */\n gradient?: GuideEncodingEntry;\n};\n\nexport const defaultLegendConfig: LegendConfig = {};\n\nconst COMMON_LEGEND_PROPERTY_INDEX: Flag = {\n entryPadding: 1,\n format: 1,\n offset: 1,\n orient: 1,\n padding: 1,\n tickCount: 1,\n title: 1,\n type: 1,\n values: 1,\n zindex: 1\n};\n\nconst VG_LEGEND_PROPERTY_INDEX: Flag = {\n ...COMMON_LEGEND_PROPERTY_INDEX,\n // channel scales\n opacity: 1,\n shape: 1,\n stroke: 1,\n fill: 1,\n size: 1,\n // encode\n encode: 1\n};\n\nexport const LEGEND_PROPERTIES = flagKeys(COMMON_LEGEND_PROPERTY_INDEX);\n\nexport const VG_LEGEND_PROPERTIES = flagKeys(VG_LEGEND_PROPERTY_INDEX);\n","import {SingleDefChannel} from './channel';\nimport {VgBinding, VgEventStream} from './vega.schema';\n\nexport const SELECTION_ID = '_vgsid_';\nexport type SelectionType = 'single' | 'multi' | 'interval';\nexport type SelectionResolution = 'global' | 'union' | 'intersect';\n\nexport interface BaseSelectionDef {\n /**\n * A [Vega event stream](https://vega.github.io/vega/docs/event-streams/) (object or selector) that triggers the selection.\n * For interval selections, the event stream must specify a [start and end](https://vega.github.io/vega/docs/event-streams/#between-filters).\n */\n on?: VgEventStream;\n /**\n * With layered and multi-view displays, a strategy that determines how\n * selections' data queries are resolved when applied in a filter transform,\n * conditional encoding rule, or scale domain.\n *\n */\n resolve?: SelectionResolution;\n\n // TODO(https://github.com/vega/vega-lite/issues/2596).\n // predicate?: string;\n // domain?: SelectionDomain;\n\n // Transforms\n\n /**\n * An array of encoding channels. The corresponding data field values\n * must match for a data tuple to fall within the selection.\n */\n encodings?: SingleDefChannel[];\n\n /**\n * An array of field names whose values must match for a data tuple to\n * fall within the selection.\n */\n fields?: string[];\n\n /**\n * By default, all data values are considered to lie within an empty selection.\n * When set to `none`, empty selections contain no data values.\n */\n empty?: 'all' | 'none';\n}\n\nexport interface SingleSelectionConfig extends BaseSelectionDef {\n /**\n * Establish a two-way binding between a single selection and input elements\n * (also known as dynamic query widgets). A binding takes the form of\n * Vega's [input element binding definition](https://vega.github.io/vega/docs/signals/#bind)\n * or can be a mapping between projected field/encodings and binding definitions.\n *\n * See the [bind transform](https://vega.github.io/vega-lite/docs/bind.html) documentation for more information.\n */\n bind?: VgBinding | {[key: string]: VgBinding};\n\n /**\n * When true, an invisible voronoi diagram is computed to accelerate discrete\n * selection. The data value _nearest_ the mouse cursor is added to the selection.\n *\n * See the [nearest transform](https://vega.github.io/vega-lite/docs/nearest.html) documentation for more information.\n */\n nearest?: boolean;\n}\n\nexport interface MultiSelectionConfig extends BaseSelectionDef {\n /**\n * Controls whether data values should be toggled or only ever inserted into\n * multi selections. Can be `true`, `false` (for insertion only), or a\n * [Vega expression](https://vega.github.io/vega/docs/expressions/).\n *\n * __Default value:__ `true`, which corresponds to `event.shiftKey` (i.e.,\n * data values are toggled when a user interacts with the shift-key pressed).\n *\n * See the [toggle transform](https://vega.github.io/vega-lite/docs/toggle.html) documentation for more information.\n */\n toggle?: string | boolean;\n\n /**\n * When true, an invisible voronoi diagram is computed to accelerate discrete\n * selection. The data value _nearest_ the mouse cursor is added to the selection.\n *\n * See the [nearest transform](https://vega.github.io/vega-lite/docs/nearest.html) documentation for more information.\n */\n nearest?: boolean;\n}\n\nexport interface BrushConfig {\n /**\n * The fill color of the interval mark.\n *\n * __Default value:__ `#333333`\n *\n */\n fill?: string;\n /**\n * The fill opacity of the interval mark (a value between 0 and 1).\n *\n * __Default value:__ `0.125`\n */\n fillOpacity?: number;\n /**\n * The stroke color of the interval mark.\n *\n * __Default value:__ `#ffffff`\n */\n stroke?: string;\n /**\n * The stroke opacity of the interval mark (a value between 0 and 1).\n */\n strokeOpacity?: number;\n /**\n * The stroke width of the interval mark.\n */\n strokeWidth?: number;\n /**\n * An array of alternating stroke and space lengths,\n * for creating dashed or dotted lines.\n */\n strokeDash?: number[];\n /**\n * The offset (in pixels) with which to begin drawing the stroke dash array.\n */\n strokeDashOffset?: number;\n}\n\nexport interface IntervalSelectionConfig extends BaseSelectionDef {\n /**\n * When truthy, allows a user to interactively move an interval selection\n * back-and-forth. Can be `true`, `false` (to disable panning), or a\n * [Vega event stream definition](https://vega.github.io/vega/docs/event-streams/)\n * which must include a start and end event to trigger continuous panning.\n *\n * __Default value:__ `true`, which corresponds to\n * `[mousedown, window:mouseup] > window:mousemove!` which corresponds to\n * clicks and dragging within an interval selection to reposition it.\n */\n translate?: string | boolean;\n\n /**\n * When truthy, allows a user to interactively resize an interval selection.\n * Can be `true`, `false` (to disable zooming), or a [Vega event stream\n * definition](https://vega.github.io/vega/docs/event-streams/). Currently,\n * only `wheel` events are supported.\n *\n *\n * __Default value:__ `true`, which corresponds to `wheel!`.\n */\n zoom?: string | boolean;\n\n /**\n * Establishes a two-way binding between the interval selection and the scales\n * used within the same view. This allows a user to interactively pan and\n * zoom the view.\n */\n bind?: 'scales';\n\n /**\n * An interval selection also adds a rectangle mark to depict the\n * extents of the interval. The `mark` property can be used to customize the\n * appearance of the mark.\n */\n mark?: BrushConfig;\n}\n\nexport interface SingleSelection extends SingleSelectionConfig {\n type: 'single';\n}\n\nexport interface MultiSelection extends MultiSelectionConfig {\n type: 'multi';\n}\n\nexport interface IntervalSelection extends IntervalSelectionConfig {\n type: 'interval';\n}\n\nexport type SelectionDef = SingleSelection | MultiSelection | IntervalSelection;\n\nexport interface SelectionConfig {\n /**\n * The default definition for a [`single`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations\n * for a single selection definition (except `type`) may be specified here.\n *\n * For instance, setting `single` to `{\"on\": \"dblclick\"}` populates single selections on double-click by default.\n */\n single?: SingleSelectionConfig;\n /**\n * The default definition for a [`multi`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations\n * for a multi selection definition (except `type`) may be specified here.\n *\n * For instance, setting `multi` to `{\"toggle\": \"event.altKey\"}` adds additional values to\n * multi selections when clicking with the alt-key pressed by default.\n */\n multi?: MultiSelectionConfig;\n /**\n * The default definition for an [`interval`](https://vega.github.io/vega-lite/docs/selection.html#type) selection. All properties and transformations\n * for an interval selection definition (except `type`) may be specified here.\n *\n * For instance, setting `interval` to `{\"translate\": false}` disables the ability to move\n * interval selections by default.\n */\n interval?: IntervalSelectionConfig;\n}\n\nexport const defaultConfig:SelectionConfig = {\n single: {\n on: 'click',\n fields: [SELECTION_ID],\n resolve: 'global',\n empty: 'all'\n },\n multi: {\n on: 'click',\n fields: [SELECTION_ID],\n toggle: 'event.shiftKey',\n resolve: 'global',\n empty: 'all'\n },\n interval: {\n on: '[mousedown, window:mouseup] > window:mousemove!',\n encodings: ['x', 'y'],\n translate: '[mousedown, window:mouseup] > window:mousemove!',\n zoom: 'wheel!',\n mark: {fill: '#333', fillOpacity: 0.125, stroke: 'white'},\n resolve: 'global'\n }\n};\n","import {Anchor, TitleOrient, VgMarkConfig, VgTitleConfig} from './vega.schema';\n\nexport interface TitleBase {\n /**\n * The orientation of the title relative to the chart. One of `\"top\"` (the default), `\"bottom\"`, `\"left\"`, or `\"right\"`.\n */\n orient?: TitleOrient;\n\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"`, or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n *\n * __Default value:__ `\"middle\"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views.\n * `\"start\"` for other composite views.\n *\n * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `\"start\"`.\n */\n anchor?: Anchor;\n\n /**\n * The orthogonal offset in pixels by which to displace the title from its position along the edge of the chart.\n */\n offset?: number;\n\n /**\n * A [mark style property](https://vega.github.io/vega-lite/docs/config.html#style) to apply to the title text mark.\n *\n * __Default value:__ `\"group-title\"`.\n */\n style?: string | string[];\n\n // TODO: name, encode, interactive, zindex\n}\n\nexport interface TitleParams extends TitleBase {\n /**\n * The title text.\n */\n text: string;\n}\n\nexport function extractTitleConfig(titleConfig: VgTitleConfig): {\n mark: VgMarkConfig,\n nonMark: TitleBase\n} {\n const {\n // These are non-mark title config that need to be hardcoded\n anchor, offset, orient,\n // color needs to be redirect to fill\n color,\n // The rest are mark config.\n ...titleMarkConfig\n } = titleConfig;\n\n const mark: VgMarkConfig = {\n ...titleMarkConfig,\n ...color ? {fill: color} : {}\n };\n\n const nonMark: TitleBase = {\n ...anchor ? {anchor} : {},\n ...offset ? {offset} : {},\n ...orient ? {orient} : {}\n };\n\n return {mark, nonMark};\n}\n","import {isObject} from 'vega-util';\nimport {AxisConfigMixins} from './axis';\nimport {COMPOSITE_MARK_STYLES} from './compositemark';\nimport {CompositeMarkConfigMixins, CompositeMarkStyle, VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX} from './compositemark/index';\nimport {VL_ONLY_GUIDE_CONFIG} from './guide';\nimport {HeaderConfig} from './header';\nimport {defaultLegendConfig, LegendConfig} from './legend';\nimport * as mark from './mark';\nimport {Mark, MarkConfigMixins, PRIMITIVE_MARKS, VL_ONLY_MARK_CONFIG_PROPERTIES, VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX} from './mark';\nimport {ProjectionConfig} from './projection';\nimport {defaultScaleConfig, ScaleConfig} from './scale';\nimport {defaultConfig as defaultSelectionConfig, SelectionConfig} from './selection';\nimport {StackOffset} from './stack';\nimport {extractTitleConfig} from './title';\nimport {TopLevelProperties} from './toplevelprops';\nimport {duplicate, keys, mergeDeep} from './util';\nimport {StrokeJoin, VgMarkConfig, VgScheme, VgTitleConfig} from './vega.schema';\n\n\nexport interface ViewConfig {\n /**\n * The default width of the single plot or each plot in a trellis plot when the visualization has a continuous (non-ordinal) x-scale or ordinal x-scale with `rangeStep` = `null`.\n *\n * __Default value:__ `200`\n *\n */\n width?: number;\n\n /**\n * The default height of the single plot or each plot in a trellis plot when the visualization has a continuous (non-ordinal) y-scale with `rangeStep` = `null`.\n *\n * __Default value:__ `200`\n *\n */\n height?: number;\n\n /**\n * Whether the view should be clipped.\n */\n clip?: boolean;\n\n // FILL_STROKE_CONFIG\n /**\n * The fill color.\n *\n * __Default value:__ (none)\n *\n */\n fill?: string;\n\n /**\n * The fill opacity (value between [0,1]).\n *\n * __Default value:__ (none)\n *\n */\n fillOpacity?: number;\n\n /**\n * The stroke color.\n *\n * __Default value:__ (none)\n *\n */\n stroke?: string;\n\n /**\n * The stroke opacity (value between [0,1]).\n *\n * __Default value:__ (none)\n *\n */\n strokeOpacity?: number;\n\n /**\n * The stroke width, in pixels.\n *\n * __Default value:__ (none)\n *\n */\n strokeWidth?: number;\n\n /**\n * An array of alternating stroke, space lengths for creating dashed or dotted lines.\n *\n * __Default value:__ (none)\n *\n */\n strokeDash?: number[];\n\n /**\n * The offset (in pixels) into which to begin drawing with the stroke dash array.\n *\n * __Default value:__ (none)\n *\n */\n strokeDashOffset?: number;\n\n /**\n * The stroke line join method. One of miter (default), round or bevel.\n *\n * __Default value:__ 'miter'\n *\n */\n strokeJoin?: StrokeJoin;\n\n /**\n * The stroke line join method. One of miter (default), round or bevel.\n *\n * __Default value:__ 'miter'\n *\n */\n strokeMiterLimit?: number;\n}\n\nexport const defaultViewConfig: ViewConfig = {\n width: 200,\n height: 200\n};\n\nexport type RangeConfigValue = (number|string)[] | VgScheme | {step: number};\n\nexport type RangeConfig = RangeConfigProps & {[name: string]: RangeConfigValue};\n\nexport interface RangeConfigProps {\n /**\n * Default range for _nominal_ (categorical) fields.\n */\n category?: string[] | VgScheme;\n\n /**\n * Default range for diverging _quantitative_ fields.\n */\n diverging?: string[] | VgScheme;\n\n /**\n * Default range for _quantitative_ heatmaps.\n */\n heatmap?: string[] | VgScheme;\n\n /**\n * Default range for _ordinal_ fields.\n */\n ordinal?: string[] | VgScheme;\n\n /**\n * Default range for _quantitative_ and _temporal_ fields.\n */\n ramp?: string[] | VgScheme;\n\n /**\n * Default range palette for the `shape` channel.\n */\n symbol?: string[];\n}\n\nexport interface VLOnlyConfig {\n /**\n * Default axis and legend title for count fields.\n *\n * __Default value:__ `'Number of Records'`.\n *\n * @type {string}\n */\n countTitle?: string;\n\n /**\n * Defines how Vega-Lite should handle invalid values (`null` and `NaN`).\n * - If set to `\"filter\"` (default), all data items with null values will be skipped (for line, trail, and area marks) or filtered (for other marks).\n * - If `null`, all data items are included. In this case, invalid values will be interpreted as zeroes.\n */\n invalidValues?: 'filter' | null;\n\n /**\n * Defines how Vega-Lite generates title for fields. There are three possible styles:\n * - `\"verbal\"` (Default) - displays function in a verbal style (e.g., \"Sum of field\", \"Year-month of date\", \"field (binned)\").\n * - `\"function\"` - displays function using parentheses and capitalized texts (e.g., \"SUM(field)\", \"YEARMONTH(date)\", \"BIN(field)\").\n * - `\"plain\"` - displays only the field name without functions (e.g., \"field\", \"date\", \"field\").\n */\n fieldTitle?: 'verbal' | 'functional' | 'plain';\n\n /**\n * D3 Number format for axis labels and text tables. For example \"s\" for SI units. Use [D3's number format pattern](https://github.com/d3/d3-format#locale_format).\n */\n numberFormat?: string;\n\n /**\n * Default datetime format for axis and legend labels. The format can be set directly on each axis and legend. Use [D3's time format pattern](https://github.com/d3/d3-time-format#locale_format).\n *\n * __Default value:__ `''` (The format will be automatically determined).\n *\n */\n timeFormat?: string;\n\n\n /** Default properties for [single view plots](https://vega.github.io/vega-lite/docs/spec.html#single). */\n view?: ViewConfig;\n\n /**\n * Scale configuration determines default properties for all [scales](https://vega.github.io/vega-lite/docs/scale.html). For a full list of scale configuration options, please see the [corresponding section of the scale documentation](https://vega.github.io/vega-lite/docs/scale.html#config).\n */\n scale?: ScaleConfig;\n\n /** An object hash for defining default properties for each type of selections. */\n selection?: SelectionConfig;\n\n /** Default stack offset for stackable mark. */\n stack?: StackOffset;\n}\n\nexport interface StyleConfigIndex {\n [style: string]: VgMarkConfig;\n}\n\n\nexport interface Config extends TopLevelProperties, VLOnlyConfig, MarkConfigMixins, CompositeMarkConfigMixins, AxisConfigMixins {\n\n /**\n * An object hash that defines default range arrays or schemes for using with scales.\n * For a full list of scale range configuration options, please see the [corresponding section of the scale documentation](https://vega.github.io/vega-lite/docs/scale.html#config).\n */\n range?: RangeConfig;\n\n /**\n * Legend configuration, which determines default properties for all [legends](https://vega.github.io/vega-lite/docs/legend.html). For a full list of legend configuration options, please see the [corresponding section of in the legend documentation](https://vega.github.io/vega-lite/docs/legend.html#config).\n */\n legend?: LegendConfig;\n\n /**\n * Header configuration, which determines default properties for all [header](https://vega.github.io/vega-lite/docs/header.html). For a full list of header configuration options, please see the [corresponding section of in the header documentation](https://vega.github.io/vega-lite/docs/header.html#config).\n */\n header?: HeaderConfig;\n\n /**\n * Title configuration, which determines default properties for all [titles](https://vega.github.io/vega-lite/docs/title.html). For a full list of title configuration options, please see the [corresponding section of the title documentation](https://vega.github.io/vega-lite/docs/title.html#config).\n */\n title?: VgTitleConfig;\n\n /**\n * Projection configuration, which determines default properties for all [projections](https://vega.github.io/vega-lite/docs/projection.html). For a full list of projection configuration options, please see the [corresponding section of the projection documentation](https://vega.github.io/vega-lite/docs/projection.html#config).\n */\n projection?: ProjectionConfig;\n\n /** An object hash that defines key-value mappings to determine default properties for marks with a given [style](https://vega.github.io/vega-lite/docs/mark.html#mark-def). The keys represent styles names; the values have to be valid [mark configuration objects](https://vega.github.io/vega-lite/docs/mark.html#config). */\n style?: StyleConfigIndex;\n}\n\nexport const defaultConfig: Config = {\n padding: 5,\n timeFormat: '',\n countTitle: 'Number of Records',\n\n invalidValues: 'filter',\n\n view: defaultViewConfig,\n\n mark: mark.defaultMarkConfig,\n area: {},\n bar: mark.defaultBarConfig,\n circle: {},\n geoshape: {},\n line: {},\n point: {},\n rect: {},\n rule: {color: 'black'}, // Need this to override default color in mark config\n square: {},\n text: {color: 'black'}, // Need this to override default color in mark config\n tick: mark.defaultTickConfig,\n trail: {},\n\n box: {size: 14, extent: 1.5},\n boxWhisker: {},\n boxMid: {color: 'white'},\n\n scale: defaultScaleConfig,\n projection: {},\n axis: {},\n axisX: {},\n axisY: {minExtent: 30},\n axisLeft: {},\n axisRight: {},\n axisTop: {},\n axisBottom: {},\n axisBand: {},\n legend: defaultLegendConfig,\n\n selection: defaultSelectionConfig,\n style: {},\n\n title: {},\n};\n\nexport function initConfig(config: Config) {\n return mergeDeep(duplicate(defaultConfig), config);\n}\n\nconst MARK_STYLES = ['view'].concat(PRIMITIVE_MARKS, COMPOSITE_MARK_STYLES) as ('view' | Mark | CompositeMarkStyle)[];\n\n\nconst VL_ONLY_CONFIG_PROPERTIES: (keyof Config)[] = [\n 'padding', 'numberFormat', 'timeFormat', 'countTitle',\n 'stack', 'scale', 'selection', 'invalidValues',\n 'overlay' as keyof Config // FIXME: Redesign and unhide this\n];\n\nconst VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = {\n view: ['width', 'height'],\n ...VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX,\n ...VL_ONLY_COMPOSITE_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX\n};\n\nexport function stripAndRedirectConfig(config: Config) {\n config = duplicate(config);\n\n for (const prop of VL_ONLY_CONFIG_PROPERTIES) {\n delete config[prop];\n }\n\n // Remove Vega-Lite only axis/legend config\n if (config.axis) {\n for (const prop of VL_ONLY_GUIDE_CONFIG) {\n delete config.axis[prop];\n }\n }\n if (config.legend) {\n for (const prop of VL_ONLY_GUIDE_CONFIG) {\n delete config.legend[prop];\n }\n }\n\n // Remove Vega-Lite only generic mark config\n if (config.mark) {\n for (const prop of VL_ONLY_MARK_CONFIG_PROPERTIES) {\n delete config.mark[prop];\n }\n }\n\n for (const markType of MARK_STYLES) {\n // Remove Vega-Lite-only mark config\n for (const prop of VL_ONLY_MARK_CONFIG_PROPERTIES) {\n delete config[markType][prop];\n }\n\n // Remove Vega-Lite only mark-specific config\n const vlOnlyMarkSpecificConfigs = VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX[markType];\n if (vlOnlyMarkSpecificConfigs) {\n for (const prop of vlOnlyMarkSpecificConfigs) {\n delete config[markType][prop];\n }\n }\n\n // Redirect mark config to config.style so that mark config only affect its own mark type\n // without affecting other marks that share the same underlying Vega marks.\n // For example, config.rect should not affect bar marks.\n redirectConfig(config, markType);\n }\n\n // Redirect config.title -- so that title config do not\n // affect header labels, which also uses `title` directive to implement.\n redirectConfig(config, 'title', 'group-title');\n\n // Remove empty config objects\n for (const prop in config) {\n if (isObject(config[prop]) && keys(config[prop]).length === 0) {\n delete config[prop];\n }\n }\n\n return keys(config).length > 0 ? config : undefined;\n}\n\nfunction redirectConfig(config: Config, prop: Mark | CompositeMarkStyle | 'title' | 'view', toProp?: string) {\n const propConfig: VgMarkConfig = prop === 'title' ? extractTitleConfig(config.title).mark : config[prop];\n\n if (prop === 'view') {\n toProp = 'cell'; // View's default style is \"cell\"\n }\n\n const style: VgMarkConfig = {\n ...propConfig,\n ...config.style[prop]\n };\n // set config.style if it is not an empty object\n if (keys(style).length > 0) {\n config.style[toProp || prop] = style;\n }\n delete config[prop];\n}\n","import {isArray} from 'vega-util';\nimport {SUM_OPS} from './aggregate';\nimport {NONPOSITION_CHANNELS, NonPositionChannel, X, X2, Y2} from './channel';\nimport {channelHasField, Encoding} from './encoding';\nimport {Field, FieldDef, getFieldDef, isFieldDef, isStringFieldDef, PositionFieldDef, vgField} from './fielddef';\nimport * as log from './log';\nimport {AREA, BAR, CIRCLE, isMarkDef, isPathMark, LINE, Mark, MarkDef, POINT, RULE, SQUARE, TEXT, TICK} from './mark';\nimport {ScaleType} from './scale';\nimport {contains, Flag} from './util';\n\n\nexport type StackOffset = 'zero' | 'center' | 'normalize';\n\nconst STACK_OFFSET_INDEX: Flag = {\n zero: 1,\n center: 1,\n normalize: 1\n};\n\nexport function isStackOffset(s: string): s is StackOffset {\n return !!STACK_OFFSET_INDEX[s];\n}\n\nexport interface StackProperties {\n /** Dimension axis of the stack. */\n groupbyChannel: 'x' | 'y';\n\n /** Measure axis of the stack. */\n fieldChannel: 'x' | 'y';\n\n /** Stack-by fields e.g., color, detail */\n stackBy: {\n fieldDef: FieldDef,\n channel: NonPositionChannel\n }[];\n\n /**\n * See `\"stack\"` property of Position Field Def.\n */\n offset: StackOffset;\n\n /**\n * Whether this stack will produce impute transform\n */\n impute: boolean;\n}\n\nexport const STACKABLE_MARKS = [BAR, AREA, RULE, POINT, CIRCLE, SQUARE, LINE, TEXT, TICK];\nexport const STACK_BY_DEFAULT_MARKS = [BAR, AREA];\n\n\nfunction potentialStackedChannel(encoding: Encoding): 'x' | 'y' | undefined {\n const xDef = encoding.x;\n const yDef = encoding.y;\n\n if (isFieldDef(xDef) && isFieldDef(yDef)) {\n if (xDef.type === 'quantitative' && yDef.type === 'quantitative') {\n if (xDef.stack) {\n return 'x';\n } else if (yDef.stack) {\n return 'y';\n }\n // if there is no explicit stacking, only apply stack if there is only one aggregate for x or y\n if ((!!xDef.aggregate) !== (!!yDef.aggregate)) {\n return xDef.aggregate ? 'x' : 'y';\n }\n } else if (xDef.type === 'quantitative') {\n return 'x';\n } else if (yDef.type === 'quantitative') {\n return 'y';\n }\n } else if (isFieldDef(xDef) && xDef.type === 'quantitative') {\n return 'x';\n } else if (isFieldDef(yDef) && yDef.type === 'quantitative') {\n return 'y';\n }\n return undefined;\n}\n\n// Note: CompassQL uses this method and only pass in required properties of each argument object.\n// If required properties change, make sure to update CompassQL.\nexport function stack(m: Mark | MarkDef, encoding: Encoding, stackConfig: StackOffset): StackProperties {\n const mark = isMarkDef(m) ? m.type : m;\n // Should have stackable mark\n if (!contains(STACKABLE_MARKS, mark)) {\n return null;\n }\n\n const fieldChannel = potentialStackedChannel(encoding);\n if (!fieldChannel) {\n return null;\n }\n\n const stackedFieldDef = encoding[fieldChannel] as PositionFieldDef;\n const stackedField = isStringFieldDef(stackedFieldDef) ? vgField(stackedFieldDef, {}) : undefined;\n\n const dimensionChannel = fieldChannel === 'x' ? 'y' : 'x';\n const dimensionDef = encoding[dimensionChannel];\n const dimensionField = isStringFieldDef(dimensionDef) ? vgField(dimensionDef, {}) : undefined;\n\n // Should have grouping level of detail that is different from the dimension field\n const stackBy = NONPOSITION_CHANNELS.reduce((sc, channel) => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((cDef) => {\n const fieldDef = getFieldDef(cDef);\n if (fieldDef.aggregate) {\n return;\n }\n\n // Check whether the channel's field is identical to x/y's field or if the channel is a repeat\n const f = isStringFieldDef(fieldDef) ? vgField(fieldDef, {}) : undefined;\n if (\n // if fielddef is a repeat, just include it in the stack by\n !f ||\n // otherwise, the field must be different from x and y fields.\n (f !== dimensionField && f !== stackedField)\n ) {\n sc.push({channel, fieldDef});\n }\n });\n }\n return sc;\n }, []);\n\n if (stackBy.length === 0) {\n return null;\n }\n\n // Automatically determine offset\n let offset: StackOffset = undefined;\n if (stackedFieldDef.stack !== undefined) {\n offset = stackedFieldDef.stack;\n } else if (contains(STACK_BY_DEFAULT_MARKS, mark)) {\n // Bar and Area with sum ops are automatically stacked by default\n offset = stackConfig === undefined ? 'zero' : stackConfig;\n } else {\n offset = stackConfig;\n }\n\n if (!offset || !isStackOffset(offset)) {\n return null;\n }\n\n // warn when stacking non-linear\n if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== ScaleType.LINEAR) {\n log.warn(log.message.cannotStackNonLinearScale(stackedFieldDef.scale.type));\n }\n\n // Check if it is a ranged mark\n if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) {\n if (stackedFieldDef.stack !== undefined) {\n log.warn(log.message.cannotStackRangedMark(fieldChannel));\n }\n return null;\n }\n\n // Warn if stacking summative aggregate\n if (stackedFieldDef.aggregate && !contains(SUM_OPS, stackedFieldDef.aggregate)) {\n log.warn(log.message.stackNonSummativeAggregate(stackedFieldDef.aggregate));\n }\n\n return {\n groupbyChannel: dimensionDef ? dimensionChannel : undefined,\n fieldChannel,\n impute: isPathMark(mark),\n stackBy,\n offset\n };\n}\n","import {isObject} from 'vega-util';\nimport {COLUMN, ROW, X, X2, Y, Y2} from './channel';\nimport * as compositeMark from './compositemark';\nimport {Config} from './config';\nimport {Data} from './data';\nimport * as vlEncoding from './encoding';\nimport {channelHasField, Encoding, EncodingWithFacet, isRanged} from './encoding';\nimport {FacetMapping} from './facet';\nimport {Field, FieldDef, RepeatRef} from './fielddef';\nimport * as log from './log';\nimport {AnyMark, AreaConfig, isMarkDef, isPathMark, isPrimitiveMark, LineConfig, Mark, MarkConfig, MarkDef} from './mark';\nimport {Projection} from './projection';\nimport {Repeat} from './repeat';\nimport {Resolve} from './resolve';\nimport {SelectionDef} from './selection';\nimport {stack} from './stack';\nimport {TitleParams} from './title';\nimport {ConcatLayout, GenericCompositionLayout, TopLevelProperties} from './toplevelprops';\nimport {Transform} from './transform';\nimport {Dict, duplicate, hash, keys, omit, pick, vals} from './util';\n\n\nexport type TopLevel = S & TopLevelProperties & {\n /**\n * URL to [JSON schema](http://json-schema.org/) for a Vega-Lite specification. Unless you have a reason to change this, use `https://vega.github.io/schema/vega-lite/v2.json`. Setting the `$schema` property allows automatic validation and autocomplete in editors that support JSON schema.\n * @format uri\n */\n $schema?: string;\n\n /**\n * Vega-Lite configuration object. This property can only be defined at the top-level of a specification.\n */\n config?: Config;\n};\n\nexport type BaseSpec = Partial & {\n /**\n * Title for the plot.\n */\n title?: string | TitleParams;\n\n /**\n * Name of the visualization for later reference.\n */\n name?: string;\n\n /**\n * Description of this mark for commenting purpose.\n */\n description?: string;\n\n /**\n * An object describing the data source\n */\n data?: Data;\n\n /**\n * An array of data transformations such as filter and new field calculation.\n */\n transform?: Transform[];\n};\n\nexport type DataMixins = {\n /**\n * An object describing the data source\n */\n data: Data;\n};\n\n\n// TODO(https://github.com/vega/vega-lite/issues/2503): Make this generic so we can support some form of top-down sizing.\nexport interface LayoutSizeMixins {\n /**\n * The width of a visualization.\n *\n * __Default value:__ This will be determined by the following rules:\n *\n * - If a view's [`autosize`](https://vega.github.io/vega-lite/docs/size.html#autosize) type is `\"fit\"` or its x-channel has a [continuous scale](https://vega.github.io/vega-lite/docs/scale.html#continuous), the width will be the value of [`config.view.width`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - For x-axis with a band or point scale: if [`rangeStep`](https://vega.github.io/vega-lite/docs/scale.html#band) is a numeric value or unspecified, the width is [determined by the range step, paddings, and the cardinality of the field mapped to x-channel](https://vega.github.io/vega-lite/docs/scale.html#band). Otherwise, if the `rangeStep` is `null`, the width will be the value of [`config.view.width`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - If no field is mapped to `x` channel, the `width` will be the value of [`config.scale.textXRangeStep`](https://vega.github.io/vega-lite/docs/size.html#default-width-and-height) for `text` mark and the value of `rangeStep` for other marks.\n *\n * __Note:__ For plots with [`row` and `column` channels](https://vega.github.io/vega-lite/docs/encoding.html#facet), this represents the width of a single view.\n *\n * __See also:__ The documentation for [width and height](https://vega.github.io/vega-lite/docs/size.html) contains more examples.\n */\n width?: number;\n\n /**\n * The height of a visualization.\n *\n * __Default value:__\n * - If a view's [`autosize`](https://vega.github.io/vega-lite/docs/size.html#autosize) type is `\"fit\"` or its y-channel has a [continuous scale](https://vega.github.io/vega-lite/docs/scale.html#continuous), the height will be the value of [`config.view.height`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - For y-axis with a band or point scale: if [`rangeStep`](https://vega.github.io/vega-lite/docs/scale.html#band) is a numeric value or unspecified, the height is [determined by the range step, paddings, and the cardinality of the field mapped to y-channel](https://vega.github.io/vega-lite/docs/scale.html#band). Otherwise, if the `rangeStep` is `null`, the height will be the value of [`config.view.height`](https://vega.github.io/vega-lite/docs/spec.html#config).\n * - If no field is mapped to `y` channel, the `height` will be the value of `rangeStep`.\n *\n * __Note__: For plots with [`row` and `column` channels](https://vega.github.io/vega-lite/docs/encoding.html#facet), this represents the height of a single view.\n *\n * __See also:__ The documentation for [width and height](https://vega.github.io/vega-lite/docs/size.html) contains more examples.\n */\n height?: number;\n}\n\nexport interface GenericUnitSpec, M> extends BaseSpec, LayoutSizeMixins {\n\n /**\n * A string describing the mark type (one of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"rule\"`, `\"geoshape\"`, and `\"text\"`) or a [mark definition object](https://vega.github.io/vega-lite/docs/mark.html#mark-def).\n */\n mark: M;\n\n /**\n * A key-value mapping between encoding channels and definition of fields.\n */\n encoding?: E;\n\n\n /**\n * An object defining properties of geographic projection, which will be applied to `shape` path for `\"geoshape\"` marks\n * and to `latitude` and `\"longitude\"` channels for other marks.\n */\n projection?: Projection;\n\n /**\n * A key-value mapping between selection names and definitions.\n */\n selection?: {[name: string]: SelectionDef};\n}\n\nexport type NormalizedUnitSpec = GenericUnitSpec, Mark | MarkDef>;\n\n/**\n * Unit spec that can have a composite mark.\n */\nexport type CompositeUnitSpec = GenericUnitSpec, AnyMark>;\n\n/**\n * Unit spec that can have a composite mark and row or column channels.\n */\nexport type FacetedCompositeUnitSpec = GenericUnitSpec, AnyMark>;\n\nexport interface GenericLayerSpec> extends BaseSpec, LayoutSizeMixins {\n /**\n * Layer or single view specifications to be layered.\n *\n * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as layering facet specifications is not allowed.\n */\n layer: (GenericLayerSpec | U)[];\n\n /**\n * Scale, axis, and legend resolutions for layers.\n */\n resolve?: Resolve;\n}\n\n/**\n * Layer Spec with encoding and projection\n */\nexport interface ExtendedLayerSpec extends GenericLayerSpec {\n /**\n * A shared key-value mapping between encoding channels and definition of fields in the underlying layers.\n */\n encoding?: Encoding;\n\n\n /**\n * An object defining properties of the geographic projection shared by underlying layers.\n */\n projection?: Projection;\n}\n\nexport type NormalizedLayerSpec = GenericLayerSpec;\n\n\nexport interface GenericFacetSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n > extends BaseSpec, GenericCompositionLayout {\n /**\n * An object that describes mappings between `row` and `column` channels and their field definitions.\n */\n facet: FacetMapping;\n\n /**\n * A specification of the view that gets faceted.\n */\n spec: L | U;\n // TODO: replace this with GenericSpec once we support all cases;\n\n /**\n * Scale, axis, and legend resolutions for facets.\n */\n resolve?: Resolve;\n}\n\nexport type NormalizedFacetSpec = GenericFacetSpec;\n\nexport interface GenericRepeatSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> extends BaseSpec, GenericCompositionLayout {\n /**\n * An object that describes what fields should be repeated into views that are laid out as a `row` or `column`.\n */\n repeat: Repeat;\n\n spec: GenericSpec;\n\n /**\n * Scale and legend resolutions for repeated charts.\n */\n resolve?: Resolve;\n}\n\nexport type NormalizedRepeatSpec = GenericRepeatSpec;\n\nexport interface GenericVConcatSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> extends BaseSpec, ConcatLayout {\n /**\n * A list of views that should be concatenated and put into a column.\n */\n vconcat: (GenericSpec)[];\n\n /**\n * Scale, axis, and legend resolutions for vertically concatenated charts.\n */\n resolve?: Resolve;\n}\n\nexport interface GenericHConcatSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> extends BaseSpec, ConcatLayout {\n /**\n * A list of views that should be concatenated and put into a row.\n */\n hconcat: (GenericSpec)[];\n\n /**\n * Scale, axis, and legend resolutions for horizontally concatenated charts.\n */\n resolve?: Resolve;\n}\n\nexport type NormalizedConcatSpec =\n GenericVConcatSpec | GenericHConcatSpec;\n\nexport type GenericSpec<\n U extends GenericUnitSpec,\n L extends GenericLayerSpec\n> = U | L | GenericFacetSpec | GenericRepeatSpec |\n GenericVConcatSpec |GenericHConcatSpec;\n\nexport type NormalizedSpec = GenericSpec;\n\nexport type TopLevelFacetedUnitSpec = TopLevel & DataMixins;\nexport type TopLevelFacetSpec = TopLevel> & DataMixins;\n\nexport type TopLevelSpec = TopLevelFacetedUnitSpec | TopLevelFacetSpec | TopLevel |\nTopLevel> | TopLevel> | TopLevel>;\n\n/* Custom type guards */\n\n\nexport function isFacetSpec(spec: BaseSpec): spec is GenericFacetSpec {\n return spec['facet'] !== undefined;\n}\n\nexport function isUnitSpec(spec: BaseSpec): spec is FacetedCompositeUnitSpec | NormalizedUnitSpec {\n return !!spec['mark'];\n}\n\nexport function isLayerSpec(spec: BaseSpec): spec is GenericLayerSpec {\n return spec['layer'] !== undefined;\n}\n\nexport function isRepeatSpec(spec: BaseSpec): spec is GenericRepeatSpec {\n return spec['repeat'] !== undefined;\n}\n\nexport function isConcatSpec(spec: BaseSpec):\n spec is GenericVConcatSpec |\n GenericHConcatSpec {\n return isVConcatSpec(spec) || isHConcatSpec(spec);\n}\n\nexport function isVConcatSpec(spec: BaseSpec): spec is GenericVConcatSpec {\n return spec['vconcat'] !== undefined;\n}\n\nexport function isHConcatSpec(spec: BaseSpec): spec is GenericHConcatSpec {\n return spec['hconcat'] !== undefined;\n}\n\n/**\n * Decompose extended unit specs into composition of pure unit specs.\n */\n// TODO: consider moving this to another file. Maybe vl.spec.normalize or vl.normalize\nexport function normalize(spec: TopLevelSpec | GenericSpec | FacetedCompositeUnitSpec, config: Config): NormalizedSpec {\n if (isFacetSpec(spec)) {\n return normalizeFacet(spec, config);\n }\n if (isLayerSpec(spec)) {\n return normalizeLayer(spec, config);\n }\n if (isRepeatSpec(spec)) {\n return normalizeRepeat(spec, config);\n }\n if (isVConcatSpec(spec)) {\n return normalizeVConcat(spec, config);\n }\n if (isHConcatSpec(spec)) {\n return normalizeHConcat(spec, config);\n }\n if (isUnitSpec(spec)) {\n const hasRow = channelHasField(spec.encoding, ROW);\n const hasColumn = channelHasField(spec.encoding, COLUMN);\n\n if (hasRow || hasColumn) {\n return normalizeFacetedUnit(spec, config);\n }\n return normalizeNonFacetUnit(spec, config);\n }\n throw new Error(log.message.INVALID_SPEC);\n}\n\nfunction normalizeFacet(spec: GenericFacetSpec, config: Config): NormalizedFacetSpec {\n const {spec: subspec, ...rest} = spec;\n return {\n ...rest,\n // TODO: remove \"any\" once we support all facet listed in https://github.com/vega/vega-lite/issues/2760\n spec: normalize(subspec, config) as any\n };\n}\n\nfunction mergeEncoding(opt: {parentEncoding: Encoding, encoding: Encoding}): Encoding {\n const {parentEncoding, encoding} = opt;\n if (parentEncoding && encoding) {\n const overriden = keys(parentEncoding).reduce((o, key) => {\n if (encoding[key]) {\n o.push(key);\n }\n return o;\n }, []);\n\n if (overriden.length > 0) {\n log.warn(log.message.encodingOverridden(overriden));\n }\n }\n\n const merged = {\n ...(parentEncoding || {}),\n ...(encoding || {})\n };\n return keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeProjection(opt: {parentProjection: Projection, projection: Projection}) {\n const {parentProjection, projection} = opt;\n if (parentProjection && projection) {\n log.warn(log.message.projectionOverridden({parentProjection, projection}));\n }\n return projection || parentProjection;\n}\n\nfunction normalizeLayer(\n spec: ExtendedLayerSpec,\n config: Config,\n parentEncoding?: Encoding,\n parentProjection?: Projection\n): NormalizedLayerSpec {\n const {layer, encoding, projection, ...rest} = spec;\n const mergedEncoding = mergeEncoding({parentEncoding, encoding});\n const mergedProjection = mergeProjection({parentProjection, projection});\n return {\n ...rest,\n layer: layer.map((subspec) => {\n if (isLayerSpec(subspec)) {\n return normalizeLayer(subspec, config, mergedEncoding, mergedProjection);\n }\n return normalizeNonFacetUnit(subspec, config, mergedEncoding, mergedProjection);\n })\n };\n}\n\nfunction normalizeRepeat(spec: GenericRepeatSpec, config: Config): NormalizedRepeatSpec {\n const {spec: subspec, ...rest} = spec;\n return {\n ...rest,\n spec: normalize(subspec, config)\n };\n}\n\nfunction normalizeVConcat(spec: GenericVConcatSpec, config: Config): NormalizedConcatSpec {\n const {vconcat: vconcat, ...rest} = spec;\n return {\n ...rest,\n vconcat: vconcat.map((subspec) => normalize(subspec, config))\n };\n}\n\nfunction normalizeHConcat(spec: GenericHConcatSpec, config: Config): NormalizedConcatSpec {\n const {hconcat: hconcat, ...rest} = spec;\n return {\n ...rest,\n hconcat: hconcat.map((subspec) => normalize(subspec, config))\n };\n}\n\nfunction normalizeFacetedUnit(spec: FacetedCompositeUnitSpec, config: Config): NormalizedFacetSpec {\n // New encoding in the inside spec should not contain row / column\n // as row/column should be moved to facet\n const {row: row, column: column, ...encoding} = spec.encoding;\n\n // Mark and encoding should be moved into the inner spec\n const {mark, width, projection, height, selection, encoding: _, ...outerSpec} = spec;\n\n return {\n ...outerSpec,\n facet: {\n ...(row ? {row} : {}),\n ...(column ? {column}: {}),\n },\n spec: normalizeNonFacetUnit({\n ...(projection ? {projection} : {}),\n mark,\n ...(width ? {width} : {}),\n ...(height ? {height} : {}),\n encoding,\n ...(selection ? {selection} : {})\n }, config)\n };\n}\n\nfunction isNonFacetUnitSpecWithPrimitiveMark(spec: GenericUnitSpec, AnyMark>):\n spec is GenericUnitSpec, Mark> {\n return isPrimitiveMark(spec.mark);\n}\n\nfunction getPointOverlay(markDef: MarkDef, markConfig: LineConfig, encoding: Encoding): MarkConfig {\n if (markDef.point === 'transparent') {\n return {opacity: 0};\n } else if (markDef.point) { // truthy : true or object\n return isObject(markDef.point) ? markDef.point : {};\n } else if (markDef.point !== undefined) { // false or null\n return null;\n } else { // undefined (not disabled)\n if (markConfig.point || encoding.shape) {\n // enable point overlay if config[mark].point is truthy or if encoding.shape is provided\n return isObject(markConfig.point) ? markConfig.point : {};\n }\n // markDef.point is defined as falsy\n return null;\n }\n}\n\nfunction getLineOverlay(markDef: MarkDef, markConfig: AreaConfig): MarkConfig {\n if (markDef.line) { // true or object\n return markDef.line === true ? {} : markDef.line;\n } else if (markDef.line !== undefined) { // false or null\n return null;\n } else { // undefined (not disabled)\n if (markConfig.line) {\n // enable line overlay if config[mark].line is truthy\n return markConfig.line === true ? {} : markConfig.line;\n }\n // markDef.point is defined as falsy\n return null;\n }\n}\n\nfunction normalizeNonFacetUnit(\n spec: GenericUnitSpec, AnyMark>, config: Config,\n parentEncoding?: Encoding, parentProjection?: Projection\n): NormalizedUnitSpec | NormalizedLayerSpec {\n const {encoding, projection} = spec;\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n\n\n // merge parent encoding / projection first\n if (parentEncoding || parentProjection) {\n const mergedProjection = mergeProjection({parentProjection, projection});\n const mergedEncoding = mergeEncoding({parentEncoding, encoding});\n return normalizeNonFacetUnit({\n ...spec,\n ...(mergedProjection ? {projection: mergedProjection} : {}),\n ...(mergedEncoding ? {encoding: mergedEncoding} : {}),\n }, config);\n }\n\n if (isNonFacetUnitSpecWithPrimitiveMark(spec)) {\n // TODO: thoroughly test\n if (isRanged(encoding)) {\n return normalizeRangedUnit(spec);\n }\n\n if (mark === 'line' && (encoding.x2 || encoding.y2)) {\n log.warn(log.message.lineWithRange(!!encoding.x2, !!encoding.y2));\n\n return normalizeNonFacetUnit({\n mark: 'rule',\n ...spec\n }, config, parentEncoding, parentProjection);\n }\n\n if (isPathMark(mark)) {\n return normalizePathOverlay(spec, config);\n }\n\n return spec; // Nothing to normalize\n } else {\n return compositeMark.normalize(spec, config);\n }\n}\n\nfunction normalizeRangedUnit(spec: NormalizedUnitSpec) {\n const hasX = channelHasField(spec.encoding, X);\n const hasY = channelHasField(spec.encoding, Y);\n const hasX2 = channelHasField(spec.encoding, X2);\n const hasY2 = channelHasField(spec.encoding, Y2);\n if ((hasX2 && !hasX) || (hasY2 && !hasY)) {\n const normalizedSpec = duplicate(spec);\n if (hasX2 && !hasX) {\n normalizedSpec.encoding.x = normalizedSpec.encoding.x2;\n delete normalizedSpec.encoding.x2;\n }\n if (hasY2 && !hasY) {\n normalizedSpec.encoding.y = normalizedSpec.encoding.y2;\n delete normalizedSpec.encoding.y2;\n }\n\n return normalizedSpec;\n }\n return spec;\n}\n\nfunction dropLineAndPoint(markDef: MarkDef): MarkDef | Mark {\n const {point: _point, line: _line, ...mark} = markDef;\n\n return keys(mark).length > 1 ? mark : mark.type;\n}\n\nfunction normalizePathOverlay(spec: NormalizedUnitSpec, config: Config = {}): NormalizedLayerSpec | NormalizedUnitSpec {\n\n // _ is used to denote a dropped property of the unit spec\n // which should not be carried over to the layer spec\n const {selection, projection, encoding, mark, ...outerSpec} = spec;\n const markDef = isMarkDef(mark) ? mark : {type: mark};\n\n const pointOverlay = getPointOverlay(markDef, config[markDef.type], encoding);\n const lineOverlay = markDef.type === 'area' && getLineOverlay(markDef, config[markDef.type]);\n\n if (!pointOverlay && !lineOverlay) {\n return {\n ...spec,\n // Do not include point / line overlay in the normalize spec\n mark: dropLineAndPoint(markDef)\n };\n }\n\n const layer: NormalizedUnitSpec[] = [{\n ...(selection ? {selection} : {}),\n // Do not include point / line overlay in the normalize spec\n mark: dropLineAndPoint({\n ...markDef,\n // make area mark translucent by default\n // TODO: extract this 0.7 to be shared with default opacity for point/tick/...\n ...(markDef.type === 'area' ? {opacity: 0.7} : {}),\n }),\n // drop shape from encoding as this might be used to trigger point overlay\n encoding: omit(encoding, ['shape'])\n }];\n\n // FIXME: determine rules for applying selections.\n\n // Need to copy stack config to overlayed layer\n const stackProps = stack(markDef, encoding, config ? config.stack : undefined);\n\n let overlayEncoding = encoding;\n if (stackProps) {\n const {fieldChannel: stackFieldChannel, offset} = stackProps;\n overlayEncoding = {\n ...encoding,\n [stackFieldChannel]: {\n ...encoding[stackFieldChannel],\n ...(offset ? {stack: offset} : {})\n }\n };\n }\n\n if (lineOverlay) {\n layer.push({\n ...(projection ? {projection} : {}),\n mark: {\n type: 'line',\n ...pick(markDef, ['clip', 'interpolate']),\n ...lineOverlay\n },\n encoding: overlayEncoding\n });\n }\n if (pointOverlay) {\n layer.push({\n ...(projection ? {projection} : {}),\n mark: {\n type: 'point',\n opacity: 1,\n filled: true,\n ...pick(markDef, ['clip']),\n ...pointOverlay\n },\n encoding: overlayEncoding\n });\n }\n\n return {\n ...outerSpec,\n layer\n };\n}\n\n// TODO: add vl.spec.validate & move stuff from vl.validate to here\n\n/* Accumulate non-duplicate fieldDefs in a dictionary */\nfunction accumulate(dict: any, defs: FieldDef[]): any {\n defs.forEach(function(fieldDef) {\n // Consider only pure fieldDef properties (ignoring scale, axis, legend)\n const pureFieldDef = ['field', 'type', 'value', 'timeUnit', 'bin', 'aggregate'].reduce((f, key) => {\n if (fieldDef[key] !== undefined) {\n f[key] = fieldDef[key];\n }\n return f;\n }, {});\n const key = hash(pureFieldDef);\n dict[key] = dict[key] || fieldDef;\n });\n return dict;\n}\n\n/* Recursively get fieldDefs from a spec, returns a dictionary of fieldDefs */\nfunction fieldDefIndex(spec: GenericSpec, dict: Dict> = {}): Dict> {\n // FIXME(https://github.com/vega/vega-lite/issues/2207): Support fieldDefIndex for repeat\n if (isLayerSpec(spec)) {\n spec.layer.forEach(layer => {\n if (isUnitSpec(layer)) {\n accumulate(dict, vlEncoding.fieldDefs(layer.encoding));\n } else {\n fieldDefIndex(layer, dict);\n }\n });\n } else if (isFacetSpec(spec)) {\n accumulate(dict, vlEncoding.fieldDefs(spec.facet));\n fieldDefIndex(spec.spec, dict);\n } else if (isRepeatSpec(spec)) {\n fieldDefIndex(spec.spec, dict);\n } else if (isConcatSpec(spec)) {\n const childSpec = isVConcatSpec(spec) ? spec.vconcat : spec.hconcat;\n childSpec.forEach(child => fieldDefIndex(child, dict));\n } else { // Unit Spec\n accumulate(dict, vlEncoding.fieldDefs(spec.encoding));\n }\n return dict;\n}\n\n/* Returns all non-duplicate fieldDefs in a spec in a flat array */\nexport function fieldDefs(spec: GenericSpec): FieldDef[] {\n return vals(fieldDefIndex(spec));\n}\n\nexport function isStacked(spec: TopLevel, config?: Config): boolean {\n config = config || spec.config;\n if (isPrimitiveMark(spec.mark)) {\n return stack(spec.mark, spec.encoding,\n config ? config.stack : undefined\n ) !== null;\n }\n return false;\n}\n","import {isString} from 'vega-util';\n\nimport {InlineDataset} from './data';\nimport * as log from './log';\nimport {Dict} from './util';\nimport {RowCol, VgLayoutAlign} from './vega.schema';\n\n/**\n * @minimum 0\n */\nexport type Padding = number | {top?: number, bottom?: number, left?: number, right?: number};\n\nexport type Datasets = Dict;\n\nexport interface TopLevelProperties {\n /**\n * CSS color property to use as the background of visualization.\n *\n * __Default value:__ none (transparent)\n */\n background?: string;\n\n /**\n * The default visualization padding, in pixels, from the edge of the visualization canvas to the data rectangle. If a number, specifies padding for all sides.\n * If an object, the value should have the format `{\"left\": 5, \"top\": 5, \"right\": 5, \"bottom\": 5}` to specify padding for each side of the visualization.\n *\n * __Default value__: `5`\n */\n padding?: Padding;\n\n /**\n * Sets how the visualization size should be determined. If a string, should be one of `\"pad\"`, `\"fit\"` or `\"none\"`.\n * Object values can additionally specify parameters for content sizing and automatic resizing.\n * `\"fit\"` is only supported for single and layered views that don't use `rangeStep`.\n *\n * __Default value__: `pad`\n */\n autosize?: AutosizeType | AutoSizeParams;\n\n /**\n * A global data store for named datasets. This is a mapping from names to inline datasets.\n * This can be an array of objects or primitive values or a string. Arrays of primitive values are ingested as objects with a `data` property.\n */\n datasets?: Datasets;\n}\n\nexport interface BoundsMixins {\n /**\n * The bounds calculation method to use for determining the extent of a sub-plot. One of `full` (the default) or `flush`.\n *\n * - If set to `full`, the entire calculated bounds (including axes, title, and legend) will be used.\n * - If set to `flush`, only the specified width and height values for the sub-view will be used. The `flush` setting can be useful when attempting to place sub-plots without axes or legends into a uniform grid structure.\n *\n * __Default value:__ `\"full\"`\n */\n\n bounds?: 'full' | 'flush';\n}\n\n/**\n * Base layout mixins for V/HConcatSpec.\n * Concat layout should not have RowCol generic fo its property.\n */\nexport interface ConcatLayout extends BoundsMixins {\n /**\n * Boolean flag indicating if subviews should be centered relative to their respective rows or columns.\n *\n * __Default value:__ `false`\n */\n center?: boolean;\n\n /**\n * The spacing in pixels between sub-views of the concat operator.\n *\n * __Default value__: `10`\n */\n spacing?: number;\n}\n\n/**\n * Base layout for FacetSpec and RepeatSpec.\n * This is named \"GenericComposition\" layout as ConcatLayout is a GenericCompositionLayout too\n * (but _not_ vice versa).\n */\nexport interface GenericCompositionLayout extends BoundsMixins {\n /**\n * The alignment to apply to grid rows and columns.\n * The supported string values are `\"all\"`, `\"each\"`, and `\"none\"`.\n *\n * - For `\"none\"`, a flow layout will be used, in which adjacent subviews are simply placed one after the other.\n * - For `\"each\"`, subviews will be aligned into a clean grid structure, but each row or column may be of variable size.\n * - For `\"all\"`, subviews will be aligned and each row or column will be sized identically based on the maximum observed size. String values for this property will be applied to both grid rows and columns.\n *\n * Alternatively, an object value of the form `{\"row\": string, \"column\": string}` can be used to supply different alignments for rows and columns.\n *\n * __Default value:__ `\"all\"`.\n */\n align?: VgLayoutAlign | RowCol;\n\n /**\n * Boolean flag indicating if subviews should be centered relative to their respective rows or columns.\n *\n * An object value of the form `{\"row\": boolean, \"column\": boolean}` can be used to supply different centering values for rows and columns.\n *\n * __Default value:__ `false`\n */\n center?: boolean | RowCol;\n\n /**\n * The spacing in pixels between sub-views of the composition operator.\n * An object of the form `{\"row\": number, \"column\": number}` can be used to set\n * different spacing values for rows and columns.\n *\n * __Default value__: `10`\n */\n spacing?: number | RowCol;\n}\n\nexport function extractCompositionLayout(layout: GenericCompositionLayout): GenericCompositionLayout {\n const {align = undefined, center = undefined, bounds = undefined, spacing = undefined} = layout || {};\n return {align, bounds, center, spacing};\n}\n\nexport type AutosizeType = 'pad' | 'fit' | 'none';\n\nexport interface AutoSizeParams {\n /**\n * The sizing format type. One of `\"pad\"`, `\"fit\"` or `\"none\"`. See the [autosize type](https://vega.github.io/vega-lite/docs/size.html#autosize) documentation for descriptions of each.\n *\n * __Default value__: `\"pad\"`\n */\n type?: AutosizeType;\n\n /**\n * A boolean flag indicating if autosize layout should be re-calculated on every view update.\n *\n * __Default value__: `false`\n */\n resize?: boolean;\n\n /**\n * Determines how size calculation should be performed, one of `\"content\"` or `\"padding\"`. The default setting (`\"content\"`) interprets the width and height settings as the data rectangle (plotting) dimensions, to which padding is then added. In contrast, the `\"padding\"` setting includes the padding within the view size calculations, such that the width and height settings indicate the **total** intended size of the view.\n *\n * __Default value__: `\"content\"`\n */\n contains?: 'content' | 'padding';\n}\n\nfunction _normalizeAutoSize(autosize: AutosizeType | AutoSizeParams) {\n return isString(autosize) ? {type: autosize} : autosize || {};\n}\n\nexport function normalizeAutoSize(topLevelAutosize: AutosizeType | AutoSizeParams, configAutosize: AutosizeType | AutoSizeParams, isUnitOrLayer: boolean = true): AutoSizeParams {\n const autosize: AutoSizeParams = {\n type: 'pad',\n ..._normalizeAutoSize(configAutosize),\n ..._normalizeAutoSize(topLevelAutosize)\n };\n\n if (autosize.type === 'fit') {\n if (!isUnitOrLayer) {\n log.warn(log.message.FIT_NON_SINGLE);\n autosize.type = 'pad';\n }\n }\n\n return autosize;\n}\n\nconst TOP_LEVEL_PROPERTIES: (keyof TopLevelProperties)[] = [\n 'background', 'padding', 'datasets'\n // We do not include \"autosize\" here as it is supported by only unit and layer specs and thus need to be normalized\n];\n\nexport function extractTopLevelProperties(t: T) {\n return TOP_LEVEL_PROPERTIES.reduce((o, p) => {\n if (t && t[p] !== undefined) {\n o[p] = t[p];\n }\n return o;\n }, {});\n}\n","/*\n * Constants and utilities for data.\n */\nimport {VgData} from './vega.schema';\n\nexport interface Parse {\n [field: string]: null | string | 'string' | 'boolean' | 'date' | 'number';\n}\n\nexport interface DataFormatBase {\n /**\n * If set to `\"auto\"` (the default), perform automatic type inference to determine the desired data types.\n * If set to `null`, disable type inference based on the spec and only use type inference based on the data.\n * Alternatively, a parsing directive object can be provided for explicit data types. Each property of the object corresponds to a field name, and the value to the desired data type (one of `\"number\"`, `\"boolean\"`, `\"date\"`, or null (do not parse the field)).\n * For example, `\"parse\": {\"modified_on\": \"date\"}` parses the `modified_on` field in each input record a Date value.\n *\n * For `\"date\"`, we parse data based using Javascript's [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).\n * For Specific date formats can be provided (e.g., `{foo: 'date:\"%m%d%Y\"'}`), using the [d3-time-format syntax](https://github.com/d3/d3-time-format#locale_format). UTC date format parsing is supported similarly (e.g., `{foo: 'utc:\"%m%d%Y\"'}`). See more about [UTC time](https://vega.github.io/vega-lite/docs/timeunit.html#utc)\n */\n parse?: 'auto' | Parse | null;\n}\n\nexport interface CsvDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'csv' | 'tsv';\n}\n\nexport interface DsvDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'dsv';\n\n /**\n * The delimiter between records. The delimiter must be a single character (i.e., a single 16-bit code unit); so, ASCII delimiters are fine, but emoji delimiters are not.\n *\n * @minLength 1\n * @maxLength 1\n */\n delimiter: string;\n}\n\nexport interface JsonDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'json';\n /**\n * The JSON property containing the desired data.\n * This parameter can be used when the loaded JSON file may have surrounding structure or meta-data.\n * For example `\"property\": \"values.features\"` is equivalent to retrieving `json.values.features`\n * from the loaded JSON object.\n */\n property?: string;\n}\n\nexport interface TopoDataFormat extends DataFormatBase {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`, `\"dsv\"`.\n * The default format type is determined by the extension of the file URL.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: 'topojson';\n /**\n * The name of the TopoJSON object set to convert to a GeoJSON feature collection.\n * For example, in a map of the world, there may be an object set named `\"countries\"`.\n * Using the feature property, we can extract this set and generate a GeoJSON feature object for each country.\n */\n feature?: string;\n /**\n * The name of the TopoJSON object set to convert to mesh.\n * Similar to the `feature` option, `mesh` extracts a named TopoJSON object set.\n * Unlike the `feature` option, the corresponding geo data is returned as a single, unified mesh instance, not as individual GeoJSON features.\n * Extracting a mesh is useful for more efficiently drawing borders or other geographic elements that you do not need to associate with specific regions such as individual countries, states or counties.\n */\n mesh?: string;\n}\n\nexport type DataFormat = CsvDataFormat | DsvDataFormat | JsonDataFormat | TopoDataFormat;\n\nexport type DataFormatType = 'json' | 'csv' | 'tsv' | 'dsv' | 'topojson';\n\nexport type Data = UrlData | InlineData | NamedData;\n\nexport type InlineDataset = number[] | string[] | boolean[] | object[] | string | object;\n\nexport interface DataBase {\n /**\n * An object that specifies the format for parsing the data.\n */\n format?: DataFormat;\n /**\n * Provide a placeholder name and bind data at runtime.\n */\n name?: string;\n}\n\nexport interface UrlData extends DataBase {\n /**\n * An URL from which to load the data set. Use the `format.type` property\n * to ensure the loaded data is correctly parsed.\n */\n url: string;\n}\n\nexport interface InlineData extends DataBase {\n /**\n * The full data set, included inline. This can be an array of objects or primitive values, an object, or a string.\n * Arrays of primitive values are ingested as objects with a `data` property. Strings are parsed according to the specified format type.\n */\n values: InlineDataset;\n}\n\nexport interface NamedData extends DataBase {\n /**\n * Provide a placeholder name and bind data at runtime.\n */\n name: string;\n}\n\nexport function isUrlData(data: Partial | Partial): data is UrlData {\n return !!data['url'];\n}\n\nexport function isInlineData(data: Partial | Partial): data is InlineData {\n return !!data['values'];\n}\n\nexport function isNamedData(data: Partial): data is NamedData {\n return !!data['name'] && !isUrlData(data) && !isInlineData(data);\n}\n\nexport type DataSourceType = 'raw' | 'main' | 'row' | 'column' | 'lookup';\n\nexport const MAIN: 'main' = 'main';\nexport const RAW: 'raw' = 'raw';\n","/**\n * Parse an event selector string.\n * Returns an array of event stream definitions.\n */\nexport default function(selector, source, marks) {\n DEFAULT_SOURCE = source || VIEW;\n MARKS = marks || DEFAULT_MARKS;\n return parseMerge(selector.trim()).map(parseSelector);\n}\n\nvar VIEW = 'view',\n LBRACK = '[',\n RBRACK = ']',\n LBRACE = '{',\n RBRACE = '}',\n COLON = ':',\n COMMA = ',',\n NAME = '@',\n GT = '>',\n ILLEGAL = /[[\\]{}]/,\n DEFAULT_SOURCE,\n MARKS,\n DEFAULT_MARKS = {\n '*': 1,\n arc: 1,\n area: 1,\n group: 1,\n image: 1,\n line: 1,\n path: 1,\n rect: 1,\n rule: 1,\n shape: 1,\n symbol: 1,\n text: 1,\n trail: 1\n };\n\nfunction isMarkType(type) {\n return MARKS.hasOwnProperty(type);\n}\n\nfunction find(s, i, endChar, pushChar, popChar) {\n var count = 0,\n n = s.length,\n c;\n for (; i= 0) --count;\n else if (pushChar && pushChar.indexOf(c) >= 0) ++count;\n }\n return i;\n}\n\nfunction parseMerge(s) {\n var output = [],\n start = 0,\n n = s.length,\n i = 0;\n\n while (i < n) {\n i = find(s, i, COMMA, LBRACK + LBRACE, RBRACK + RBRACE);\n output.push(s.substring(start, i).trim());\n start = ++i;\n }\n\n if (output.length === 0) {\n throw 'Empty event selector: ' + s;\n }\n return output;\n}\n\nfunction parseSelector(s) {\n return s[0] === '['\n ? parseBetween(s)\n : parseStream(s);\n}\n\nfunction parseBetween(s) {\n var n = s.length,\n i = 1,\n b, stream;\n\n i = find(s, i, RBRACK, LBRACK, RBRACK);\n if (i === n) {\n throw 'Empty between selector: ' + s;\n }\n\n b = parseMerge(s.substring(1, i));\n if (b.length !== 2) {\n throw 'Between selector must have two elements: ' + s;\n }\n\n s = s.slice(i + 1).trim();\n if (s[0] !== GT) {\n throw 'Expected \\'>\\' after between selector: ' + s;\n }\n\n b = b.map(parseSelector);\n\n stream = parseSelector(s.slice(1).trim());\n if (stream.between) {\n return {\n between: b,\n stream: stream\n };\n } else {\n stream.between = b;\n }\n\n return stream;\n}\n\nfunction parseStream(s) {\n var stream = {source: DEFAULT_SOURCE},\n source = [],\n throttle = [0, 0],\n markname = 0,\n start = 0,\n n = s.length,\n i = 0, j,\n filter;\n\n // extract throttle from end\n if (s[n-1] === RBRACE) {\n i = s.lastIndexOf(LBRACE);\n if (i >= 0) {\n try {\n throttle = parseThrottle(s.substring(i+1, n-1));\n } catch (e) {\n throw 'Invalid throttle specification: ' + s;\n }\n s = s.slice(0, i).trim();\n n = s.length;\n } else throw 'Unmatched right brace: ' + s;\n i = 0;\n }\n\n if (!n) throw s;\n\n // set name flag based on first char\n if (s[0] === NAME) markname = ++i;\n\n // extract first part of multi-part stream selector\n j = find(s, i, COLON);\n if (j < n) {\n source.push(s.substring(start, j).trim());\n start = i = ++j;\n }\n\n // extract remaining part of stream selector\n i = find(s, i, LBRACK);\n if (i === n) {\n source.push(s.substring(start, n).trim());\n } else {\n source.push(s.substring(start, i).trim());\n filter = [];\n start = ++i;\n if (start === n) throw 'Unmatched left bracket: ' + s;\n }\n\n // extract filters\n while (i < n) {\n i = find(s, i, RBRACK);\n if (i === n) throw 'Unmatched left bracket: ' + s;\n filter.push(s.substring(start, i).trim());\n if (i < n-1 && s[++i] !== LBRACK) throw 'Expected left bracket: ' + s;\n start = ++i;\n }\n\n // marshall event stream specification\n if (!(n = source.length) || ILLEGAL.test(source[n-1])) {\n throw 'Invalid event selector: ' + s;\n }\n\n if (n > 1) {\n stream.type = source[1];\n if (markname) {\n stream.markname = source[0].slice(1);\n } else if (isMarkType(source[0])) {\n stream.marktype = source[0];\n } else {\n stream.source = source[0];\n }\n } else {\n stream.type = source[0];\n }\n if (stream.type.slice(-1) === '!') {\n stream.consume = true;\n stream.type = stream.type.slice(0, -1)\n }\n if (filter != null) stream.filter = filter;\n if (throttle[0]) stream.throttle = throttle[0];\n if (throttle[1]) stream.debounce = throttle[1];\n\n return stream;\n}\n\nfunction parseThrottle(s) {\n var a = s.split(COMMA);\n if (!s.length || a.length > 2) throw s;\n return a.map(function(_) {\n var x = +_;\n if (x !== x) throw s;\n return x;\n });\n}\n","import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {BaseBin} from './bin';\nimport {NiceTime, ScaleType} from './scale';\nimport {SortOrder} from './sort';\nimport {StackOffset} from './stack';\nimport {WindowOnlyOp} from './transform';\nimport {Flag, flagKeys} from './util';\n\nexport interface VgData {\n name: string;\n source?: string;\n values?: any;\n format?: {\n type?: string;\n parse?: string | object;\n property?: string;\n feature?: string;\n mesh?: string;\n };\n url?: string;\n transform?: VgTransform[];\n}\n\n\nexport interface VgParentRef {\n parent: string;\n}\n\nexport type VgFieldRef = string | VgParentRef | VgParentRef[];\n\nexport type VgSortField = true | {\n field?: VgFieldRef,\n op: AggregateOp,\n order?: SortOrder\n};\n\n/**\n * Unioned domains can only be sorted by count aggregate.\n */\nexport type VgUnionSortField = true | {\n op: 'count'\n order?: SortOrder\n};\n\nexport interface VgDataRef {\n data: string;\n field: VgFieldRef;\n sort?: VgSortField;\n}\n\nexport interface VgSignalRef {\n signal: string;\n}\n\nexport function isVgSignalRef(o: any): o is VgSignalRef {\n return !!o['signal'];\n}\n\nexport type VgEventStream = any;\n\n// TODO: add type of value (Make it VgValueRef {value?:T ...})\nexport interface VgValueRef {\n value?: number | string | boolean;\n field?: string | {\n datum?: string,\n group?: string,\n parent?: string\n };\n signal?: string;\n scale?: string; // TODO: object\n mult?: number;\n offset?: number | VgValueRef;\n band?: boolean | number | VgValueRef;\n}\n\n// TODO: add vg prefix\nexport interface DataRefUnionDomain {\n fields: (any[] | VgDataRef | VgSignalRef)[];\n sort?: VgUnionSortField;\n}\n\nexport interface VgFieldRefUnionDomain {\n data: string;\n fields: VgFieldRef[];\n sort?: VgUnionSortField;\n}\n\nexport type VgScheme = {scheme: string, extent?: number[], count?: number};\nexport type VgRange = string | VgDataRef | (number|string|VgDataRef|VgSignalRef)[] | VgScheme | VgRangeStep;\n\nexport type VgRangeStep = {step: number | VgSignalRef};\nexport function isVgRangeStep(range: VgRange): range is VgRangeStep {\n return !!range['step'];\n}\n\n// Domains that are not a union of domains\nexport type VgNonUnionDomain = any[] | VgDataRef | VgSignalRef;\nexport type VgDomain = VgNonUnionDomain | DataRefUnionDomain | VgFieldRefUnionDomain;\n\nexport type VgMarkGroup = any;\n\nexport type VgProjectionType = 'albers' | 'albersUsa' | 'azimuthalEqualArea' | 'azimuthalEquidistant' | 'conicConformal' | 'conicEqualArea' | 'conicEquidistant' | 'equirectangular' | 'gnomonic' | 'mercator' | 'orthographic' | 'stereographic' | 'transverseMercator';\n\n\nexport type VgProjection = {\n /*\n * The name of the projection.\n */\n name: string;\n /*\n * The type of the projection.\n */\n type?: VgProjectionType;\n /*\n * The clip angle of the projection.\n */\n clipAngle?: number;\n /*\n * Sets the projection’s viewport clip extent to the specified bounds in pixels\n */\n clipExtent?: number[][];\n /*\n * Sets the projection’s scale factor to the specified value\n */\n scale?: number;\n /*\n * The translation of the projection.\n */\n translate?: number[];\n /*\n * The center of the projection.\n */\n center?: number[];\n /**\n * The rotation of the projection.\n */\n rotate?: number[];\n /*\n * The desired precision of the projection.\n */\n precision?: String;\n /*\n * GeoJSON data to which the projection should attempt to automatically fit the translate and scale parameters..\n */\n fit?: VgSignalRef | Object | any[];\n /*\n * Used in conjunction with fit, provides the pixel area to which the projection should be automatically fit.\n */\n extent?: VgSignalRef | number[][];\n /*\n * Used in conjunction with fit, provides the width and height in pixels of the area to which the projection should be automatically fit.\n */\n size?: VgSignalRef | (number | VgSignalRef)[];\n\n /* The following properties are all supported for specific types of projections. Consult the d3-geo-projection library for more information: https://github.com/d3/d3-geo-projection */\n coefficient?: number;\n distance?: number;\n fraction?: number;\n lobes?: number;\n parallel?: number;\n radius?: number;\n ratio?: number;\n spacing?: number;\n tilt?: number;\n};\n\nexport interface VgScale {\n name: string;\n type: ScaleType;\n domain: VgDomain;\n domainRaw?: VgSignalRef;\n range: VgRange;\n\n clamp?: boolean;\n base?: number;\n exponent?: number;\n interpolate?: ScaleInterpolate | ScaleInterpolateParams;\n nice?: boolean | number | NiceTime | {interval: string, step: number};\n padding?: number;\n paddingInner?: number;\n paddingOuter?: number;\n reverse?: boolean;\n round?: boolean;\n zero?: boolean;\n}\n\nexport type ScaleInterpolate = 'rgb'| 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long';\n\nexport interface ScaleInterpolateParams {\n type: 'rgb' | 'cubehelix' | 'cubehelix-long';\n gamma?: number;\n}\n\nexport type VgLayoutAlign = 'none' | 'each' | 'all';\n\nexport type RowCol = {\n row?: T,\n column?: T\n};\n\nexport interface VgLayout {\n center?: boolean | RowCol;\n padding?: number | RowCol;\n headerBand?: number | RowCol;\n footerBand?: number | RowCol;\n offset?: number | {\n rowHeader?: number,\n rowFooter?: number,\n rowTitle?: number,\n columnHeader?: number,\n columnFooter?: number,\n columnTitle?: number\n };\n bounds?: 'full' | 'flush';\n columns?: number | {signal: string};\n align?: VgLayoutAlign | RowCol;\n}\n\nexport function isDataRefUnionedDomain(domain: VgDomain): domain is DataRefUnionDomain {\n if (!isArray(domain)) {\n return 'fields' in domain && !('data' in domain);\n }\n return false;\n}\n\nexport function isFieldRefUnionDomain(domain: VgDomain): domain is VgFieldRefUnionDomain {\n if (!isArray(domain)) {\n return 'fields' in domain && 'data' in domain;\n }\n return false;\n}\n\nexport function isDataRefDomain(domain: VgDomain): domain is VgDataRef {\n if (!isArray(domain)) {\n return 'field' in domain && 'data' in domain;\n }\n return false;\n}\n\nexport function isSignalRefDomain(domain: VgDomain): domain is VgSignalRef {\n if (!isArray(domain)) {\n return 'signal' in domain;\n }\n return false;\n}\n\nexport interface VgEventHandler {\n events: string[] | VgSignalRef;\n update?: string;\n encode?: string;\n force?: boolean;\n between?: any[];\n}\n\nexport interface VgSignal {\n name: string;\n bind?: string;\n description?: string;\n on?: VgEventHandler[];\n update?: string;\n react?: boolean;\n value?: string | number | boolean | {} | VgSignalRef;\n // only for nested signals\n push?: string;\n}\n\nexport type VgEncodeChannel = 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height'|'opacity'|'fill'|'fillOpacity'|'stroke'|'strokeWidth'|'strokeCap'|'strokeOpacity'|'strokeDash'|'strokeDashOffset'|'strokeMiterLimit'|'strokeJoin'|'cursor'|'clip'|'size'|'shape'|'path'|'innerRadius'|'outerRadius'|'startAngle'|'endAngle'|'interpolate'|'tension'|'orient'|'url'|'align'|'baseline'|'text'|'dir'|'ellipsis'|'limit'|'dx'|'dy'|'radius'|'theta'|'angle'|'font'|'fontSize'|'fontWeight'|'fontStyle'|'tooltip'|'href'|'cursor'|'defined'|'cornerRadius';\nexport type VgEncodeEntry = {\n [k in VgEncodeChannel]?: VgValueRef | (VgValueRef & {test?: string})[];\n};\n\n\n// TODO: make export interface VgEncodeEntry {\n// x?: VgValueRef\n// y?: VgValueRef\n// ...\n// color?: VgValueRef\n// ...\n// }\n\nexport type AxisOrient = 'top' | 'right' | 'left' | 'bottom';\n\nexport interface VgAxis {\n scale: string;\n domain?: boolean;\n format?: string;\n grid?: boolean;\n gridScale?: string;\n\n labels?: boolean;\n\n labelBound?: boolean | number;\n labelFlush?: boolean | number;\n labelPadding?: number;\n labelOverlap?: boolean | 'parity' | 'greedy';\n maxExtent?: number;\n minExtent?: number;\n offset?: number;\n orient?: AxisOrient;\n position?: number;\n\n ticks?: boolean;\n tickCount?: number;\n tickSize?: number;\n\n title?: string;\n titlePadding?: number;\n\n values?: any[] | VgSignalRef;\n zindex?: number;\n\n encode?: VgAxisEncode;\n}\n\nexport type LegendType = 'symbol' | 'gradient';\n\nexport interface VgLegend {\n fill?: string;\n stroke?: string;\n size?: string;\n shape?: string;\n opacity?: string;\n\n entryPadding?: number;\n format?: string;\n\n offset?: number;\n orient?: LegendOrient;\n padding?: number;\n\n tickCount?: number;\n title?: string;\n type?: LegendType;\n values?: any[] | VgSignalRef;\n zindex?: number;\n\n encode?: VgLegendEncode;\n}\n\nexport interface VgBinTransform extends BaseBin {\n type: 'bin';\n extent?: number[] | {signal: string};\n field: string;\n as: string[];\n signal?: string;\n}\n\nexport interface VgExtentTransform {\n type: 'extent';\n field: string;\n signal: string;\n}\n\nexport interface VgFormulaTransform {\n type: 'formula';\n as: string;\n expr: string;\n}\n\nexport interface VgFilterTransform {\n type: 'filter';\n expr: string;\n}\n\nexport interface VgAggregateTransform {\n type: 'aggregate';\n groupby?: VgFieldRef[];\n fields?: VgFieldRef[];\n ops?: AggregateOp[];\n as?: string[];\n cross?: boolean;\n drop?: boolean;\n}\n\nexport interface VgCollectTransform {\n type: 'collect';\n sort: VgSort;\n}\n\nexport interface VgLookupTransform {\n type: 'lookup';\n from: string;\n key: string;\n fields: string[];\n values?: string[];\n as?: string[];\n default?: string;\n}\n\nexport interface VgStackTransform {\n type: 'stack';\n offset?: StackOffset;\n groupby: string[];\n field: string;\n sort: VgSort;\n as: string[];\n}\n\nexport interface VgIdentifierTransform {\n type: 'identifier';\n as: string;\n}\n\nexport type VgTransform = VgBinTransform | VgExtentTransform | VgFormulaTransform | VgAggregateTransform | VgFilterTransform | VgImputeTransform | VgStackTransform | VgCollectTransform | VgLookupTransform | VgIdentifierTransform | VgGeoPointTransform | VgGeoJSONTransform | VgGeoJSONTransform | VgWindowTransform;\n\nexport interface VgGeoPointTransform {\n type: 'geopoint';\n projection: string; // projection name\n fields: VgFieldRef[];\n as?: string[];\n}\n\nexport interface VgGeoShapeTransform {\n type: 'geoshape';\n projection: string; // projection name\n field?: VgFieldRef;\n as?: string;\n}\n\nexport interface VgGeoJSONTransform {\n type: 'geojson';\n fields?: VgFieldRef[];\n geojson?: VgFieldRef;\n signal: string;\n}\n\nexport type VgPostEncodingTransform = VgGeoShapeTransform;\n\nexport interface VgAxisEncode {\n ticks?: VgGuideEncode;\n labels?: VgGuideEncode;\n title?: VgGuideEncode;\n grid?: VgGuideEncode;\n domain?: VgGuideEncode;\n}\n\nexport interface VgLegendEncode {\n title?: VgGuideEncode;\n labels?: VgGuideEncode;\n legend?: VgGuideEncode;\n symbols?: VgGuideEncode;\n gradient?: VgGuideEncode;\n}\n\nexport type VgGuideEncode = any; // TODO: replace this (See guideEncode in Vega Schema)\n\nexport type VgSort = {\n field: string;\n order?: VgComparatorOrder;\n} | {\n field: string[];\n order?: (VgComparatorOrder)[];\n};\n\nexport interface VgImputeTransform {\n type: 'impute';\n groupby?: string[];\n field: string;\n key: string;\n keyvals?: string[];\n method?: 'value' | 'median' | 'max' | 'min' | 'mean';\n value?: any;\n}\n\nexport type VgCheckboxBinding = {\n input: 'checkbox';\n element?: string;\n};\n\nexport type VgRadioBinding = {\n input: 'radio';\n options: string[];\n element?: string;\n};\n\nexport type VgSelectBinding = {\n input: 'select';\n options: string[];\n element?: string;\n};\n\nexport type VgRangeBinding = {\n input: 'range';\n min?: number;\n max?: number;\n step?: number;\n element?: string;\n};\n\nexport type VgGenericBinding = {\n input: string;\n element?: string;\n};\n\nexport type VgBinding = VgCheckboxBinding | VgRadioBinding |\n VgSelectBinding | VgRangeBinding | VgGenericBinding;\n\n\n/**\n * Base object for Vega's Axis and Axis Config.\n * All of these properties are both properties of Vega's Axis and Axis Config.\n */\nexport interface VgAxisBase {\n /**\n * A boolean flag indicating if the domain (the axis baseline) should be included as part of the axis.\n *\n * __Default value:__ `true`\n */\n domain?: boolean;\n\n /**\n * A boolean flag indicating if grid lines should be included as part of the axis\n *\n * __Default value:__ `true` for [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous) that are not binned; otherwise, `false`.\n */\n grid?: boolean;\n\n /**\n * A boolean flag indicating if labels should be included as part of the axis.\n *\n * __Default value:__ `true`.\n */\n labels?: boolean;\n\n /**\n * Indicates if labels should be hidden if they exceed the axis range. If `false `(the default) no bounds overlap analysis is performed. If `true`, labels will be hidden if they exceed the axis range by more than 1 pixel. If this property is a number, it specifies the pixel tolerance: the maximum amount by which a label bounding box may exceed the axis range.\n *\n * __Default value:__ `false`.\n */\n labelBound?: boolean | number;\n\n /**\n * Indicates if the first and last axis labels should be aligned flush with the scale range. Flush alignment for a horizontal axis will left-align the first label and right-align the last label. For vertical axes, bottom and top text baselines are applied instead. If this property is a number, it also indicates the number of pixels by which to offset the first and last labels; for example, a value of 2 will flush-align the first and last labels and also push them 2 pixels outward from the center of the axis. The additional adjustment can sometimes help the labels better visually group with corresponding axis ticks.\n *\n * __Default value:__ `true` for axis of a continuous x-scale. Otherwise, `false`.\n */\n labelFlush?: boolean | number;\n\n /**\n * The strategy to use for resolving overlap of axis labels. If `false` (the default), no overlap reduction is attempted. If set to `true` or `\"parity\"`, a strategy of removing every other label is used (this works well for standard linear axes). If set to `\"greedy\"`, a linear scan of the labels is performed, removing any labels that overlaps with the last visible label (this often works better for log-scaled axes).\n *\n * __Default value:__ `true` for non-nominal fields with non-log scales; `\"greedy\"` for log scales; otherwise `false`.\n */\n labelOverlap?: boolean | 'parity' | 'greedy';\n\n /**\n * The padding, in pixels, between axis and text labels.\n */\n labelPadding?: number;\n\n /**\n * Boolean value that determines whether the axis should include ticks.\n */\n ticks?: boolean;\n\n /**\n * The size in pixels of axis ticks.\n *\n * @minimum 0\n */\n tickSize?: number;\n\n /**\n * Max length for axis title if the title is automatically generated from the field's description.\n *\n * @minimum 0\n * __Default value:__ `undefined`.\n */\n titleMaxLength?: number;\n\n /**\n * The padding, in pixels, between title and axis.\n */\n titlePadding?: number;\n\n /**\n * The minimum extent in pixels that axis ticks and labels should use. This determines a minimum offset value for axis titles.\n *\n * __Default value:__ `30` for y-axis; `undefined` for x-axis.\n */\n minExtent?: number;\n\n /**\n * The maximum extent in pixels that axis ticks and labels should use. This determines a maximum offset value for axis titles.\n *\n * __Default value:__ `undefined`.\n */\n maxExtent?: number;\n}\n\nexport interface VgAxisConfig extends VgAxisBase {\n /**\n * An interpolation fraction indicating where, for `band` scales, axis ticks should be positioned. A value of `0` places ticks at the left edge of their bands. A value of `0.5` places ticks in the middle of their bands.\n */\n bandPosition?: number;\n /**\n * Stroke width of axis domain line\n *\n * __Default value:__ (none, using Vega default).\n */\n domainWidth?: number;\n\n /**\n * Color of axis domain line.\n *\n * __Default value:__ (none, using Vega default).\n */\n domainColor?: string;\n\n // ---------- Grid ----------\n /**\n * Color of gridlines.\n */\n gridColor?: string;\n\n /**\n * The offset (in pixels) into which to begin drawing with the grid dash array.\n */\n gridDash?: number[];\n\n /**\n * The stroke opacity of grid (value between [0,1])\n *\n * __Default value:__ (`1` by default)\n * @minimum 0\n * @maximum 1\n */\n gridOpacity?: number;\n\n /**\n * The grid width, in pixels.\n * @minimum 0\n */\n gridWidth?: number;\n\n // ---------- Ticks ----------\n /**\n * The color of the axis's tick.\n */\n tickColor?: string;\n\n\n /**\n * The rotation angle of the axis labels.\n *\n * __Default value:__ `-90` for nominal and ordinal fields; `0` otherwise.\n *\n * @minimum -360\n * @maximum 360\n */\n labelAngle?: number;\n\n /**\n * The color of the tick label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the tick label.\n */\n labelFont?: string;\n\n /**\n * The font size of the label, in pixels.\n *\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * Maximum allowed pixel width of axis tick labels.\n */\n labelLimit?: number;\n\n /**\n * Boolean flag indicating if pixel position values should be rounded to the nearest integer.\n */\n tickRound?: boolean;\n\n /**\n * The width, in pixels, of ticks.\n *\n * @minimum 0\n */\n tickWidth?: number;\n\n // ---------- Title ----------\n\n /**\n * Horizontal text alignment of axis titles.\n */\n titleAlign?: string;\n\n /**\n * Angle in degrees of axis titles.\n */\n titleAngle?: number;\n /**\n * Vertical text baseline for axis titles.\n */\n titleBaseline?: string;\n /**\n * Color of the title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * Font of the title. (e.g., `\"Helvetica Neue\"`).\n */\n titleFont?: string;\n\n /**\n * Font size of the title.\n *\n * @minimum 0\n */\n titleFontSize?: number;\n\n /**\n * Font weight of the title.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n titleFontWeight?: FontWeight;\n\n /**\n * Maximum allowed pixel width of axis titles.\n */\n titleLimit?: number;\n\n /**\n * X-coordinate of the axis title relative to the axis group.\n */\n titleX?: number;\n\n /**\n * Y-coordinate of the axis title relative to the axis group.\n */\n titleY?: number;\n}\n\nexport type LegendOrient = 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'none';\n\nexport interface VgLegendBase {\n /**\n * Padding (in pixels) between legend entries in a symbol legend.\n */\n entryPadding?: number;\n\n\n /**\n * The orientation of the legend, which determines how the legend is positioned within the scene. One of \"left\", \"right\", \"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\", \"none\".\n *\n * __Default value:__ `\"right\"`\n */\n orient?: LegendOrient;\n\n /**\n * The offset, in pixels, by which to displace the legend from the edge of the enclosing group or data rectangle.\n *\n * __Default value:__ `0`\n */\n offset?: number;\n\n /**\n * The padding, in pixels, between the legend and axis.\n */\n padding?: number;\n}\n\nexport interface VgLegendConfig extends VgLegendBase {\n\n /**\n * Corner radius for the full legend.\n */\n cornerRadius?: number;\n\n /**\n * Background fill color for the full legend.\n */\n fillColor?: string;\n\n /**\n * Border stroke color for the full legend.\n */\n strokeColor?: string;\n\n /**\n * Border stroke dash pattern for the full legend.\n */\n strokeDash?: number[];\n\n /**\n * Border stroke width for the full legend.\n */\n strokeWidth?: number;\n // ---------- Gradient ----------\n /**\n * The color of the gradient stroke, can be in hex color code or regular color name.\n */\n gradientStrokeColor?: string;\n\n /**\n * The width of the gradient stroke, in pixels.\n * @minimum 0\n */\n gradientStrokeWidth?: number;\n\n /**\n * The height of the gradient, in pixels.\n * @minimum 0\n */\n gradientHeight?: number;\n\n /**\n * Text baseline for color ramp gradient labels.\n */\n gradientLabelBaseline?: string;\n\n /**\n * The maximum allowed length in pixels of color ramp gradient labels.\n */\n gradientLabelLimit?: number;\n\n /**\n * Vertical offset in pixels for color ramp gradient labels.\n */\n gradientLabelOffset?: number;\n\n /**\n * The width of the gradient, in pixels.\n * @minimum 0\n */\n gradientWidth?: number;\n\n // ---------- Label ----------\n /**\n * The alignment of the legend label, can be left, middle or right.\n */\n labelAlign?: string;\n\n /**\n * The position of the baseline of legend label, can be top, middle or bottom.\n */\n labelBaseline?: string;\n\n /**\n * The color of the legend label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the legend label.\n */\n labelFont?: string;\n\n /**\n * The font size of legend label.\n *\n * __Default value:__ `10`.\n *\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * Maximum allowed pixel width of axis tick labels.\n */\n labelLimit?: number;\n\n /**\n * The offset of the legend label.\n * @minimum 0\n */\n labelOffset?: number;\n\n // ---------- Symbols ----------\n /**\n * The color of the legend symbol,\n */\n symbolColor?: string;\n\n /**\n * Default shape type (such as \"circle\") for legend symbols.\n */\n symbolType?: string;\n\n /**\n * The size of the legend symbol, in pixels.\n * @minimum 0\n */\n symbolSize?: number;\n\n /**\n * The width of the symbol's stroke.\n * @minimum 0\n */\n symbolStrokeWidth?: number;\n\n // ---------- Title ----------\n /**\n * Horizontal text alignment for legend titles.\n */\n titleAlign?: string;\n\n /**\n * Vertical text baseline for legend titles.\n */\n titleBaseline?: string;\n /**\n * The color of the legend title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * The font of the legend title.\n */\n titleFont?: string;\n\n /**\n * The font size of the legend title.\n */\n titleFontSize?: number;\n\n /**\n * The font weight of the legend title.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n titleFontWeight?: FontWeight;\n\n /**\n * Maximum allowed pixel width of axis titles.\n */\n titleLimit?: number;\n\n /**\n * The padding, in pixels, between title and legend.\n */\n titlePadding?: number;\n}\n\nexport type FontStyle = 'normal' | 'italic';\n\nexport type FontWeightString = 'normal' | 'bold';\n/**\n * @TJS-type integer\n * @minimum 100\n * @maximum 900\n */\nexport type FontWeightNumber = number;\nexport type FontWeight = FontWeightString | FontWeightNumber;\nexport type HorizontalAlign = 'left' | 'right' | 'center';\nexport type Interpolate = 'linear' | 'linear-closed' |\n 'step' | 'step-before' | 'step-after' |\n 'basis' | 'basis-open' | 'basis-closed' |\n 'cardinal' | 'cardinal-open' | 'cardinal-closed' |\n 'bundle' | 'monotone';\nexport type Orient = 'horizontal' | 'vertical';\nexport type VerticalAlign = 'top' | 'middle' | 'bottom';\nexport type Cursor = 'auto' | 'default' | 'none' |\n 'context-menu' | 'help' | 'pointer' |\n 'progress' | 'wait' | 'cell' |\n 'crosshair' | 'text' | 'vertical-text' |\n 'alias' | 'copy' | 'move' |\n 'no-drop' | 'not-allowed' | 'e-resize' |\n 'n-resize' | 'ne-resize' | 'nw-resize' |\n 's-resize' | 'se-resize' | 'sw-resize' |\n 'w-resize' | 'ew-resize' | 'ns-resize' |\n 'nesw-resize' | 'nwse-resize' | 'col-resize' |\n 'row-resize' | 'all-scroll' | 'zoom-in' |\n 'zoom-out' | 'grab' | 'grabbing';\nexport type StrokeCap = 'butt' | 'round' | 'square';\nexport type StrokeJoin = 'miter' | 'round' | 'bevel';\nexport type Dir = 'ltr' | 'rtl';\n\nexport interface VgMarkConfig {\n\n /**\n * Default Fill Color. This has higher precedence than `config.color`\n *\n * __Default value:__ (None)\n *\n */\n fill?: string;\n\n /**\n * Default Stroke Color. This has higher precedence than `config.color`\n *\n * __Default value:__ (None)\n *\n */\n stroke?: string;\n\n // ---------- Opacity ----------\n /**\n * The overall opacity (value between [0,1]).\n *\n * __Default value:__ `0.7` for non-aggregate plots with `point`, `tick`, `circle`, or `square` marks or layered `bar` charts and `1` otherwise.\n *\n * @minimum 0\n * @maximum 1\n */\n opacity?: number;\n\n\n /**\n * The fill opacity (value between [0,1]).\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n * @maximum 1\n */\n fillOpacity?: number;\n\n /**\n * The stroke opacity (value between [0,1]).\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n * @maximum 1\n */\n strokeOpacity?: number;\n\n // ---------- Stroke Style ----------\n /**\n * The stroke width, in pixels.\n *\n * @minimum 0\n */\n strokeWidth?: number;\n\n /**\n * The stroke cap for line ending style. One of `\"butt\"`, `\"round\"`, or `\"square\"`.\n *\n * __Default value:__ `\"square\"`\n */\n strokeCap?: StrokeCap;\n\n /**\n * An array of alternating stroke, space lengths for creating dashed or dotted lines.\n */\n strokeDash?: number[];\n\n /**\n * The offset (in pixels) into which to begin drawing with the stroke dash array.\n */\n strokeDashOffset?: number;\n\n /**\n * The stroke line join method. One of `\"miter\"`, `\"round\"` or `\"bevel\"`.\n *\n * __Default value:__ `\"miter\"`\n */\n strokeJoin?: StrokeJoin;\n\n /**\n * The miter limit at which to bevel a line join.\n */\n strokeMiterLimit?: number;\n\n // ---------- Orientation: Bar, Tick, Line, Area ----------\n /**\n * The orientation of a non-stacked bar, tick, area, and line charts.\n * The value is either horizontal (default) or vertical.\n * - For bar, rule and tick, this determines whether the size of the bar and tick\n * should be applied to x or y dimension.\n * - For area, this property determines the orient property of the Vega output.\n * - For line and trail marks, this property determines the sort order of the points in the line\n * if `config.sortLineBy` is not specified.\n * For stacked charts, this is always determined by the orientation of the stack;\n * therefore explicitly specified value will be ignored.\n */\n orient?: Orient;\n\n // ---------- Interpolation: Line / area ----------\n /**\n * The line interpolation method to use for line and area marks. One of the following:\n * - `\"linear\"`: piecewise linear segments, as in a polyline.\n * - `\"linear-closed\"`: close the linear segments to form a polygon.\n * - `\"step\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"step-before\"`: alternate between vertical and horizontal segments, as in a step function.\n * - `\"step-after\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"basis\"`: a B-spline, with control point duplication on the ends.\n * - `\"basis-open\"`: an open B-spline; may not intersect the start or end.\n * - `\"basis-closed\"`: a closed B-spline, as in a loop.\n * - `\"cardinal\"`: a Cardinal spline, with control point duplication on the ends.\n * - `\"cardinal-open\"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points.\n * - `\"cardinal-closed\"`: a closed Cardinal spline, as in a loop.\n * - `\"bundle\"`: equivalent to basis, except the tension parameter is used to straighten the spline.\n * - `\"monotone\"`: cubic interpolation that preserves monotonicity in y.\n */\n interpolate?: Interpolate;\n /**\n * Depending on the interpolation type, sets the tension parameter (for line and area marks).\n * @minimum 0\n * @maximum 1\n */\n tension?: number;\n\n /**\n * The default symbol shape to use. One of: `\"circle\"` (default), `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, or `\"triangle-down\"`, or a custom SVG path.\n *\n * __Default value:__ `\"circle\"`\n *\n */\n shape?: string;\n\n /**\n * The pixel area each the point/circle/square.\n * For example: in the case of circles, the radius is determined in part by the square root of the size value.\n *\n * __Default value:__ `30`\n *\n * @minimum 0\n */\n size?: number;\n\n // Text / Label Mark Config\n\n /**\n * The horizontal alignment of the text. One of `\"left\"`, `\"right\"`, `\"center\"`.\n */\n align?: HorizontalAlign;\n\n /**\n * The rotation angle of the text, in degrees.\n * @minimum 0\n * @maximum 360\n */\n angle?: number;\n\n /**\n * The vertical alignment of the text. One of `\"top\"`, `\"middle\"`, `\"bottom\"`.\n *\n * __Default value:__ `\"middle\"`\n *\n */\n baseline?: VerticalAlign;\n\n /**\n * The direction of the text. One of `\"ltr\"` (left-to-right) or `\"rtl\"` (right-to-left). This property determines on which side is truncated in response to the limit parameter.\n *\n * __Default value:__ `\"ltr\"`\n */\n dir?: Dir;\n\n /**\n * The horizontal offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property.\n */\n dx?: number;\n\n /**\n * The vertical offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property.\n */\n dy?: number;\n\n /**\n * Polar coordinate radial offset, in pixels, of the text label from the origin determined by the `x` and `y` properties.\n * @minimum 0\n */\n radius?: number;\n\n /**\n * The maximum length of the text mark in pixels. The text value will be automatically truncated if the rendered size exceeds the limit.\n *\n * __Default value:__ `0`, indicating no limit\n */\n limit?: number;\n\n /**\n * The ellipsis string for text truncated in response to the limit parameter.\n *\n * __Default value:__ `\"…\"`\n */\n ellipsis?: string;\n\n /**\n * Polar coordinate angle, in radians, of the text label from the origin determined by the `x` and `y` properties. Values for `theta` follow the same convention of `arc` mark `startAngle` and `endAngle` properties: angles are measured in radians, with `0` indicating \"north\".\n */\n theta?: number;\n\n /**\n * The typeface to set the text in (e.g., `\"Helvetica Neue\"`).\n */\n font?: string;\n\n /**\n * The font size, in pixels.\n * @minimum 0\n */\n fontSize?: number;\n\n /**\n * The font style (e.g., `\"italic\"`).\n */\n fontStyle?: FontStyle;\n /**\n * The font weight.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n fontWeight?: FontWeight;\n\n /**\n * Placeholder text if the `text` channel is not specified\n */\n text?: string;\n\n /**\n * A URL to load upon mouse click. If defined, the mark acts as a hyperlink.\n *\n * @format uri\n */\n href?: string;\n\n /**\n * The mouse cursor used over the mark. Any valid [CSS cursor type](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Values) can be used.\n */\n cursor?: Cursor;\n\n /**\n * The tooltip text to show upon mouse hover.\n */\n tooltip?: any;\n\n // ---------- Corner Radius: Bar, Tick, Rect ----------\n\n /**\n * The radius in pixels of rounded rectangle corners.\n *\n * __Default value:__ `0`\n */\n cornerRadius?: number;\n}\n\nconst VG_MARK_CONFIG_INDEX: Flag = {\n opacity: 1,\n fill: 1,\n fillOpacity: 1,\n stroke: 1,\n strokeCap: 1,\n strokeWidth: 1,\n strokeOpacity: 1,\n strokeDash: 1,\n strokeDashOffset: 1,\n strokeJoin: 1,\n strokeMiterLimit: 1,\n size: 1,\n shape: 1,\n interpolate: 1,\n tension: 1,\n orient: 1,\n align: 1,\n baseline: 1,\n text: 1,\n dir: 1,\n dx: 1,\n dy: 1,\n ellipsis: 1,\n limit: 1,\n radius: 1,\n theta: 1,\n angle: 1,\n font: 1,\n fontSize: 1,\n fontWeight: 1,\n fontStyle: 1,\n cursor: 1,\n href: 1,\n tooltip: 1,\n cornerRadius: 1,\n // commented below are vg channel that do not have mark config.\n // 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height'\n // clip: 1,\n // endAngle: 1,\n // innerRadius: 1,\n // outerRadius: 1,\n // path: 1,\n // startAngle: 1,\n // url: 1,\n};\n\nexport const VG_MARK_CONFIGS = flagKeys(VG_MARK_CONFIG_INDEX);\n\nexport type Anchor = 'start' | 'middle' | 'end';\n\nexport interface VgTitle {\n /**\n * The title text.\n */\n text: string;\n\n /**\n * The orientation of the title relative to the chart. One of `\"top\"` (the default), `\"bottom\"`, `\"left\"`, or `\"right\"`.\n */\n orient?: TitleOrient;\n\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"` (the default), or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n */\n anchor?: Anchor;\n\n /**\n * The orthogonal offset in pixels by which to displace the title from its position along the edge of the chart.\n */\n offset?: number;\n\n style?: string | string[];\n\n // TODO: name, encode, interactive, zindex\n}\n\nexport type TitleOrient = 'top' | 'bottom' | 'left' | 'right';\n\nexport interface VgTitleConfig {\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"`, or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n *\n * __Default value:__ `\"middle\"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views.\n * `\"start\"` for other composite views.\n *\n * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `\"start\"`.\n */\n anchor?: Anchor;\n /**\n * Angle in degrees of title text.\n */\n angle?:\tnumber;\n /**\n * Vertical text baseline for title text.\n */\n baseline?: VerticalAlign;\n /**\n * Text color for title text.\n */\n color?:\tstring;\n /**\n * Font name for title text.\n */\n font?:\tstring;\n /**\n * Font size in pixels for title text.\n *\n * __Default value:__ `10`.\n *\n * @minimum 0\n */\n fontSize?:\tnumber;\n /**\n * Font weight for title text.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n fontWeight?: FontWeight;\n /**\n * The maximum allowed length in pixels of legend labels.\n *\n * @minimum 0\n */\n limit?:\tnumber;\n /**\n * Offset in pixels of the title from the chart body and axes.\n */\n offset?:\tnumber;\n /**\n * Default title orientation (\"top\", \"bottom\", \"left\", or \"right\")\n */\n orient?: TitleOrient;\n}\n\nexport type VgComparatorOrder = 'ascending' | 'descending';\n\nexport interface VgComparator {\n field?: string | string[];\n order?: VgComparatorOrder | VgComparatorOrder[];\n}\n\nexport interface VgWindowTransform {\n type: 'window';\n params?: Number[];\n as?: string[];\n ops?: (AggregateOp | WindowOnlyOp)[];\n fields?: string[];\n frame?: Number[];\n ignorePeers?: Boolean;\n groupby?: string[];\n sort?: VgComparator;\n}\n","import {isArray} from 'vega-util';\n\nimport {AXIS_PARTS, AXIS_PROPERTY_TYPE} from '../../axis';\nimport {Config} from '../../config';\nimport {FieldDefBase, title as fieldDefTitle} from '../../fielddef';\nimport {keys} from '../../util';\nimport {VgAxis} from '../../vega.schema';\nimport {AxisComponent, AxisComponentIndex} from './component';\n\nfunction assembleTitle(title: string | FieldDefBase[], config: Config) {\n if (isArray(title)) {\n return title.map(fieldDef => fieldDefTitle(fieldDef, config)).join(', ');\n }\n return title;\n}\n\nexport function assembleAxis(\n axisCmpt: AxisComponent,\n kind: 'main' | 'grid',\n config: Config,\n opt: {\n header: boolean // whether this is called via a header\n } = {header: false}\n): VgAxis {\n const {orient, scale, title, zindex, ...axis} = axisCmpt.combine();\n\n // Remove properties that are not valid for this kind of axis\n keys(axis).forEach((key) => {\n const propType = AXIS_PROPERTY_TYPE[key];\n if (propType && propType !== kind && propType !== 'both') {\n delete axis[key];\n }\n });\n\n if (kind === 'grid') {\n if (!axis.grid) {\n return undefined;\n }\n\n // Remove unnecessary encode block\n if (axis.encode) {\n // Only need to keep encode block for grid\n const {grid} = axis.encode;\n axis.encode = {\n ...(grid ? {grid} : {})\n };\n\n if (keys(axis.encode).length === 0) {\n delete axis.encode;\n }\n }\n\n return {\n scale,\n orient,\n ...axis,\n domain: false,\n labels: false,\n\n // Always set min/maxExtent to 0 to ensure that `config.axis*.minExtent` and `config.axis*.maxExtent`\n // would not affect gridAxis\n maxExtent: 0,\n minExtent: 0,\n ticks: false,\n zindex: zindex !== undefined ? zindex : 0 // put grid behind marks by default\n };\n } else { // kind === 'main'\n\n if (!opt.header && axisCmpt.mainExtracted) {\n // if mainExtracted has been extracted to a separate facet\n return undefined;\n }\n\n // Remove unnecessary encode block\n if (axis.encode) {\n for (const part of AXIS_PARTS) {\n if (\n !axisCmpt.hasAxisPart(part)\n ) {\n delete axis.encode[part];\n }\n }\n if (keys(axis.encode).length === 0) {\n delete axis.encode;\n }\n }\n\n const titleString = assembleTitle(title, config);\n\n return {\n scale,\n orient,\n grid: false,\n ...(titleString ? {title: titleString} : {}),\n ...axis,\n zindex: zindex !== undefined ? zindex : 1 // put axis line above marks by default\n };\n }\n}\n\nexport function assembleAxes(axisComponents: AxisComponentIndex, config: Config): VgAxis[] {\n const {x=[], y=[]} = axisComponents;\n return [\n ...x.map(a => assembleAxis(a, 'main', config)),\n ...x.map(a => assembleAxis(a, 'grid', config)),\n ...y.map(a => assembleAxis(a, 'main', config)),\n ...y.map(a => assembleAxis(a, 'grid', config))\n ].filter(a => a); // filter undefined\n}\n","import {TextBaseline} from 'vega';\nimport {Guide} from './guide';\nimport {FontWeight, VgTitleConfig} from './vega.schema';\n\nexport const HEADER_TITLE_PROPERTIES_MAP: {\n [k in keyof HeaderConfig]: keyof VgTitleConfig\n} = {\n titleAnchor: 'anchor',\n titleAngle: 'angle',\n titleBaseline: 'baseline',\n titleColor: 'color',\n titleFont: 'font',\n titleFontSize: 'fontSize',\n titleFontWeight: 'fontWeight',\n titleLimit: 'limit'\n};\n\nexport const HEADER_LABEL_PROPERTIES_MAP: {\n [k in keyof HeaderConfig]: keyof VgTitleConfig\n} = {\n labelAngle: 'angle',\n labelColor: 'color',\n labelFont: 'font',\n labelFontSize: 'fontSize',\n labelLimit: 'limit',\n};\n\nexport const HEADER_TITLE_PROPERTIES = Object.keys(HEADER_TITLE_PROPERTIES_MAP);\n\nexport const HEADER_LABEL_PROPERTIES = Object.keys(HEADER_LABEL_PROPERTIES_MAP);\n\nexport interface HeaderConfig {\n // ---------- Title ----------\n /**\n * The anchor position for placing the title. One of `\"start\"`, `\"middle\"`, or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.\n *\n * __Default value:__ `\"middle\"` for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views.\n * `\"start\"` for other composite views.\n *\n * __Note:__ [For now](https://github.com/vega/vega-lite/issues/2875), `anchor` is only customizable only for [single](https://vega.github.io/vega-lite/docs/spec.html) and [layered](https://vega.github.io/vega-lite/docs/layer.html) views. For other composite views, `anchor` is always `\"start\"`.\n */\n titleAnchor?: string;\n\n /**\n * The rotation angle of the header title.\n *\n * __Default value:__ `0`.\n *\n * @minimum -360\n * @maximum 360\n */\n titleAngle?: number;\n /**\n * Vertical text baseline for the header title. One of `\"top\"`, `\"bottom\"`, `\"middle\"`.\n *\n * __Default value:__ `\"middle\"`\n */\n titleBaseline?: TextBaseline;\n /**\n * Color of the header title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * Font of the header title. (e.g., `\"Helvetica Neue\"`).\n */\n titleFont?: string;\n\n /**\n * Font size of the header title.\n *\n * @minimum 0\n */\n titleFontSize?: number;\n\n /**\n * Font weight of the header title.\n * This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`).\n */\n titleFontWeight?: FontWeight;\n\n /**\n * The maximum length of the header title in pixels. The text value will be automatically truncated if the rendered size exceeds the limit.\n *\n * __Default value:__ `0`, indicating no limit\n */\n titleLimit?: number;\n\n // ---------- Label ----------\n /**\n * The rotation angle of the header labels.\n *\n * __Default value:__ `0`.\n *\n * @minimum -360\n * @maximum 360\n */\n labelAngle?: number;\n\n /**\n * The color of the header label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the header label.\n */\n labelFont?: string;\n\n /**\n * The font size of the header label, in pixels.\n *\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * The maximum length of the header label in pixels. The text value will be automatically truncated if the rendered size exceeds the limit.\n *\n * __Default value:__ `0`, indicating no limit\n */\n labelLimit?: number;\n}\n\n/**\n * Headers of row / column channels for faceted plots.\n */\nexport interface Header extends HeaderConfig, Guide {}\n","import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {DateTime} from './datetime';\nimport {VgComparatorOrder} from './vega.schema';\n\nexport type SortOrder = VgComparatorOrder | null;\n\n\n/**\n * A sort definition for transform\n */\nexport interface SortField {\n /**\n * The name of the field to sort.\n */\n field: string;\n\n /**\n * Whether to sort the field in ascending or descending order.\n */\n order?: VgComparatorOrder;\n}\n\n\n/**\n * A sort definition for sorting a discrete scale in an encoding field definition.\n */\n\nexport interface EncodingSortField {\n /**\n * The data [field](https://vega.github.io/vega-lite/docs/field.html) to sort by.\n *\n * __Default value:__ If unspecified, defaults to the field specified in the outer data reference.\n */\n field?: F;\n /**\n * An [aggregate operation](https://vega.github.io/vega-lite/docs/aggregate.html#ops) to perform on the field prior to sorting (e.g., `\"count\"`, `\"mean\"` and `\"median\"`).\n * This property is required in cases where the sort field and the data reference field do not match.\n * The input data objects will be aggregated, grouped by the encoded data field.\n *\n * For a full list of operations, please see the documentation for [aggregate](https://vega.github.io/vega-lite/docs/aggregate.html#ops).\n */\n op: AggregateOp;\n\n /**\n * The sort order. One of `\"ascending\"` (default), `\"descending\"`, or `null` (no not sort).\n */\n order?: SortOrder;\n}\n\nexport type Sort = number[] | string[] | boolean[] | DateTime[] | SortOrder | EncodingSortField | null;\n\nexport function isSortField(sort: Sort): sort is EncodingSortField {\n return !!sort && (sort['op'] === 'count' || !!sort['field']) && !!sort['op'];\n}\n\nexport function isSortArray(sort: Sort): sort is number[] | string[] | boolean[] | DateTime[] {\n return !!sort && isArray(sort);\n}\n","/**\n * Utility files for producing Vega ValueRef for marks\n */\nimport {isArray, isFunction, isString} from 'vega-util';\n\nimport {Channel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {\n ChannelDef,\n ChannelDefWithCondition,\n FieldDef,\n FieldRefOption,\n isFieldDef,\n isValueDef,\n TextFieldDef,\n vgField,\n} from '../../fielddef';\nimport * as log from '../../log';\nimport {Mark, MarkDef} from '../../mark';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {StackProperties} from '../../stack';\nimport {QUANTITATIVE} from '../../type';\nimport {contains, some} from '../../util';\nimport {VgSignalRef, VgValueRef} from '../../vega.schema';\nimport {binRequiresRange, formatSignalRef} from '../common';\nimport {ScaleComponent} from '../scale/component';\n\n\n// TODO: we need to find a way to refactor these so that scaleName is a part of scale\n// but that's complicated. For now, this is a huge step moving forward.\n\n/**\n * @return Vega ValueRef for normal x- or y-position without projection\n */\nexport function position(channel: 'x' | 'y', channelDef: ChannelDef, scaleName: string, scale: ScaleComponent,\n stack: StackProperties, defaultRef: VgValueRef | (() => VgValueRef)): VgValueRef {\n if (isFieldDef(channelDef) && stack && channel === stack.fieldChannel) {\n // x or y use stack_end so that stacked line's point mark use stack_end too.\n return fieldRef(channelDef, scaleName, {suffix: 'end'});\n }\n return midPoint(channel, channelDef, scaleName, scale, stack, defaultRef);\n}\n\n/**\n * @return Vega ValueRef for normal x2- or y2-position without projection\n */\nexport function position2(channel: 'x2' | 'y2', aFieldDef: ChannelDef, a2fieldDef: ChannelDef, scaleName: string, scale: ScaleComponent,\n stack: StackProperties, defaultRef: VgValueRef | (() => VgValueRef)): VgValueRef {\n if (isFieldDef(aFieldDef) && stack &&\n // If fieldChannel is X and channel is X2 (or Y and Y2)\n channel.charAt(0) === stack.fieldChannel.charAt(0)\n ) {\n return fieldRef(aFieldDef, scaleName, {suffix: 'start'});\n }\n return midPoint(channel, a2fieldDef, scaleName, scale, stack, defaultRef);\n}\n\n\n\nexport function getOffset(channel: 'x' | 'y' | 'x2' | 'y2', markDef: MarkDef) {\n const offsetChannel = channel + 'Offset';\n // TODO: in the future read from encoding channel too\n\n const markDefOffsetValue = markDef[offsetChannel];\n if (markDefOffsetValue) {\n return markDefOffsetValue;\n }\n\n return undefined;\n}\n\n/**\n * Value Ref for binned fields\n */\nexport function bin(fieldDef: FieldDef, scaleName: string, side: 'start' | 'end', offset?: number) {\n const binSuffix = side === 'start' ? undefined : 'end';\n return fieldRef(fieldDef, scaleName, {binSuffix}, offset ? {offset} : {});\n}\n\nexport function fieldRef(\n fieldDef: FieldDef, scaleName: string, opt: FieldRefOption,\n mixins?: {offset?: number | VgValueRef, band?: number|boolean}\n ): VgValueRef {\n\n const ref: VgValueRef = {\n ...(scaleName ? {scale: scaleName} : {}),\n field: vgField(fieldDef, opt),\n };\n\n if (mixins) {\n return {\n ...ref,\n ...mixins\n };\n }\n return ref;\n}\n\nexport function bandRef(scaleName: string, band: number|boolean = true): VgValueRef {\n return {\n scale: scaleName,\n band: band\n };\n}\n\n/**\n * Signal that returns the middle of a bin. Should only be used with x and y.\n */\nfunction binMidSignal(fieldDef: FieldDef, scaleName: string) {\n return {\n signal: `(` +\n `scale(\"${scaleName}\", ${vgField(fieldDef, {expr: 'datum'})})` +\n ` + ` +\n `scale(\"${scaleName}\", ${vgField(fieldDef, {binSuffix: 'end', expr: 'datum'})})`+\n `)/2`\n };\n}\n\n/**\n * @returns {VgValueRef} Value Ref for xc / yc or mid point for other channels.\n */\nexport function midPoint(\n channel: Channel,\n channelDef: ChannelDef,\n scaleName: string,\n scale: ScaleComponent,\n stack: StackProperties,\n defaultRef: VgValueRef | (() => VgValueRef)\n): VgValueRef {\n // TODO: datum support\n\n if (channelDef) {\n /* istanbul ignore else */\n\n if (isFieldDef(channelDef)) {\n if (channelDef.bin) {\n // Use middle only for x an y to place marks in the center between start and end of the bin range.\n // We do not use the mid point for other channels (e.g. size) so that properties of legends and marks match.\n if (contains([X, Y], channel) && channelDef.type === QUANTITATIVE) {\n if (stack && stack.impute) {\n // For stack, we computed bin_mid so we can impute.\n return fieldRef(channelDef, scaleName, {binSuffix: 'mid'});\n }\n // For non-stack, we can just calculate bin mid on the fly using signal.\n return binMidSignal(channelDef, scaleName);\n }\n return fieldRef(channelDef, scaleName, binRequiresRange(channelDef, channel) ? {binSuffix: 'range'} : {});\n }\n\n if (scale) {\n const scaleType = scale.get('type');\n if (hasDiscreteDomain(scaleType)) {\n if (scaleType === 'band') {\n // For band, to get mid point, need to offset by half of the band\n return fieldRef(channelDef, scaleName, {binSuffix: 'range'}, {band: 0.5});\n }\n return fieldRef(channelDef, scaleName, {binSuffix: 'range'});\n }\n }\n return fieldRef(channelDef, scaleName, {}); // no need for bin suffix\n } else if (isValueDef(channelDef)) {\n const value = channelDef.value;\n\n if (contains(['x', 'x2'], channel) && value === 'width') {\n return {field: {group: 'width'}};\n } else if (contains(['y', 'y2'], channel) && value === 'height') {\n return {field: {group: 'height'}};\n }\n\n return {value};\n }\n\n // If channelDef is neither field def or value def, it's a condition-only def.\n // In such case, we will use default ref.\n }\n\n return isFunction(defaultRef) ? defaultRef() : defaultRef;\n}\n\nexport function text(textDef: ChannelDefWithCondition>, config: Config): VgValueRef {\n // text\n if (textDef) {\n if (isFieldDef(textDef)) {\n return formatSignalRef(textDef, textDef.format, 'datum', config);\n } else if (isValueDef(textDef)) {\n return {value: textDef.value};\n }\n }\n return undefined;\n}\n\nexport function mid(sizeRef: VgSignalRef): VgValueRef {\n return {...sizeRef, mult: 0.5};\n}\n\n/**\n * Whether the scale definitely includes zero in the domain\n */\nfunction domainDefinitelyIncludeZero(scale: ScaleComponent) {\n if (scale.get('zero') !== false) {\n return true;\n }\n const domains = scale.domains;\n if (isArray(domains)) {\n return some(domains, (d) => isArray(d) && d.length === 2 && d[0] <=0 && d[1] >= 0);\n }\n return false;\n}\n\nexport function getDefaultRef(\n defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax',\n channel: 'x' | 'y', scaleName: string, scale: ScaleComponent, mark: Mark\n) {\n return () => {\n if (isString(defaultRef)) {\n if (scaleName) {\n const scaleType = scale.get('type');\n if (contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scaleType)) {\n // Log scales cannot have zero.\n // Zero in time scale is arbitrary, and does not affect ratio.\n // (Time is an interval level of measurement, not ratio).\n // See https://en.wikipedia.org/wiki/Level_of_measurement for more info.\n if (mark === 'bar' || mark === 'area') {\n log.warn(log.message.nonZeroScaleUsedWithLengthMark(mark, channel, {scaleType}));\n }\n } else {\n if (domainDefinitelyIncludeZero(scale)) {\n return {\n scale: scaleName,\n value: 0\n };\n }\n if (mark === 'bar' || mark === 'area') {\n log.warn(log.message.nonZeroScaleUsedWithLengthMark(\n mark, channel, {zeroFalse: scale.explicit.zero === false}\n ));\n }\n }\n }\n\n if (defaultRef === 'zeroOrMin') {\n return channel === 'x' ? {value: 0} : {field: {group: 'height'}};\n } else { // zeroOrMax\n return channel === 'x' ? {field: {group: 'width'}} : {value: 0};\n }\n }\n return defaultRef;\n };\n}\n\n","export default function(_) {\n return typeof _ === 'function';\n}\n","import {isArray} from 'vega-util';\n\nimport {NONPOSITION_SCALE_CHANNELS, PositionScaleChannel} from '../../channel';\nimport {\n ChannelDef,\n FieldDef,\n FieldDefWithCondition,\n getFieldDef,\n isConditionalSelection,\n isValueDef,\n TextFieldDef,\n ValueDefWithCondition,\n vgField,\n} from '../../fielddef';\nimport * as log from '../../log';\nimport {MarkDef} from '../../mark';\nimport {expression} from '../../predicate';\nimport {hasContinuousDomain} from '../../scale';\nimport {contains} from '../../util';\nimport {VG_MARK_CONFIGS, VgEncodeEntry, VgValueRef} from '../../vega.schema';\nimport {getMarkConfig} from '../common';\nimport {selectionPredicate} from '../selection/selection';\nimport {UnitModel} from '../unit';\nimport * as ref from './valueref';\n\nexport function color(model: UnitModel, opt: {valueOnly: boolean} = {valueOnly: false}): VgEncodeEntry {\n const {markDef, encoding, config} = model;\n const {filled, type: markType} = markDef;\n\n const configValue = {\n fill: getMarkConfig('fill', markDef, config),\n stroke: getMarkConfig('stroke', markDef, config),\n color: getMarkConfig('color', markDef, config)\n };\n\n const transparentIfNeeded = contains(['bar', 'point', 'circle', 'square', 'geoshape'], markType) ? 'transparent' : undefined;\n\n const defaultValue = {\n fill: markDef.fill || configValue.fill ||\n // If there is no fill, always fill symbols, bar, geoshape\n // with transparent fills https://github.com/vega/vega-lite/issues/1316\n transparentIfNeeded,\n stroke: markDef.stroke || configValue.stroke\n };\n\n const colorVgChannel = filled ? 'fill' : 'stroke';\n\n const fillStrokeMarkDefAndConfig: VgEncodeEntry = {\n ...(defaultValue.fill ? {\n fill: {value: defaultValue.fill}\n } : {}),\n ...(defaultValue.stroke ? {\n stroke: {value: defaultValue.stroke}\n } : {}),\n };\n\n if (encoding.fill || encoding.stroke) {\n // ignore encoding.color, markDef.color, config.color\n if (markDef.color) {\n // warn for markDef.color (no need to warn encoding.color as it will be dropped in normalized already)\n log.warn(log.message.droppingColor('property', {fill: 'fill' in encoding, stroke: 'stroke' in encoding}));\n }\n\n return {\n ...nonPosition('fill', model, {defaultValue: defaultValue.fill || transparentIfNeeded}),\n ...nonPosition('stroke', model, {defaultValue: defaultValue.stroke})\n };\n } else if (encoding.color) {\n\n return {\n ...fillStrokeMarkDefAndConfig,\n // override them with encoded color field\n ...nonPosition('color', model, {\n vgChannel: colorVgChannel,\n // apply default fill/stroke first, then color config, then transparent if needed.\n defaultValue: markDef[colorVgChannel] || markDef.color || configValue[colorVgChannel] || configValue.color || (filled ? transparentIfNeeded : undefined)\n })\n };\n } else if (markDef.fill || markDef.stroke) {\n // Ignore markDef.color, config.color\n if (markDef.color) {\n log.warn(log.message.droppingColor('property', {fill: 'fill' in markDef, stroke: 'stroke' in markDef}));\n }\n return fillStrokeMarkDefAndConfig;\n } else if (markDef.color) {\n return {\n ...fillStrokeMarkDefAndConfig, // in this case, fillStrokeMarkDefAndConfig only include config\n\n // override config with markDef.color\n [colorVgChannel]: {value: markDef.color}\n };\n } else if (configValue.fill || configValue.stroke) {\n // ignore config.color\n return fillStrokeMarkDefAndConfig;\n } else if (configValue.color) {\n return {\n ...(transparentIfNeeded ? {fill: {value: 'transparent'}} : {}),\n [colorVgChannel]: {value: configValue.color}\n };\n }\n return {};\n}\n\nexport type Ignore = Record<'size' | 'orient', 'ignore' | 'include'>;\n\nexport function baseEncodeEntry(model: UnitModel, ignore: Ignore) {\n return {\n ...markDefProperties(model.markDef, ignore),\n ...color(model),\n ...nonPosition('opacity', model),\n ...tooltip(model),\n ...text(model, 'href')\n };\n}\n\nfunction markDefProperties(mark: MarkDef, ignore: Ignore) {\n return VG_MARK_CONFIGS.reduce((m, prop) => {\n if (mark[prop] !== undefined && ignore[prop] !== 'ignore') {\n m[prop] = {value: mark[prop]};\n }\n return m;\n }, {});\n}\n\nexport function valueIfDefined(prop: string, value: string | number | boolean): VgEncodeEntry {\n if (value !== undefined) {\n return {[prop]: {value: value}};\n }\n return undefined;\n}\n\nfunction validPredicate(vgRef: string) {\n return `${vgRef} !== null && !isNaN(${vgRef})`;\n}\n\nexport function defined(model: UnitModel): VgEncodeEntry {\n if (model.config.invalidValues === 'filter') {\n const fields = ['x', 'y'].map((channel: PositionScaleChannel) => {\n const scaleComponent = model.getScaleComponent(channel);\n if (scaleComponent) {\n const scaleType = scaleComponent.get('type');\n\n // Discrete domain scales can handle invalid values, but continuous scales can't.\n if (hasContinuousDomain(scaleType)) {\n return model.vgField(channel, {expr: 'datum'});\n }\n }\n return undefined;\n })\n .filter(field => !!field)\n .map(validPredicate);\n\n if (fields.length > 0) {\n return {\n defined: {signal: fields.join(' && ')}\n };\n }\n }\n\n return {};\n}\n\n/**\n * Return mixins for non-positional channels with scales. (Text doesn't have scale.)\n */\nexport function nonPosition(channel: typeof NONPOSITION_SCALE_CHANNELS[0], model: UnitModel, opt: {defaultValue?: number | string | boolean, vgChannel?: string, defaultRef?: VgValueRef} = {}): VgEncodeEntry {\n const {defaultValue, vgChannel} = opt;\n const defaultRef = opt.defaultRef || (defaultValue !== undefined ? {value: defaultValue} : undefined);\n\n const channelDef = model.encoding[channel];\n\n return wrapCondition(model, channelDef, vgChannel || channel, (cDef) => {\n return ref.midPoint(\n channel, cDef, model.scaleName(channel),\n model.getScaleComponent(channel),\n null, // No need to provide stack for non-position as it does not affect mid point\n defaultRef\n );\n });\n}\n\n/**\n * Return a mixin that include a Vega production rule for a Vega-Lite conditional channel definition.\n * or a simple mixin if channel def has no condition.\n */\nexport function wrapCondition(\n model: UnitModel, channelDef: ChannelDef, vgChannel: string,\n refFn: (cDef: ChannelDef) => VgValueRef\n ): VgEncodeEntry {\n const condition = channelDef && channelDef.condition;\n const valueRef = refFn(channelDef);\n if (condition) {\n const conditions = isArray(condition) ? condition : [condition];\n const vgConditions = conditions.map((c) => {\n const conditionValueRef = refFn(c);\n const test = isConditionalSelection(c) ? selectionPredicate(model, c.selection) : expression(model, c.test);\n return {\n test,\n ...conditionValueRef\n };\n });\n return {\n [vgChannel]: [\n ...vgConditions,\n ...(valueRef !== undefined ? [valueRef] : [])\n ]\n };\n } else {\n return valueRef !== undefined ? {[vgChannel]: valueRef} : {};\n }\n}\n\nexport function tooltip(model: UnitModel) {\n const channel = 'tooltip';\n const channelDef = model.encoding[channel];\n if (isArray(channelDef)) {\n const keyValues = channelDef.map((fieldDef) => {\n const key = fieldDef.title !== undefined ? fieldDef.title : vgField(fieldDef, {binSuffix: 'range'});\n const value = ref.text(fieldDef, model.config).signal;\n return `\"${key}\": ${value}`;\n });\n return {tooltip: {signal: `{${keyValues.join(', ')}}`}};\n } else {\n // if not an array, behave just like text\n return textCommon(model, channel, channelDef);\n }\n}\n\nexport function text(model: UnitModel, channel: 'text' | 'href' = 'text') {\n const channelDef = model.encoding[channel];\n return textCommon(model, channel, channelDef);\n}\n\nfunction textCommon(model: UnitModel, channel: 'text' | 'href' | 'tooltip', channelDef: FieldDefWithCondition> | ValueDefWithCondition>) {\n return wrapCondition(model, channelDef, channel, (cDef) => ref.text(cDef, model.config));\n}\n\nexport function bandPosition(fieldDef: FieldDef, channel: 'x'|'y', model: UnitModel) {\n const scaleName = model.scaleName(channel);\n const sizeChannel = channel === 'x' ? 'width' : 'height';\n\n if (model.encoding.size || model.markDef.size !== undefined) {\n const orient = model.markDef.orient;\n if (orient) {\n const centeredBandPositionMixins = {\n // Use xc/yc and place the mark at the middle of the band\n // This way we never have to deal with size's condition for x/y position.\n [channel+'c']: ref.fieldRef(fieldDef, scaleName, {}, {band: 0.5})\n };\n\n if (getFieldDef(model.encoding.size)) {\n return {\n ...centeredBandPositionMixins,\n ...nonPosition('size', model, {vgChannel: sizeChannel})\n };\n } else if (isValueDef(model.encoding.size)) {\n return {\n ...centeredBandPositionMixins,\n ...nonPosition('size', model, {vgChannel: sizeChannel})\n };\n } else if (model.markDef.size !== undefined) {\n return {\n ...centeredBandPositionMixins,\n [sizeChannel]: {value: model.markDef.size}\n };\n }\n } else {\n log.warn(log.message.cannotApplySizeToNonOrientedMark(model.markDef.type));\n }\n }\n return {\n [channel]: ref.fieldRef(fieldDef, scaleName, {binSuffix: 'range'}),\n [sizeChannel]: ref.bandRef(scaleName)\n };\n}\n\nexport function centeredBandPosition(channel: 'x' | 'y', model: UnitModel, defaultPosRef: VgValueRef, defaultSizeRef: VgValueRef) {\n const centerChannel: 'xc' | 'yc' = channel === 'x' ? 'xc' : 'yc';\n const sizeChannel = channel === 'x' ? 'width' : 'height';\n return {\n ...pointPosition(channel, model, defaultPosRef, centerChannel),\n ...nonPosition('size', model, {defaultRef: defaultSizeRef, vgChannel: sizeChannel})\n };\n}\n\nexport function binnedPosition(fieldDef: FieldDef, channel: 'x'|'y', scaleName: string, spacing: number, reverse: boolean) {\n if (channel === 'x') {\n return {\n x2: ref.bin(fieldDef, scaleName, 'start', reverse ? 0 : spacing),\n x: ref.bin(fieldDef, scaleName, 'end', reverse ? spacing : 0)\n };\n } else {\n return {\n y2: ref.bin(fieldDef, scaleName, 'start', reverse ? spacing : 0),\n y: ref.bin(fieldDef, scaleName, 'end', reverse ? 0 : spacing)\n };\n }\n}\n\n\n/**\n * Return mixins for point (non-band) position channels.\n */\nexport function pointPosition(channel: 'x'|'y', model: UnitModel, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax', vgChannel?: 'x'|'y'|'xc'|'yc') {\n // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613\n\n const {encoding, mark, stack} = model;\n\n const channelDef = encoding[channel];\n const scaleName = model.scaleName(channel);\n const scale = model.getScaleComponent(channel);\n\n\n const offset = ref.getOffset(channel, model.markDef);\n\n\n const valueRef = !channelDef && (encoding.latitude || encoding.longitude) ?\n // use geopoint output if there are lat/long and there is no point position overriding lat/long.\n {field: model.getName(channel)} :\n {\n ...ref.position(channel, encoding[channel], scaleName, scale, stack,\n ref.getDefaultRef(defaultRef, channel, scaleName, scale, mark)\n ),\n ...(offset ? {offset}: {})\n };\n\n return {\n [vgChannel || channel]: valueRef\n };\n}\n\n/**\n * Return mixins for x2, y2.\n * If channel is not specified, return one channel based on orientation.\n */\nexport function pointPosition2(model: UnitModel, defaultRef: 'zeroOrMin' | 'zeroOrMax', channel: 'x2' | 'y2') {\n const {encoding, mark, stack} = model;\n\n const baseChannel = channel === 'x2' ? 'x' : 'y';\n const channelDef = encoding[baseChannel];\n const scaleName = model.scaleName(baseChannel);\n const scale = model.getScaleComponent(baseChannel);\n\n const offset = ref.getOffset(channel, model.markDef);\n\n const valueRef = !channelDef && (encoding.latitude || encoding.longitude) ?\n // use geopoint output if there are lat2/long2 and there is no point position2 overriding lat2/long2.\n {field: model.getName(channel)}:\n {\n ...ref.position2(channel, channelDef, encoding[channel], scaleName, scale, stack,\n ref.getDefaultRef(defaultRef, baseChannel, scaleName, scale, mark)\n ),\n ...(offset ? {offset} : {})\n };\n\n return {[channel]: valueRef};\n}\n","import {isArray} from 'vega-util';\nimport {Channel, isScaleChannel} from '../channel';\nimport {Config, ViewConfig} from '../config';\nimport {FieldDef, FieldDefBase, FieldRefOption, isScaleFieldDef, isTimeFieldDef, OrderFieldDef, ValueDef, vgField} from '../fielddef';\nimport {GuideEncodingEntry} from '../guide';\nimport {MarkConfig, MarkDef, TextConfig} from '../mark';\nimport {ScaleType} from '../scale';\nimport {formatExpression, TimeUnit} from '../timeunit';\nimport {QUANTITATIVE} from '../type';\nimport {contains, keys, stringify} from '../util';\nimport {VgEncodeChannel, VgEncodeEntry, VgMarkConfig, VgSort} from '../vega.schema';\nimport {AxisComponentProps} from './axis/component';\nimport {wrapCondition} from './mark/mixins';\nimport {Explicit} from './split';\nimport {UnitModel} from './unit';\n\n\nexport function applyConfig(e: VgEncodeEntry,\n config: ViewConfig | MarkConfig | TextConfig, // TODO(#1842): consolidate MarkConfig | TextConfig?\n propsList: string[]) {\n for (const property of propsList) {\n const value = config[property];\n if (value !== undefined) {\n e[property] = {value: value};\n }\n }\n return e;\n}\n\nexport function applyMarkConfig(e: VgEncodeEntry, model: UnitModel, propsList: (keyof MarkConfig)[]) {\n for (const property of propsList) {\n const value = getMarkConfig(property, model.markDef, model.config);\n if (value !== undefined) {\n e[property] = {value: value};\n }\n }\n return e;\n}\n\nexport function getStyles(mark: MarkDef): string[] {\n return [].concat(mark.type, mark.style || []);\n}\n\n/**\n * Return property value from style or mark specific config property if exists.\n * Otherwise, return general mark specific config.\n */\nexport function getMarkConfig

(prop: P, mark: MarkDef, config: Config): MarkConfig[P] {\n // By default, read from mark config first!\n let value = config.mark[prop];\n\n // Then read mark specific config, which has higher precedence\n const markSpecificConfig = config[mark.type];\n if (markSpecificConfig[prop] !== undefined) {\n value = markSpecificConfig[prop];\n }\n\n // Then read style config, which has even higher precedence.\n const styles = getStyles(mark);\n for (const style of styles) {\n const styleConfig = config.style[style];\n\n // MarkConfig extends VgMarkConfig so a prop may not be a valid property for style\n // However here we also check if it is defined, so it is okay to cast here\n const p = prop as keyof VgMarkConfig;\n if (styleConfig && styleConfig[p] !== undefined) {\n value = styleConfig[p];\n }\n }\n\n return value;\n}\n\nexport function formatSignalRef(fieldDef: FieldDef, specifiedFormat: string, expr: 'datum' | 'parent', config: Config) {\n const format = numberFormat(fieldDef, specifiedFormat, config);\n if (fieldDef.bin) {\n const startField = vgField(fieldDef, {expr});\n const endField = vgField(fieldDef, {expr, binSuffix: 'end'});\n return {\n signal: binFormatExpression(startField, endField, format, config)\n };\n } else if (fieldDef.type === 'quantitative') {\n return {\n signal: `${formatExpr(vgField(fieldDef, {expr, binSuffix: 'range'}), format)}`\n };\n } else if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = isScaleFieldDef(fieldDef) && fieldDef['scale'] && fieldDef['scale'].type === ScaleType.UTC;\n return {\n signal: timeFormatExpression(vgField(fieldDef, {expr}), fieldDef.timeUnit, specifiedFormat, config.text.shortTimeLabels, config.timeFormat, isUTCScale, true)\n };\n } else {\n return {\n signal: `''+${vgField(fieldDef, {expr})}`\n };\n }\n}\n\nexport function getSpecifiedOrDefaultValue(specifiedValue: T, defaultValue: T | {signal: string}) {\n if (specifiedValue !== undefined) {\n return specifiedValue;\n }\n return defaultValue;\n}\n\n/**\n * Returns number format for a fieldDef\n *\n * @param format explicitly specified format\n */\nexport function numberFormat(fieldDef: FieldDef, specifiedFormat: string, config: Config) {\n if (fieldDef.type === QUANTITATIVE) {\n // add number format for quantitative type only\n\n // Specified format in axis/legend has higher precedence than fieldDef.format\n if (specifiedFormat) {\n return specifiedFormat;\n }\n\n // TODO: need to make this work correctly for numeric ordinal / nominal type\n return config.numberFormat;\n }\n return undefined;\n}\n\nfunction formatExpr(field: string, format: string) {\n return `format(${field}, \"${format || ''}\")`;\n}\n\nexport function numberFormatExpr(field: string, specifiedFormat: string, config: Config) {\n return formatExpr(field, specifiedFormat || config.numberFormat);\n}\n\n\nexport function binFormatExpression(startField: string, endField: string, format: string, config: Config) {\n return `${startField} === null || isNaN(${startField}) ? \"null\" : ${numberFormatExpr(startField, format, config)} + \" - \" + ${numberFormatExpr(endField, format, config)}`;\n}\n\n\n/**\n * Returns the time expression used for axis/legend labels or text mark for a temporal field\n */\nexport function timeFormatExpression(field: string, timeUnit: TimeUnit, format: string, shortTimeLabels: boolean, timeFormatConfig: string, isUTCScale: boolean, alwaysReturn: boolean = false): string {\n if (!timeUnit || format) {\n // If there is not time unit, or if user explicitly specify format for axis/legend/text.\n format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit.\n\n if (format || alwaysReturn) {\n return `${isUTCScale ? 'utc' : 'time'}Format(${field}, '${format}')`;\n } else {\n return undefined;\n }\n } else {\n return formatExpression(timeUnit, field, shortTimeLabels, isUTCScale);\n }\n}\n\n/**\n * Return Vega sort parameters (tuple of field and order).\n */\nexport function sortParams(orderDef: OrderFieldDef | OrderFieldDef[], fieldRefOption?: FieldRefOption): VgSort {\n return (isArray(orderDef) ? orderDef : [orderDef]).reduce((s, orderChannelDef) => {\n s.field.push(vgField(orderChannelDef, fieldRefOption));\n s.order.push(orderChannelDef.sort || 'ascending');\n return s;\n }, {field:[], order: []});\n}\n\nexport type AxisTitleComponent = AxisComponentProps['title'];\n\nexport function mergeTitleFieldDefs(f1: FieldDefBase[], f2: FieldDefBase[]) {\n const merged = [...f1];\n\n f2.forEach((fdToMerge) => {\n for (const fieldDef1 of merged) {\n // If already exists, no need to append to merged array\n if (stringify(fieldDef1) === stringify(fdToMerge)) {\n return;\n }\n }\n merged.push(fdToMerge);\n });\n return merged;\n}\n\nexport function mergeTitle(title1: string, title2: string) {\n return title1 === title2 ?\n title1 : // if title is the same just use one of them\n title1 + ', ' + title2; // join title with comma if different\n}\n\nexport function mergeTitleComponent(\n v1: Explicit, v2: Explicit\n) {\n if (isArray(v1.value) && isArray(v2.value)) {\n return {\n explicit: v1.explicit,\n value: mergeTitleFieldDefs(v1.value, v2.value)\n };\n } else if (!isArray(v1.value) && !isArray(v2.value)) {\n return {\n explicit: v1.explicit, // keep the old explicit\n value: mergeTitle(v1.value, v2.value)\n };\n }\n /* istanbul ignore next: Condition should not happen -- only for warning in development. */\n throw new Error('It should never reach here');\n}\n\n/**\n * Checks whether a fieldDef for a particular channel requires a computed bin range.\n */\nexport function binRequiresRange(fieldDef: FieldDef, channel: Channel) {\n if (!fieldDef.bin) {\n console.warn('Only use this method with binned field defs');\n return false;\n }\n\n // We need the range only when the user explicitly forces a binned field to be use discrete scale. In this case, bin range is used in axis and legend labels.\n // We could check whether the axis or legend exists (not disabled) but that seems overkill.\n return isScaleChannel(channel) && contains(['ordinal', 'nominal'], fieldDef.type);\n}\n\nexport function guideEncodeEntry(encoding: GuideEncodingEntry, model: UnitModel) {\n return keys(encoding).reduce((encode, channel: VgEncodeChannel) => {\n const valueDef = encoding[channel];\n return {\n ...encode,\n ...wrapCondition(model, valueDef, channel, (x: ValueDef) => ({value: x.value}))\n };\n }, {});\n}\n","\nimport {DataSourceType} from '../../data';\nimport {Dict, StringSet} from '../../util';\n\n\n/**\n * A node in the dataflow tree.\n */\nexport class DataFlowNode {\n private _children: DataFlowNode[] = [];\n\n private _parent: DataFlowNode = null;\n\n constructor(parent: DataFlowNode, public readonly debugName?: string) {\n if (parent) {\n this.parent = parent;\n }\n }\n\n /**\n * Clone this node with a deep copy but don't clone links to children or parents.\n */\n public clone(): DataFlowNode {\n throw new Error('Cannot clone node');\n }\n\n /**\n * Set of fields that are being created by this node.\n */\n public producedFields(): StringSet {\n return {};\n }\n\n public dependentFields(): StringSet {\n return {};\n }\n\n get parent() {\n return this._parent;\n }\n\n /**\n * Set the parent of the node and also add this not to the parent's children.\n */\n set parent(parent: DataFlowNode) {\n this._parent = parent;\n parent.addChild(this);\n }\n\n get children() {\n return this._children;\n }\n\n public numChildren() {\n return this._children.length;\n }\n\n public addChild(child: DataFlowNode) {\n this._children.push(child);\n }\n\n public removeChild(oldChild: DataFlowNode) {\n this._children.splice(this._children.indexOf(oldChild), 1);\n }\n\n /**\n * Remove node from the dataflow.\n */\n public remove() {\n for (const child of this._children) {\n child.parent = this._parent;\n }\n this._parent.removeChild(this);\n }\n\n /**\n * Insert another node as a parent of this node.\n */\n public insertAsParentOf(other: DataFlowNode) {\n const parent = other.parent;\n parent.removeChild(this);\n this.parent = parent;\n other.parent = this;\n }\n\n public swapWithParent() {\n const parent = this._parent;\n const newParent = parent.parent;\n\n // reconnect the children\n for (const child of this._children) {\n child.parent = parent;\n }\n\n // remove old links\n this._children = []; // equivalent to removing every child link one by one\n parent.removeChild(this);\n parent.parent.removeChild(parent);\n\n\n // swap two nodes\n this.parent = newParent;\n parent.parent = this;\n }\n}\n\nexport class OutputNode extends DataFlowNode {\n private _source: string;\n\n private _name: string;\n\n public clone(): this {\n const cloneObj = new (this.constructor);\n cloneObj.debugName = 'clone_' + this.debugName;\n cloneObj._source = this._source;\n cloneObj._name = 'clone_' + this._name;\n cloneObj.type = this.type;\n cloneObj.refCounts = this.refCounts;\n cloneObj.refCounts[cloneObj._name] = 0;\n return cloneObj;\n }\n\n /**\n * @param source The name of the source. Will change in assemble.\n * @param type The type of the output node.\n * @param refCounts A global ref counter map.\n */\n constructor(parent: DataFlowNode, source: string, public readonly type: DataSourceType, private readonly refCounts: Dict) {\n super(parent, source);\n\n this._source = this._name = source;\n\n if (this.refCounts && !(this._name in this.refCounts)) {\n this.refCounts[this._name] = 0;\n }\n }\n\n /**\n * Request the datasource name and increase the ref counter.\n *\n * During the parsing phase, this will return the simple name such as 'main' or 'raw'.\n * It is crucial to request the name from an output node to mark it as a required node.\n * If nobody ever requests the name, this datasource will not be instantiated in the assemble phase.\n *\n * In the assemble phase, this will return the correct name.\n */\n public getSource() {\n this.refCounts[this._name]++;\n return this._source;\n }\n\n public isRequired(): boolean {\n return !!this.refCounts[this._name];\n }\n\n public setSource(source: string) {\n this._source = source;\n }\n}\n","import {DateTime} from '../../datetime';\nimport {FieldDef, isScaleFieldDef, vgField} from '../../fielddef';\nimport {fieldFilterExpression} from '../../predicate';\nimport {isSortArray} from '../../sort';\nimport {duplicate} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\nimport {ModelWithField} from '../model';\nimport {SingleDefChannel} from './../../channel';\nimport {CalculateTransform} from './../../transform';\nimport {DataFlowNode} from './dataflow';\n\n/**\n * We don't know what a calculate node depends on so we should never move it beyond anything that produces fields.\n */\nexport class CalculateNode extends DataFlowNode {\n public clone() {\n return new CalculateNode(null, duplicate(this.transform));\n }\n\n constructor(parent: DataFlowNode, private transform: CalculateTransform) {\n super(parent);\n }\n\n public static parseAllForSortIndex(parent: DataFlowNode, model: ModelWithField) {\n // get all the encoding with sort fields from model\n model.forEachFieldDef((fieldDef: FieldDef, channel: SingleDefChannel) => {\n if (!isScaleFieldDef(fieldDef)) {\n return;\n }\n if (isSortArray(fieldDef.sort)) {\n const {field, timeUnit} = fieldDef;\n const sort: (number | string | boolean | DateTime)[] = fieldDef.sort;\n // generate `datum[\"a\"] === val0 ? 0 : datum[\"a\"] === val1 ? 1 : ... : n` via FieldEqualPredicate\n const calculate = sort.map((sortValue, i) => {\n return `${fieldFilterExpression({field, timeUnit, equal: sortValue})} ? ${i} : `;\n }).join('') + sort.length;\n\n parent = new CalculateNode(parent, {\n calculate,\n as: sortArrayIndexField(fieldDef, channel)\n });\n }\n });\n return parent;\n }\n\n public producedFields() {\n const out = {};\n out[this.transform.as] = true;\n return out;\n }\n\n public assemble(): VgFormulaTransform {\n return {\n type: 'formula',\n expr: this.transform.calculate,\n as: this.transform.as\n };\n }\n}\n\nexport function sortArrayIndexField(fieldDef: FieldDef, channel: SingleDefChannel, expr?: 'datum') {\n return vgField(fieldDef, {prefix: channel, suffix: 'sort_index', expr});\n}\n","/**\n * Utility for generating row / column headers\n */\nimport {isArray} from 'vega-util';\nimport {Config} from '../../config';\nimport {FacetFieldDef} from '../../facet';\nimport {vgField} from '../../fielddef';\nimport {HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP, HeaderConfig} from '../../header';\nimport {isSortField} from '../../sort';\nimport {keys} from '../../util';\nimport {AxisOrient, VgAxis, VgComparator, VgMarkGroup, VgTitleConfig} from '../../vega.schema';\nimport {formatSignalRef} from '../common';\nimport {sortArrayIndexField} from '../data/calculate';\nimport {Model} from '../model';\n\n\nexport type HeaderChannel = 'row' | 'column';\nexport const HEADER_CHANNELS: HeaderChannel[] = ['row', 'column'];\n\nexport type HeaderType = 'header' | 'footer';\nexport const HEADER_TYPES: HeaderType[] = ['header', 'footer'];\n\n/**\n * A component that represents all header, footers and title of a Vega group with layout directive.\n */\nexport interface LayoutHeaderComponent {\n title?: string;\n\n // TODO: repeat and concat can have multiple header / footer.\n // Need to redesign this part a bit.\n\n facetFieldDef?: FacetFieldDef;\n\n /**\n * An array of header components for headers.\n * For facet, there should be only one header component, which is data-driven.\n * For repeat and concat, there can be multiple header components that explicitly list different axes.\n */\n header?: HeaderComponent[];\n\n /**\n * An array of header components for footers.\n * For facet, there should be only one header component, which is data-driven.\n * For repeat and concat, there can be multiple header components that explicitly list different axes.\n */\n footer?: HeaderComponent[];\n}\n\n/**\n * A component that represents one group of row/column-header/footer.\n */\nexport interface HeaderComponent {\n\n labels: boolean;\n\n sizeSignal: {signal: string};\n\n axes: VgAxis[];\n}\n\nexport function getHeaderType(orient: AxisOrient) {\n if (orient === 'top' || orient === 'left') {\n return 'header';\n }\n return 'footer';\n}\n\nexport function getTitleGroup(model: Model, channel: HeaderChannel) {\n const title = model.component.layoutHeaders[channel].title;\n const textOrient = channel === 'row' ? 'left' : undefined;\n const config = model.config? model.config : undefined;\n const facetFieldDef = model.component.layoutHeaders[channel].facetFieldDef? model.component.layoutHeaders[channel].facetFieldDef : undefined;\n\n return {\n name: `${channel}-title`,\n type: 'group',\n role: `${channel}-title`,\n title: {\n text: title,\n offset: 10,\n orient: textOrient,\n style: 'guide-title',\n ...getHeaderProperties(config, facetFieldDef, HEADER_TITLE_PROPERTIES, HEADER_TITLE_PROPERTIES_MAP)\n }\n };\n}\n\nexport function getHeaderGroups(model: Model, channel: HeaderChannel): VgMarkGroup[] {\n const layoutHeader = model.component.layoutHeaders[channel];\n const groups = [];\n for (const headerType of HEADER_TYPES) {\n if (layoutHeader[headerType]) {\n for (const headerCmpt of layoutHeader[headerType]) {\n groups.push(getHeaderGroup(model, channel, headerType, layoutHeader, headerCmpt));\n }\n }\n }\n return groups;\n}\n\n// 0, (0,90), 90, (90, 180), 180, (180, 270), 270, (270, 0)\n\nexport function labelAlign(angle: number) {\n // to keep angle in [0, 360)\n angle = ((angle % 360) + 360) % 360;\n if ((angle + 90) % 180 === 0) { // for 90 and 270\n return {}; // default center\n } else if (angle < 90 || 270 < angle) {\n return {align: {value: 'right'}};\n } else if (135 <= angle && angle < 225) {\n return {align: {value: 'left'}};\n }\n return {};\n}\n\nexport function labelBaseline(angle: number) {\n // to keep angle in [0, 360)\n angle = ((angle % 360) + 360) % 360;\n if (45 <= angle && angle <= 135) {\n return {baseline: 'top'};\n }\n return {baseline: 'middle'};\n}\n\nfunction getSort(facetFieldDef: FacetFieldDef, channel: 'row' | 'column'): VgComparator {\n const {sort} = facetFieldDef;\n if (isSortField(sort)) {\n return {\n field: vgField(sort, {expr: 'datum'}),\n order: sort.order || 'ascending'\n };\n } else if (isArray(sort)) {\n return {\n field: sortArrayIndexField(facetFieldDef, channel, 'datum'),\n order: 'ascending'\n };\n } else {\n return {\n field: vgField(facetFieldDef, {expr: 'datum'}),\n order: sort || 'ascending'\n };\n }\n}\n\nexport function getHeaderGroup(model: Model, channel: HeaderChannel, headerType: HeaderType, layoutHeader: LayoutHeaderComponent, headerCmpt: HeaderComponent) {\n if (headerCmpt) {\n let title = null;\n const {facetFieldDef} = layoutHeader;\n if (facetFieldDef && headerCmpt.labels) {\n const {header = {}} = facetFieldDef;\n const {format, labelAngle} = header;\n const config = model.config? model.config : undefined;\n\n const update = {\n ...labelAlign(labelAngle)\n };\n\n title = {\n text: formatSignalRef(facetFieldDef, format, 'parent', model.config),\n offset: 10,\n orient: channel === 'row' ? 'left' : 'top',\n style: 'guide-label',\n ...getHeaderProperties(config, facetFieldDef, HEADER_LABEL_PROPERTIES, HEADER_LABEL_PROPERTIES_MAP),\n ...(keys(update).length > 0 ? {encode: {update}} : {})\n };\n }\n\n const axes = headerCmpt.axes;\n\n const hasAxes = axes && axes.length > 0;\n if (title || hasAxes) {\n const sizeChannel = channel === 'row' ? 'height' : 'width';\n\n\n\n return {\n name: model.getName(`${channel}_${headerType}`),\n type: 'group',\n role: `${channel}-${headerType}`,\n ...(layoutHeader.facetFieldDef ? {\n from: {data: model.getName(channel + '_domain')},\n sort: getSort(facetFieldDef, channel)\n } : {}),\n ...(title ? {title} : {}),\n ...(headerCmpt.sizeSignal ? {\n encode: {\n update: {\n [sizeChannel]: headerCmpt.sizeSignal\n }\n }\n }: {}),\n ...(hasAxes ? {axes} : {})\n };\n }\n }\n return null;\n}\n\nexport function getHeaderProperties(config: Config, facetFieldDef: FacetFieldDef, properties: string[], propertiesMap: {[k in keyof HeaderConfig]: keyof VgTitleConfig}) {\n const props = {};\n for (const prop of properties) {\n if (config && config.header) {\n if (config.header[prop]) {\n props[propertiesMap[prop]] = config.header[prop];\n }\n }\n if (facetFieldDef && facetFieldDef.header) {\n if (facetFieldDef.header[prop]) {\n props[propertiesMap[prop]] = facetFieldDef.header[prop];\n }\n }\n }\n return props;\n}\n","\nimport {hasDiscreteDomain} from '../../scale';\nimport {isVgRangeStep, VgRangeStep, VgSignal} from '../../vega.schema';\nimport {isFacetModel, Model} from '../model';\nimport {ScaleComponent} from '../scale/component';\n\nexport function assembleLayoutSignals(model: Model): VgSignal[] {\n return [].concat(\n sizeSignals(model, 'width'),\n sizeSignals(model, 'height')\n );\n}\n\nexport function sizeSignals(model: Model, sizeType: 'width' | 'height'): VgSignal[] {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const size = model.component.layoutSize.get(sizeType);\n if (!size || size === 'merged') {\n return [];\n }\n\n // Read size signal name from name map, just in case it is the top-level size signal that got renamed.\n const name = model.getSizeSignalRef(sizeType).signal;\n\n if (size === 'range-step') {\n const scaleComponent = model.getScaleComponent(channel);\n\n if (scaleComponent) {\n const type = scaleComponent.get('type');\n const range = scaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const scaleName = model.scaleName(channel);\n\n if (isFacetModel(model.parent)) {\n // If parent is facet and this is an independent scale, return only signal signal\n // as the width/height will be calculated using the cardinality from\n // facet's aggregate rather than reading from scale domain\n const parentResolve = model.parent.component.resolve;\n if (parentResolve.scale[channel] === 'independent') {\n return [stepSignal(scaleName, range)];\n }\n }\n\n return [\n stepSignal(scaleName, range),\n {\n name,\n update: sizeExpr(scaleName, scaleComponent, `domain('${scaleName}').length`)\n }\n ];\n }\n }\n /* istanbul ignore next: Condition should not happen -- only for warning in development. */\n throw new Error('layout size is range step although there is no rangeStep.');\n } else {\n return [{\n name,\n value: size\n }];\n }\n}\n\nfunction stepSignal(scaleName: string, range: VgRangeStep): VgSignal {\n return {\n name: scaleName + '_step',\n value: range.step,\n };\n}\n\nexport function sizeExpr(scaleName: string, scaleComponent: ScaleComponent, cardinality: string) {\n const type = scaleComponent.get('type');\n const padding = scaleComponent.get('padding');\n let paddingOuter = scaleComponent.get('paddingOuter');\n paddingOuter = paddingOuter !== undefined ? paddingOuter : padding;\n\n let paddingInner = scaleComponent.get('paddingInner');\n paddingInner = type === 'band' ?\n // only band has real paddingInner\n (paddingInner !== undefined ? paddingInner : padding) :\n // For point, as calculated in https://github.com/vega/vega-scale/blob/master/src/band.js#L128,\n // it's equivalent to have paddingInner = 1 since there is only n-1 steps between n points.\n 1;\n return `bandspace(${cardinality}, ${paddingInner}, ${paddingOuter}) * ${scaleName}_step`;\n}\n\n\n","import {POSITION_SCALE_CHANNELS, ScaleChannel} from '../channel';\nimport * as log from '../log';\nimport {Resolve, ResolveMode} from '../resolve';\nimport {contains} from '../util';\nimport {isConcatModel, isFacetModel, isLayerModel, isRepeatModel, Model} from './model';\n\nexport function defaultScaleResolve(channel: ScaleChannel, model: Model): ResolveMode {\n if (isLayerModel(model) || isFacetModel(model)) {\n return 'shared';\n } else if (isConcatModel(model) || isRepeatModel(model)) {\n return contains(POSITION_SCALE_CHANNELS, channel) ? 'independent' : 'shared';\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('invalid model type for resolve');\n}\n\nexport function parseGuideResolve(resolve: Resolve, channel: ScaleChannel): ResolveMode {\n const channelScaleResolve = resolve.scale[channel];\n const guide = contains(POSITION_SCALE_CHANNELS, channel) ? 'axis' : 'legend';\n\n if (channelScaleResolve === 'independent') {\n if (resolve[guide][channel] === 'shared') {\n log.warn(log.message.independentScaleMeansIndependentGuide(channel));\n }\n return 'independent';\n }\n\n return resolve[guide][channel] || 'shared';\n}\n","import * as log from '../log';\nimport {duplicate, keys, stringify} from '../util';\n\n\n/**\n * Generic class for storing properties that are explicitly specified\n * and implicitly determined by the compiler.\n * This is important for scale/axis/legend merging as\n * we want to prioritize properties that users explicitly specified.\n */\nexport class Split {\n constructor(\n public readonly explicit: Partial = {},\n public readonly implicit: Partial = {}\n ) {}\n\n public clone() {\n return new Split(duplicate(this.explicit), duplicate(this.implicit));\n }\n\n public combine(): Partial {\n // FIXME remove \"as any\".\n // Add \"as any\" to avoid an error \"Spread types may only be created from object types\".\n return {\n ...this.explicit as any, // Explicit properties comes first\n ...this.implicit as any\n };\n }\n\n public get(key: K): T[K] {\n // Explicit has higher precedence\n return this.explicit[key] !== undefined ? this.explicit[key] : this.implicit[key];\n }\n\n public getWithExplicit(key: K): Explicit {\n // Explicit has higher precedence\n if (this.explicit[key] !== undefined) {\n return {explicit: true, value: this.explicit[key]};\n } else if (this.implicit[key] !== undefined) {\n return {explicit: false, value: this.implicit[key]};\n }\n return {explicit: false, value: undefined};\n }\n\n public setWithExplicit(key: K, value: Explicit) {\n if (value.value !== undefined) {\n this.set(key, value.value, value.explicit);\n }\n }\n\n public set(key: K, value: T[K], explicit: boolean) {\n delete this[explicit ? 'implicit' : 'explicit'][key];\n this[explicit ? 'explicit' : 'implicit'][key] = value;\n return this;\n }\n\n public copyKeyFromSplit(key: keyof T, s: Split) {\n // Explicit has higher precedence\n if (s.explicit[key] !== undefined) {\n this.set(key, s.explicit[key], true);\n } else if (s.implicit[key] !== undefined) {\n this.set(key, s.implicit[key], false);\n }\n }\n public copyKeyFromObject>(key: keyof T, s: S) {\n // Explicit has higher precedence\n if (s[key] !== undefined) {\n this.set(key, s[key], true);\n }\n }\n\n /**\n * Merge split object into this split object. Properties from the other split\n * overwrite properties from this split.\n */\n public copyAll(other: Split) {\n for (const key of keys(other.combine())) {\n const val = other.getWithExplicit(key);\n this.setWithExplicit(key, val);\n }\n }\n}\n\nexport interface Explicit {\n explicit: boolean;\n value: T;\n}\n\n\nexport function makeExplicit(value: T): Explicit {\n return {\n explicit: true,\n value\n };\n}\n\nexport function makeImplicit(value: T): Explicit {\n return {\n explicit: false,\n value\n };\n}\n\nexport function tieBreakByComparing(compare: (v1: T, v2: T) => number) {\n return (v1: Explicit, v2: Explicit, property: keyof S | never, propertyOf: string | number | symbol): Explicit => {\n const diff = compare(v1.value, v2.value);\n if (diff > 0) {\n return v1;\n } else if (diff < 0) {\n return v2;\n }\n return defaultTieBreaker(v1, v2, property, propertyOf);\n };\n}\n\nexport function defaultTieBreaker(v1: Explicit, v2: Explicit, property: keyof S, propertyOf: string | number | symbol) {\n if (v1.explicit && v2.explicit) {\n log.warn(log.message.mergeConflictingProperty(property, propertyOf, v1.value, v2.value));\n }\n // If equal score, prefer v1.\n return v1;\n}\n\nexport function mergeValuesWithExplicit(\n v1: Explicit, v2: Explicit,\n property: keyof S,\n propertyOf: 'scale' | 'axis' | 'legend' | '',\n tieBreaker: (v1: Explicit, v2: Explicit, property: keyof S, propertyOf: string) => Explicit = defaultTieBreaker\n ) {\n if (v1 === undefined || v1.value === undefined) {\n // For first run\n return v2;\n }\n\n if (v1.explicit && !v2.explicit) {\n return v1;\n } else if (v2.explicit && !v1.explicit) {\n return v2;\n } else if (stringify(v1.value) === stringify(v2.value)) {\n return v1;\n } else {\n return tieBreaker(v1, v2, property, propertyOf);\n }\n}\n","import {Legend} from '../..//legend';\nimport {NonPositionScaleChannel} from '../../channel';\nimport {VgLegend} from '../../vega.schema';\nimport {Split} from '../split';\n\n\nexport class LegendComponent extends Split {}\n\n// Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\nexport type LegendComponentIndex = {[P in NonPositionScaleChannel]?: LegendComponent};\n\nexport type LegendIndex = {[P in NonPositionScaleChannel]?: Legend};\n","import {isArray} from 'vega-util';\n\nimport {Channel, COLOR, NonPositionScaleChannel, OPACITY, SHAPE} from '../../channel';\nimport {\n Conditional,\n FieldDef,\n FieldDefWithCondition,\n hasConditionalValueDef,\n isTimeFieldDef,\n isValueDef,\n MarkPropFieldDef,\n ValueDef,\n ValueDefWithCondition,\n} from '../../fielddef';\nimport {AREA, BAR, CIRCLE, FILL_STROKE_CONFIG, GEOSHAPE, LINE, POINT, SQUARE, TEXT, TICK} from '../../mark';\nimport {ScaleType} from '../../scale';\nimport {keys} from '../../util';\nimport {LegendType, VgEncodeEntry} from '../../vega.schema';\nimport {applyMarkConfig, timeFormatExpression} from '../common';\nimport * as mixins from '../mark/mixins';\nimport {UnitModel} from '../unit';\n\nexport function symbols(fieldDef: FieldDef, symbolsSpec: any, model: UnitModel, channel: Channel, type: LegendType): VgEncodeEntry {\n if (type === 'gradient') {\n return undefined;\n }\n\n let out = {\n ...applyMarkConfig({}, model, FILL_STROKE_CONFIG),\n ...mixins.color(model)\n };\n\n switch (model.mark) {\n case BAR:\n case TICK:\n case TEXT:\n out.shape = {value: 'square'};\n break;\n case CIRCLE:\n case SQUARE:\n out.shape = {value: model.mark};\n break;\n case POINT:\n case LINE:\n case GEOSHAPE:\n case AREA:\n // use default circle\n break;\n }\n\n const {markDef, encoding} = model;\n const filled = markDef.filled;\n\n if (out.fill) {\n // for fill legend, we don't want any fill in symbol\n if (channel === 'fill' || (filled && channel === COLOR)) {\n delete out.fill;\n } else {\n if (out.fill['field']) {\n // For others, remove fill field\n delete out.fill;\n } else if (isArray(out.fill)) {\n const fill = getFirstConditionValue(encoding.fill || encoding.color) || markDef.fill || (filled && markDef.color);\n if (fill) {\n out.fill = {value: fill};\n }\n }\n }\n }\n\n if (out.stroke) {\n if (channel === 'stroke' || (!filled && channel === COLOR)) {\n delete out.stroke;\n } else {\n if (out.stroke['field']) {\n // For others, remove stroke field\n delete out.stroke;\n } else if (isArray(out.stroke)) {\n const stroke = getFirstConditionValue(encoding.stroke || encoding.color) || markDef.stroke || (!filled && markDef.color);\n if (stroke) {\n out.stroke = {value: stroke};\n }\n }\n }\n }\n\n if (out.fill && out.fill['value'] !== 'transparent' && !out.stroke) {\n // for non color channel's legend, we need to override symbol stroke config from Vega config\n out.stroke = {value: 'transparent'};\n }\n\n if (channel !== SHAPE) {\n const shape = getFirstConditionValue(encoding.shape) || markDef.shape;\n if (shape) {\n out.shape = {value: shape};\n }\n }\n\n if (channel !== OPACITY) {\n const opacity = getMaxValue(encoding.opacity) || markDef.opacity;\n if (opacity) { // only apply opacity if it is neither zero or undefined\n out.opacity = {value: opacity};\n }\n }\n\n out = {...out, ...symbolsSpec};\n\n return keys(out).length > 0 ? out : undefined;\n}\n\nexport function gradient(fieldDef: FieldDef, gradientSpec: any, model: UnitModel, channel: Channel, type: LegendType) {\n let out: any = {};\n\n if (type === 'gradient') {\n const opacity = getMaxValue(model.encoding.opacity) || model.markDef.opacity;\n if (opacity) { // only apply opacity if it is neither zero or undefined\n out.opacity = {value: opacity};\n }\n }\n\n out = {...out, ...gradientSpec};\n return keys(out).length > 0 ? out : undefined;\n}\n\nexport function labels(fieldDef: FieldDef, labelsSpec: any, model: UnitModel, channel: NonPositionScaleChannel, type: LegendType) {\n const legend = model.legend(channel);\n const config = model.config;\n\n let out: any = {};\n\n if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC;\n const expr = timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat, isUTCScale);\n labelsSpec = {\n ...(expr ? {text: {signal: expr}} : {}),\n ...labelsSpec,\n };\n }\n\n out = {...out, ...labelsSpec};\n\n return keys(out).length > 0 ? out : undefined;\n}\n\nfunction getMaxValue(channelDef: FieldDefWithCondition> | ValueDefWithCondition>) {\n return getConditionValue(channelDef,\n (v: number, conditionalDef) => Math.max(v, conditionalDef.value as any)\n );\n}\n\nfunction getFirstConditionValue(channelDef: FieldDefWithCondition> | ValueDefWithCondition>) {\n return getConditionValue(channelDef,\n (v: number, conditionalDef) => v !== undefined ? v : conditionalDef.value\n );\n}\n\nfunction getConditionValue(\n channelDef: FieldDefWithCondition> | ValueDefWithCondition>,\n reducer: (val: T, conditionalDef: Conditional) => T\n): T {\n\n if (hasConditionalValueDef(channelDef)) {\n return (isArray(channelDef.condition) ? channelDef.condition : [channelDef.condition])\n .reduce(reducer, channelDef.value as any);\n } else if (isValueDef(channelDef)) {\n return channelDef.value as any;\n }\n return undefined;\n}\n","import {COLOR, FILL, NonPositionScaleChannel, OPACITY, SHAPE, SIZE, STROKE} from '../../channel';\nimport {isFieldDef, title as fieldDefTitle} from '../../fielddef';\nimport {Legend, LEGEND_PROPERTIES, VG_LEGEND_PROPERTIES} from '../../legend';\nimport {GEOJSON} from '../../type';\nimport {deleteNestedProperty, keys} from '../../util';\nimport {VgLegend, VgLegendEncode} from '../../vega.schema';\nimport {getSpecifiedOrDefaultValue, guideEncodeEntry, mergeTitleComponent, numberFormat} from '../common';\nimport {isUnitModel, Model} from '../model';\nimport {parseGuideResolve} from '../resolve';\nimport {defaultTieBreaker, Explicit, makeImplicit, mergeValuesWithExplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {LegendComponent, LegendComponentIndex} from './component';\nimport * as encode from './encode';\nimport * as properties from './properties';\n\n\nexport function parseLegend(model: Model) {\n if (isUnitModel(model)) {\n model.component.legends = parseUnitLegend(model);\n } else {\n model.component.legends = parseNonUnitLegend(model);\n }\n}\n\nfunction parseUnitLegend(model: UnitModel): LegendComponentIndex {\n const {encoding} = model;\n return [COLOR, FILL, STROKE, SIZE, SHAPE, OPACITY].reduce(function (legendComponent, channel) {\n const def = encoding[channel];\n if (model.legend(channel) && model.getScaleComponent(channel) && !(isFieldDef(def) && (channel === SHAPE && def.type === GEOJSON))) {\n legendComponent[channel] = parseLegendForChannel(model, channel);\n }\n return legendComponent;\n }, {});\n}\n\nfunction getLegendDefWithScale(model: UnitModel, channel: NonPositionScaleChannel): VgLegend {\n // For binned field with continuous scale, use a special scale so we can overrride the mark props and labels\n switch (channel) {\n case COLOR:\n const scale = model.scaleName(COLOR);\n return model.markDef.filled ? {fill: scale} : {stroke: scale};\n case FILL:\n case STROKE:\n case SIZE:\n case SHAPE:\n case OPACITY:\n return {[channel]: model.scaleName(channel)};\n }\n}\n\nexport function parseLegendForChannel(model: UnitModel, channel: NonPositionScaleChannel): LegendComponent {\n const fieldDef = model.fieldDef(channel);\n const legend = model.legend(channel);\n\n const legendCmpt = new LegendComponent({}, getLegendDefWithScale(model, channel));\n\n LEGEND_PROPERTIES.forEach(function(property) {\n const value = getProperty(property, legend, channel, model);\n if (value !== undefined) {\n const explicit =\n // specified legend.values is already respected, but may get transformed.\n property === 'values' ? !!legend.values :\n // title can be explicit if fieldDef.title is set\n property === 'title' && value === model.fieldDef(channel).title ? true :\n // Otherwise, things are explicit if the returned value matches the specified property\n value === legend[property];\n if (explicit || model.config.legend[property] === undefined) {\n legendCmpt.set(property, value, explicit);\n }\n }\n });\n\n // 2) Add mark property definition groups\n const legendEncoding = legend.encoding || {};\n const legendEncode = ['labels', 'legend', 'title', 'symbols', 'gradient'].reduce((e: VgLegendEncode, part) => {\n const legendEncodingPart = guideEncodeEntry(legendEncoding[part] || {}, model);\n const value = encode[part] ?\n // TODO: replace legendCmpt with type is sufficient\n encode[part](fieldDef, legendEncodingPart, model, channel, legendCmpt.get('type')) : // apply rule\n legendEncodingPart; // no rule -- just default values\n if (value !== undefined && keys(value).length > 0) {\n e[part] = {update: value};\n }\n return e;\n }, {} as VgLegendEncode);\n\n if (keys(legendEncode).length > 0) {\n legendCmpt.set('encode', legendEncode, !!legend.encoding);\n }\n\n return legendCmpt;\n}\n\nfunction getProperty(property: keyof (Legend | VgLegend), specifiedLegend: Legend, channel: NonPositionScaleChannel, model: UnitModel) {\n const fieldDef = model.fieldDef(channel);\n\n switch (property) {\n case 'format':\n // We don't include temporal field here as we apply format in encode block\n return numberFormat(fieldDef, specifiedLegend.format, model.config);\n case 'title':\n // For falsy value, keep undefined so we use default,\n // but use null for '', null, and false to hide the title\n const specifiedTitle = fieldDef.title !== undefined ? fieldDef.title :\n specifiedLegend.title || (specifiedLegend.title === undefined ? undefined : null);\n\n return getSpecifiedOrDefaultValue(\n specifiedTitle,\n fieldDefTitle(fieldDef, model.config)\n ) || undefined; // make falsy value undefined so output Vega spec is shorter\n case 'values':\n return properties.values(specifiedLegend, fieldDef);\n case 'type':\n return getSpecifiedOrDefaultValue(specifiedLegend.type, properties.type(fieldDef.type, channel, model.getScaleComponent(channel).get('type')));\n }\n\n // Otherwise, return specified property.\n return specifiedLegend[property];\n}\n\nfunction parseNonUnitLegend(model: Model) {\n const {legends, resolve} = model.component;\n\n for (const child of model.children) {\n parseLegend(child);\n\n keys(child.component.legends).forEach((channel: NonPositionScaleChannel) => {\n resolve.legend[channel] = parseGuideResolve(model.component.resolve, channel);\n\n if (resolve.legend[channel] === 'shared') {\n // If the resolve says shared (and has not been overridden)\n // We will try to merge and see if there is a conflict\n\n legends[channel] = mergeLegendComponent(legends[channel], child.component.legends[channel]);\n\n if (!legends[channel]) {\n // If merge returns nothing, there is a conflict so we cannot make the legend shared.\n // Thus, mark legend as independent and remove the legend component.\n resolve.legend[channel] = 'independent';\n delete legends[channel];\n }\n }\n });\n }\n\n keys(legends).forEach((channel: NonPositionScaleChannel) => {\n for (const child of model.children) {\n if (!child.component.legends[channel]) {\n // skip if the child does not have a particular legend\n continue;\n }\n\n if (resolve.legend[channel] === 'shared') {\n // After merging shared legend, make sure to remove legend from child\n delete child.component.legends[channel];\n }\n }\n });\n return legends;\n}\n\nexport function mergeLegendComponent(mergedLegend: LegendComponent, childLegend: LegendComponent): LegendComponent {\n if (!mergedLegend) {\n return childLegend.clone();\n }\n const mergedOrient = mergedLegend.getWithExplicit('orient');\n const childOrient = childLegend.getWithExplicit('orient');\n\n\n if (mergedOrient.explicit && childOrient.explicit && mergedOrient.value !== childOrient.value) {\n // TODO: throw warning if resolve is explicit (We don't have info about explicit/implicit resolve yet.)\n // Cannot merge due to inconsistent orient\n return undefined;\n }\n let typeMerged = false;\n // Otherwise, let's merge\n for (const prop of VG_LEGEND_PROPERTIES) {\n const mergedValueWithExplicit = mergeValuesWithExplicit(\n mergedLegend.getWithExplicit(prop),\n childLegend.getWithExplicit(prop),\n prop, 'legend',\n\n // Tie breaker function\n (v1: Explicit, v2: Explicit): any => {\n switch (prop) {\n case 'title':\n return mergeTitleComponent(v1, v2);\n case 'type':\n // There are only two types. If we have different types, then prefer symbol over gradient.\n typeMerged = true;\n return makeImplicit('symbol');\n }\n return defaultTieBreaker(v1, v2, prop, 'legend');\n }\n );\n mergedLegend.setWithExplicit(prop, mergedValueWithExplicit);\n }\n if (typeMerged) {\n if(((mergedLegend.implicit || {}).encode || {}).gradient) {\n deleteNestedProperty(mergedLegend.implicit, ['encode', 'gradient']);\n }\n if (((mergedLegend.explicit || {}).encode || {}).gradient) {\n deleteNestedProperty(mergedLegend.explicit, ['encode', 'gradient']);\n }\n }\n\n\n return mergedLegend;\n}\n\n","import {Channel, isColorChannel} from '../../channel';\nimport {FieldDef, valueArray} from '../../fielddef';\nimport {Legend} from '../../legend';\nimport {isBinScale, ScaleType} from '../../scale';\nimport {Type} from '../../type';\nimport {contains} from '../../util';\n\nexport function values(legend: Legend, fieldDef: FieldDef) {\n const vals = legend.values;\n\n if (vals) {\n return valueArray(fieldDef, vals);\n }\n return undefined;\n}\n\nexport function type(t: Type, channel: Channel, scaleType: ScaleType): 'gradient' {\n if (\n isColorChannel(channel) && (\n (t === 'quantitative' && !isBinScale(scaleType)) ||\n (t === 'temporal' && contains(['time', 'utc'], scaleType))\n )\n ) {\n return 'gradient';\n }\n return undefined;\n}\n","import {flatten, keys, stringify, vals} from '../../util';\nimport {VgLegend} from '../../vega.schema';\nimport {Model} from '../model';\nimport {LegendComponent} from './component';\nimport {mergeLegendComponent} from './parse';\n\nexport function assembleLegends(model: Model): VgLegend[] {\n const legendComponentIndex = model.component.legends;\n const legendByDomain: {[domainHash: string]: LegendComponent[]} = {};\n\n for (const channel of keys(legendComponentIndex)) {\n const scaleComponent = model.getScaleComponent(channel);\n const domainHash = stringify(scaleComponent.domains);\n if (legendByDomain[domainHash]) {\n for (const mergedLegendComponent of legendByDomain[domainHash]) {\n const merged = mergeLegendComponent(mergedLegendComponent, legendComponentIndex[channel]);\n if (!merged) {\n // If cannot merge, need to add this legend separately\n legendByDomain[domainHash].push(legendComponentIndex[channel]);\n }\n }\n\n } else {\n legendByDomain[domainHash] = [legendComponentIndex[channel].clone()];\n }\n }\n\n return flatten(vals(legendByDomain)).map((legendCmpt: LegendComponent) => legendCmpt.combine());\n}\n","import {contains} from '../../util';\nimport {isVgSignalRef, VgProjection, VgSignalRef} from '../../vega.schema';\nimport {isConcatModel, isLayerModel, isRepeatModel, Model} from '../model';\n\nexport function assembleProjections(model: Model): VgProjection[] {\n if (isLayerModel(model) || isConcatModel(model) || isRepeatModel(model)) {\n return assembleProjectionsForModelAndChildren(model);\n } else {\n return assembleProjectionForModel(model);\n }\n}\n\nexport function assembleProjectionsForModelAndChildren(model: Model): VgProjection[] {\n return model.children.reduce((projections, child) => {\n return projections.concat(child.assembleProjections());\n }, assembleProjectionForModel(model));\n}\n\nexport function assembleProjectionForModel(model: Model): VgProjection[] {\n const component = model.component.projection;\n if (!component || component.merged) {\n return [];\n }\n\n const projection = component.combine();\n const {name, ...rest} = projection; // we need to extract name so that it is always present in the output and pass TS type validation\n\n const size: VgSignalRef = {\n signal: `[${component.size.map((ref) => ref.signal).join(', ')}]`\n };\n\n const fit: string[] = component.data.reduce((sources, data) => {\n const source: string = isVgSignalRef(data) ? data.signal : `data('${model.lookupDataSource(data)}')`;\n if (!contains(sources, source)) {\n // build a unique list of sources\n sources.push(source);\n }\n return sources;\n }, []);\n\n if (fit.length <= 0) {\n throw new Error(\"Projection's fit didn't find any data sources\");\n }\n\n return [{\n name,\n size,\n fit: {\n signal: fit.length > 1 ? `[${fit.join(', ')}]` : fit[0]\n },\n ...rest\n }];\n}\n","\nimport {VgProjectionType} from './vega.schema';\n\nexport type ProjectionType = VgProjectionType;\n\nexport interface Projection {\n /**\n * The cartographic projection to use. This value is case-insensitive, for example `\"albers\"` and `\"Albers\"` indicate the same projection type. You can find all valid projection types [in the documentation](https://vega.github.io/vega-lite/docs/projection.html#projection-types).\n *\n * __Default value:__ `mercator`\n */\n type?: ProjectionType;\n\n /**\n * Sets the projection’s clipping circle radius to the specified angle in degrees. If `null`, switches to [antimeridian](http://bl.ocks.org/mbostock/3788999) cutting rather than small-circle clipping.\n */\n clipAngle?: number;\n\n /**\n * Sets the projection’s viewport clip extent to the specified bounds in pixels. The extent bounds are specified as an array `[[x0, y0], [x1, y1]]`, where `x0` is the left-side of the viewport, `y0` is the top, `x1` is the right and `y1` is the bottom. If `null`, no viewport clipping is performed.\n */\n clipExtent?: number[][];\n\n /**\n * Sets the projection’s center to the specified center, a two-element array of longitude and latitude in degrees.\n *\n * __Default value:__ `[0, 0]`\n */\n center?: number[];\n\n /**\n * Sets the projection’s three-axis rotation to the specified angles, which must be a two- or three-element array of numbers [`lambda`, `phi`, `gamma`] specifying the rotation angles in degrees about each spherical axis. (These correspond to yaw, pitch and roll.)\n *\n * __Default value:__ `[0, 0, 0]`\n */\n rotate?: number[];\n\n /**\n * Sets the threshold for the projection’s [adaptive resampling](http://bl.ocks.org/mbostock/3795544) to the specified value in pixels. This value corresponds to the [Douglas–Peucker distance](http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm). If precision is not specified, returns the projection’s current resampling precision which defaults to `√0.5 ≅ 0.70710…`.\n */\n precision?: String;\n\n /* The following properties are all supported for specific types of projections. Consult the d3-geo-projection library for more information: https://github.com/d3/d3-geo-projection */\n coefficient?: number;\n distance?: number;\n fraction?: number;\n lobes?: number;\n parallel?: number;\n radius?: number;\n ratio?: number;\n spacing?: number;\n tilt?: number;\n}\n\n/**\n * Any property of Projection can be in config\n */\nexport interface ProjectionConfig extends Projection { }\n\nexport const PROJECTION_PROPERTIES: (keyof Projection)[] = [\n 'type',\n 'clipAngle',\n 'clipExtent',\n 'center',\n 'rotate',\n 'precision',\n 'coefficient',\n 'distance',\n 'fraction',\n 'lobes',\n 'parallel',\n 'radius',\n 'ratio',\n 'spacing',\n 'tilt'\n];\n","import {Projection} from '../../projection';\nimport {VgProjection, VgSignalRef} from '../../vega.schema';\nimport {Split} from '../split';\n\nexport class ProjectionComponent extends Split {\n public merged = false;\n\n constructor(name: string, public specifiedProjection: Projection, public size: VgSignalRef[], public data: (string | VgSignalRef)[]) {\n super(\n {...specifiedProjection}, // all explicit properties of projection\n {name} // name as initial implicit property\n );\n }\n}\n","import {LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2, SHAPE} from '../../channel';\nimport {MAIN} from '../../data';\nimport {PROJECTION_PROPERTIES} from '../../projection';\nimport {GEOJSON} from '../../type';\nimport {duplicate, every, stringify} from '../../util';\nimport {VgSignalRef} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {UnitModel} from '../unit';\nimport {ProjectionComponent} from './component';\n\nexport function parseProjection(model: Model) {\n if (isUnitModel(model)) {\n model.component.projection = parseUnitProjection(model);\n } else {\n // because parse happens from leaves up (unit specs before layer spec),\n // we can be sure that the above if statement has already occurred\n // and therefore we have access to child.component.projection\n // for each of model's children\n model.component.projection = parseNonUnitProjections(model);\n }\n}\n\nfunction parseUnitProjection(model: UnitModel): ProjectionComponent {\n const {specifiedProjection, config, hasProjection} = model;\n\n if (hasProjection) {\n const data: (VgSignalRef | string)[] = [];\n\n [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach((posssiblePair) => {\n if (model.channelHasField(posssiblePair[0]) || model.channelHasField(posssiblePair[1])) {\n data.push({\n signal: model.getName(`geojson_${data.length}`)\n });\n }\n });\n\n if (model.channelHasField(SHAPE) && model.fieldDef(SHAPE).type === GEOJSON) {\n data.push({\n signal: model.getName(`geojson_${data.length}`)\n });\n }\n\n if (data.length === 0) {\n // main source is geojson, so we can just use that\n data.push(model.requestDataName(MAIN));\n }\n\n return new ProjectionComponent(model.projectionName(true), {\n ...(config.projection || {}),\n ...(specifiedProjection || {}),\n }, [model.getSizeSignalRef('width'), model.getSizeSignalRef('height')], data);\n }\n\n return undefined;\n}\n\n\nfunction mergeIfNoConflict(first: ProjectionComponent, second: ProjectionComponent): ProjectionComponent {\n const allPropertiesShared = every(PROJECTION_PROPERTIES, (prop) => {\n // neither has the poperty\n if (!first.explicit.hasOwnProperty(prop) &&\n !second.explicit.hasOwnProperty(prop)) {\n return true;\n }\n // both have property and an equal value for property\n if (first.explicit.hasOwnProperty(prop) &&\n second.explicit.hasOwnProperty(prop) &&\n // some properties might be signals or objects and require hashing for comparison\n stringify(first.get(prop)) === stringify(second.get(prop))) {\n return true;\n }\n return false;\n });\n\n const size = stringify(first.size) === stringify(second.size);\n if (size) {\n if (allPropertiesShared) {\n return first;\n } else if (stringify(first.explicit) === stringify({})) {\n return second;\n } else if (stringify(second.explicit) === stringify({})) {\n return first;\n }\n }\n\n // if all properties don't match, let each unit spec have its own projection\n return null;\n}\n\nfunction parseNonUnitProjections(model: Model): ProjectionComponent {\n if (model.children.length === 0) {\n return undefined;\n }\n\n let nonUnitProjection: ProjectionComponent;\n const mergable = every(model.children, (child) => {\n parseProjection(child);\n const projection = child.component.projection;\n if (!projection) {\n // child layer does not use a projection\n return true;\n } else if (!nonUnitProjection) {\n // cached 'projection' is null, cache this one\n nonUnitProjection = projection;\n return true;\n } else {\n const merge = mergeIfNoConflict(nonUnitProjection, projection);\n if (merge) {\n nonUnitProjection = merge;\n }\n return !!merge;\n }\n });\n\n // it cached one and all other children share the same projection,\n if (nonUnitProjection && mergable) {\n // so we can elevate it to the layer level\n const name = model.projectionName(true);\n const modelProjection = new ProjectionComponent(\n name,\n nonUnitProjection.specifiedProjection,\n nonUnitProjection.size,\n duplicate(nonUnitProjection.data)\n );\n\n // rename and assign all others as merged\n model.children.forEach((child) => {\n if (child.component.projection) {\n modelProjection.data = modelProjection.data.concat(child.component.projection.data);\n child.renameProjection(child.component.projection.get('name'), name);\n child.component.projection.merged = true;\n }\n });\n\n return modelProjection;\n }\n\n return undefined;\n}\n","import {AggregateOp} from 'vega';\n\nimport {Channel, isScaleChannel} from '../../channel';\nimport {FieldDef, vgField} from '../../fielddef';\nimport * as log from '../../log';\nimport {AggregateTransform} from '../../transform';\nimport {Dict, differ, duplicate, keys, StringSet} from '../../util';\nimport {VgAggregateTransform} from '../../vega.schema';\nimport {binRequiresRange} from '../common';\nimport {UnitModel} from './../unit';\nimport {DataFlowNode} from './dataflow';\n\nfunction addDimension(dims: {[field: string]: boolean}, channel: Channel, fieldDef: FieldDef) {\n if (fieldDef.bin) {\n dims[vgField(fieldDef, {})] = true;\n dims[vgField(fieldDef, {binSuffix: 'end'})] = true;\n\n if (binRequiresRange(fieldDef, channel)) {\n dims[vgField(fieldDef, {binSuffix: 'range'})] = true;\n }\n } else {\n dims[vgField(fieldDef)] = true;\n }\n return dims;\n}\n\nfunction mergeMeasures(parentMeasures: Dict>, childMeasures: Dict>) {\n for (const f in childMeasures) {\n if (childMeasures.hasOwnProperty(f)) {\n // when we merge a measure, we either have to add an aggregation operator or even a new field\n const ops = childMeasures[f];\n for (const op in ops) {\n if (ops.hasOwnProperty(op)) {\n if (f in parentMeasures) {\n // add operator to existing measure field\n parentMeasures[f][op] = ops[op];\n } else {\n parentMeasures[f] = {op: ops[op]};\n }\n }\n }\n }\n }\n}\n\nexport class AggregateNode extends DataFlowNode {\n public clone() {\n return new AggregateNode(null, {...this.dimensions}, duplicate(this.measures));\n }\n\n /**\n * @param dimensions string set for dimensions\n * @param measures dictionary mapping field name => dict of aggregation functions and names to use\n */\n constructor(parent: DataFlowNode, private dimensions: StringSet, private measures: Dict<{[key in AggregateOp]?: string}>) {\n super(parent);\n }\n\n public static makeFromEncoding(parent: DataFlowNode, model: UnitModel): AggregateNode {\n let isAggregate = false;\n model.forEachFieldDef(fd => {\n if (fd.aggregate) {\n isAggregate = true;\n }\n });\n\n const meas = {};\n const dims = {};\n\n if (!isAggregate) {\n // no need to create this node if the model has no aggregation\n return null;\n }\n\n model.forEachFieldDef((fieldDef, channel) => {\n const {aggregate, field} = fieldDef;\n if (aggregate) {\n if (aggregate === 'count') {\n meas['*'] = meas['*'] || {};\n meas['*']['count'] = vgField(fieldDef);\n } else {\n meas[field] = meas[field] || {};\n meas[field][aggregate] = vgField(fieldDef);\n\n // For scale channel with domain === 'unaggregated', add min/max so we can use their union as unaggregated domain\n if (isScaleChannel(channel) && model.scaleDomain(channel) === 'unaggregated') {\n meas[field]['min'] = vgField({field, aggregate: 'min'});\n meas[field]['max'] = vgField({field, aggregate: 'max'});\n }\n }\n } else {\n addDimension(dims, channel, fieldDef);\n }\n });\n\n if ((keys(dims).length + keys(meas).length) === 0) {\n return null;\n }\n\n return new AggregateNode(parent, dims, meas);\n }\n\n public static makeFromTransform(parent: DataFlowNode, t: AggregateTransform): AggregateNode {\n const dims = {};\n const meas = {};\n\n for (const s of t.aggregate) {\n const {op, field, as} = s;\n if (op) {\n if (op === 'count') {\n meas['*'] = meas['*'] || {};\n meas['*']['count'] = as || vgField(s);\n } else {\n meas[field] = meas[field] || {};\n meas[field][op] = as || vgField(s);\n }\n }\n }\n\n for (const s of t.groupby || []) {\n dims[s] = true;\n }\n\n if ((keys(dims).length + keys(meas).length) === 0) {\n return null;\n }\n\n return new AggregateNode(parent, dims, meas);\n }\n\n public merge(other: AggregateNode) {\n if (!differ(this.dimensions, other.dimensions)) {\n mergeMeasures(this.measures, other.measures);\n other.remove();\n } else {\n log.debug('different dimensions, cannot merge');\n }\n }\n\n public addDimensions(fields: string[]) {\n fields.forEach(f => this.dimensions[f] = true);\n }\n\n public dependentFields() {\n const out = {};\n\n keys(this.dimensions).forEach(f => out[f] = true);\n keys(this.measures).forEach(m => out[m] = true);\n\n return out;\n }\n\n public producedFields() {\n const out = {};\n\n keys(this.measures).forEach(field => {\n keys(this.measures[field]).forEach(op => {\n out[`${op}_${field}`] = true;\n });\n });\n\n return out;\n }\n\n public assemble(): VgAggregateTransform {\n const ops: AggregateOp[] = [];\n const fields: string[] = [];\n const as: string[] = [];\n\n for (const field of keys(this.measures)) {\n for (const op of keys(this.measures[field])) {\n as.push(this.measures[field][op]);\n ops.push(op);\n fields.push(field);\n }\n }\n\n const result: VgAggregateTransform = {\n type: 'aggregate',\n groupby: keys(this.dimensions),\n ops,\n fields,\n as\n };\n\n return result;\n }\n}\n","import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {COLUMN, ROW, ScaleChannel} from '../../channel';\nimport {vgField} from '../../fielddef';\nimport * as log from '../../log';\nimport {hasDiscreteDomain} from '../../scale';\nimport {EncodingSortField, isSortField} from '../../sort';\nimport {isVgRangeStep, VgData} from '../../vega.schema';\nimport {FacetModel} from '../facet';\nimport {Model} from '../model';\nimport {assembleDomain, getFieldFromDomain} from '../scale/domain';\nimport {sortArrayIndexField} from './calculate';\nimport {DataFlowNode} from './dataflow';\n\ntype ChildIndependentFieldsWithStep = {\n x?: string,\n y?: string\n};\n\ninterface FacetChannelInfo {\n name: string;\n fields: string[];\n sortField?: EncodingSortField;\n\n sortIndexField?: string;\n}\n\n/**\n * A node that helps us track what fields we are faceting by.\n */\nexport class FacetNode extends DataFlowNode {\n private readonly column: FacetChannelInfo;\n\n private readonly row: FacetChannelInfo;\n\n private readonly childModel: Model;\n\n /**\n * @param model The facet model.\n * @param name The name that this facet source will have.\n * @param data The source data for this facet data.\n */\n public constructor(parent: DataFlowNode, public readonly model: FacetModel, public readonly name: string, public data: string) {\n super(parent);\n\n for (const channel of [COLUMN, ROW]) {\n const fieldDef = model.facet[channel];\n if (fieldDef) {\n const {bin, sort} = fieldDef;\n this[channel] = {\n name: model.getName(`${channel}_domain`),\n fields: [\n vgField(fieldDef),\n ...(bin ? [vgField(fieldDef, {binSuffix: 'end'})] : [])\n ],\n ...(\n isSortField(sort) ? {sortField: sort} :\n isArray(sort) ? {sortIndexField: sortArrayIndexField(fieldDef, channel)} :\n {}\n )\n };\n }\n }\n this.childModel = model.child;\n }\n\n get fields() {\n return [\n ...(this.column && this.column.fields) || [],\n ...(this.row && this.row.fields) || []\n ];\n }\n\n /**\n * The name to reference this source is its name.\n */\n public getSource() {\n return this.name;\n }\n\n private getChildIndependentFieldsWithStep() {\n const childIndependentFieldsWithStep: ChildIndependentFieldsWithStep = {};\n\n for (const channel of ['x', 'y'] as ScaleChannel[]) {\n const childScaleComponent = this.childModel.component.scales[channel];\n if (childScaleComponent && !childScaleComponent.merged) {\n const type = childScaleComponent.get('type');\n const range = childScaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const domain = assembleDomain(this.childModel, channel);\n const field = getFieldFromDomain(domain);\n if (field) {\n childIndependentFieldsWithStep[channel] = field;\n } else {\n log.warn('Unknown field for ${channel}. Cannot calculate view size.');\n }\n }\n }\n }\n\n return childIndependentFieldsWithStep;\n }\n\n private assembleRowColumnData(channel: 'row' | 'column', crossedDataName: string, childIndependentFieldsWithStep: ChildIndependentFieldsWithStep): VgData {\n const childChannel = channel === 'row' ? 'y' : 'x';\n\n const fields: string[] = [];\n const ops: AggregateOp[] = [];\n const as: string[] = [];\n\n if (childIndependentFieldsWithStep[childChannel]) {\n if (crossedDataName) {\n // If there is a crossed data, calculate max\n fields.push(`distinct_${childIndependentFieldsWithStep[childChannel]}`);\n\n ops.push('max');\n } else {\n // If there is no crossed data, just calculate distinct\n fields.push(childIndependentFieldsWithStep[childChannel]);\n ops.push('distinct');\n }\n // Although it is technically a max, just name it distinct so it's easier to refer to it\n as.push(`distinct_${childIndependentFieldsWithStep[childChannel]}`);\n }\n\n const {sortField, sortIndexField} = this[channel];\n if (sortField) {\n const {op, field} = sortField;\n fields.push(field);\n ops.push(op);\n as.push(vgField(sortField));\n } else if (sortIndexField) {\n fields.push(sortIndexField);\n ops.push('max');\n as.push(sortIndexField);\n }\n\n return {\n name: this[channel].name,\n // Use data from the crossed one if it exist\n source: crossedDataName || this.data,\n transform: [{\n type: 'aggregate',\n groupby: this[channel].fields,\n ...(fields.length ? {\n fields, ops, as\n } : {})\n }]\n };\n }\n\n public assemble() {\n const data: VgData[] = [];\n let crossedDataName = null;\n const childIndependentFieldsWithStep = this.getChildIndependentFieldsWithStep();\n\n if (this.column && this.row && (childIndependentFieldsWithStep.x || childIndependentFieldsWithStep.y)) {\n // Need to create a cross dataset to correctly calculate cardinality\n crossedDataName = `cross_${this.column.name}_${this.row.name}`;\n\n const fields = [].concat(\n childIndependentFieldsWithStep.x ? [childIndependentFieldsWithStep.x] : [],\n childIndependentFieldsWithStep.y ? [childIndependentFieldsWithStep.y] : [],\n );\n const ops = fields.map((): AggregateOp => 'distinct');\n\n data.push({\n name: crossedDataName,\n source: this.data,\n transform: [{\n type: 'aggregate',\n groupby: [...this.column.fields, ...this.row.fields],\n fields,\n ops\n }]\n });\n }\n\n for (const channel of [COLUMN, ROW]) {\n if (this[channel]) {\n data.push(this.assembleRowColumnData(channel, crossedDataName, childIndependentFieldsWithStep));\n }\n }\n\n return data;\n }\n}\n","import {isScaleChannel} from '../../channel';\nimport {FieldDef, vgField as fieldRef} from '../../fielddef';\nimport {isPathMark} from '../../mark';\nimport {hasContinuousDomain, ScaleType} from '../../scale';\nimport {Dict, keys} from '../../util';\nimport {VgFilterTransform} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {DataFlowNode} from './dataflow';\n\nexport class FilterInvalidNode extends DataFlowNode {\n public clone() {\n return new FilterInvalidNode(null, {...this.fieldDefs});\n }\n\n constructor(parent: DataFlowNode, private fieldDefs: Dict>) {\n super(parent);\n }\n\n public static make(parent: DataFlowNode, model: UnitModel): FilterInvalidNode {\n const {config, mark} = model;\n if (config.invalidValues !== 'filter' ) {\n return null;\n }\n\n const filter = model.reduceFieldDef((aggregator: Dict>, fieldDef, channel) => {\n const scaleComponent = isScaleChannel(channel) && model.getScaleComponent(channel);\n if (scaleComponent) {\n const scaleType = scaleComponent.get('type');\n\n\n // While discrete domain scales can handle invalid values, continuous scales can't.\n // Thus, for non-path marks, we have to filter null for scales with continuous domains.\n // (For path marks, we will use \"defined\" property and skip these values instead.)\n if (hasContinuousDomain(scaleType) && !fieldDef.aggregate && !isPathMark(mark)) {\n aggregator[fieldDef.field] = fieldDef;\n }\n }\n return aggregator;\n }, {} as Dict>);\n\n if (!keys(filter).length) {\n return null;\n }\n\n return new FilterInvalidNode(parent, filter);\n }\n\n get filter() {\n return this.fieldDefs;\n }\n\n // create the VgTransforms for each of the filtered fields\n public assemble(): VgFilterTransform {\n const filters = keys(this.filter).reduce((vegaFilters, field) => {\n const fieldDef = this.fieldDefs[field];\n const ref = fieldRef(fieldDef, {expr: 'datum'});\n\n if (fieldDef !== null) {\n vegaFilters.push(`${ref} !== null`);\n vegaFilters.push(`!isNaN(${ref})`);\n }\n return vegaFilters;\n }, []);\n\n return filters.length > 0 ?\n {\n type: 'filter',\n expr: filters.join(' && ')\n } : null;\n }\n}\n","import {isNumber, isString, toSet} from 'vega-util';\nimport {AncestorParse} from '.';\nimport {isCountingAggregateOp} from '../../aggregate';\nimport {DateTime, isDateTime} from '../../datetime';\nimport {isNumberFieldDef, isScaleFieldDef, isTimeFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {forEachLeaf} from '../../logical';\nimport {isFieldEqualPredicate, isFieldOneOfPredicate, isFieldPredicate, isFieldRangePredicate} from '../../predicate';\nimport {isSortField} from '../../sort';\nimport {FilterTransform} from '../../transform';\nimport {accessPathDepth, accessPathWithDatum, Dict, duplicate, keys, removePathFromField, StringSet} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\nimport {isFacetModel, isUnitModel, Model} from '../model';\nimport {Split} from '../split';\nimport {DataFlowNode} from './dataflow';\n\n\n/**\n * @param field The field.\n * @param parse What to parse the field as.\n */\nfunction parseExpression(field: string, parse: string): string {\n const f = accessPathWithDatum(field);\n if (parse === 'number') {\n return `toNumber(${f})`;\n } else if (parse === 'boolean') {\n return `toBoolean(${f})`;\n } else if (parse === 'string') {\n return `toString(${f})`;\n } else if (parse === 'date') {\n return `toDate(${f})`;\n } else if (parse === 'flatten') {\n return f;\n } else if (parse.indexOf('date:') === 0) {\n const specifier = parse.slice(5, parse.length);\n return `timeParse(${f},${specifier})`;\n } else if (parse.indexOf('utc:') === 0) {\n const specifier = parse.slice(4, parse.length);\n return `utcParse(${f},${specifier})`;\n } else {\n log.warn(log.message.unrecognizedParse(parse));\n return null;\n }\n}\n\nexport class ParseNode extends DataFlowNode {\n private _parse: Dict;\n\n public clone() {\n return new ParseNode(null, duplicate(this._parse));\n }\n\n constructor(parent: DataFlowNode, parse: Dict) {\n super(parent);\n\n this._parse = parse;\n }\n\n /**\n * Creates a parse node from a data.format.parse and updates ancestorParse.\n */\n public static makeExplicit(parent: DataFlowNode, model: Model, ancestorParse: AncestorParse) {\n // Custom parse\n let explicit = {};\n const data = model.data;\n if (data && data.format && data.format.parse) {\n explicit = data.format.parse;\n }\n\n return this.makeWithAncestors(parent, explicit, {}, ancestorParse);\n }\n\n public static makeImplicitFromFilterTransform(parent: DataFlowNode, transform: FilterTransform, ancestorParse: AncestorParse) {\n const parse = {};\n forEachLeaf(transform.filter, filter => {\n if (isFieldPredicate(filter)) {\n // Automatically add a parse node for filters with filter objects\n let val: string | number | boolean | DateTime = null;\n\n // For EqualFilter, just use the equal property.\n // For RangeFilter and OneOfFilter, all array members should have\n // the same type, so we only use the first one.\n if (isFieldEqualPredicate(filter)) {\n val = filter.equal;\n } else if (isFieldRangePredicate(filter)) {\n val = filter.range[0];\n } else if (isFieldOneOfPredicate(filter)) {\n val = (filter.oneOf || filter['in'])[0];\n } // else -- for filter expression, we can't infer anything\n if (val) {\n if (isDateTime(val)) {\n parse[filter.field] = 'date';\n } else if (isNumber(val)) {\n parse[filter.field] = 'number';\n } else if (isString(val)) {\n parse[filter.field] = 'string';\n }\n }\n\n if (filter.timeUnit) {\n parse[filter.field] = 'date';\n }\n }\n });\n\n if (keys(parse).length === 0) {\n return null;\n }\n\n return this.makeWithAncestors(parent, {}, parse, ancestorParse);\n }\n\n /**\n * Creates a parse node for implicit parsing from a model and updates ancestorParse.\n */\n public static makeImplicitFromEncoding(parent: DataFlowNode, model: Model, ancestorParse: AncestorParse) {\n const implicit = {};\n\n if (isUnitModel(model) || isFacetModel(model)) {\n // Parse encoded fields\n model.forEachFieldDef(fieldDef => {\n if (isTimeFieldDef(fieldDef)) {\n implicit[fieldDef.field] = 'date';\n } else if (isNumberFieldDef(fieldDef)) {\n if (!isCountingAggregateOp(fieldDef.aggregate)) {\n implicit[fieldDef.field] = 'number';\n }\n } else if (accessPathDepth(fieldDef.field) > 1) {\n // For non-date/non-number (strings and booleans), derive a flattened field for a referenced nested field.\n // (Parsing numbers / dates already flattens numeric and temporal fields.)\n if (!(fieldDef.field in implicit)) {\n implicit[fieldDef.field] = 'flatten';\n }\n } else if (isScaleFieldDef(fieldDef) && isSortField(fieldDef.sort) && accessPathDepth(fieldDef.sort.field) > 1) {\n // Flatten fields that we sort by but that are not otherwise flattened.\n if (!(fieldDef.sort.field in implicit)) {\n implicit[fieldDef.sort.field] = 'flatten';\n }\n }\n });\n }\n\n return this.makeWithAncestors(parent, {}, implicit, ancestorParse);\n }\n\n /**\n * Creates a parse node from \"explicit\" parse and \"implicit\" parse and updates ancestorParse.\n */\n private static makeWithAncestors(parent: DataFlowNode, explicit: Dict, implicit: Dict, ancestorParse: AncestorParse) {\n // We should not parse what has already been parsed in a parent (explicitly or implicitly) or what has been derived (maked as \"derived\"). We also don't need to flatten a field that has already been parsed.\n for (const field of keys(implicit)) {\n const parsedAs = ancestorParse.getWithExplicit(field);\n if (parsedAs.value !== undefined) {\n // We always ignore derived fields even if they are implicitly defined because we expect users to create the right types.\n if (parsedAs.explicit || parsedAs.value === implicit[field] || parsedAs.value === 'derived' || implicit[field] === 'flatten') {\n delete implicit[field];\n } else {\n log.warn(log.message.differentParse(field, implicit[field], parsedAs.value));\n }\n }\n }\n\n for (const field of keys(explicit)) {\n const parsedAs = ancestorParse.get(field);\n if (parsedAs !== undefined) {\n // Don't parse a field again if it has been parsed with the same type already.\n if (parsedAs === explicit[field]) {\n delete explicit[field];\n } else {\n log.warn(log.message.differentParse(field, explicit[field], parsedAs));\n }\n }\n }\n\n const parse = new Split(explicit, implicit);\n\n // add the format parse from this model so that children don't parse the same field again\n ancestorParse.copyAll(parse);\n\n // copy only non-null parses\n const p = {};\n for (const key of keys(parse.combine())) {\n const val = parse.get(key);\n if (val !== null) {\n p[key] = val;\n }\n }\n\n if (keys(p).length === 0 || ancestorParse.parseNothing) {\n return null;\n }\n\n return new ParseNode(parent, p);\n }\n\n public get parse() {\n return this._parse;\n }\n\n public merge(other: ParseNode) {\n this._parse = {...this._parse, ...other.parse};\n other.remove();\n }\n\n /**\n * Assemble an object for Vega's format.parse property.\n */\n public assembleFormatParse() {\n const formatParse = {};\n for (const field of keys(this._parse)) {\n const p = this._parse[field];\n if (accessPathDepth(field) === 1) {\n formatParse[field] = p;\n }\n }\n return formatParse;\n }\n\n // format parse depends and produces all fields in its parse\n public producedFields(): StringSet {\n return toSet(keys(this._parse));\n }\n\n public dependentFields(): StringSet {\n return toSet(keys(this._parse));\n }\n\n public assembleTransforms(onlyNested = false): VgFormulaTransform[] {\n return keys(this._parse)\n .filter(field => onlyNested ? accessPathDepth(field) > 1 : true)\n .map(field => {\n const expr = parseExpression(field, this._parse[field]);\n if (!expr) {\n return null;\n }\n\n const formula: VgFormulaTransform = {\n type: 'formula',\n expr,\n as: removePathFromField(field) // Vega output is always flattened\n };\n return formula;\n }).filter(t => t !== null);\n }\n}\n","import {Data, DataFormatType, isInlineData, isNamedData, isUrlData} from '../../data';\nimport {contains, hash} from '../../util';\nimport {VgData} from '../../vega.schema';\nimport {DataFlowNode} from './dataflow';\n\nexport class SourceNode extends DataFlowNode {\n private _data: Partial;\n\n private _name: string;\n\n private _hash: string | number;\n\n constructor(data: Data) {\n super(null); // source cannot have parent\n\n data = data || {name: 'source'};\n\n if (isInlineData(data)) {\n this._data = {values: data.values};\n } else if (isUrlData(data)) {\n this._data = {url: data.url};\n\n if (!data.format) {\n data.format = {};\n }\n\n if (!data.format || !data.format.type) {\n // Extract extension from URL using snippet from\n // http://stackoverflow.com/questions/680929/how-to-extract-extension-from-filename-string-in-javascript\n let defaultExtension = /(?:\\.([^.]+))?$/.exec(data.url)[1];\n if (!contains(['json', 'csv', 'tsv', 'dsv', 'topojson'], defaultExtension)) {\n defaultExtension = 'json';\n }\n\n // defaultExtension has type string but we ensure that it is DataFormatType above\n data.format.type = defaultExtension as DataFormatType;\n }\n } else if (isNamedData(data)) {\n this._data = {};\n }\n\n // any dataset can be named\n if (data.name) {\n this._name = data.name;\n }\n\n if (data.format) {\n const {parse = null, ...format} = data.format;\n this._data.format = format;\n }\n }\n\n get data() {\n return this._data;\n }\n\n public hasName(): boolean {\n return !!this._name;\n }\n\n get dataName() {\n return this._name;\n }\n\n set dataName(name: string) {\n this._name = name;\n }\n\n set parent(parent: DataFlowNode) {\n throw new Error('Source nodes have to be roots.');\n }\n\n public remove() {\n throw new Error('Source nodes are roots and cannot be removed.');\n }\n\n /**\n * Return a unique identifier for this data source.\n */\n public hash() {\n if (isInlineData(this._data)) {\n if (!this._hash) {\n // Hashing can be expensive for large inline datasets.\n this._hash = hash(this._data);\n }\n return this._hash;\n } else if (isUrlData(this._data)) {\n return hash([this._data.url, this._data.format]);\n } else {\n return this._name;\n }\n }\n\n public assemble(): VgData {\n return {\n name: this._name,\n ...this._data,\n transform: []\n };\n }\n}\n","import {vgField} from '../../fielddef';\nimport {fieldExpr, TimeUnit} from '../../timeunit';\nimport {TimeUnitTransform} from '../../transform';\nimport {Dict, duplicate, keys, vals} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\nimport {ModelWithField} from '../model';\nimport {DataFlowNode} from './dataflow';\n\n\nexport interface TimeUnitComponent {\n as: string;\n timeUnit: TimeUnit;\n field: string;\n}\n\nexport class TimeUnitNode extends DataFlowNode {\n public clone() {\n return new TimeUnitNode(null, duplicate(this.formula));\n }\n\n constructor(parent: DataFlowNode, private formula: Dict) {\n super(parent);\n }\n\n public static makeFromEncoding(parent: DataFlowNode, model: ModelWithField) {\n const formula = model.reduceFieldDef((timeUnitComponent: TimeUnitComponent, fieldDef) => {\n if (fieldDef.timeUnit) {\n const f = vgField(fieldDef);\n timeUnitComponent[f] = {\n as: f,\n timeUnit: fieldDef.timeUnit,\n field: fieldDef.field\n };\n }\n return timeUnitComponent;\n }, {} as Dict);\n\n if (keys(formula).length === 0) {\n return null;\n }\n\n return new TimeUnitNode(parent, formula);\n }\n\n public static makeFromTransform(parent: DataFlowNode, t: TimeUnitTransform) {\n return new TimeUnitNode(parent, {\n [t.field]: {\n as: t.as,\n timeUnit: t.timeUnit,\n field: t.field\n }\n });\n }\n\n public merge(other: TimeUnitNode) {\n this.formula = {...this.formula, ...other.formula};\n other.remove();\n }\n\n public producedFields() {\n const out = {};\n\n vals(this.formula).forEach(f => {\n out[f.as] = true;\n });\n\n return out;\n }\n\n public dependentFields() {\n const out = {};\n\n vals(this.formula).forEach(f => {\n out[f.field] = true;\n });\n\n return out;\n }\n\n public assemble() {\n return vals(this.formula).map(c => {\n return {\n type: 'formula',\n as: c.as,\n expr: fieldExpr(c.timeUnit, c.field)\n } as VgFormulaTransform;\n });\n }\n}\n","import {hasIntersection, keys} from '../../util';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {ParseNode} from './formatparse';\nimport {SourceNode} from './source';\nimport {TimeUnitNode} from './timeunit';\n\n\n/**\n * Start optimization path at the leaves. Useful for merging up or removing things.\n *\n * If the callback returns true, the recursion continues.\n */\nexport function iterateFromLeaves(f: (node: DataFlowNode) => boolean) {\n function optimizeNextFromLeaves(node: DataFlowNode) {\n if (node instanceof SourceNode) {\n return;\n }\n\n const next = node.parent;\n if (f(node)) {\n optimizeNextFromLeaves(next);\n }\n }\n\n return optimizeNextFromLeaves;\n}\n\n/**\n * Move parse nodes up to forks.\n */\nexport function moveParseUp(node: DataFlowNode) {\n const parent = node.parent;\n\n // move parse up by merging or swapping\n if (node instanceof ParseNode) {\n if (parent instanceof SourceNode) {\n return false;\n }\n\n if (parent.numChildren() > 1) {\n // don't move parse further up but continue with parent.\n return true;\n }\n\n if (parent instanceof ParseNode) {\n parent.merge(node);\n } else {\n // don't swap with nodes that produce something that the parse node depends on (e.g. lookup)\n if (hasIntersection(parent.producedFields(), node.dependentFields())) {\n return true;\n }\n\n node.swapWithParent();\n }\n }\n\n return true;\n}\n\n/**\n * Repeatedly remove leaf nodes that are not output or facet nodes.\n * The reason is that we don't need subtrees that don't have any output nodes.\n * Facet nodes are needed for the row or column domains.\n */\nexport function removeUnusedSubtrees(node: DataFlowNode) {\n if (node instanceof OutputNode || node.numChildren() > 0 || node instanceof FacetNode) {\n // no need to continue with parent because it is output node or will have children (there was a fork)\n return false;\n } else {\n node.remove();\n }\n return true;\n}\n\n/**\n * Removes duplicate time unit nodes (as determined by the name of the\n * output field) that may be generated due to selections projected over\n * time units.\n */\nexport function removeDuplicateTimeUnits(leaf: DataFlowNode) {\n let fields = {};\n return iterateFromLeaves((node: DataFlowNode) => {\n if (node instanceof TimeUnitNode) {\n const pfields = node.producedFields();\n const dupe = keys(pfields).every((k) => !!fields[k]);\n\n if (dupe) {\n node.remove();\n } else {\n fields = {...fields, ...pfields};\n }\n }\n\n return true;\n })(leaf);\n}\n","import {isArray, isString} from 'vega-util';\nimport {FieldDef, isFieldDef, vgField} from '../../fielddef';\nimport {StackOffset} from '../../stack';\nimport {StackTransform} from '../../transform';\nimport {duplicate} from '../../util';\nimport {VgComparatorOrder, VgSort, VgTransform} from '../../vega.schema';\nimport {sortParams} from '../common';\nimport {UnitModel} from './../unit';\nimport {DataFlowNode} from './dataflow';\n\nfunction getStackByFields(model: UnitModel): string[] {\n return model.stack.stackBy.reduce((fields, by) => {\n const fieldDef = by.fieldDef;\n\n const _field = vgField(fieldDef);\n if (_field) {\n fields.push(_field);\n }\n return fields;\n }, [] as string[]);\n}\n\nexport interface StackComponent {\n\n /**\n * Faceted field.\n */\n facetby: string[];\n\n dimensionFieldDef?: FieldDef;\n\n /**\n * Stack measure's field. Used in makeFromEncoding.\n */\n stackField: string;\n\n /**\n * Level of detail fields for each level in the stacked charts such as color or detail.\n * Used in makeFromEncoding.\n */\n stackby?: string[];\n\n /**\n * Field that determines order of levels in the stacked charts.\n * Used in both but optional in transform.\n */\n sort: VgSort;\n\n /** Mode for stacking marks.\n */\n offset: StackOffset;\n\n /**\n * Whether to impute the data before stacking. Used only in makeFromEncoding.\n */\n impute?: boolean;\n\n /**\n * The data fields to group by.\n */\n groupby?: string[];\n /**\n * Output field names of each stack field.\n */\n as: string[];\n\n}\n\nfunction isValidAsArray(as: string[] | string): as is string[] {\n return isArray(as) && as.every(s => isString(s)) && as.length >1;\n}\n\nexport class StackNode extends DataFlowNode {\n private _stack: StackComponent;\n\n public clone() {\n return new StackNode(null, duplicate(this._stack));\n }\n\n constructor(parent: DataFlowNode, stack: StackComponent) {\n super(parent);\n\n this._stack = stack;\n }\n\n public static makeFromTransform(parent: DataFlowNode, stackTransform: StackTransform) {\n\n const {stack, groupby, as, offset='zero'} = stackTransform;\n\n const sortFields: string[] = [];\n const sortOrder: VgComparatorOrder[] = [];\n if (stackTransform.sort !== undefined) {\n for (const sortField of stackTransform.sort) {\n sortFields.push(sortField.field);\n sortOrder.push(sortField.order === undefined ? 'ascending' : sortField.order as VgComparatorOrder);\n }\n }\n const sort: VgSort = {\n field: sortFields,\n order: sortOrder,\n };\n let normalizedAs: Array;\n if (isValidAsArray(as)) {\n normalizedAs = as;\n } else if(isString(as)) {\n normalizedAs = [as, as + '_end'];\n } else {\n normalizedAs = [stackTransform.stack + '_start', stackTransform.stack + '_end'];\n }\n\n return new StackNode (parent, {\n stackField: stack,\n groupby,\n offset,\n sort,\n facetby: [],\n as: normalizedAs\n });\n\n }\n public static makeFromEncoding(parent: DataFlowNode, model: UnitModel) {\n\n const stackProperties = model.stack;\n\n if (!stackProperties) {\n return null;\n }\n\n let dimensionFieldDef: FieldDef;\n if (stackProperties.groupbyChannel) {\n dimensionFieldDef = model.fieldDef(stackProperties.groupbyChannel);\n }\n\n const stackby = getStackByFields(model);\n const orderDef = model.encoding.order;\n\n let sort: VgSort;\n if (isArray(orderDef) || isFieldDef(orderDef)) {\n sort = sortParams(orderDef);\n } else {\n // default = descending by stackFields\n // FIXME is the default here correct for binned fields?\n sort = stackby.reduce((s, field) => {\n s.field.push(field);\n s.order.push('descending');\n return s;\n }, {field:[], order: []});\n }\n // Refactored to add \"as\" in the make phase so that we can get producedFields\n // from the as property\n const field = model.vgField(stackProperties.fieldChannel);\n\n return new StackNode(parent, {\n dimensionFieldDef,\n stackField:field,\n facetby: [],\n stackby,\n sort,\n offset: stackProperties.offset,\n impute: stackProperties.impute,\n as: [field + '_start', field + '_end']\n });\n }\n\n get stack(): StackComponent {\n return this._stack;\n }\n\n public addDimensions(fields: string[]) {\n this._stack.facetby = this._stack.facetby.concat(fields);\n }\n\n public dependentFields() {\n const out = {};\n\n out[this._stack.stackField] = true;\n\n this.getGroupbyFields().forEach(f => out[f] = true);\n this._stack.facetby.forEach(f => out[f] = true);\n const field = this._stack.sort.field;\n isArray(field) ? field.forEach(f => out[f] = true) : out[field] = true;\n\n return out;\n }\n\n public producedFields() {\n return this._stack.as.reduce((result, item) => {\n result[item] = true;\n return result;\n }, {});\n }\n\n private getGroupbyFields() {\n const {dimensionFieldDef, impute, groupby} = this._stack;\n if (dimensionFieldDef) {\n if (dimensionFieldDef.bin) {\n if (impute) {\n // For binned group by field with impute, we calculate bin_mid\n // as we cannot impute two fields simultaneously\n return [vgField(dimensionFieldDef, {binSuffix: 'mid'})];\n }\n return [\n // For binned group by field without impute, we need both bin (start) and bin_end\n vgField(dimensionFieldDef, {}),\n vgField(dimensionFieldDef, {binSuffix: 'end'})\n ];\n }\n return [vgField(dimensionFieldDef)];\n }\n return groupby || [];\n }\n\n public assemble(): VgTransform[] {\n const transform: VgTransform[] = [];\n const {facetby, dimensionFieldDef, stackField: field, stackby, sort, offset, impute, as} = this._stack;\n\n // Impute\n if (impute && dimensionFieldDef) {\n const dimensionField = dimensionFieldDef ? vgField(dimensionFieldDef, {binSuffix: 'mid'}): undefined;\n\n if (dimensionFieldDef.bin) {\n // As we can only impute one field at a time, we need to calculate\n // mid point for a binned field\n transform.push({\n type: 'formula',\n expr: '(' +\n vgField(dimensionFieldDef, {expr: 'datum'}) +\n '+' +\n vgField(dimensionFieldDef, {expr: 'datum', binSuffix: 'end'}) +\n ')/2',\n as: dimensionField\n });\n }\n\n transform.push({\n type: 'impute',\n field,\n groupby: stackby,\n key: dimensionField,\n method: 'value',\n value: 0\n });\n }\n\n // Stack\n transform.push({\n type: 'stack',\n groupby: this.getGroupbyFields().concat(facetby),\n field,\n sort,\n as,\n offset\n });\n\n return transform;\n }\n}\n","import {MAIN} from '../../data';\nimport {every, flatten, keys, vals} from '../../util';\nimport {AggregateNode} from './aggregate';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {FilterInvalidNode} from './filterinvalid';\nimport {DataComponent} from './index';\nimport * as optimizers from './optimizers';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\n\nexport const FACET_SCALE_PREFIX = 'scale_';\n\n/**\n * Clones the subtree and ignores output nodes except for the leafs, which are renamed.\n */\nfunction cloneSubtree(facet: FacetNode) {\n function clone(node: DataFlowNode): DataFlowNode[] {\n if (!(node instanceof FacetNode)) {\n const copy = node.clone();\n\n if (copy instanceof OutputNode) {\n const newName = FACET_SCALE_PREFIX + copy.getSource();\n copy.setSource(newName);\n\n facet.model.component.data.outputNodes[newName] = copy;\n } else if (copy instanceof AggregateNode || copy instanceof StackNode) {\n copy.addDimensions(facet.fields);\n }\n flatten(node.children.map(clone)).forEach((n: DataFlowNode) => n.parent = copy);\n\n return [copy];\n }\n\n return flatten(node.children.map(clone));\n }\n return clone;\n}\n\n/**\n * Move facet nodes down to the next fork or output node. Also pull the main output with the facet node.\n * After moving down the facet node, make a copy of the subtree and make it a child of the main output.\n */\nfunction moveFacetDown(node: DataFlowNode) {\n if (node instanceof FacetNode) {\n if (node.numChildren() === 1 && !(node.children[0] instanceof OutputNode)) {\n // move down until we hit a fork or output node\n\n const child = node.children[0];\n\n if (child instanceof AggregateNode || child instanceof StackNode) {\n child.addDimensions(node.fields);\n }\n\n child.swapWithParent();\n moveFacetDown(node);\n } else {\n // move main to facet\n moveMainDownToFacet(node.model.component.data.main);\n\n // replicate the subtree and place it before the facet's main node\n const copy: DataFlowNode[] = flatten(node.children.map(cloneSubtree(node)));\n copy.forEach(c => c.parent = node.model.component.data.main);\n }\n } else {\n node.children.forEach(moveFacetDown);\n }\n}\n\nfunction moveMainDownToFacet(node: DataFlowNode) {\n if (node instanceof OutputNode && node.type === MAIN) {\n if (node.numChildren() === 1) {\n const child = node.children[0];\n\n if (!(child instanceof FacetNode)) {\n child.swapWithParent();\n moveMainDownToFacet(node);\n }\n }\n }\n}\n\n/**\n * Remove nodes that are not required starting from a root.\n */\nfunction removeUnnecessaryNodes(node: DataFlowNode) {\n\n // remove empty null filter nodes\n if (node instanceof FilterInvalidNode && every(vals(node.filter), f => f === null)) {\n node.remove();\n }\n\n // remove output nodes that are not required\n if (node instanceof OutputNode && !node.isRequired()) {\n node.remove();\n }\n\n node.children.forEach(removeUnnecessaryNodes);\n}\n\n/**\n * Return all leaf nodes.\n */\nfunction getLeaves(roots: DataFlowNode[]) {\n const leaves: DataFlowNode[] = [];\n function append(node: DataFlowNode) {\n if (node.numChildren() === 0) {\n leaves.push(node);\n } else {\n node.children.forEach(append);\n }\n }\n\n roots.forEach(append);\n return leaves;\n}\n\n/**\n * Optimizes the dataflow of the passed in data component.\n */\nexport function optimizeDataflow(dataComponent: DataComponent) {\n let roots: SourceNode[] = vals(dataComponent.sources);\n\n roots.forEach(removeUnnecessaryNodes);\n\n // remove source nodes that don't have any children because they also don't have output nodes\n roots = roots.filter(r => r.numChildren() > 0);\n getLeaves(roots).forEach(optimizers.iterateFromLeaves(optimizers.removeUnusedSubtrees));\n roots = roots.filter(r => r.numChildren() > 0);\n\n getLeaves(roots).forEach(optimizers.iterateFromLeaves(optimizers.moveParseUp));\n getLeaves(roots).forEach(optimizers.removeDuplicateTimeUnits);\n\n roots.forEach(moveFacetDown);\n\n keys(dataComponent.sources).forEach(s => {\n if (dataComponent.sources[s].numChildren() === 0) {\n delete dataComponent.sources[s];\n }\n });\n}\n","import {isString} from 'vega-util';\nimport {SHARED_DOMAIN_OP_INDEX} from '../../aggregate';\nimport {binToString, isBinParams} from '../../bin';\nimport {isScaleChannel, ScaleChannel} from '../../channel';\nimport {MAIN, RAW} from '../../data';\nimport {DateTime} from '../../datetime';\nimport {FieldDef, ScaleFieldDef, valueExpr, vgField} from '../../fielddef';\nimport * as log from '../../log';\nimport {Domain, hasDiscreteDomain, isBinScale, isSelectionDomain, ScaleConfig, ScaleType} from '../../scale';\nimport {EncodingSortField, isSortArray, isSortField} from '../../sort';\nimport {TimeUnit} from '../../timeunit';\nimport {Type} from '../../type';\nimport * as util from '../../util';\nimport {isDataRefDomain, isDataRefUnionedDomain, isFieldRefUnionDomain, VgDataRef, VgDomain, VgFieldRefUnionDomain, VgNonUnionDomain, VgSortField, VgUnionSortField} from '../../vega.schema';\nimport {binRequiresRange} from '../common';\nimport {sortArrayIndexField} from '../data/calculate';\nimport {FACET_SCALE_PREFIX} from '../data/optimize';\nimport {isFacetModel, isUnitModel, Model} from '../model';\nimport {SELECTION_DOMAIN} from '../selection/selection';\nimport {UnitModel} from '../unit';\nimport {ScaleComponentIndex} from './component';\n\n\nexport function parseScaleDomain(model: Model) {\n if (isUnitModel(model)) {\n parseUnitScaleDomain(model);\n } else {\n parseNonUnitScaleDomain(model);\n }\n}\n\nfunction parseUnitScaleDomain(model: UnitModel) {\n const scales = model.specifiedScales;\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n util.keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n const specifiedScale = scales[channel];\n const specifiedDomain = specifiedScale ? specifiedScale.domain : undefined;\n\n const domains = parseDomainForChannel(model, channel);\n const localScaleCmpt = localScaleComponents[channel];\n localScaleCmpt.domains = domains;\n\n if (isSelectionDomain(specifiedDomain)) {\n // As scale parsing occurs before selection parsing, we use a temporary\n // signal here and append the scale.domain definition. This is replaced\n // with the correct domainRaw signal during scale assembly.\n // For more information, see isRawSelectionDomain in selection.ts.\n\n // FIXME: replace this with a special property in the scaleComponent\n localScaleCmpt.set('domainRaw', {\n signal: SELECTION_DOMAIN + util.hash(specifiedDomain)\n }, true);\n }\n\n if (model.component.data.isFaceted) {\n // get resolve from closest facet parent as this decides whether we need to refer to cloned subtree or not\n let facetParent: Model = model;\n while (!isFacetModel(facetParent) && facetParent.parent) {\n facetParent = facetParent.parent;\n }\n\n const resolve = facetParent.component.resolve.scale[channel];\n\n if (resolve === 'shared') {\n for (const domain of domains) {\n // Replace the scale domain with data output from a cloned subtree after the facet.\n if (isDataRefDomain(domain)) {\n // use data from cloned subtree (which is the same as data but with a prefix added once)\n domain.data = FACET_SCALE_PREFIX + domain.data.replace(FACET_SCALE_PREFIX, '');\n }\n }\n }\n }\n });\n}\n\nfunction parseNonUnitScaleDomain(model: Model) {\n for (const child of model.children) {\n parseScaleDomain(child);\n }\n\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n util.keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n let domains: VgNonUnionDomain[];\n let domainRaw = null;\n\n for (const child of model.children) {\n const childComponent = child.component.scales[channel];\n if (childComponent) {\n if (domains === undefined) {\n domains = childComponent.domains;\n } else {\n domains = domains.concat(childComponent.domains);\n }\n\n const dr = childComponent.get('domainRaw');\n if (domainRaw && dr && domainRaw.signal !== dr.signal) {\n log.warn('The same selection must be used to override scale domains in a layered view.');\n }\n domainRaw = dr;\n }\n }\n\n localScaleComponents[channel].domains = domains;\n\n if (domainRaw) {\n localScaleComponents[channel].set('domainRaw', domainRaw, true);\n }\n });\n}\n\n\n/**\n * Remove unaggregated domain if it is not applicable\n * Add unaggregated domain if domain is not specified and config.scale.useUnaggregatedDomain is true.\n */\nfunction normalizeUnaggregatedDomain(domain: Domain, fieldDef: FieldDef, scaleType: ScaleType, scaleConfig: ScaleConfig) {\n if (domain === 'unaggregated') {\n const {valid, reason} = canUseUnaggregatedDomain(fieldDef, scaleType);\n if(!valid) {\n log.warn(reason);\n return undefined;\n }\n } else if (domain === undefined && scaleConfig.useUnaggregatedDomain) {\n // Apply config if domain is not specified.\n const {valid} = canUseUnaggregatedDomain(fieldDef, scaleType);\n if (valid) {\n return 'unaggregated';\n }\n }\n\n return domain;\n}\n\nexport function parseDomainForChannel(model: UnitModel, channel: ScaleChannel): VgNonUnionDomain[] {\n const scaleType = model.getScaleComponent(channel).get('type');\n\n const domain = normalizeUnaggregatedDomain(model.scaleDomain(channel), model.fieldDef(channel), scaleType, model.config.scale);\n if (domain !== model.scaleDomain(channel)) {\n model.specifiedScales[channel] = {\n ...model.specifiedScales[channel],\n domain\n };\n }\n\n // If channel is either X or Y then union them with X2 & Y2 if they exist\n if (channel === 'x' && model.channelHasField('x2')) {\n if (model.channelHasField('x')) {\n return parseSingleChannelDomain(scaleType, domain, model, 'x').concat(parseSingleChannelDomain(scaleType, domain, model, 'x2'));\n } else {\n return parseSingleChannelDomain(scaleType, domain, model, 'x2');\n }\n } else if (channel === 'y' && model.channelHasField('y2')) {\n if (model.channelHasField('y')) {\n return parseSingleChannelDomain(scaleType, domain, model, 'y').concat(parseSingleChannelDomain(scaleType, domain, model, 'y2'));\n } else {\n return parseSingleChannelDomain(scaleType, domain, model, 'y2');\n }\n }\n return parseSingleChannelDomain(scaleType, domain, model, channel);\n}\n\nfunction mapDomainToDataSignal(domain: T[], type: Type, timeUnit: TimeUnit) {\n return domain.map(v => {\n const data = valueExpr(v, {timeUnit, type});\n return {signal: `{data: ${data}}`};\n });\n}\n\nfunction parseSingleChannelDomain(scaleType: ScaleType, domain: Domain, model: UnitModel, channel: ScaleChannel | 'x2' | 'y2'): VgNonUnionDomain[] {\n const fieldDef = model.fieldDef(channel);\n\n if (domain && domain !== 'unaggregated' && !isSelectionDomain(domain)) { // explicit value\n const {type, timeUnit} = fieldDef;\n if (type === 'temporal' || timeUnit) {\n return mapDomainToDataSignal(domain, type, timeUnit);\n }\n\n return [domain];\n }\n\n const stack = model.stack;\n if (stack && channel === stack.fieldChannel) {\n if(stack.offset === 'normalize') {\n return [[0, 1]];\n }\n\n const data = model.requestDataName(MAIN);\n return [{\n data,\n field: model.vgField(channel, {suffix: 'start'})\n }, {\n data,\n field: model.vgField(channel, {suffix: 'end'})\n }];\n }\n\n const sort = isScaleChannel(channel) ? domainSort(model, channel, scaleType) : undefined;\n\n if (domain === 'unaggregated') {\n const data = model.requestDataName(MAIN);\n const {field} = fieldDef;\n return [{\n data,\n field: vgField({field, aggregate: 'min'})\n }, {\n data,\n field: vgField({field, aggregate: 'max'})\n }];\n } else if (fieldDef.bin) { // bin\n if (isBinScale(scaleType)) {\n const signal = model.getName(`${binToString(fieldDef.bin)}_${fieldDef.field}_bins`);\n return [{signal: `sequence(${signal}.start, ${signal}.stop + ${signal}.step, ${signal}.step)`}];\n }\n\n if (hasDiscreteDomain(scaleType)) {\n // ordinal bin scale takes domain from bin_range, ordered by bin start\n // This is useful for both axis-based scale (x/y) and legend-based scale (other channels).\n return [{\n // If sort by aggregation of a specified sort field, we need to use RAW table,\n // so we can aggregate values for the scale independently from the main aggregation.\n data: util.isBoolean(sort) ? model.requestDataName(MAIN) : model.requestDataName(RAW),\n // Use range if we added it and the scale does not support computing a range as a signal.\n field: model.vgField(channel, binRequiresRange(fieldDef, channel) ? {binSuffix: 'range'} : {}),\n // we have to use a sort object if sort = true to make the sort correct by bin start\n sort: sort === true || !isSortField(sort) ? {\n field: model.vgField(channel, {}),\n op: 'min' // min or max doesn't matter since we sort by the start of the bin range\n } : sort\n }];\n } else { // continuous scales\n if (channel === 'x' || channel === 'y') {\n if (isBinParams(fieldDef.bin) && fieldDef.bin.extent) {\n return [fieldDef.bin.extent];\n }\n // X/Y position have to include start and end for non-ordinal scale\n const data = model.requestDataName(MAIN);\n return [{\n data,\n field: model.vgField(channel, {})\n }, {\n data,\n field: model.vgField(channel, {binSuffix: 'end'})\n }];\n } else {\n // TODO: use bin_mid\n return [{\n data: model.requestDataName(MAIN),\n field: model.vgField(channel, {})\n }];\n }\n }\n } else if (sort) {\n return [{\n // If sort by aggregation of a specified sort field, we need to use RAW table,\n // so we can aggregate values for the scale independently from the main aggregation.\n data: util.isBoolean(sort) ? model.requestDataName(MAIN) : model.requestDataName(RAW),\n field: model.vgField(channel),\n sort: sort\n }];\n } else {\n return [{\n data: model.requestDataName(MAIN),\n field: model.vgField(channel)\n }];\n }\n}\n\n\nexport function domainSort(model: UnitModel, channel: ScaleChannel, scaleType: ScaleType): true | EncodingSortField {\n if (!hasDiscreteDomain(scaleType)) {\n return undefined;\n }\n\n const fieldDef: ScaleFieldDef = model.fieldDef(channel);\n const sort = fieldDef.sort;\n\n // if the sort is specified with array, use the derived sort index field\n if (isSortArray(sort)) {\n return {\n op: 'min',\n field: sortArrayIndexField(fieldDef, channel),\n order: 'ascending'\n };\n }\n\n // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale)\n if (isSortField(sort)) {\n // flatten nested fields\n return {\n ...sort,\n ...(sort.field ? {field: util.replacePathInField(sort.field)} : {})\n };\n }\n\n if (sort === 'descending') {\n return {\n op: 'min',\n field: model.vgField(channel),\n order: 'descending'\n };\n }\n\n if (util.contains(['ascending', undefined /* default =ascending*/], sort)) {\n return true;\n }\n\n // sort == null\n return undefined;\n}\n\n\n\n/**\n * Determine if a scale can use unaggregated domain.\n * @return {Boolean} Returns true if all of the following conditons applies:\n * 1. `scale.domain` is `unaggregated`\n * 2. Aggregation function is not `count` or `sum`\n * 3. The scale is quantitative or time scale.\n */\nexport function canUseUnaggregatedDomain(fieldDef: FieldDef, scaleType: ScaleType): {valid: boolean, reason?: string} {\n if (!fieldDef.aggregate) {\n return {\n valid: false,\n reason: log.message.unaggregateDomainHasNoEffectForRawField(fieldDef)\n };\n }\n\n if (!SHARED_DOMAIN_OP_INDEX[fieldDef.aggregate]) {\n return {\n valid: false,\n reason: log.message.unaggregateDomainWithNonSharedDomainOp(fieldDef.aggregate)\n };\n }\n\n if (fieldDef.type === 'quantitative') {\n if (scaleType === 'log') {\n return {\n valid: false,\n reason: log.message.unaggregatedDomainWithLogScale(fieldDef)\n };\n }\n }\n\n return {valid: true};\n}\n\n/**\n * Converts an array of domains to a single Vega scale domain.\n */\nexport function mergeDomains(domains: VgNonUnionDomain[]): VgDomain {\n const uniqueDomains = util.unique(domains.map(domain => {\n // ignore sort property when computing the unique domains\n if (isDataRefDomain(domain)) {\n const {sort: _s, ...domainWithoutSort} = domain;\n return domainWithoutSort;\n }\n return domain;\n }), util.hash);\n\n const sorts: VgSortField[] = util.unique(domains.map(d => {\n if (isDataRefDomain(d)) {\n const s = d.sort;\n if (s !== undefined && !util.isBoolean(s)) {\n if (s.op === 'count') {\n // let's make sure that if op is count, we don't use a field\n delete s.field;\n }\n if (s.order === 'ascending') {\n // drop order: ascending as it is the default\n delete s.order;\n }\n }\n return s;\n }\n return undefined;\n }).filter(s => s !== undefined), util.hash);\n\n if (uniqueDomains.length === 1) {\n const domain = domains[0];\n if (isDataRefDomain(domain) && sorts.length > 0) {\n let sort = sorts[0];\n if (sorts.length > 1) {\n log.warn(log.message.MORE_THAN_ONE_SORT);\n sort = true;\n }\n return {\n ...domain,\n sort\n };\n }\n return domain;\n }\n\n // only keep simple sort properties that work with unioned domains\n const simpleSorts = util.unique(sorts.map(s => {\n if (s === true) {\n return s;\n }\n if (s.op === 'count') {\n return s;\n }\n log.warn(log.message.domainSortDropped(s));\n return true;\n }), util.hash) as VgUnionSortField[];\n\n let sort: VgUnionSortField = undefined;\n\n if (simpleSorts.length === 1) {\n sort = simpleSorts[0];\n } else if (simpleSorts.length > 1) {\n log.warn(log.message.MORE_THAN_ONE_SORT);\n sort = true;\n }\n\n const allData = util.unique(domains.map(d => {\n if (isDataRefDomain(d)) {\n return d.data;\n }\n return null;\n }), x => x);\n\n if (allData.length === 1 && allData[0] !== null) {\n // create a union domain of different fields with a single data source\n const domain: VgFieldRefUnionDomain = {\n data: allData[0],\n fields: uniqueDomains.map(d => (d as VgDataRef).field),\n ...(sort ? {sort} : {})\n };\n\n return domain;\n }\n\n return {fields: uniqueDomains, ...(sort ? {sort} : {})};\n}\n\n/**\n * Return a field if a scale single field.\n * Return `undefined` otherwise.\n *\n */\nexport function getFieldFromDomain(domain: VgDomain): string {\n if (isDataRefDomain(domain) && isString(domain.field)) {\n return domain.field;\n } else if (isDataRefUnionedDomain(domain)) {\n let field;\n for (const nonUnionDomain of domain.fields) {\n if (isDataRefDomain(nonUnionDomain) && isString(nonUnionDomain.field)) {\n if (!field) {\n field = nonUnionDomain.field;\n } else if (field !== nonUnionDomain.field) {\n log.warn('Detected faceted independent scales that union domain of multiple fields from different data sources. We will use the first field. The result view size may be incorrect.');\n return field;\n }\n }\n }\n log.warn('Detected faceted independent scales that union domain of identical fields from different source detected. We will assume that this is the same field from a different fork of the same data source. However, if this is not case, the result view size maybe incorrect.');\n return field;\n } else if (isFieldRefUnionDomain(domain)) {\n log.warn('Detected faceted independent scales that union domain of multiple fields from the same data source. We will use the first field. The result view size may be incorrect.');\n const field = domain.fields[0];\n return isString(field) ? field : undefined;\n }\n\n return undefined;\n}\n\nexport function assembleDomain(model: Model, channel: ScaleChannel) {\n const scaleComponent = model.component.scales[channel];\n const domains = scaleComponent.domains.map(domain => {\n // Correct references to data as the original domain's data was determined\n // in parseScale, which happens before parseData. Thus the original data\n // reference can be incorrect.\n\n if (isDataRefDomain(domain)) {\n domain.data = model.lookupDataSource(domain.data);\n }\n return domain;\n });\n\n // domains is an array that has to be merged into a single vega domain\n return mergeDomains(domains);\n}\n","import {isArray} from 'vega-util';\nimport {Channel, ScaleChannel} from '../../channel';\nimport {keys} from '../../util';\nimport {isVgRangeStep, isVgSignalRef, VgRange, VgScale} from '../../vega.schema';\nimport {isConcatModel, isLayerModel, isRepeatModel, Model} from '../model';\nimport {isRawSelectionDomain, selectionScaleDomain} from '../selection/selection';\nimport {assembleDomain} from './domain';\n\nexport function assembleScales(model: Model): VgScale[] {\n if (isLayerModel(model) || isConcatModel(model) || isRepeatModel(model)) {\n // For concat / layer / repeat, include scales of children too\n return model.children.reduce((scales, child) => {\n return scales.concat(assembleScales(child));\n }, assembleScalesForModel(model));\n } else {\n // For facet, child scales would not be included in the parent's scope.\n // For unit, there is no child.\n return assembleScalesForModel(model);\n }\n}\n\nexport function assembleScalesForModel(model: Model): VgScale[] {\n return keys(model.component.scales).reduce((scales: VgScale[], channel: ScaleChannel) => {\n const scaleComponent = model.component.scales[channel];\n if (scaleComponent.merged) {\n // Skipped merged scales\n return scales;\n }\n\n const scale = scaleComponent.combine();\n\n // need to separate const and non const object destruction\n let {domainRaw, range} = scale;\n const {name, type, domainRaw: _d, range: _r, ...otherScaleProps} = scale;\n\n range = assembleScaleRange(range, name, model, channel);\n\n // As scale parsing occurs before selection parsing, a temporary signal\n // is used for domainRaw. Here, we detect if this temporary signal\n // is set, and replace it with the correct domainRaw signal.\n // For more information, see isRawSelectionDomain in selection.ts.\n if (domainRaw && isRawSelectionDomain(domainRaw)) {\n domainRaw = selectionScaleDomain(model, domainRaw);\n }\n\n\n scales.push({\n name,\n type,\n domain: assembleDomain(model, channel),\n ...(domainRaw ? {domainRaw} : {}),\n range: range,\n ...otherScaleProps\n });\n\n return scales;\n }, [] as VgScale[]);\n}\n\nexport function assembleScaleRange(scaleRange: VgRange, scaleName: string, model: Model, channel: Channel) {\n // add signals to x/y range\n if (channel === 'x' || channel === 'y') {\n if (isVgRangeStep(scaleRange)) {\n // For x/y range step, use a signal created in layout assemble instead of a constant range step.\n return {\n step: {signal: scaleName + '_step'}\n };\n } else if (isArray(scaleRange) && scaleRange.length === 2) {\n const r0 = scaleRange[0];\n const r1 = scaleRange[1];\n if (r0 === 0 && isVgSignalRef(r1)) {\n // Replace width signal just in case it is renamed.\n return [0, {signal: model.getSizeName(r1.signal)}];\n } else if (isVgSignalRef(r0) && r1 === 0) {\n // Replace height signal just in case it is renamed.\n return [{signal: model.getSizeName(r0.signal)}, 0];\n }\n }\n }\n return scaleRange;\n}\n","import {selector as parseSelector} from 'vega-event-selector';\nimport {isString, stringValue} from 'vega-util';\nimport {Channel, ScaleChannel, X, Y} from '../../channel';\nimport {warn} from '../../log';\nimport {LogicalOperand} from '../../logical';\nimport {BrushConfig, SELECTION_ID, SelectionDef, SelectionResolution, SelectionType} from '../../selection';\nimport {accessPathWithDatum, Dict, logicalExpr, varName} from '../../util';\nimport {VgBinding, VgData, VgEventStream, VgSignalRef} from '../../vega.schema';\nimport {DataFlowNode} from '../data/dataflow';\nimport {TimeUnitNode} from '../data/timeunit';\nimport {FacetModel} from '../facet';\nimport {LayerModel} from '../layer';\nimport {isFacetModel, isUnitModel, Model} from '../model';\nimport {UnitModel} from '../unit';\nimport intervalCompiler from './interval';\nimport multiCompiler from './multi';\nimport {SelectionComponent} from './selection';\nimport singleCompiler from './single';\nimport {forEachTransform} from './transforms/transforms';\n\n\nexport const STORE = '_store';\nexport const TUPLE = '_tuple';\nexport const MODIFY = '_modify';\nexport const SELECTION_DOMAIN = '_selection_domain_';\n\nexport interface SelectionComponent {\n name: string;\n type: SelectionType;\n events: VgEventStream;\n // predicate?: string;\n bind?: 'scales' | VgBinding | {[key: string]: VgBinding};\n resolve: SelectionResolution;\n empty: 'all' | 'none';\n mark?: BrushConfig;\n\n _signalNames: {};\n\n // Transforms\n project?: ProjectComponent[];\n fields?: any;\n timeUnit?: TimeUnitNode;\n scales?: Channel[];\n toggle?: any;\n translate?: any;\n zoom?: any;\n nearest?: any;\n}\n\nexport interface ProjectComponent {\n field?: string;\n channel?: ScaleChannel;\n}\n\nexport interface SelectionCompiler {\n signals: (model: UnitModel, selCmpt: SelectionComponent) => any[];\n topLevelSignals?: (model: Model, selCmpt: SelectionComponent, signals: any[]) => any[];\n modifyExpr: (model: UnitModel, selCmpt: SelectionComponent) => string;\n marks?: (model: UnitModel, selCmpt:SelectionComponent, marks: any[]) => any[];\n predicate: string; // Vega expr string to determine inclusion in selection.\n scaleDomain: string; // Vega expr string to materialize a scale domain.\n}\n\nexport function parseUnitSelection(model: UnitModel, selDefs: Dict) {\n const selCmpts: Dict = {};\n const selectionConfig = model.config.selection;\n\n for (let name in selDefs) {\n if (!selDefs.hasOwnProperty(name)) {\n continue;\n }\n\n const selDef = selDefs[name];\n const cfg = selectionConfig[selDef.type];\n\n // Set default values from config if a property hasn't been specified,\n // or if it is true. E.g., \"translate\": true should use the default\n // event handlers for translate. However, true may be a valid value for\n // a property (e.g., \"nearest\": true).\n for (const key in cfg) {\n // A selection should contain either `encodings` or `fields`, only use\n // default values for these two values if neither of them is specified.\n if ((key === 'encodings' && selDef.fields) || (key === 'fields' && selDef.encodings)) {\n continue;\n }\n\n if (key === 'mark') {\n selDef[key] = {...cfg[key], ...selDef[key]};\n }\n\n if (selDef[key] === undefined || selDef[key] === true) {\n selDef[key] = cfg[key] || selDef[key];\n }\n }\n\n name = varName(name);\n const selCmpt = selCmpts[name] = {\n ...selDef,\n name: name,\n events: isString(selDef.on) ? parseSelector(selDef.on, 'scope') : selDef.on,\n } as SelectionComponent;\n\n forEachTransform(selCmpt, txCompiler => {\n if (txCompiler.parse) {\n txCompiler.parse(model, selDef, selCmpt);\n }\n });\n }\n\n return selCmpts;\n}\n\nexport function assembleUnitSelectionSignals(model: UnitModel, signals: any[]) {\n forEachSelection(model, (selCmpt, selCompiler) => {\n const name = selCmpt.name;\n let modifyExpr = selCompiler.modifyExpr(model, selCmpt);\n\n signals.push.apply(signals, selCompiler.signals(model, selCmpt));\n\n forEachTransform(selCmpt, txCompiler => {\n if (txCompiler.signals) {\n signals = txCompiler.signals(model, selCmpt, signals);\n }\n if (txCompiler.modifyExpr) {\n modifyExpr = txCompiler.modifyExpr(model, selCmpt, modifyExpr);\n }\n });\n\n signals.push({\n name: name + MODIFY,\n on: [{\n events: {signal: name + TUPLE},\n update: `modify(${stringValue(selCmpt.name + STORE)}, ${modifyExpr})`\n }]\n });\n });\n\n const facetModel = getFacetModel(model);\n if (signals.length && facetModel) {\n const name = stringValue(facetModel.getName('cell'));\n signals.unshift({\n name: 'facet',\n value: {},\n on: [{\n events: parseSelector('mousemove', 'scope'),\n update: `isTuple(facet) ? facet : group(${name}).datum`\n }]\n });\n }\n\n return signals;\n}\n\nexport function assembleTopLevelSignals(model: UnitModel, signals: any[]) {\n let needsUnit = false;\n forEachSelection(model, (selCmpt, selCompiler) => {\n if (selCompiler.topLevelSignals) {\n signals = selCompiler.topLevelSignals(model, selCmpt, signals);\n }\n\n forEachTransform(selCmpt, txCompiler => {\n if (txCompiler.topLevelSignals) {\n signals = txCompiler.topLevelSignals(model, selCmpt, signals);\n }\n });\n\n needsUnit = true;\n });\n\n if (needsUnit) {\n const hasUnit = signals.filter((s) => s.name === 'unit');\n if (!(hasUnit.length)) {\n signals.unshift({\n name: 'unit',\n value: {},\n on: [{events: 'mousemove', update: 'isTuple(group()) ? group() : unit'}]\n });\n }\n }\n\n return signals;\n}\n\nexport function assembleUnitSelectionData(model: UnitModel, data: VgData[]): VgData[] {\n forEachSelection(model, selCmpt => {\n const contains = data.filter((d) => d.name === selCmpt.name + STORE);\n if (!contains.length) {\n data.push({name: selCmpt.name + STORE});\n }\n });\n\n return data;\n}\n\nexport function assembleUnitSelectionMarks(model: UnitModel, marks: any[]): any[] {\n forEachSelection(model, (selCmpt, selCompiler) => {\n marks = selCompiler.marks ? selCompiler.marks(model, selCmpt, marks) : marks;\n forEachTransform(selCmpt, (txCompiler) => {\n if (txCompiler.marks) {\n marks = txCompiler.marks(model, selCmpt, marks);\n }\n });\n });\n\n return marks;\n}\n\nexport function assembleLayerSelectionMarks(model: LayerModel, marks: any[]): any[] {\n model.children.forEach(child => {\n if (isUnitModel(child)) {\n marks = assembleUnitSelectionMarks(child, marks);\n }\n });\n\n return marks;\n}\n\nexport function selectionPredicate(model: Model, selections: LogicalOperand, dfnode?: DataFlowNode): string {\n const stores: string[] = [];\n function expr(name: string): string {\n const vname = varName(name);\n const selCmpt = model.getSelectionComponent(vname, name);\n const store = stringValue(vname + STORE);\n\n if (selCmpt.timeUnit) {\n const child = dfnode || model.component.data.raw;\n const tunode = selCmpt.timeUnit.clone();\n if (child.parent) {\n tunode.insertAsParentOf(child);\n } else {\n child.parent = tunode;\n }\n }\n\n if (selCmpt.empty !== 'none') {\n stores.push(store);\n }\n\n return compiler(selCmpt.type).predicate + `(${store}, datum` +\n (selCmpt.resolve === 'global' ? ')' : `, ${stringValue(selCmpt.resolve)})`);\n }\n\n const predicateStr = logicalExpr(selections, expr);\n return (stores.length\n ? '!(' + stores.map((s) => `length(data(${s}))`).join(' || ') + ') || '\n : ''\n ) + `(${predicateStr})`;\n}\n\n// Selections are parsed _after_ scales. If a scale domain is set to\n// use a selection, the SELECTION_DOMAIN constant is used as the\n// domainRaw.signal during scale.parse and then replaced with the necessary\n// selection expression function during scale.assemble. To not pollute the\n// type signatures to account for this setup, the selection domain definition\n// is coerced to a string and appended to SELECTION_DOMAIN.\nexport function isRawSelectionDomain(domainRaw: VgSignalRef) {\n return domainRaw.signal.indexOf(SELECTION_DOMAIN) >= 0;\n}\nexport function selectionScaleDomain(model: Model, domainRaw: VgSignalRef): VgSignalRef {\n const selDomain = JSON.parse(domainRaw.signal.replace(SELECTION_DOMAIN, ''));\n const name = varName(selDomain.selection);\n\n let selCmpt = model.component.selection && model.component.selection[name];\n if (selCmpt) {\n warn('Use \"bind\": \"scales\" to setup a binding for scales and selections within the same view.');\n } else {\n selCmpt = model.getSelectionComponent(name, selDomain.selection);\n if (!selDomain.encoding && !selDomain.field) {\n selDomain.field = selCmpt.project[0].field;\n if (selCmpt.project.length > 1) {\n warn('A \"field\" or \"encoding\" must be specified when using a selection as a scale domain. ' +\n `Using \"field\": ${stringValue(selDomain.field)}.`);\n }\n }\n return {\n signal: compiler(selCmpt.type).scaleDomain +\n `(${stringValue(name + STORE)}, ${stringValue(selDomain.encoding || null)}, ` +\n stringValue(selDomain.field || null) +\n (selCmpt.resolve === 'global' ? ')' : `, ${stringValue(selCmpt.resolve)})`)\n };\n }\n\n return {signal: 'null'};\n}\n\n// Utility functions\n\nfunction forEachSelection(model: Model, cb: (selCmpt: SelectionComponent, selCompiler: SelectionCompiler) => void) {\n const selections = model.component.selection;\n for (const name in selections) {\n if (selections.hasOwnProperty(name)) {\n const sel = selections[name];\n cb(sel, compiler(sel.type));\n }\n }\n}\n\nfunction compiler(type: SelectionType): SelectionCompiler {\n switch (type) {\n case 'single':\n return singleCompiler;\n case 'multi':\n return multiCompiler;\n case 'interval':\n return intervalCompiler;\n }\n return null;\n}\n\nfunction getFacetModel(model: Model): FacetModel {\n let parent = model.parent;\n while (parent) {\n if (isFacetModel(parent)) {\n break;\n }\n parent = parent.parent;\n }\n\n return parent as FacetModel;\n}\n\nexport function unitName(model: Model) {\n let name = stringValue(model.name);\n const facet = getFacetModel(model);\n if (facet) {\n name += (facet.facet.row ? ` + '_' + (${accessPathWithDatum(facet.vgField('row'), 'facet')})` : '')\n + (facet.facet.column ? ` + '_' + (${accessPathWithDatum(facet.vgField('column'), 'facet')})` : '');\n }\n return name;\n}\n\nexport function requiresSelectionId(model: Model) {\n let identifier = false;\n forEachSelection(model, (selCmpt) => {\n identifier = identifier || selCmpt.project.some((proj) => proj.field === SELECTION_ID);\n });\n return identifier;\n}\n\nexport function channelSignalName(selCmpt: SelectionComponent, channel: Channel, range: 'visual' | 'data') {\n const sgNames = selCmpt._signalNames || (selCmpt._signalNames = {});\n if (sgNames[channel] && sgNames[channel][range]) {\n return sgNames[channel][range];\n }\n\n sgNames[channel] = sgNames[channel] || {};\n const basename = varName(selCmpt.name + '_' + (range === 'visual' ? channel : selCmpt.fields[channel]));\n let name = basename;\n let counter = 1;\n while (sgNames[name]) {\n name = `${basename}_${counter++}`;\n }\n\n return (sgNames[name] = sgNames[channel][range] = name);\n}\n\nexport function positionalProjections(selCmpt: SelectionComponent) {\n let x:ProjectComponent = null;\n let xi:number = null;\n let y:ProjectComponent = null;\n let yi: number = null;\n\n selCmpt.project.forEach((p, i) => {\n if (p.channel === X) {\n x = p;\n xi = i;\n } else if (p.channel === Y) {\n y = p;\n yi = i;\n }\n });\n return {x, xi, y, yi};\n}\n","import {ScaleChannel} from '../../channel';\nimport {Scale, ScaleType} from '../../scale';\nimport {Omit} from '../../util';\nimport {VgNonUnionDomain, VgScale} from '../../vega.schema';\nimport {Explicit, Split} from '../split';\n\n/**\n * All VgDomain property except domain.\n * (We exclude domain as we have a special \"domains\" array that allow us merge them all at once in assemble.)\n */\n// TODO: also exclude domainRaw and property implement the right scaleComponent for selection domain\nexport type ScaleComponentProps = Omit;\n\nexport class ScaleComponent extends Split {\n public merged = false;\n\n public domains: VgNonUnionDomain[] = [];\n\n constructor(name: string, typeWithExplicit: Explicit) {\n super(\n {}, // no initial explicit property\n {name} // name as initial implicit property\n );\n this.setWithExplicit('type', typeWithExplicit);\n }\n}\n\n// Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\nexport type ScaleComponentIndex = {[P in ScaleChannel]?: ScaleComponent};\n\nexport type ScaleIndex = {[P in ScaleChannel]?: Scale};\n","import {isNumber} from 'vega-util';\n\nimport {Channel, COLOR, FILL, OPACITY, SCALE_CHANNELS, ScaleChannel, SHAPE, SIZE, STROKE, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport * as log from '../../log';\nimport {Mark} from '../../mark';\nimport {\n channelScalePropertyIncompatability,\n isExtendedScheme,\n Range,\n Scale,\n ScaleConfig,\n ScaleType,\n scaleTypeSupportProperty,\n Scheme,\n} from '../../scale';\nimport {hasContinuousDomain} from '../../scale';\nimport {Type} from '../../type';\nimport * as util from '../../util';\nimport {isVgRangeStep, VgRange, VgScheme} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {Explicit, makeExplicit, makeImplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {ScaleComponentIndex} from './component';\nimport {parseNonUnitScaleProperty} from './properties';\n\n\nexport type RangeMixins = {range: Range} | {rangeStep: number} | {scheme: Scheme};\n\nexport const RANGE_PROPERTIES: (keyof Scale)[] = ['range', 'rangeStep', 'scheme'];\n\n\nexport function parseScaleRange(model: Model) {\n if (isUnitModel(model)) {\n parseUnitScaleRange(model);\n } else {\n parseNonUnitScaleProperty(model, 'range');\n }\n}\n\nfunction parseUnitScaleRange(model: UnitModel) {\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n // use SCALE_CHANNELS instead of scales[channel] to ensure that x, y come first!\n SCALE_CHANNELS.forEach((channel: ScaleChannel) => {\n const localScaleCmpt = localScaleComponents[channel];\n if (!localScaleCmpt) {\n return;\n }\n const mergedScaleCmpt = model.getScaleComponent(channel);\n\n\n const specifiedScale = model.specifiedScales[channel];\n const fieldDef = model.fieldDef(channel);\n\n // Read if there is a specified width/height\n const sizeType = channel === 'x' ? 'width' : channel === 'y' ? 'height' : undefined;\n let sizeSpecified = sizeType ? !!model.component.layoutSize.get(sizeType) : undefined;\n\n const scaleType = mergedScaleCmpt.get('type');\n\n // if autosize is fit, size cannot be data driven\n const rangeStep = util.contains(['point', 'band'], scaleType) || !!specifiedScale.rangeStep;\n if (sizeType && model.fit && !sizeSpecified && rangeStep) {\n log.warn(log.message.CANNOT_FIX_RANGE_STEP_WITH_FIT);\n sizeSpecified = true;\n }\n\n const xyRangeSteps = getXYRangeStep(model);\n\n const rangeWithExplicit = parseRangeForChannel(\n channel, scaleType, fieldDef.type, specifiedScale, model.config,\n localScaleCmpt.get('zero'), model.mark, sizeSpecified, model.getName(sizeType), xyRangeSteps\n );\n\n localScaleCmpt.setWithExplicit('range', rangeWithExplicit);\n });\n}\n\nfunction getXYRangeStep(model: UnitModel) {\n const xyRangeSteps: number[] = [];\n\n const xScale = model.getScaleComponent('x');\n const xRange = xScale && xScale.get('range');\n if (xRange && isVgRangeStep(xRange) && isNumber(xRange.step)) {\n xyRangeSteps.push(xRange.step);\n }\n\n const yScale = model.getScaleComponent('y');\n const yRange = yScale && yScale.get('range');\n if (yRange && isVgRangeStep(yRange) && isNumber(yRange.step)) {\n xyRangeSteps.push(yRange.step);\n }\n\n return xyRangeSteps;\n}\n\n/**\n * Return mixins that includes one of the range properties (range, rangeStep, scheme).\n */\nexport function parseRangeForChannel(\n channel: Channel, scaleType: ScaleType, type: Type, specifiedScale: Scale, config: Config,\n zero: boolean, mark: Mark, sizeSpecified: boolean, sizeSignal: string, xyRangeSteps: number[]\n ): Explicit {\n\n const noRangeStep = sizeSpecified || specifiedScale.rangeStep === null;\n\n // Check if any of the range properties is specified.\n // If so, check if it is compatible and make sure that we only output one of the properties\n for (const property of RANGE_PROPERTIES) {\n if (specifiedScale[property] !== undefined) {\n const supportedByScaleType = scaleTypeSupportProperty(scaleType, property);\n const channelIncompatability = channelScalePropertyIncompatability(channel, property);\n if (!supportedByScaleType) {\n log.warn(log.message.scalePropertyNotWorkWithScaleType(scaleType, property, channel));\n } else if (channelIncompatability) { // channel\n log.warn(channelIncompatability);\n } else {\n switch (property) {\n case 'range':\n return makeExplicit(specifiedScale[property]);\n case 'scheme':\n return makeExplicit(parseScheme(specifiedScale[property]));\n case 'rangeStep':\n const rangeStep = specifiedScale[property];\n if (rangeStep !== null) {\n if (!sizeSpecified) {\n return makeExplicit({step: rangeStep});\n } else {\n // If top-level size is specified, we ignore specified rangeStep.\n log.warn(log.message.rangeStepDropped(channel));\n }\n }\n }\n }\n }\n }\n return makeImplicit(\n defaultRange(\n channel, scaleType, type, config,\n zero, mark, sizeSignal, xyRangeSteps, noRangeStep\n )\n );\n}\n\nfunction parseScheme(scheme: Scheme) {\n if (isExtendedScheme(scheme)) {\n const r: VgScheme = {scheme: scheme.name};\n if (scheme.count) {\n r.count = scheme.count;\n }\n if (scheme.extent) {\n r.extent = scheme.extent;\n }\n return r;\n }\n return {scheme: scheme};\n}\n\nexport function defaultRange(\n channel: Channel, scaleType: ScaleType, type: Type, config: Config, zero: boolean, mark: Mark,\n sizeSignal: string, xyRangeSteps: number[], noRangeStep: boolean\n): VgRange {\n switch (channel) {\n case X:\n case Y:\n if (util.contains(['point', 'band'], scaleType) && !noRangeStep) {\n if (channel === X && mark === 'text') {\n if (config.scale.textXRangeStep) {\n return {step: config.scale.textXRangeStep};\n }\n } else {\n if (config.scale.rangeStep) {\n return {step: config.scale.rangeStep};\n }\n }\n }\n\n // If range step is null, use zero to width or height.\n // Note that these range signals are temporary\n // as they can be merged and renamed.\n // (We do not have the right size signal here since parseLayoutSize() happens after parseScale().)\n // We will later replace these temporary names with\n // the final name in assembleScaleRange()\n\n if (channel === Y && hasContinuousDomain(scaleType)) {\n // For y continuous scale, we have to start from the height as the bottom part has the max value.\n return [{signal: sizeSignal}, 0];\n } else {\n return [0, {signal: sizeSignal}];\n }\n case SIZE:\n // TODO: support custom rangeMin, rangeMax\n const rangeMin = sizeRangeMin(mark, zero, config);\n const rangeMax = sizeRangeMax(mark, xyRangeSteps, config);\n return [rangeMin, rangeMax];\n case SHAPE:\n return 'symbol';\n case COLOR:\n case FILL:\n case STROKE:\n if (scaleType === 'ordinal') {\n // Only nominal data uses ordinal scale by default\n return type === 'nominal' ? 'category' : 'ordinal';\n }\n return mark === 'rect' || mark === 'geoshape' ? 'heatmap' : 'ramp';\n case OPACITY:\n // TODO: support custom rangeMin, rangeMax\n return [config.scale.minOpacity, config.scale.maxOpacity];\n }\n /* istanbul ignore next: should never reach here */\n throw new Error(`Scale range undefined for channel ${channel}`);\n}\n\nfunction sizeRangeMin(mark: Mark, zero: boolean, config: Config) {\n if (zero) {\n return 0;\n }\n switch (mark) {\n case 'bar':\n case 'tick':\n return config.scale.minBandSize;\n case 'line':\n case 'trail':\n case 'rule':\n return config.scale.minStrokeWidth;\n case 'text':\n return config.scale.minFontSize;\n case 'point':\n case 'square':\n case 'circle':\n return config.scale.minSize;\n }\n /* istanbul ignore next: should never reach here */\n // sizeRangeMin not implemented for the mark\n throw new Error(log.message.incompatibleChannel('size', mark));\n}\n\nfunction sizeRangeMax(mark: Mark, xyRangeSteps: number[], config: Config) {\n const scaleConfig = config.scale;\n switch (mark) {\n case 'bar':\n case 'tick':\n if (config.scale.maxBandSize !== undefined) {\n return config.scale.maxBandSize;\n }\n return minXYRangeStep(xyRangeSteps, config.scale) - 1;\n case 'line':\n case 'trail':\n case 'rule':\n return config.scale.maxStrokeWidth;\n case 'text':\n return config.scale.maxFontSize;\n case 'point':\n case 'square':\n case 'circle':\n if (config.scale.maxSize) {\n return config.scale.maxSize;\n }\n\n // FIXME this case totally should be refactored\n const pointStep = minXYRangeStep(xyRangeSteps, scaleConfig);\n return (pointStep - 2) * (pointStep - 2);\n }\n /* istanbul ignore next: should never reach here */\n // sizeRangeMax not implemented for the mark\n throw new Error(log.message.incompatibleChannel('size', mark));\n}\n\n/**\n * @returns {number} Range step of x or y or minimum between the two if both are ordinal scale.\n */\nfunction minXYRangeStep(xyRangeSteps: number[], scaleConfig: ScaleConfig): number {\n if (xyRangeSteps.length > 0) {\n return Math.min.apply(null, xyRangeSteps);\n }\n if (scaleConfig.rangeStep) {\n return scaleConfig.rangeStep;\n }\n return 21; // FIXME: re-evaluate the default value here.\n}\n","import {Channel, ScaleChannel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {FieldDef, ScaleFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {BarConfig, MarkDef} from '../../mark';\nimport {channelScalePropertyIncompatability, Domain, hasContinuousDomain, isContinuousToContinuous, NiceTime, Scale, ScaleConfig, ScaleType, scaleTypeSupportProperty} from '../../scale';\nimport {Sort} from '../../sort';\nimport * as util from '../../util';\nimport {contains, keys} from '../../util';\nimport {VgScale} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {Explicit, mergeValuesWithExplicit, tieBreakByComparing} from '../split';\nimport {UnitModel} from '../unit';\nimport {ScaleComponentIndex, ScaleComponentProps} from './component';\nimport {parseScaleRange} from './range';\n\nexport function parseScaleProperty(model: Model, property: keyof (Scale | ScaleComponentProps)) {\n if (isUnitModel(model)) {\n parseUnitScaleProperty(model, property);\n } else {\n parseNonUnitScaleProperty(model, property);\n }\n}\n\nfunction parseUnitScaleProperty(model: UnitModel, property: keyof (Scale | ScaleComponentProps)) {\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n const specifiedScale = model.specifiedScales[channel];\n const localScaleCmpt = localScaleComponents[channel];\n const mergedScaleCmpt = model.getScaleComponent(channel);\n const fieldDef = model.fieldDef(channel);\n const config = model.config;\n\n const specifiedValue = specifiedScale[property];\n const sType = mergedScaleCmpt.get('type');\n\n const supportedByScaleType = scaleTypeSupportProperty(sType, property);\n const channelIncompatability = channelScalePropertyIncompatability(channel, property);\n\n if (specifiedValue !== undefined) {\n // If there is a specified value, check if it is compatible with scale type and channel\n if (!supportedByScaleType) {\n log.warn(log.message.scalePropertyNotWorkWithScaleType(sType, property, channel));\n } else if (channelIncompatability) { // channel\n log.warn(channelIncompatability);\n }\n }\n if (supportedByScaleType && channelIncompatability === undefined) {\n if (specifiedValue !== undefined) {\n // copyKeyFromObject ensure type safety\n localScaleCmpt.copyKeyFromObject(property, specifiedScale);\n } else {\n const value = getDefaultValue(\n property, channel, fieldDef,\n mergedScaleCmpt.get('type'),\n mergedScaleCmpt.get('padding'),\n mergedScaleCmpt.get('paddingInner'),\n specifiedScale.domain,\n model.markDef, config\n );\n if (value !== undefined) {\n localScaleCmpt.set(property, value, false);\n }\n }\n }\n });\n}\n\n// Note: This method is used in Voyager.\nexport function getDefaultValue(\n property: keyof Scale, channel: Channel, fieldDef: ScaleFieldDef,\n scaleType: ScaleType, scalePadding: number, scalePaddingInner: number,\n specifiedDomain: Scale['domain'], markDef: MarkDef, config: Config) {\n const scaleConfig = config.scale;\n\n // If we have default rule-base, determine default value first\n switch (property) {\n case 'nice':\n return nice(scaleType, channel, fieldDef);\n case 'padding':\n return padding(channel, scaleType, scaleConfig, fieldDef, markDef, config.bar);\n case 'paddingInner':\n return paddingInner(scalePadding, channel, scaleConfig);\n case 'paddingOuter':\n return paddingOuter(scalePadding, channel, scaleType, scalePaddingInner, scaleConfig);\n case 'reverse':\n return reverse(scaleType, fieldDef.sort);\n case 'zero':\n return zero(channel, fieldDef, specifiedDomain, markDef);\n }\n // Otherwise, use scale config\n return scaleConfig[property];\n}\n\nexport function parseNonUnitScaleProperty(model: Model, property: keyof (Scale | ScaleComponentProps)) {\n const localScaleComponents: ScaleComponentIndex = model.component.scales;\n\n for (const child of model.children) {\n if (property === 'range') {\n parseScaleRange(child);\n } else {\n parseScaleProperty(child, property);\n }\n }\n\n keys(localScaleComponents).forEach((channel: ScaleChannel) => {\n let valueWithExplicit: Explicit;\n\n for (const child of model.children) {\n const childComponent = child.component.scales[channel];\n if (childComponent) {\n const childValueWithExplicit = childComponent.getWithExplicit(property);\n valueWithExplicit = mergeValuesWithExplicit(\n valueWithExplicit, childValueWithExplicit,\n property,\n 'scale',\n tieBreakByComparing((v1, v2) => {\n switch (property) {\n case 'range':\n // For range step, prefer larger step\n if (v1.step && v2.step) {\n return v1.step - v2.step;\n }\n return 0;\n // TODO: precedence rule for other properties\n }\n return 0;\n })\n );\n }\n }\n localScaleComponents[channel].setWithExplicit(property, valueWithExplicit);\n });\n}\n\nexport function nice(scaleType: ScaleType, channel: Channel, fieldDef: FieldDef): boolean | NiceTime {\n if (fieldDef.bin || util.contains([ScaleType.TIME, ScaleType.UTC], scaleType)) {\n return undefined;\n }\n return util.contains([X, Y], channel); // return true for quantitative X/Y unless binned\n}\n\nexport function padding(channel: Channel, scaleType: ScaleType, scaleConfig: ScaleConfig, fieldDef: FieldDef, markDef: MarkDef, barConfig: BarConfig) {\n if (util.contains([X, Y], channel)) {\n if (isContinuousToContinuous(scaleType)) {\n if (scaleConfig.continuousPadding !== undefined) {\n return scaleConfig.continuousPadding;\n }\n\n const {type, orient} = markDef;\n if (type === 'bar' && !fieldDef.bin) {\n if (\n (orient === 'vertical' && channel === 'x') ||\n (orient === 'horizontal' && channel === 'y')\n ) {\n return barConfig.continuousBandSize;\n }\n }\n }\n\n if (scaleType === ScaleType.POINT) {\n return scaleConfig.pointPadding;\n }\n }\n return undefined;\n}\n\nexport function paddingInner(paddingValue: number, channel: Channel, scaleConfig: ScaleConfig) {\n if (paddingValue !== undefined) {\n // If user has already manually specified \"padding\", no need to add default paddingInner.\n return undefined;\n }\n\n if (util.contains([X, Y], channel)) {\n // Padding is only set for X and Y by default.\n // Basically it doesn't make sense to add padding for color and size.\n\n // paddingOuter would only be called if it's a band scale, just return the default for bandScale.\n return scaleConfig.bandPaddingInner;\n }\n return undefined;\n}\n\nexport function paddingOuter(paddingValue: number, channel: Channel, scaleType: ScaleType, paddingInnerValue: number, scaleConfig: ScaleConfig) {\n if (paddingValue !== undefined) {\n // If user has already manually specified \"padding\", no need to add default paddingOuter.\n return undefined;\n }\n\n if (util.contains([X, Y], channel)) {\n // Padding is only set for X and Y by default.\n // Basically it doesn't make sense to add padding for color and size.\n if (scaleType === ScaleType.BAND) {\n if (scaleConfig.bandPaddingOuter !== undefined) {\n return scaleConfig.bandPaddingOuter;\n }\n /* By default, paddingOuter is paddingInner / 2. The reason is that\n size (width/height) = step * (cardinality - paddingInner + 2 * paddingOuter).\n and we want the width/height to be integer by default.\n Note that step (by default) and cardinality are integers.) */\n return paddingInnerValue / 2;\n }\n }\n return undefined;\n}\n\nexport function reverse(scaleType: ScaleType, sort: Sort) {\n if (hasContinuousDomain(scaleType) && sort === 'descending') {\n // For continuous domain scales, Vega does not support domain sort.\n // Thus, we reverse range instead if sort is descending\n return true;\n }\n return undefined;\n}\n\nexport function zero(channel: Channel, fieldDef: FieldDef, specifiedScale: Domain, markDef: MarkDef) {\n\n // If users explicitly provide a domain range, we should not augment zero as that will be unexpected.\n const hasCustomDomain = !!specifiedScale && specifiedScale !== 'unaggregated';\n if (hasCustomDomain) {\n return false;\n }\n\n // If there is no custom domain, return true only for the following cases:\n\n // 1) using quantitative field with size\n // While this can be either ratio or interval fields, our assumption is that\n // ratio are more common.\n if (channel === 'size' && fieldDef.type === 'quantitative') {\n return true;\n }\n\n // 2) non-binned, quantitative x-scale or y-scale\n // (For binning, we should not include zero by default because binning are calculated without zero.)\n if (!fieldDef.bin && util.contains([X, Y], channel)) {\n const {orient, type} = markDef;\n if (contains(['bar', 'area', 'line', 'trail'], type)) {\n if (\n (orient === 'horizontal' && channel === 'y') ||\n (orient === 'vertical' && channel === 'x')\n ) {\n return false;\n }\n }\n\n return true;\n }\n return false;\n}\n","import {Channel, isColorChannel, isScaleChannel, rangeType} from '../../channel';\nimport {FieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {Mark} from '../../mark';\nimport {channelSupportScaleType, ScaleConfig, ScaleType, scaleTypeSupportDataType} from '../../scale';\nimport * as util from '../../util';\n\nexport type RangeType = 'continuous' | 'discrete' | 'flexible' | undefined;\n\n/**\n * Determine if there is a specified scale type and if it is appropriate,\n * or determine default type if type is unspecified or inappropriate.\n */\n// NOTE: CompassQL uses this method.\nexport function scaleType(\n specifiedType: ScaleType, channel: Channel, fieldDef: FieldDef,\n mark: Mark, scaleConfig: ScaleConfig\n): ScaleType {\n\n const defaultScaleType = defaultType(channel, fieldDef, mark, scaleConfig);\n\n if (!isScaleChannel(channel)) {\n // There is no scale for these channels\n return null;\n }\n if (specifiedType !== undefined) {\n // Check if explicitly specified scale type is supported by the channel\n if (!channelSupportScaleType(channel, specifiedType)) {\n log.warn(log.message.scaleTypeNotWorkWithChannel(channel, specifiedType, defaultScaleType));\n return defaultScaleType;\n }\n\n // Check if explicitly specified scale type is supported by the data type\n if (!scaleTypeSupportDataType(specifiedType, fieldDef.type, fieldDef.bin)) {\n log.warn(log.message.scaleTypeNotWorkWithFieldDef(specifiedType, defaultScaleType));\n return defaultScaleType;\n }\n\n return specifiedType;\n }\n\n return defaultScaleType;\n}\n\n/**\n * Determine appropriate default scale type.\n */\n// NOTE: Voyager uses this method.\nfunction defaultType(\n channel: Channel, fieldDef: FieldDef, mark: Mark, scaleConfig: ScaleConfig\n): ScaleType {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n if (isColorChannel(channel)|| rangeType(channel) === 'discrete') {\n if (channel === 'shape' && fieldDef.type === 'ordinal') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'ordinal'));\n }\n return 'ordinal';\n }\n\n if (util.contains(['x', 'y'], channel)) {\n if (util.contains(['rect', 'bar', 'rule'], mark)) {\n // The rect/bar mark should fit into a band.\n // For rule, using band scale to make rule align with axis ticks better https://github.com/vega/vega-lite/issues/3429\n return 'band';\n }\n if (mark === 'bar') {\n return 'band';\n }\n }\n // Otherwise, use ordinal point scale so we can easily get center positions of the marks.\n return 'point';\n\n case 'temporal':\n if (isColorChannel(channel)) {\n return 'sequential';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'temporal'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n return 'time';\n\n case 'quantitative':\n if (isColorChannel(channel)) {\n if (fieldDef.bin) {\n return 'bin-ordinal';\n }\n // Use `sequential` as the default color scale for continuous data\n // since it supports both array range and scheme range.\n return 'sequential';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'quantitative'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n\n // x and y use a linear scale because selections don't work with bin scales.\n // Binned scales apply discretization but pan/zoom apply transformations to a [min, max] extent domain.\n if (fieldDef.bin && channel !== 'x' && channel !== 'y') {\n return 'bin-linear';\n }\n return 'linear';\n\n case 'latitude':\n case 'longitude':\n case 'geojson':\n return undefined;\n }\n\n /* istanbul ignore next: should never reach this */\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n","import {SCALE_CHANNELS, ScaleChannel, SHAPE, X, Y} from '../../channel';\nimport {FieldDef, getFieldDef, hasConditionalFieldDef, isFieldDef} from '../../fielddef';\nimport {GEOSHAPE} from '../../mark';\nimport {\n NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES,\n Scale,\n scaleCompatible,\n ScaleType,\n scaleTypePrecedence,\n} from '../../scale';\nimport {GEOJSON} from '../../type';\nimport {keys} from '../../util';\nimport {VgScale} from '../../vega.schema';\nimport {isUnitModel, Model} from '../model';\nimport {defaultScaleResolve} from '../resolve';\nimport {Explicit, mergeValuesWithExplicit, tieBreakByComparing} from '../split';\nimport {UnitModel} from '../unit';\nimport {ScaleComponent, ScaleComponentIndex} from './component';\nimport {parseScaleDomain} from './domain';\nimport {parseScaleProperty} from './properties';\nimport {parseScaleRange} from './range';\nimport {scaleType} from './type';\n\nexport function parseScale(model: Model) {\n parseScaleCore(model);\n parseScaleDomain(model);\n for (const prop of NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES) {\n parseScaleProperty(model, prop);\n }\n // range depends on zero\n parseScaleRange(model);\n}\n\nexport function parseScaleCore(model: Model) {\n if (isUnitModel(model)) {\n model.component.scales = parseUnitScaleCore(model);\n } else {\n model.component.scales = parseNonUnitScaleCore(model);\n }\n}\n\n/**\n * Parse scales for all channels of a model.\n */\nfunction parseUnitScaleCore(model: UnitModel): ScaleComponentIndex {\n const {encoding, config, mark} = model;\n\n return SCALE_CHANNELS.reduce((scaleComponents: ScaleComponentIndex, channel: ScaleChannel) => {\n let fieldDef: FieldDef;\n let specifiedScale: Scale | null = undefined;\n\n const channelDef = encoding[channel];\n\n // Don't generate scale for shape of geoshape\n if (\n isFieldDef(channelDef) && mark === GEOSHAPE &&\n channel === SHAPE && channelDef.type === GEOJSON\n ) {\n return scaleComponents;\n }\n\n if (isFieldDef(channelDef)) {\n fieldDef = channelDef;\n specifiedScale = channelDef.scale;\n } else if (hasConditionalFieldDef(channelDef)) {\n fieldDef = channelDef.condition;\n specifiedScale = channelDef.condition['scale']; // We use ['scale'] since we know that channel here has scale for sure\n } else if (channel === X) {\n fieldDef = getFieldDef(encoding.x2);\n } else if (channel === Y) {\n fieldDef = getFieldDef(encoding.y2);\n }\n\n if (fieldDef && specifiedScale !== null && specifiedScale !== false) {\n specifiedScale = specifiedScale || {};\n const specifiedScaleType = specifiedScale.type;\n const sType = scaleType(specifiedScale.type, channel, fieldDef, mark, config.scale);\n scaleComponents[channel] = new ScaleComponent(\n model.scaleName(channel + '', true),\n {value: sType, explicit: specifiedScaleType === sType}\n );\n }\n return scaleComponents;\n }, {});\n}\n\nconst scaleTypeTieBreaker = tieBreakByComparing(\n (st1: ScaleType, st2: ScaleType) => (scaleTypePrecedence(st1) - scaleTypePrecedence(st2))\n);\n\n\nfunction parseNonUnitScaleCore(model: Model) {\n const scaleComponents: ScaleComponentIndex = model.component.scales = {};\n\n const scaleTypeWithExplicitIndex: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleChannel]?: Explicit\n } = {};\n const resolve = model.component.resolve;\n\n // Parse each child scale and determine if a particular channel can be merged.\n for (const child of model.children) {\n parseScaleCore(child);\n\n // Instead of always merging right away -- check if it is compatible to merge first!\n keys(child.component.scales).forEach((channel: ScaleChannel) => {\n // if resolve is undefined, set default first\n resolve.scale[channel] = resolve.scale[channel] || defaultScaleResolve(channel, model);\n\n if (resolve.scale[channel] === 'shared') {\n const explicitScaleType = scaleTypeWithExplicitIndex[channel];\n const childScaleType = child.component.scales[channel].getWithExplicit('type');\n\n if (explicitScaleType) {\n if (scaleCompatible(explicitScaleType.value, childScaleType.value)) {\n // merge scale component if type are compatible\n scaleTypeWithExplicitIndex[channel] = mergeValuesWithExplicit(\n explicitScaleType, childScaleType, 'type', 'scale', scaleTypeTieBreaker\n );\n } else {\n // Otherwise, update conflicting channel to be independent\n resolve.scale[channel] = 'independent';\n // Remove from the index so they don't get merged\n delete scaleTypeWithExplicitIndex[channel];\n }\n } else {\n scaleTypeWithExplicitIndex[channel] = childScaleType;\n }\n }\n });\n }\n\n // Merge each channel listed in the index\n keys(scaleTypeWithExplicitIndex).forEach((channel: ScaleChannel) => {\n // Create new merged scale component\n const name = model.scaleName(channel, true);\n const typeWithExplicit = scaleTypeWithExplicitIndex[channel];\n scaleComponents[channel] = new ScaleComponent(name, typeWithExplicit);\n\n // rename each child and mark them as merged\n for (const child of model.children) {\n const childScale = child.component.scales[channel];\n if (childScale) {\n child.renameScale(childScale.get('name'), name);\n childScale.merged = true;\n }\n }\n });\n\n return scaleComponents;\n}\n","import {isNumber, isString} from 'vega-util';\nimport {Channel, isChannel, isScaleChannel, ScaleChannel, SingleDefChannel} from '../channel';\nimport {Config} from '../config';\nimport {Data, DataSourceType} from '../data';\nimport {forEach, reduce} from '../encoding';\nimport {ChannelDef, FieldDef, FieldRefOption, getFieldDef, vgField} from '../fielddef';\nimport * as log from '../log';\nimport {Resolve} from '../resolve';\nimport {hasDiscreteDomain} from '../scale';\nimport {BaseSpec, isFacetSpec, isLayerSpec, isUnitSpec} from '../spec';\nimport {extractTitleConfig, TitleParams} from '../title';\nimport {extractCompositionLayout, GenericCompositionLayout} from '../toplevelprops';\nimport {normalizeTransform, Transform} from '../transform';\nimport {contains, Dict, keys, varName} from '../util';\nimport {isVgRangeStep, VgAxis, VgData, VgEncodeEntry, VgLayout, VgLegend, VgMarkGroup, VgProjection, VgSignal, VgSignalRef, VgTitle} from '../vega.schema';\nimport {assembleAxes} from './axis/assemble';\nimport {AxisComponentIndex} from './axis/component';\nimport {ConcatModel} from './concat';\nimport {DataComponent} from './data';\nimport {FacetModel} from './facet';\nimport {getHeaderGroups, getTitleGroup, HEADER_CHANNELS, LayoutHeaderComponent} from './header/index';\nimport {LayerModel} from './layer';\nimport {sizeExpr} from './layoutsize/assemble';\nimport {LayoutSizeComponent, LayoutSizeIndex} from './layoutsize/component';\nimport {assembleLegends} from './legend/assemble';\nimport {LegendComponentIndex} from './legend/component';\nimport {parseLegend} from './legend/parse';\nimport {assembleProjections} from './projection/assemble';\nimport {ProjectionComponent} from './projection/component';\nimport {parseProjection} from './projection/parse';\nimport {RepeatModel} from './repeat';\nimport {RepeaterValue} from './repeater';\nimport {assembleScales} from './scale/assemble';\nimport {ScaleComponent, ScaleComponentIndex} from './scale/component';\nimport {assembleDomain, getFieldFromDomain} from './scale/domain';\nimport {parseScale} from './scale/parse';\nimport {SelectionComponent} from './selection/selection';\nimport {Split} from './split';\nimport {UnitModel} from './unit';\n\n/**\n * Composable Components that are intermediate results of the parsing phase of the\n * compilations. The components represents parts of the specification in a form that\n * can be easily merged (during parsing for composite specs).\n * In addition, these components are easily transformed into Vega specifications\n * during the \"assemble\" phase, which is the last phase of the compilation step.\n */\nexport interface Component {\n data: DataComponent;\n\n layoutSize: LayoutSizeComponent;\n\n layoutHeaders: {\n row?: LayoutHeaderComponent,\n column?: LayoutHeaderComponent\n };\n\n mark: VgMarkGroup[];\n scales: ScaleComponentIndex;\n projection: ProjectionComponent;\n selection: Dict;\n\n /** Dictionary mapping channel to VgAxis definition */\n axes: AxisComponentIndex;\n\n /** Dictionary mapping channel to VgLegend definition */\n legends: LegendComponentIndex;\n\n resolve: Resolve;\n}\n\nexport interface NameMapInterface {\n rename(oldname: string, newName: string): void;\n has(name: string): boolean;\n get(name: string): string;\n}\n\nexport class NameMap implements NameMapInterface {\n private nameMap: Dict;\n\n constructor() {\n this.nameMap = {};\n }\n\n public rename(oldName: string, newName: string) {\n this.nameMap[oldName] = newName;\n }\n\n\n public has(name: string): boolean {\n return this.nameMap[name] !== undefined;\n }\n\n public get(name: string): string {\n // If the name appears in the _nameMap, we need to read its new name.\n // We have to loop over the dict just in case the new name also gets renamed.\n while (this.nameMap[name] && name !== this.nameMap[name]) {\n name = this.nameMap[name];\n }\n\n return name;\n }\n}\n\n/*\n We use type guards instead of `instanceof` as `instanceof` makes\n different parts of the compiler depend on the actual implementation of\n the model classes, which in turn depend on different parts of the compiler.\n Thus, `instanceof` leads to circular dependency problems.\n\n On the other hand, type guards only make different parts of the compiler\n depend on the type of the model classes, but not the actual implementation.\n*/\n\nexport function isUnitModel(model: Model): model is UnitModel {\n return model && model.type === 'unit';\n}\n\nexport function isFacetModel(model: Model): model is FacetModel {\n return model && model.type === 'facet';\n}\n\nexport function isRepeatModel(model: Model): model is RepeatModel {\n return model && model.type === 'repeat';\n}\n\nexport function isConcatModel(model: Model): model is ConcatModel {\n return model && model.type === 'concat';\n}\n\nexport function isLayerModel(model: Model): model is LayerModel {\n return model && model.type === 'layer';\n}\n\nexport abstract class Model {\n public abstract readonly type: 'unit' | 'facet' | 'layer' | 'concat' | 'repeat';\n public readonly parent: Model;\n public readonly name: string;\n\n public readonly title: TitleParams;\n public readonly description: string;\n\n public readonly data: Data;\n public readonly transforms: Transform[];\n public readonly layout: GenericCompositionLayout;\n\n /** Name map for scales, which can be renamed by a model's parent. */\n protected scaleNameMap: NameMapInterface;\n\n /** Name map for projections, which can be renamed by a model's parent. */\n protected projectionNameMap: NameMapInterface;\n\n /** Name map for size, which can be renamed by a model's parent. */\n protected layoutSizeNameMap: NameMapInterface;\n\n public readonly repeater: RepeaterValue;\n\n public readonly config: Config;\n\n public readonly component: Component;\n\n public abstract readonly children: Model[] = [];\n\n constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, repeater: RepeaterValue, resolve: Resolve) {\n this.parent = parent;\n this.config = config;\n this.repeater = repeater;\n\n // If name is not provided, always use parent's givenName to avoid name conflicts.\n this.name = spec.name || parentGivenName;\n this.title = isString(spec.title) ? {text: spec.title} : spec.title;\n\n // Shared name maps\n this.scaleNameMap = parent ? parent.scaleNameMap : new NameMap();\n this.projectionNameMap = parent ? parent.projectionNameMap : new NameMap();\n this.layoutSizeNameMap = parent ? parent.layoutSizeNameMap : new NameMap();\n\n this.data = spec.data;\n\n this.description = spec.description;\n this.transforms = normalizeTransform(spec.transform || []);\n this.layout = isUnitSpec(spec) || isLayerSpec(spec) ? undefined : extractCompositionLayout(spec);\n\n this.component = {\n data: {\n sources: parent ? parent.component.data.sources : {},\n outputNodes: parent ? parent.component.data.outputNodes : {},\n outputNodeRefCounts: parent ? parent.component.data.outputNodeRefCounts : {},\n // data is faceted if the spec is a facet spec or the parent has faceted data and no data is defined\n isFaceted: isFacetSpec(spec) || (parent && parent.component.data.isFaceted && !spec.data)\n },\n layoutSize: new Split(),\n layoutHeaders:{row: {}, column: {}},\n mark: null,\n resolve: {\n scale: {}, axis: {}, legend: {},\n ...(resolve || {})\n },\n selection: null,\n scales: null,\n projection: null,\n axes: {},\n legends: {},\n };\n }\n\n public get width(): VgSignalRef {\n return this.getSizeSignalRef('width');\n }\n\n\n public get height(): VgSignalRef {\n return this.getSizeSignalRef('height');\n }\n\n protected initSize(size: LayoutSizeIndex) {\n const {width, height} = size;\n if (width) {\n this.component.layoutSize.set('width', width, true);\n }\n\n if (height) {\n this.component.layoutSize.set('height', height, true);\n }\n }\n\n public parse() {\n this.parseScale();\n\n this.parseLayoutSize(); // depends on scale\n this.renameTopLevelLayoutSize();\n\n this.parseSelection();\n this.parseProjection();\n this.parseData(); // (pathorder) depends on markDef; selection filters depend on parsed selections; depends on projection because some transforms require the finalized projection name.\n this.parseAxisAndHeader(); // depends on scale and layout size\n this.parseLegend(); // depends on scale, markDef\n this.parseMarkGroup(); // depends on data name, scale, layout size, axisGroup, and children's scale, axis, legend and mark.\n }\n\n public abstract parseData(): void;\n\n public abstract parseSelection(): void;\n\n\n public parseScale() {\n parseScale(this);\n }\n\n public parseProjection() {\n parseProjection(this);\n }\n\n public abstract parseLayoutSize(): void;\n\n /**\n * Rename top-level spec's size to be just width / height, ignoring model name.\n * This essentially merges the top-level spec's width/height signals with the width/height signals\n * to help us reduce redundant signals declaration.\n */\n private renameTopLevelLayoutSize() {\n if (this.getName('width') !== 'width') {\n this.renameLayoutSize(this.getName('width'), 'width');\n }\n if (this.getName('height') !== 'height') {\n this.renameLayoutSize(this.getName('height'), 'height');\n }\n }\n\n public abstract parseMarkGroup(): void;\n\n public abstract parseAxisAndHeader(): void;\n\n public parseLegend() {\n parseLegend(this);\n }\n\n public abstract assembleSelectionTopLevelSignals(signals: any[]): any[];\n public abstract assembleSelectionSignals(): any[];\n\n public abstract assembleSelectionData(data: VgData[]): VgData[];\n\n public assembleGroupStyle(): string {\n if (this.type === 'unit' || this.type === 'layer') {\n return 'cell';\n }\n return undefined;\n }\n\n public assembleLayoutSize(): VgEncodeEntry {\n if (this.type === 'unit' || this.type === 'layer') {\n return {\n width: this.getSizeSignalRef('width'),\n height: this.getSizeSignalRef('height')\n };\n }\n return undefined;\n }\n\n public assembleLayout(): VgLayout {\n if (!this.layout) {\n return undefined;\n }\n\n const {align, bounds, center, spacing = {}} = this.layout;\n\n return {\n padding: isNumber(spacing) ? spacing : {\n row: spacing.row || 10,\n column: spacing.column || 10\n },\n ...this.assembleDefaultLayout(),\n ...(align ? {align} : {}),\n ...(bounds ? {bounds} : {}),\n ...(center ? {center} : {})\n };\n }\n\n protected assembleDefaultLayout(): VgLayout {\n return {};\n }\n\n public abstract assembleLayoutSignals(): VgSignal[];\n\n public assembleHeaderMarks(): VgMarkGroup[] {\n const {layoutHeaders} = this.component;\n let headerMarks = [];\n\n for (const channel of HEADER_CHANNELS) {\n if (layoutHeaders[channel].title) {\n headerMarks.push(getTitleGroup(this, channel));\n }\n }\n\n for (const channel of HEADER_CHANNELS) {\n headerMarks = headerMarks.concat(getHeaderGroups(this, channel));\n }\n return headerMarks;\n }\n\n public abstract assembleMarks(): VgMarkGroup[]; // TODO: VgMarkGroup[]\n\n public assembleAxes(): VgAxis[] {\n return assembleAxes(this.component.axes, this.config);\n }\n\n public assembleLegends(): VgLegend[] {\n return assembleLegends(this);\n }\n\n public assembleProjections(): VgProjection[] {\n return assembleProjections(this);\n }\n\n public assembleTitle(): VgTitle {\n const title: VgTitle = {\n ...extractTitleConfig(this.config.title).nonMark,\n ...this.title\n };\n\n if (title.text) {\n if (!contains(['unit', 'layer'], this.type)) {\n // As described in https://github.com/vega/vega-lite/issues/2875:\n // Due to vega/vega#960 (comment), we only support title's anchor for unit and layered spec for now.\n\n if (title.anchor && title.anchor !== 'start') {\n log.warn(log.message.cannotSetTitleAnchor(this.type));\n }\n title.anchor = 'start';\n }\n\n return keys(title).length > 0 ? title : undefined;\n }\n return undefined;\n }\n\n /**\n * Assemble the mark group for this model. We accept optional `signals` so that we can include concat top-level signals with the top-level model's local signals.\n */\n public assembleGroup(signals: VgSignal[] = []) {\n const group: VgMarkGroup = {};\n\n signals = signals.concat(this.assembleSelectionSignals());\n\n if (signals.length > 0) {\n group.signals = signals;\n }\n\n const layout = this.assembleLayout();\n if (layout) {\n group.layout = layout;\n }\n\n group.marks = [].concat(\n this.assembleHeaderMarks(),\n this.assembleMarks()\n );\n\n // Only include scales if this spec is top-level or if parent is facet.\n // (Otherwise, it will be merged with upper-level's scope.)\n const scales = (!this.parent || isFacetModel(this.parent)) ? assembleScales(this) : [];\n if (scales.length > 0) {\n group.scales = scales;\n }\n\n const axes = this.assembleAxes();\n if (axes.length > 0) {\n group.axes = axes;\n }\n\n const legends = this.assembleLegends();\n if (legends.length > 0) {\n group.legends = legends;\n }\n\n return group;\n }\n\n public hasDescendantWithFieldOnChannel(channel: Channel) {\n for (const child of this.children) {\n if (isUnitModel(child)) {\n if (child.channelHasField(channel)) {\n return true;\n }\n } else {\n if (child.hasDescendantWithFieldOnChannel(channel)) {\n return true;\n }\n }\n }\n return false;\n }\n\n public getName(text: string) {\n return varName((this.name ? this.name + '_' : '') + text);\n }\n\n /**\n * Request a data source name for the given data source type and mark that data source as required. This method should be called in parse, so that all used data source can be correctly instantiated in assembleData().\n */\n public requestDataName(name: DataSourceType) {\n const fullName = this.getName(name);\n\n // Increase ref count. This is critical because otherwise we won't create a data source.\n // We also increase the ref counts on OutputNode.getSource() calls.\n const refCounts = this.component.data.outputNodeRefCounts;\n refCounts[fullName] = (refCounts[fullName] || 0) + 1;\n\n return fullName;\n }\n\n public getSizeSignalRef(sizeType: 'width' | 'height'): VgSignalRef {\n if (isFacetModel(this.parent)) {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const scaleComponent = this.component.scales[channel];\n\n if (scaleComponent && !scaleComponent.merged) { // independent scale\n const type = scaleComponent.get('type');\n const range = scaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const scaleName = scaleComponent.get('name');\n const domain = assembleDomain(this, channel);\n const field = getFieldFromDomain(domain);\n if (field) {\n const fieldRef = vgField({aggregate: 'distinct', field}, {expr: 'datum'});\n return {\n signal: sizeExpr(scaleName, scaleComponent, fieldRef)\n };\n } else {\n log.warn('Unknown field for ${channel}. Cannot calculate view size.');\n return null;\n }\n\n }\n }\n }\n\n return {\n signal: this.layoutSizeNameMap.get(this.getName(sizeType))\n };\n }\n\n /**\n * Lookup the name of the datasource for an output node. You probably want to call this in assemble.\n */\n public lookupDataSource(name: string) {\n const node = this.component.data.outputNodes[name];\n\n if (!node) {\n // Name not found in map so let's just return what we got.\n // This can happen if we already have the correct name.\n return name;\n }\n\n return node.getSource();\n }\n\n public getSizeName(oldSizeName: string): string {\n return this.layoutSizeNameMap.get(oldSizeName);\n }\n\n public renameLayoutSize(oldName: string, newName: string) {\n this.layoutSizeNameMap.rename(oldName, newName);\n }\n\n public renameScale(oldName: string, newName: string) {\n this.scaleNameMap.rename(oldName, newName);\n }\n\n public renameProjection(oldName: string, newName: string) {\n this.projectionNameMap.rename(oldName, newName);\n }\n\n /**\n * @return scale name for a given channel after the scale has been parsed and named.\n */\n public scaleName(originalScaleName: Channel | string, parse?: boolean): string {\n if (parse) {\n // During the parse phase always return a value\n // No need to refer to rename map because a scale can't be renamed\n // before it has the original name.\n return this.getName(originalScaleName);\n }\n\n // If there is a scale for the channel, it should either\n // be in the scale component or exist in the name map\n if (\n // If there is a scale for the channel, there should be a local scale component for it\n (isChannel(originalScaleName) && isScaleChannel(originalScaleName) && this.component.scales[originalScaleName]) ||\n // in the scale name map (the scale get merged by its parent)\n this.scaleNameMap.has(this.getName(originalScaleName))\n ) {\n return this.scaleNameMap.get(this.getName(originalScaleName));\n }\n return undefined;\n }\n\n /**\n * @return projection name after the projection has been parsed and named.\n */\n public projectionName(parse?: boolean): string {\n if (parse) {\n // During the parse phase always return a value\n // No need to refer to rename map because a projection can't be renamed\n // before it has the original name.\n return this.getName('projection');\n }\n\n if ((this.component.projection && !this.component.projection.merged) || this.projectionNameMap.has(this.getName('projection'))) {\n return this.projectionNameMap.get(this.getName('projection'));\n }\n return undefined;\n }\n\n /**\n * Corrects the data references in marks after assemble.\n */\n public correctDataNames = (mark: VgMarkGroup) => {\n // TODO: make this correct\n\n // for normal data references\n if (mark.from && mark.from.data) {\n mark.from.data = this.lookupDataSource(mark.from.data);\n }\n\n // for access to facet data\n if (mark.from && mark.from.facet && mark.from.facet.data) {\n mark.from.facet.data = this.lookupDataSource(mark.from.facet.data);\n }\n\n return mark;\n }\n\n /**\n * Traverse a model's hierarchy to get the scale component for a particular channel.\n */\n public getScaleComponent(channel: ScaleChannel): ScaleComponent {\n /* istanbul ignore next: This is warning for debugging test */\n if (!this.component.scales) {\n throw new Error('getScaleComponent cannot be called before parseScale(). Make sure you have called parseScale or use parseUnitModelWithScale().');\n }\n\n const localScaleComponent = this.component.scales[channel];\n if (localScaleComponent && !localScaleComponent.merged) {\n return localScaleComponent;\n }\n return (this.parent ? this.parent.getScaleComponent(channel) : undefined);\n }\n\n /**\n * Traverse a model's hierarchy to get a particular selection component.\n */\n public getSelectionComponent(variableName: string, origName: string): SelectionComponent {\n let sel = this.component.selection[variableName];\n if (!sel && this.parent) {\n sel = this.parent.getSelectionComponent(variableName, origName);\n }\n if (!sel) {\n throw new Error(log.message.selectionNotFound(origName));\n }\n return sel;\n }\n}\n\n/** Abstract class for UnitModel and FacetModel. Both of which can contain fieldDefs as a part of its own specification. */\nexport abstract class ModelWithField extends Model {\n public abstract fieldDef(channel: SingleDefChannel): FieldDef;\n\n /** Get \"field\" reference for vega */\n public vgField(channel: SingleDefChannel, opt: FieldRefOption = {}) {\n const fieldDef = this.fieldDef(channel);\n\n if (!fieldDef) {\n return undefined;\n }\n\n return vgField(fieldDef, opt);\n }\n\n protected abstract getMapping(): {[key in Channel]?: any};\n\n public reduceFieldDef(f: (acc: U, fd: FieldDef, c: Channel) => U, init: T, t?: any) {\n return reduce(this.getMapping(), (acc:U , cd: ChannelDef, c: Channel) => {\n const fieldDef = getFieldDef(cd);\n if (fieldDef) {\n return f(acc, fieldDef, c);\n }\n return acc;\n }, init, t);\n }\n\n public forEachFieldDef(f: (fd: FieldDef, c: Channel) => void, t?: any) {\n forEach(this.getMapping(), (cd: ChannelDef, c: Channel) => {\n const fieldDef = getFieldDef(cd);\n if (fieldDef) {\n f(fieldDef, c);\n }\n }, t);\n }\n public abstract channelHasField(channel: Channel): boolean;\n}\n","import {stringValue} from 'vega-util';\nimport {Channel, X, Y} from '../../../channel';\nimport * as log from '../../../log';\nimport {hasContinuousDomain, isBinScale} from '../../../scale';\nimport {UnitModel} from '../../unit';\nimport {channelSignalName} from '../selection';\nimport {TransformCompiler} from './transforms';\n\n\nconst scaleBindings:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.resolve === 'global' &&\n selCmpt.bind && selCmpt.bind === 'scales';\n },\n\n parse: function(model, selDef, selCmpt) {\n const bound: Channel[] = selCmpt.scales = [];\n\n selCmpt.project.forEach(function(p) {\n const channel = p.channel;\n const scale = model.getScaleComponent(channel);\n const scaleType = scale ? scale.get('type') : undefined;\n\n if (!scale || !hasContinuousDomain(scaleType) || isBinScale(scaleType)) {\n log.warn(log.message.SCALE_BINDINGS_CONTINUOUS);\n return;\n }\n\n scale.set('domainRaw', {signal: channelSignalName(selCmpt, channel, 'data')}, true);\n bound.push(channel);\n\n // Bind both x/y for diag plot of repeated views.\n if (model.repeater && model.repeater.row === model.repeater.column) {\n const scale2 = model.getScaleComponent(channel === X ? Y : X);\n scale2.set('domainRaw', {signal: channelSignalName(selCmpt, channel, 'data')}, true);\n }\n });\n },\n\n topLevelSignals: function(model, selCmpt, signals) {\n // Top-level signals are only needed when coordinating composed views.\n if (!model.parent) {\n return signals;\n }\n\n const channels = selCmpt.scales.filter((channel) => {\n return !(signals.filter(s => s.name === channelSignalName(selCmpt, channel, 'data')).length);\n });\n\n return signals.concat(channels.map((channel) => {\n return {name: channelSignalName(selCmpt, channel, 'data')};\n }));\n },\n\n signals: function(model, selCmpt, signals) {\n // Nested signals need only push to top-level signals when within composed views.\n if (model.parent) {\n selCmpt.scales.forEach(channel => {\n const signal = signals.filter(s => s.name === channelSignalName(selCmpt, channel, 'data'))[0];\n\n signal.push = 'outer';\n delete signal.value;\n delete signal.update;\n });\n }\n\n return signals;\n }\n};\n\nexport default scaleBindings;\n\nexport function domain(model: UnitModel, channel: Channel) {\n const scale = stringValue(model.scaleName(channel));\n return `domain(${scale})`;\n}\n","import {stringValue} from 'vega-util';\nimport {X, Y} from '../../channel';\nimport {warn} from '../../log';\nimport {hasContinuousDomain, isBinScale} from '../../scale';\nimport {keys} from '../../util';\nimport {VgEventStream} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {\n channelSignalName,\n positionalProjections,\n SelectionCompiler,\n SelectionComponent,\n STORE,\n TUPLE,\n unitName,\n} from './selection';\nimport scales from './transforms/scales';\n\nexport const BRUSH = '_brush';\nexport const SCALE_TRIGGER = '_scale_trigger';\n\nconst interval:SelectionCompiler = {\n predicate: 'vlInterval',\n scaleDomain: 'vlIntervalDomain',\n\n signals: function(model, selCmpt) {\n const name = selCmpt.name;\n const hasScales = scales.has(selCmpt);\n const signals: any[] = [];\n const intervals: any[] = [];\n const tupleTriggers: string[] = [];\n const scaleTriggers: any[] = [];\n\n if (selCmpt.translate && !hasScales) {\n const filterExpr = `!event.item || event.item.mark.name !== ${stringValue(name + BRUSH)}`;\n events(selCmpt, function(_: any[], evt: VgEventStream) {\n const filters = evt.between[0].filter || (evt.between[0].filter = []);\n if (filters.indexOf(filterExpr) < 0) {\n filters.push(filterExpr);\n }\n });\n }\n\n selCmpt.project.forEach(function(p) {\n const channel = p.channel;\n if (channel !== X && channel !== Y) {\n warn('Interval selections only support x and y encoding channels.');\n return;\n }\n\n const cs = channelSignals(model, selCmpt, channel);\n const dname = channelSignalName(selCmpt, channel, 'data');\n const vname = channelSignalName(selCmpt, channel, 'visual');\n const scaleStr = stringValue(model.scaleName(channel));\n const scaleType = model.getScaleComponent(channel).get('type');\n const toNum = hasContinuousDomain(scaleType) ? '+' : '';\n\n signals.push.apply(signals, cs);\n tupleTriggers.push(dname);\n intervals.push(`{encoding: ${stringValue(channel)}, ` +\n `field: ${stringValue(p.field)}, extent: ${dname}}`);\n\n scaleTriggers.push({\n scaleName: model.scaleName(channel),\n expr: `(!isArray(${dname}) || ` +\n `(${toNum}invert(${scaleStr}, ${vname})[0] === ${toNum}${dname}[0] && ` +\n `${toNum}invert(${scaleStr}, ${vname})[1] === ${toNum}${dname}[1]))`\n });\n });\n\n // Proxy scale reactions to ensure that an infinite loop doesn't occur\n // when an interval selection filter touches the scale.\n if (!hasScales) {\n signals.push({\n name: name + SCALE_TRIGGER,\n update: scaleTriggers.map((t) => t.expr).join(' && ') +\n ` ? ${name + SCALE_TRIGGER} : {}`\n });\n }\n\n // Only add an interval to the store if it has valid data extents. Data extents\n // are set to null if pixel extents are equal to account for intervals over\n // ordinal/nominal domains which, when inverted, will still produce a valid datum.\n return signals.concat({\n name: name + TUPLE,\n on: [{\n events: tupleTriggers.map((t) => ({signal: t})),\n update: tupleTriggers.join(' && ') +\n ` ? {unit: ${unitName(model)}, intervals: [${intervals.join(', ')}]} : null`\n }]\n });\n },\n\n modifyExpr: function(model, selCmpt) {\n const tpl = selCmpt.name + TUPLE;\n return tpl + ', ' +\n (selCmpt.resolve === 'global' ? 'true' : `{unit: ${unitName(model)}}`);\n },\n\n marks: function(model, selCmpt, marks) {\n const name = selCmpt.name;\n const {xi, yi} = positionalProjections(selCmpt);\n const store = `data(${stringValue(selCmpt.name + STORE)})`;\n\n // Do not add a brush if we're binding to scales.\n if (scales.has(selCmpt)) {\n return marks;\n }\n\n const update: any = {\n x: xi !== null ? {signal: `${name}_x[0]`} : {value: 0},\n y: yi !== null ? {signal: `${name}_y[0]`} : {value: 0},\n x2: xi !== null ? {signal: `${name}_x[1]`} : {field: {group: 'width'}},\n y2: yi !== null ? {signal: `${name}_y[1]`} : {field: {group: 'height'}}\n };\n\n // If the selection is resolved to global, only a single interval is in\n // the store. Wrap brush mark's encodings with a production rule to test\n // this based on the `unit` property. Hide the brush mark if it corresponds\n // to a unit different from the one in the store.\n if (selCmpt.resolve === 'global') {\n for (const key of keys(update)) {\n update[key] = [{\n test: `${store}.length && ${store}[0].unit === ${unitName(model)}`,\n ...update[key]\n }, {value: 0}];\n }\n }\n\n // Two brush marks ensure that fill colors and other aesthetic choices do\n // not interefere with the core marks, but that the brushed region can still\n // be interacted with (e.g., dragging it around).\n const {fill, fillOpacity, ...stroke} = selCmpt.mark;\n const vgStroke = keys(stroke).reduce((def, k) => {\n def[k] = [{\n test: [\n xi !== null && `${name}_x[0] !== ${name}_x[1]`,\n yi != null && `${name}_y[0] !== ${name}_y[1]`,\n ].filter(x => x).join(' && '),\n value: stroke[k]\n }, {value: null}];\n return def;\n }, {});\n\n return [{\n name: name + BRUSH + '_bg',\n type: 'rect',\n clip: true,\n encode: {\n enter: {\n fill: {value: fill},\n fillOpacity: {value: fillOpacity}\n },\n update: update\n }\n } as any].concat(marks, {\n name: name + BRUSH,\n type: 'rect',\n clip: true,\n encode: {\n enter: {\n fill: {value: 'transparent'}\n },\n update: {...update, ...vgStroke}\n }\n });\n }\n};\nexport default interval;\n\n/**\n * Returns the visual and data signals for an interval selection.\n */\nfunction channelSignals(model: UnitModel, selCmpt: SelectionComponent, channel: 'x'|'y'): any {\n const vname = channelSignalName(selCmpt, channel, 'visual');\n const dname = channelSignalName(selCmpt, channel, 'data');\n const hasScales = scales.has(selCmpt);\n const scaleName = model.scaleName(channel);\n const scaleStr = stringValue(scaleName);\n const scale = model.getScaleComponent(channel);\n const scaleType = scale ? scale.get('type') : undefined;\n const size = model.getSizeSignalRef(channel === X ? 'width' : 'height').signal;\n const coord = `${channel}(unit)`;\n\n const on = events(selCmpt, function(def: any[], evt: VgEventStream) {\n return def.concat(\n {events: evt.between[0], update: `[${coord}, ${coord}]`}, // Brush Start\n {events: evt, update: `[${vname}[0], clamp(${coord}, 0, ${size})]`} // Brush End\n );\n });\n\n // React to pan/zooms of continuous scales. Non-continuous scales\n // (bin-linear, band, point) cannot be pan/zoomed and any other changes\n // to their domains (e.g., filtering) should clear the brushes.\n on.push({\n events: {signal: selCmpt.name + SCALE_TRIGGER},\n update: hasContinuousDomain(scaleType) && !isBinScale(scaleType) ?\n `[scale(${scaleStr}, ${dname}[0]), scale(${scaleStr}, ${dname}[1])]` : `[0, 0]`\n });\n\n return hasScales ? [{name: dname, on: []}] : [{\n name: vname, value: [], on: on\n }, {\n name: dname,\n on: [{events: {signal: vname}, update: `${vname}[0] === ${vname}[1] ? null : invert(${scaleStr}, ${vname})`}]\n }];\n}\n\nfunction events(selCmpt: SelectionComponent, cb: Function) {\n return selCmpt.events.reduce(function(on: any[], evt: VgEventStream) {\n if (!evt.between) {\n warn(`${evt} is not an ordered event stream for interval selections`);\n return on;\n }\n return cb(on, evt);\n }, []);\n}\n","import * as log from '../../../log';\nimport {isPathMark} from '../../../mark';\nimport {positionalProjections} from '../selection';\nimport {TransformCompiler} from './transforms';\n\nconst VORONOI = 'voronoi';\n\nconst nearest:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type !== 'interval' && selCmpt.nearest;\n },\n\n marks: function(model, selCmpt, marks) {\n const {x, y} = positionalProjections(selCmpt);\n const markType = model.mark;\n if (isPathMark(markType)) {\n log.warn(log.message.nearestNotSupportForContinuous(markType));\n return marks;\n }\n\n const cellDef = {\n name: model.getName(VORONOI),\n type: 'path',\n from: {data: model.getName('marks')},\n encode: {\n enter: {\n fill: {value: 'transparent'},\n strokeWidth: {value: 0.35},\n stroke: {value: 'transparent'},\n isVoronoi: {value: true}\n }\n },\n transform: [{\n type: 'voronoi',\n x: {expr: (x || (!x && !y)) ? 'datum.datum.x || 0' : '0'},\n y: {expr: (y || (!x && !y)) ? 'datum.datum.y || 0' : '0'},\n size: [model.getSizeSignalRef('width'), model.getSizeSignalRef('height')]\n }]\n };\n\n let index = 0;\n let exists = false;\n marks.forEach((mark, i) => {\n const name = mark.name || '';\n if (name === model.component.mark[0].name) {\n index = i;\n } else if (name.indexOf(VORONOI) >= 0) {\n exists = true;\n }\n });\n\n if (!exists) {\n marks.splice(index + 1, 0, cellDef);\n }\n\n return marks;\n }\n};\n\nexport default nearest;\n","import {stringValue} from 'vega-util';\n\nimport {accessPathWithDatum} from '../../util';\nimport {UnitModel} from '../unit';\nimport {SelectionCompiler, SelectionComponent, TUPLE, unitName} from './selection';\nimport nearest from './transforms/nearest';\n\nexport function signals(model: UnitModel, selCmpt: SelectionComponent) {\n const proj = selCmpt.project;\n const datum = nearest.has(selCmpt) ?\n '(item().isVoronoi ? datum.datum : datum)' : 'datum';\n const bins: string[] = [];\n const encodings = proj.map((p) => stringValue(p.channel)).filter((e) => e).join(', ');\n const fields = proj.map((p) => stringValue(p.field)).join(', ');\n const values = proj.map((p) => {\n const channel = p.channel;\n const fieldDef = model.fieldDef(channel);\n // Binned fields should capture extents, for a range test against the raw field.\n return (fieldDef && fieldDef.bin) ? (bins.push(p.field),\n `[${accessPathWithDatum(model.vgField(channel, {}), datum)}, ` +\n `${accessPathWithDatum(model.vgField(channel, {binSuffix: 'end'}), datum)}]`) :\n `${accessPathWithDatum(p.field, datum)}`;\n }).join(', ');\n\n // Only add a discrete selection to the store if a datum is present _and_\n // the interaction isn't occurring on a group mark. This guards against\n // polluting interactive state with invalid values in faceted displays\n // as the group marks are also data-driven. We force the update to account\n // for constant null states but varying toggles (e.g., shift-click in\n // whitespace followed by a click in whitespace; the store should only\n // be cleared on the second click).\n return [{\n name: selCmpt.name + TUPLE,\n value: {},\n on: [{\n events: selCmpt.events,\n update: `datum && item().mark.marktype !== 'group' ? ` +\n `{unit: ${unitName(model)}, encodings: [${encodings}], ` +\n `fields: [${fields}], values: [${values}]` +\n (bins.length ? ', ' + bins.map((b) => `${stringValue('bin_' + b)}: 1`).join(', ') : '') +\n '} : null',\n force: true\n }]\n }];\n}\n\nconst multi:SelectionCompiler = {\n predicate: 'vlMulti',\n scaleDomain: 'vlMultiDomain',\n\n signals: signals,\n\n modifyExpr: function(model, selCmpt) {\n const tpl = selCmpt.name + TUPLE;\n return tpl + ', ' +\n (selCmpt.resolve === 'global' ? 'null' : `{unit: ${unitName(model)}}`);\n }\n};\n\nexport default multi;\n","import {stringValue} from 'vega-util';\n\nimport {signals as multiSignals} from './multi';\nimport {SelectionCompiler, STORE, TUPLE, unitName} from './selection';\n\n\nconst single:SelectionCompiler = {\n predicate: 'vlSingle',\n scaleDomain: 'vlSingleDomain',\n\n signals: multiSignals,\n\n topLevelSignals: function(model, selCmpt, signals) {\n const hasSignal = signals.filter((s) => s.name === selCmpt.name);\n const data = `data(${stringValue(selCmpt.name + STORE)})`;\n const values = `${data}[0].values`;\n return hasSignal.length ? signals : signals.concat({\n name: selCmpt.name,\n update: `${data}.length && {` +\n selCmpt.project.map((p, i) => `${p.field}: ${values}[${i}]`).join(', ') + '}'\n });\n },\n\n modifyExpr: function(model, selCmpt) {\n const tpl = selCmpt.name + TUPLE;\n return tpl + ', ' +\n (selCmpt.resolve === 'global' ? 'true' : `{unit: ${unitName(model)}}`);\n }\n};\n\nexport default single;\n","import {selector as parseSelector} from 'vega-event-selector';\n\nimport {ScaleChannel, X, Y} from '../../../channel';\nimport {VgSignal} from '../../../vega.schema';\nimport {BRUSH as INTERVAL_BRUSH} from '../interval';\nimport {channelSignalName, positionalProjections, SelectionComponent} from '../selection';\nimport {UnitModel} from './../../unit';\nimport scalesCompiler, {domain} from './scales';\nimport {TransformCompiler} from './transforms';\n\n\nconst ANCHOR = '_translate_anchor';\nconst DELTA = '_translate_delta';\n\nconst translate:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.translate;\n },\n\n signals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const anchor = name + ANCHOR;\n const {x, y} = positionalProjections(selCmpt);\n let events = parseSelector(selCmpt.translate, 'scope');\n\n if (!hasScales) {\n events = events.map((e) => (e.between[0].markname = name + INTERVAL_BRUSH, e));\n }\n\n signals.push({\n name: anchor,\n value: {},\n on: [{\n events: events.map((e) => e.between[0]),\n update: '{x: x(unit), y: y(unit)' +\n (x !== null ? ', extent_x: ' + (hasScales ? domain(model, X) :\n `slice(${channelSignalName(selCmpt, 'x', 'visual')})`) : '') +\n\n (y !== null ? ', extent_y: ' + (hasScales ? domain(model, Y) :\n `slice(${channelSignalName(selCmpt, 'y', 'visual')})`) : '') + '}'\n }]\n }, {\n name: name + DELTA,\n value: {},\n on: [{\n events: events,\n update: `{x: ${anchor}.x - x(unit), y: ${anchor}.y - y(unit)}`\n }]\n });\n\n if (x !== null) {\n onDelta(model, selCmpt, X, 'width', signals);\n }\n\n if (y !== null) {\n onDelta(model, selCmpt, Y, 'height', signals);\n }\n\n return signals;\n }\n};\n\nexport default translate;\n\nfunction onDelta(model: UnitModel, selCmpt: SelectionComponent, channel: ScaleChannel, size: 'width' | 'height', signals: VgSignal[]) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const signal = signals.filter(s => {\n return s.name === channelSignalName(selCmpt, channel, hasScales ? 'data' : 'visual');\n })[0];\n const anchor = name + ANCHOR;\n const delta = name + DELTA;\n const sizeSg = model.getSizeSignalRef(size).signal;\n const scaleCmpt = model.getScaleComponent(channel);\n const scaleType = scaleCmpt.get('type');\n const sign = hasScales && channel === X ? '-' : ''; // Invert delta when panning x-scales.\n const extent = `${anchor}.extent_${channel}`;\n const offset = `${sign}${delta}.${channel} / ` + (hasScales ? `${sizeSg}` : `span(${extent})`);\n const panFn = !hasScales ? 'panLinear' :\n scaleType === 'log' ? 'panLog' :\n scaleType === 'pow' ? 'panPow' : 'panLinear';\n const update = `${panFn}(${extent}, ${offset}` +\n (hasScales && scaleType === 'pow' ? `, ${scaleCmpt.get('exponent') || 1}` : '') + ')';\n\n signal.on.push({\n events: {signal: delta},\n update: hasScales ? update : `clampRange(${update}, 0, ${sizeSg})`\n });\n}\n","import {selector as parseSelector} from 'vega-event-selector';\nimport {stringValue} from 'vega-util';\nimport {ScaleChannel, X, Y} from '../../../channel';\nimport {VgSignal} from '../../../vega.schema';\nimport {BRUSH as INTERVAL_BRUSH} from '../interval';\nimport {channelSignalName, positionalProjections, SelectionComponent} from '../selection';\nimport {UnitModel} from './../../unit';\nimport {default as scalesCompiler, domain} from './scales';\nimport {TransformCompiler} from './transforms';\n\n\nconst ANCHOR = '_zoom_anchor';\nconst DELTA = '_zoom_delta';\n\nconst zoom:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.zoom;\n },\n\n signals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const delta = name + DELTA;\n const {x, y} = positionalProjections(selCmpt);\n const sx = stringValue(model.scaleName(X));\n const sy = stringValue(model.scaleName(Y));\n let events = parseSelector(selCmpt.zoom, 'scope');\n\n if (!hasScales) {\n events = events.map((e) => (e.markname = name + INTERVAL_BRUSH, e));\n }\n\n signals.push({\n name: name + ANCHOR,\n on: [{\n events: events,\n update: !hasScales ? `{x: x(unit), y: y(unit)}` :\n '{' + [\n (sx ? `x: invert(${sx}, x(unit))` : ''),\n (sy ? `y: invert(${sy}, y(unit))` : '')\n ].filter((expr) => !!expr).join(', ') + '}'\n }]\n }, {\n name: delta,\n on: [{\n events: events,\n force: true,\n update: 'pow(1.001, event.deltaY * pow(16, event.deltaMode))'\n }]\n });\n\n if (x !== null) {\n onDelta(model, selCmpt, 'x', 'width', signals);\n }\n\n if (y !== null) {\n onDelta(model, selCmpt, 'y', 'height', signals);\n }\n\n return signals;\n }\n};\n\nexport default zoom;\n\nfunction onDelta(model: UnitModel, selCmpt: SelectionComponent, channel: ScaleChannel, size: 'width' | 'height', signals: VgSignal[]) {\n const name = selCmpt.name;\n const hasScales = scalesCompiler.has(selCmpt);\n const signal = signals.filter(s => {\n return s.name === channelSignalName(selCmpt, channel, hasScales ? 'data' : 'visual');\n })[0];\n const sizeSg = model.getSizeSignalRef(size).signal;\n const scaleCmpt = model.getScaleComponent(channel);\n const scaleType = scaleCmpt.get('type');\n const base = hasScales ? domain(model, channel) : signal.name;\n const delta = name + DELTA;\n const anchor = `${name}${ANCHOR}.${channel}`;\n const zoomFn = !hasScales ? 'zoomLinear' :\n scaleType === 'log' ? 'zoomLog' :\n scaleType === 'pow' ? 'zoomPow' : 'zoomLinear';\n const update = `${zoomFn}(${base}, ${anchor}, ${delta}` +\n (hasScales && scaleType === 'pow' ? `, ${scaleCmpt.get('exponent') || 1}` : '') + ')';\n\n signal.on.push({\n events: {signal: delta},\n update: hasScales ? update : `clampRange(${update}, 0, ${sizeSg})`\n });\n}\n","import {SelectionDef} from '../../../selection';\nimport {Dict} from '../../../util';\nimport {VgSignal} from '../../../vega.schema';\nimport {Model} from '../../model';\nimport {UnitModel} from '../../unit';\nimport {SelectionComponent} from '../selection';\n\n\nexport interface TransformCompiler {\n has: (selCmpt: SelectionComponent | SelectionDef) => boolean;\n parse?: (model: UnitModel, def: SelectionDef, selCmpt: SelectionComponent) => void;\n signals?: (model: UnitModel, selCmpt: SelectionComponent, signals: VgSignal[]) => VgSignal[];\n topLevelSignals?: (model: Model, selCmpt: SelectionComponent, signals: VgSignal[]) => VgSignal[];\n modifyExpr?: (model: UnitModel, selCmpt: SelectionComponent, expr: string) => string;\n marks?: (model: UnitModel, selCmpt:SelectionComponent, marks: any[]) => any[];\n}\n\nimport inputs from './inputs';\nimport nearest from './nearest';\nimport project from './project';\nimport scales from './scales';\nimport toggle from './toggle';\nimport translate from './translate';\nimport zoom from './zoom';\nconst compilers: Dict = {project, toggle, scales,\n translate, zoom, inputs, nearest};\n\nexport function forEachTransform(selCmpt: SelectionComponent, cb: (tx: TransformCompiler) => void) {\n for (const t in compilers) {\n if (compilers[t].has(selCmpt)) {\n cb(compilers[t]);\n }\n }\n}\n","import {SingleDefChannel} from '../../../channel';\nimport * as log from '../../../log';\nimport {SelectionDef} from '../../../selection';\nimport {keys} from '../../../util';\nimport {TimeUnitComponent, TimeUnitNode} from '../../data/timeunit';\nimport {SelectionComponent} from '../selection';\nimport {TransformCompiler} from './transforms';\n\nconst project: TransformCompiler = {\n has: function(selDef: SelectionComponent | SelectionDef) {\n const def = selDef as SelectionDef;\n return def.fields !== undefined || def.encodings !== undefined;\n },\n\n parse: function(model, selDef, selCmpt) {\n const channels = {};\n const timeUnits: {[key: string]: TimeUnitComponent} = {};\n\n // TODO: find a possible channel mapping for these fields.\n (selDef.fields || []).forEach((field) => channels[field] = null);\n\n (selDef.encodings || []).forEach((channel: SingleDefChannel) => {\n const fieldDef = model.fieldDef(channel);\n if (fieldDef) {\n if (fieldDef.timeUnit) {\n const tuField = model.vgField(channel);\n channels[tuField] = channel;\n\n // Construct TimeUnitComponents which will be combined into a\n // TimeUnitNode. This node may need to be inserted into the\n // dataflow if the selection is used across views that do not\n // have these time units defined.\n timeUnits[tuField] = {\n as: tuField,\n field: fieldDef.field,\n timeUnit: fieldDef.timeUnit\n };\n } else {\n channels[fieldDef.field] = channel;\n }\n } else {\n log.warn(log.message.cannotProjectOnChannelWithoutField(channel));\n }\n });\n\n const projection = selCmpt.project || (selCmpt.project = []);\n for (const field in channels) {\n if (channels.hasOwnProperty(field)) {\n projection.push({field: field, channel: channels[field]});\n }\n }\n\n const fields = selCmpt.fields || (selCmpt.fields = {});\n projection.filter((p) => p.channel).forEach((p) => fields[p.channel] = p.field);\n\n if (keys(timeUnits).length) {\n selCmpt.timeUnit = new TimeUnitNode(null, timeUnits);\n }\n }\n};\n\nexport default project;\n","\nimport {TUPLE, unitName} from '../selection';\nimport {TransformCompiler} from './transforms';\n\n\nconst TOGGLE = '_toggle';\n\nconst toggle:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'multi' && selCmpt.toggle;\n },\n\n signals: function(model, selCmpt, signals) {\n return signals.concat({\n name: selCmpt.name + TOGGLE,\n value: false,\n on: [{events: selCmpt.events, update: selCmpt.toggle}]\n });\n },\n\n modifyExpr: function(model, selCmpt, expr) {\n const tpl = selCmpt.name + TUPLE;\n const signal = selCmpt.name + TOGGLE;\n\n return `${signal} ? null : ${tpl}, ` +\n (selCmpt.resolve === 'global' ?\n `${signal} ? null : true, ` :\n `${signal} ? null : {unit: ${unitName(model)}}, `) +\n `${signal} ? ${tpl} : null`;\n }\n};\n\nexport default toggle;\n","import {stringValue} from 'vega-util';\nimport {accessPathWithDatum, varName} from '../../../util';\nimport {TUPLE} from '../selection';\nimport nearest from './nearest';\nimport {TransformCompiler} from './transforms';\n\n\nconst inputBindings:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'single' && selCmpt.resolve === 'global' &&\n selCmpt.bind && selCmpt.bind !== 'scales';\n },\n\n topLevelSignals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const proj = selCmpt.project;\n const bind = selCmpt.bind;\n const datum = nearest.has(selCmpt) ?\n '(item().isVoronoi ? datum.datum : datum)' : 'datum';\n\n proj.forEach(function(p) {\n const sgname = varName(`${name}_${p.field}`);\n const hasSignal = signals.filter((s) => s.name === sgname);\n if (!hasSignal.length) {\n signals.unshift({\n name: sgname,\n value: '',\n on: [{\n events: selCmpt.events,\n update: `datum && item().mark.marktype !== 'group' ? ${accessPathWithDatum(p.field, datum)} : null`\n }],\n bind: bind[p.field] || bind[p.channel] || bind\n });\n }\n });\n\n return signals;\n },\n\n signals: function(model, selCmpt, signals) {\n const name = selCmpt.name;\n const proj = selCmpt.project;\n const signal = signals.filter((s) => s.name === name + TUPLE)[0];\n const fields = proj.map((p) => stringValue(p.field)).join(', ');\n const values = proj.map((p) => varName(`${name}_${p.field}`));\n\n if (values.length) {\n signal.update = `${values.join(' && ')} ? {fields: [${fields}], values: [${values.join(', ')}]} : null`;\n }\n\n delete signal.value;\n delete signal.on;\n\n return signals;\n }\n};\n\nexport default inputBindings;\n","import {isArray, isString} from 'vega-util';\nimport {DataFlowNode} from './compile/data/dataflow';\nimport {Model} from './compile/model';\nimport {selectionPredicate} from './compile/selection/selection';\nimport {DateTime} from './datetime';\nimport {valueExpr, vgField} from './fielddef';\nimport {LogicalOperand} from './logical';\nimport {fieldExpr as timeUnitFieldExpr, normalizeTimeUnit, TimeUnit} from './timeunit';\nimport {logicalExpr} from './util';\n\nexport type Predicate =\n // a) FieldPredicate (but we don't type FieldFilter here so the schema has no nesting\n // and thus the documentation shows all of the types clearly)\n FieldEqualPredicate | FieldRangePredicate | FieldOneOfPredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate |\n // b) Selection Predicate\n SelectionPredicate |\n // c) Vega Expression string\n string;\n\n\n\nexport type FieldPredicate = FieldEqualPredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate |FieldRangePredicate | FieldOneOfPredicate;\n\nexport interface SelectionPredicate {\n /**\n * Filter using a selection name.\n */\n selection: LogicalOperand;\n}\n\nexport function isSelectionPredicate(predicate: LogicalOperand): predicate is SelectionPredicate {\n return predicate && predicate['selection'];\n}\n\nexport interface FieldPredicateBase {\n // TODO: support aggregate\n\n /**\n * Time unit for the field to be filtered.\n */\n timeUnit?: TimeUnit;\n\n /**\n * Field to be filtered.\n */\n field: string;\n}\n\nexport interface FieldEqualPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be equal to.\n */\n equal: string | number | boolean | DateTime;\n\n}\n\nexport function isFieldEqualPredicate(predicate: any): predicate is FieldEqualPredicate {\n return predicate && !!predicate.field && predicate.equal !== undefined;\n}\n\nexport interface FieldLTPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be less than.\n */\n lt: string | number | DateTime;\n\n}\n\nexport function isFieldLTPredicate(predicate: any): predicate is FieldLTPredicate {\n return predicate && !!predicate.field && predicate.lt !== undefined;\n}\n\n\nexport interface FieldLTEPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be less than or equals to.\n */\n lte: string | number | DateTime;\n\n}\n\nexport function isFieldLTEPredicate(predicate: any): predicate is FieldLTEPredicate {\n return predicate && !!predicate.field && predicate.lte !== undefined;\n}\n\n\nexport interface FieldGTPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be greater than.\n */\n gt: string | number | DateTime;\n\n}\n\nexport function isFieldGTPredicate(predicate: any): predicate is FieldGTPredicate {\n return predicate && !!predicate.field && predicate.gt !== undefined;\n}\n\nexport interface FieldGTEPredicate extends FieldPredicateBase {\n /**\n * The value that the field should be greater than or equals to.\n */\n gte: string | number | DateTime;\n\n}\n\nexport function isFieldGTEPredicate(predicate: any): predicate is FieldGTEPredicate {\n return predicate && !!predicate.field && predicate.gte !== undefined;\n}\n\nexport interface FieldRangePredicate extends FieldPredicateBase {\n /**\n * An array of inclusive minimum and maximum values\n * for a field value of a data item to be included in the filtered data.\n * @maxItems 2\n * @minItems 2\n */\n range: (number|DateTime|null)[];\n}\n\nexport function isFieldRangePredicate(predicate: any): predicate is FieldRangePredicate {\n if (predicate && predicate.field) {\n if (isArray(predicate.range) && predicate.range.length === 2) {\n return true;\n }\n }\n return false;\n}\n\nexport interface FieldOneOfPredicate extends FieldPredicateBase {\n /**\n * A set of values that the `field`'s value should be a member of,\n * for a data item included in the filtered data.\n */\n oneOf: string[] | number[] | boolean[] | DateTime[];\n\n}\n\nexport function isFieldOneOfPredicate(predicate: any): predicate is FieldOneOfPredicate {\n return predicate && !!predicate.field && (\n isArray(predicate.oneOf) ||\n isArray(predicate.in) // backward compatibility\n );\n}\n\nexport function isFieldPredicate(predicate: Predicate): predicate is FieldOneOfPredicate | FieldEqualPredicate | FieldRangePredicate | FieldLTPredicate | FieldGTPredicate | FieldLTEPredicate | FieldGTEPredicate {\n return isFieldOneOfPredicate(predicate) || isFieldEqualPredicate(predicate) || isFieldRangePredicate(predicate) || isFieldLTPredicate(predicate) || isFieldGTPredicate(predicate) || isFieldLTEPredicate(predicate) || isFieldGTEPredicate(predicate);\n}\n\n/**\n * Converts a predicate into an expression.\n */\n// model is only used for selection filters.\nexport function expression(model: Model, filterOp: LogicalOperand, node?: DataFlowNode): string {\n return logicalExpr(filterOp, (predicate: Predicate) => {\n if (isString(predicate)) {\n return predicate;\n } else if (isSelectionPredicate(predicate)) {\n return selectionPredicate(model, predicate.selection, node);\n } else { // Filter Object\n return fieldFilterExpression(predicate);\n }\n });\n}\n\nfunction predicateValueExpr(v: number | string | boolean | DateTime, timeUnit: TimeUnit) {\n return valueExpr(v, {timeUnit, time: true});\n}\n\nfunction predicateValuesExpr(vals: (number|string | boolean | DateTime)[], timeUnit: TimeUnit) {\n return vals.map((v) => predicateValueExpr(v, timeUnit));\n}\n\n// This method is used by Voyager. Do not change its behavior without changing Voyager.\nexport function fieldFilterExpression(predicate: FieldPredicate, useInRange=true) {\n const {field, timeUnit} = predicate;\n const fieldExpr = timeUnit ?\n // For timeUnit, cast into integer with time() so we can use ===, inrange, indexOf to compare values directly.\n // TODO: We calculate timeUnit on the fly here. Consider if we would like to consolidate this with timeUnit pipeline\n // TODO: support utc\n ('time(' + timeUnitFieldExpr(timeUnit, field) + ')') :\n vgField(predicate, {expr: 'datum'});\n\n if (isFieldEqualPredicate(predicate)) {\n return fieldExpr + '===' + predicateValueExpr(predicate.equal, timeUnit);\n } else if (isFieldLTPredicate(predicate)) {\n const upper = predicate.lt;\n return `${fieldExpr}<${predicateValueExpr(upper, timeUnit)}`;\n } else if (isFieldGTPredicate(predicate)) {\n const lower = predicate.gt;\n return `${fieldExpr}>${predicateValueExpr(lower, timeUnit)}`;\n } else if (isFieldLTEPredicate(predicate)) {\n const upper = predicate.lte;\n return `${fieldExpr}<=${predicateValueExpr(upper, timeUnit)}`;\n } else if (isFieldGTEPredicate(predicate)) {\n const lower = predicate.gte;\n return `${fieldExpr}>=${predicateValueExpr(lower, timeUnit)}`;\n } else if (isFieldOneOfPredicate(predicate)) {\n // \"oneOf\" was formerly \"in\" -- so we need to add backward compatibility\n let oneOf = predicate.oneOf;\n oneOf = oneOf || predicate['in'];\n return 'indexof([' +\n predicateValuesExpr(oneOf, timeUnit).join(',') +\n '], ' + fieldExpr + ') !== -1';\n } else if (isFieldRangePredicate(predicate)) {\n const lower = predicate.range[0];\n const upper = predicate.range[1];\n\n if (lower !== null && upper !== null && useInRange) {\n return 'inrange(' + fieldExpr + ', [' +\n predicateValueExpr(lower, timeUnit) + ', ' +\n predicateValueExpr(upper, timeUnit) + '])';\n }\n\n const exprs = [];\n if (lower !== null) {\n exprs.push(`${fieldExpr} >= ${predicateValueExpr(lower, timeUnit)}`);\n }\n if (upper !== null) {\n exprs.push(`${fieldExpr} <= ${predicateValueExpr(upper, timeUnit)}`);\n }\n\n return exprs.length > 0 ? exprs.join(' && ') : 'true';\n }\n\n /* istanbul ignore next: it should never reach here */\n throw new Error(`Invalid field predicate: ${JSON.stringify(predicate)}`);\n}\n\nexport function normalizePredicate(f: Predicate): Predicate {\n if (isFieldPredicate(f) && f.timeUnit) {\n return {\n ...f,\n timeUnit: normalizeTimeUnit(f.timeUnit)\n };\n }\n return f;\n}\n","import {AggregateOp} from 'vega';\n\nimport {BinParams} from './bin';\nimport {Data} from './data';\nimport {LogicalOperand, normalizeLogicalOperand} from './logical';\nimport {normalizePredicate, Predicate} from './predicate';\nimport {SortField} from './sort';\nimport {TimeUnit} from './timeunit';\n\nexport interface FilterTransform {\n /**\n * The `filter` property must be one of the predicate definitions:\n *\n * 1) an [expression](https://vega.github.io/vega-lite/docs/types.html#expression) string,\n * where `datum` can be used to refer to the current data object\n *\n * 2) one of the field predicates: [`equal`](https://vega.github.io/vega-lite/docs/filter.html#equal-predicate),\n * [`lt`](https://vega.github.io/vega-lite/docs/filter.html#lt-predicate),\n * [`lte`](https://vega.github.io/vega-lite/docs/filter.html#lte-predicate),\n * [`gt`](https://vega.github.io/vega-lite/docs/filter.html#gt-predicate),\n * [`gte`](https://vega.github.io/vega-lite/docs/filter.html#gte-predicate),\n * [`range`](https://vega.github.io/vega-lite/docs/filter.html#range-predicate),\n * or [`oneOf`](https://vega.github.io/vega-lite/docs/filter.html#one-of-predicate).\n *\n * 3) a [selection predicate](https://vega.github.io/vega-lite/docs/filter.html#selection-predicate)\n *\n * 4) a logical operand that combines (1), (2), or (3).\n */\n // TODO: https://github.com/vega/vega-lite/issues/2901\n filter: LogicalOperand;\n}\n\nexport function isFilter(t: Transform): t is FilterTransform {\n return t['filter'] !== undefined;\n}\n\nexport interface CalculateTransform {\n /**\n * A [expression](https://vega.github.io/vega-lite/docs/types.html#expression) string. Use the variable `datum` to refer to the current data object.\n */\n calculate: string;\n\n /**\n * The field for storing the computed formula value.\n */\n as: string;\n}\n\nexport interface BinTransform {\n /**\n * An object indicating bin properties, or simply `true` for using default bin parameters.\n */\n bin: boolean | BinParams;\n\n /**\n * The data field to bin.\n */\n field: string;\n\n /**\n * The output fields at which to write the start and end bin values.\n */\n as: string | string[];\n}\n\nexport interface TimeUnitTransform {\n /**\n * The timeUnit.\n */\n timeUnit: TimeUnit;\n\n /**\n * The data field to apply time unit.\n */\n field: string;\n\n /**\n * The output field to write the timeUnit value.\n */\n as: string;\n}\n\nexport interface AggregateTransform {\n /**\n * Array of objects that define fields to aggregate.\n */\n aggregate: AggregatedFieldDef[];\n\n /**\n * The data fields to group by. If not specified, a single group containing all data objects will be used.\n */\n groupby?: string[];\n}\n\nexport interface AggregatedFieldDef {\n /**\n * The aggregation operations to apply to the fields, such as sum, average or count.\n * See the [full list of supported aggregation operations](https://vega.github.io/vega-lite/docs/aggregate.html#ops)\n * for more information.\n */\n op: AggregateOp;\n\n /**\n * The data field for which to compute aggregate function. This is required for all aggregation operations except `\"count\"`.\n */\n field?: string;\n\n /**\n * The output field names to use for each aggregated field.\n */\n as: string;\n}\n\n\n/**\n * @hide\n */\nexport interface StackTransform {\n /**\n * The field which is stacked.\n */\n stack: string;\n /**\n * The data fields to group by.\n */\n groupby: string[];\n /**\n * Mode for stacking marks.\n * __Default value:__ `\"zero\"`\n */\n offset?: 'zero' | 'center' | 'normalize';\n /**\n * Field that determines the order of leaves in the stacked charts.\n */\n sort?: SortField[];\n /**\n * Output field names. This can be either a string or an array of strings with\n * two elements denoting the name for the fields for stack start and stack end\n * respectively.\n * If a single string(eg.\"val\") is provided, the end field will be \"val_end\".\n */\n as: string | string[];\n\n}\n\n\nexport type WindowOnlyOp =\n 'row_number' |\n 'rank' |\n 'dense_rank' |\n 'percent_rank' |\n 'cume_dist' |\n 'ntile' |\n 'lag' |\n 'lead' |\n 'first_value' |\n 'last_value' |\n 'nth_value';\n\nexport interface WindowFieldDef {\n /**\n * The window or aggregation operations to apply within a window, including `rank`, `lead`, `sum`, `average` or `count`. See the list of all supported operations [here](https://vega.github.io/vega-lite/docs/window.html#ops).\n */\n op: AggregateOp | WindowOnlyOp;\n\n /**\n * Parameter values for the window functions. Parameter values can be omitted for operations that do not accept a parameter.\n *\n * See the list of all supported operations and their parameters [here](https://vega.github.io/vega-lite/docs/transforms/window.html).\n */\n param?: number;\n\n /**\n * The data field for which to compute the aggregate or window function. This can be omitted for window functions that do not operate over a field such as `count`, `rank`, `dense_rank`.\n */\n field?: string;\n\n /**\n * The output name for the window operation.\n */\n as: string;\n}\n\nexport interface WindowTransform {\n /**\n * The definition of the fields in the window, and what calculations to use.\n */\n window: WindowFieldDef[];\n\n /**\n * A frame specification as a two-element array indicating how the sliding window should proceed. The array entries should either be a number indicating the offset from the current data object, or null to indicate unbounded rows preceding or following the current data object. The default value is `[null, 0]`, indicating that the sliding window includes the current object and all preceding objects. The value `[-5, 5]` indicates that the window should include five objects preceding and five objects following the current object. Finally, `[null, null]` indicates that the window frame should always include all data objects. The only operators affected are the aggregation operations and the `first_value`, `last_value`, and `nth_value` window operations. The other window operations are not affected by this.\n *\n * __Default value:__: `[null, 0]` (includes the current object and all preceding objects)\n */\n frame?: (null | number)[];\n\n /**\n * Indicates if the sliding window frame should ignore peer values. (Peer values are those considered identical by the sort criteria). The default is false, causing the window frame to expand to include all peer values. If set to true, the window frame will be defined by offset values only. This setting only affects those operations that depend on the window frame, namely aggregation operations and the first_value, last_value, and nth_value window operations.\n *\n * __Default value:__ `false`\n */\n ignorePeers?: boolean;\n\n /**\n * The data fields for partitioning the data objects into separate windows. If unspecified, all data points will be in a single group.\n */\n groupby?: string[];\n\n /**\n * A sort field definition for sorting data objects within a window. If two data objects are considered equal by the comparator, they are considered “peer” values of equal rank. If sort is not specified, the order is undefined: data objects are processed in the order they are observed and none are considered peers (the ignorePeers parameter is ignored and treated as if set to `true`).\n */\n sort?: SortField[];\n}\n\nexport interface LookupData {\n /**\n * Secondary data source to lookup in.\n */\n data: Data;\n /**\n * Key in data to lookup.\n */\n key: string;\n /**\n * Fields in foreign data to lookup.\n * If not specified, the entire object is queried.\n */\n fields?: string[];\n}\n\nexport interface LookupTransform {\n /**\n * Key in primary data source.\n */\n lookup: string;\n\n /**\n * Secondary data reference.\n */\n from: LookupData;\n\n /**\n * The field or fields for storing the computed formula value.\n * If `from.fields` is specified, the transform will use the same names for `as`.\n * If `from.fields` is not specified, `as` has to be a string and we put the whole object into the data under the specified name.\n */\n as?: string | string[];\n\n /**\n * The default value to use if lookup fails.\n *\n * __Default value:__ `null`\n */\n default?: string;\n}\n\n\n\nexport function isLookup(t: Transform): t is LookupTransform {\n return t['lookup'] !== undefined;\n}\n\nexport function isWindow(t: Transform): t is WindowTransform {\n return t['window'] !== undefined;\n}\n\nexport function isCalculate(t: Transform): t is CalculateTransform {\n return t['calculate'] !== undefined;\n}\n\nexport function isBin(t: Transform): t is BinTransform {\n return !!t['bin'];\n}\n\nexport function isTimeUnit(t: Transform): t is TimeUnitTransform {\n return t['timeUnit'] !== undefined;\n}\n\nexport function isAggregate(t: Transform): t is AggregateTransform {\n return t['aggregate'] !== undefined;\n}\n\nexport function isStack(t: Transform): t is StackTransform {\n return t['stack'] !== undefined;\n}\n\nexport type Transform = FilterTransform | CalculateTransform | LookupTransform | BinTransform | TimeUnitTransform | AggregateTransform | WindowTransform | StackTransform;\n\nexport function normalizeTransform(transform: Transform[]) {\n return transform.map(t => {\n if (isFilter(t)) {\n return {\n filter: normalizeLogicalOperand(t.filter, normalizePredicate)\n };\n }\n return t;\n });\n}\n","import {isString} from 'vega-util';\nimport {BinParams, binToString} from '../../bin';\nimport {Channel} from '../../channel';\nimport {Config} from '../../config';\nimport {FieldDef, normalizeBin, vgField} from '../../fielddef';\nimport {BinTransform} from '../../transform';\nimport {Dict, duplicate, flatten, keys, vals} from '../../util';\nimport {VgBinTransform, VgTransform} from '../../vega.schema';\nimport {binFormatExpression, binRequiresRange} from '../common';\nimport {isUnitModel, Model, ModelWithField} from '../model';\nimport {DataFlowNode} from './dataflow';\n\nfunction rangeFormula(model: ModelWithField, fieldDef: FieldDef, channel: Channel, config: Config) {\n if (binRequiresRange(fieldDef, channel)) {\n // read format from axis or legend, if there is no format then use config.numberFormat\n\n const guide = isUnitModel(model) ? (model.axis(channel) || model.legend(channel) || {}) : {};\n\n const startField = vgField(fieldDef, {expr: 'datum',});\n const endField = vgField(fieldDef, {expr: 'datum', binSuffix: 'end'});\n\n return {\n formulaAs: vgField(fieldDef, {binSuffix: 'range'}),\n formula: binFormatExpression(startField, endField, guide.format, config)\n };\n }\n return {};\n}\n\nfunction binKey(bin: BinParams, field: string) {\n return `${binToString(bin)}_${field}`;\n}\n\nfunction getSignalsFromModel(model: Model, key: string) {\n return {\n signal: model.getName(`${key}_bins`),\n extentSignal: model.getName(`${key}_extent`)\n };\n}\n\nfunction isBinTransform(t: FieldDef | BinTransform): t is BinTransform {\n return 'as' in t;\n}\n\nfunction createBinComponent(t: FieldDef | BinTransform, model: Model) {\n let as: [string, string];\n\n if (isBinTransform(t)) {\n as = isString(t.as) ? [t.as, `${t.as}_end`] : [t.as[0],t.as[1]];\n } else {\n as = [vgField(t, {}), vgField(t, {binSuffix: 'end'})];\n }\n\n const bin = normalizeBin(t.bin, undefined) || {};\n const key = binKey(bin, t.field);\n const {signal, extentSignal} = getSignalsFromModel(model, key);\n\n const binComponent: BinComponent = {\n bin: bin,\n field: t.field,\n as: as,\n ...signal ? {signal} : {},\n ...extentSignal ? {extentSignal} : {}\n };\n\n return {key, binComponent};\n}\n\nexport interface BinComponent {\n bin: BinParams;\n field: string;\n extentSignal?: string;\n signal?: string;\n as: string[];\n\n // Range Formula\n\n formula?: string;\n formulaAs?: string;\n}\n\nexport class BinNode extends DataFlowNode {\n public clone() {\n return new BinNode(null, duplicate(this.bins));\n }\n\n constructor(parent: DataFlowNode, private bins: Dict) {\n super(parent);\n }\n\n public static makeFromEncoding(parent: DataFlowNode, model: ModelWithField) {\n const bins = model.reduceFieldDef((binComponentIndex: Dict, fieldDef, channel) => {\n if (fieldDef.bin) {\n const {key, binComponent} = createBinComponent(fieldDef, model);\n binComponentIndex[key] = {\n ...binComponent,\n ...binComponentIndex[key],\n ...rangeFormula(model, fieldDef, channel, model.config)\n };\n }\n return binComponentIndex;\n }, {});\n\n if (keys(bins).length === 0) {\n return null;\n }\n\n return new BinNode(parent, bins);\n }\n\n /**\n * Creates a bin node from BinTransform.\n * The optional parameter should provide\n */\n public static makeFromTransform(parent: DataFlowNode, t: BinTransform, model: Model) {\n const {key, binComponent} = createBinComponent(t, model);\n return new BinNode(parent, {\n [key]: binComponent\n });\n }\n\n public merge(other: BinNode) {\n this.bins = {...this.bins, ...other.bins};\n other.remove();\n }\n\n public producedFields() {\n const out = {};\n\n vals(this.bins).forEach(c => {\n c.as.forEach(f => out[f] = true);\n });\n\n return out;\n }\n\n public dependentFields() {\n const out = {};\n\n vals(this.bins).forEach(c => {\n out[c.field] = true;\n });\n\n return out;\n }\n\n public assemble(): VgTransform[] {\n return flatten(vals(this.bins).map(bin => {\n const transform: VgTransform[] = [];\n\n const binTrans: VgBinTransform = {\n type: 'bin',\n field: bin.field,\n as: bin.as,\n signal: bin.signal,\n ...bin.bin\n };\n\n if (!bin.bin.extent && bin.extentSignal) {\n transform.push({\n type: 'extent',\n field: bin.field,\n signal: bin.extentSignal\n });\n binTrans.extent = {signal: bin.extentSignal};\n }\n\n transform.push(binTrans);\n\n if (bin.formula) {\n transform.push({\n type: 'formula',\n expr: bin.formula,\n as: bin.formulaAs\n });\n }\n\n return transform;\n }));\n }\n}\n","import {LogicalOperand} from '../../logical';\nimport {expression, Predicate} from '../../predicate';\nimport {duplicate} from '../../util';\nimport {VgFilterTransform} from '../../vega.schema';\nimport {Model} from '../model';\nimport {DataFlowNode} from './dataflow';\n\nexport class FilterNode extends DataFlowNode {\n private expr: string;\n public clone() {\n return new FilterNode(null, this.model, duplicate(this.filter));\n }\n\n constructor(parent: DataFlowNode, private readonly model: Model, private filter: LogicalOperand) {\n super(parent);\n this.expr = expression(this.model, this.filter, this);\n }\n\n public assemble(): VgFilterTransform {\n return {\n type: 'filter',\n expr: this.expr\n };\n }\n}\n","import {GeoPositionChannel, LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2, SHAPE} from '../../channel';\nimport {GEOJSON} from '../../type';\nimport {duplicate} from '../../util';\nimport {VgGeoJSONTransform} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {DataFlowNode} from './dataflow';\n\nexport class GeoJSONNode extends DataFlowNode {\n public clone() {\n return new GeoJSONNode(null, duplicate(this.fields), this.geojson, this.signal);\n }\n\n public static parseAll(parent: DataFlowNode, model: UnitModel): DataFlowNode {\n let geoJsonCounter = 0;\n\n [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach((coordinates: GeoPositionChannel[]) => {\n const pair = coordinates.map(\n channel => model.channelHasField(channel) ? model.fieldDef(channel).field : undefined\n );\n\n if (pair[0] || pair[1]) {\n parent = new GeoJSONNode(parent, pair, null, model.getName(`geojson_${geoJsonCounter++}`));\n }\n });\n\n if (model.channelHasField(SHAPE)) {\n const fieldDef = model.fieldDef(SHAPE);\n if (fieldDef.type === GEOJSON) {\n parent = new GeoJSONNode(parent, null, fieldDef.field, model.getName(`geojson_${geoJsonCounter++}`));\n }\n }\n\n return parent;\n }\n\n constructor(parent: DataFlowNode, private fields?: string[], private geojson?: string, private signal?: string) {\n super(parent);\n }\n\n public assemble(): VgGeoJSONTransform {\n return {\n type: 'geojson',\n ...(this.fields ? {fields: this.fields} : {}),\n ...(this.geojson ? {geojson: this.geojson} : {}),\n signal: this.signal\n };\n }\n}\n","import {GeoPositionChannel, LATITUDE, LATITUDE2, LONGITUDE, LONGITUDE2} from '../../channel';\nimport {duplicate} from '../../util';\nimport {VgGeoPointTransform} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {DataFlowNode} from './dataflow';\n\n\nexport class GeoPointNode extends DataFlowNode {\n public clone() {\n return new GeoPointNode(null, this.projection, duplicate(this.fields), duplicate(this.as));\n }\n\n constructor(parent: DataFlowNode, private projection: string, private fields: string[], private as: string[]) {\n super(parent);\n }\n\n public static parseAll(parent: DataFlowNode, model: UnitModel): DataFlowNode {\n if (!model.projectionName()) {\n return parent;\n }\n\n [[LONGITUDE, LATITUDE], [LONGITUDE2, LATITUDE2]].forEach((coordinates: GeoPositionChannel[]) => {\n const pair = coordinates.map(\n channel => model.channelHasField(channel) ? model.fieldDef(channel).field : undefined\n );\n\n const suffix = coordinates[0] === LONGITUDE2 ? '2' : '';\n\n if (pair[0] || pair[1]) {\n parent = new GeoPointNode(\n parent,\n model.projectionName(),\n pair,\n [model.getName('x' + suffix), model.getName('y' + suffix)]\n );\n }\n });\n\n return parent;\n }\n\n public assemble(): VgGeoPointTransform {\n return {\n type: 'geopoint',\n projection: this.projection,\n fields: this.fields,\n as: this.as\n };\n }\n}\n","import {SELECTION_ID} from '../../selection';\nimport {StringSet} from '../../util';\nimport {VgIdentifierTransform} from '../../vega.schema';\nimport {DataFlowNode} from './dataflow';\n\nexport class IdentifierNode extends DataFlowNode {\n public clone() {\n return new IdentifierNode(null);\n }\n\n constructor(parent: DataFlowNode) {\n super(parent);\n }\n\n public producedFields(): StringSet {\n return {[SELECTION_ID]: true};\n }\n\n public assemble(): VgIdentifierTransform {\n return {type: 'identifier', as: SELECTION_ID};\n }\n}\n","import {Dict} from '../../util';\nimport {Split} from '../split';\nimport {OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {SourceNode} from './source';\n\nexport interface DataComponent {\n /**\n * A dictionary of sources indexed by a hash.\n */\n sources: Dict;\n\n /**\n * Registry of output nodes.\n */\n outputNodes: Dict;\n\n /**\n * How often is an output node used. If it is not used, we don't need to\n * instantiate it in the assemble step.\n */\n outputNodeRefCounts: Dict;\n\n /**\n * The output node before aggregation.\n */\n raw?: OutputNode;\n\n /**\n * The main output node.\n */\n main?: OutputNode;\n\n /**\n * For facets, we store the reference to the root node.\n */\n facetRoot?: FacetNode;\n\n /**\n * True if the data for this model is faceted.\n * A dataset is faceted if a parent model is a facet and no new dataset is\n * defined (which would make the data unfaceted again).\n */\n isFaceted: boolean;\n\n /**\n * Parse properties passed down from ancestors. Helps us to keep track of what has been parsed or is derived.\n */\n ancestorParse?: AncestorParse;\n}\n\n/**\n * Class to track interesting properties (see https://15721.courses.cs.cmu.edu/spring2016/papers/graefe-ieee1995.pdf)\n * about how fields have been parsed or whether they have been derived in a transforms. We use this to not parse the\n * same field again (or differently).\n */\nexport class AncestorParse extends Split> {\n constructor(\n public readonly explicit: Partial> = {},\n public readonly implicit: Partial> = {},\n public parseNothing = false\n ) {\n super(explicit, implicit);\n }\n\n public clone(): AncestorParse {\n const clone = super.clone() as AncestorParse;\n clone.parseNothing = this.parseNothing;\n return clone;\n }\n}\n","import {isString, toSet} from 'vega-util';\nimport * as log from '../../log';\nimport {LookupTransform} from '../../transform';\nimport {StringSet} from '../../util';\nimport {VgLookupTransform} from '../../vega.schema';\nimport {Model} from '../model';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {SourceNode} from './source';\n\nexport class LookupNode extends DataFlowNode {\n constructor(parent: DataFlowNode, public readonly transform: LookupTransform, public readonly secondary: string) {\n super(parent);\n }\n\n public static make(parent: DataFlowNode, model: Model, transform: LookupTransform, counter: number) {\n const sources = model.component.data.sources;\n const s = new SourceNode(transform.from.data);\n let fromSource = sources[s.hash()];\n if (!fromSource) {\n sources[s.hash()] = s;\n fromSource = s;\n }\n\n const fromOutputName = model.getName(`lookup_${counter}`);\n const fromOutputNode = new OutputNode(fromSource, fromOutputName, 'lookup', model.component.data.outputNodeRefCounts);\n\n model.component.data.outputNodes[fromOutputName] = fromOutputNode;\n\n return new LookupNode(parent, transform, fromOutputNode.getSource());\n }\n\n public producedFields(): StringSet {\n return toSet(this.transform.from.fields || ((this.transform.as instanceof Array) ? this.transform.as : [this.transform.as]));\n }\n\n public assemble(): VgLookupTransform {\n let foreign: Partial;\n\n if (this.transform.from.fields) {\n // lookup a few fields and add create a flat output\n foreign = {\n values: this.transform.from.fields,\n ... this.transform.as ? {as: ((this.transform.as instanceof Array) ? this.transform.as : [this.transform.as])} : {}\n };\n } else {\n // lookup full record and nest it\n let asName = this.transform.as;\n if (!isString(asName)) {\n log.warn(log.message.NO_FIELDS_NEEDS_AS);\n asName = '_lookup';\n }\n\n foreign = {\n as: [asName]\n };\n }\n\n return {\n type: 'lookup',\n from: this.secondary,\n key: this.transform.from.key,\n fields: [this.transform.lookup],\n ...foreign,\n ...(this.transform.default ? {default: this.transform.default} : {})\n };\n }\n}\n","import {InlineDataset, isUrlData} from '../../data';\nimport {Dict, vals} from '../../util';\nimport {VgData} from '../../vega.schema';\nimport {DataComponent} from './';\nimport {AggregateNode} from './aggregate';\nimport {BinNode} from './bin';\nimport {CalculateNode} from './calculate';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {FilterNode} from './filter';\nimport {FilterInvalidNode} from './filterinvalid';\nimport {ParseNode} from './formatparse';\nimport {GeoJSONNode} from './geojson';\nimport {GeoPointNode} from './geopoint';\nimport {IdentifierNode} from './identifier';\nimport {LookupNode} from './lookup';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\nimport {TimeUnitNode} from './timeunit';\nimport {WindowTransformNode} from './window';\n\n/**\n * Print debug information for dataflow tree.\n */\n// tslint:disable-next-line\nfunction debug(node: DataFlowNode) {\n console.log(`${(node.constructor as any).name}${node.debugName ? ` (${node.debugName})` : ''} -> ${\n (node.children.map(c => {\n return `${(c.constructor as any).name}${c.debugName ? ` (${c.debugName})` : ''}`;\n }))\n }`);\n console.log(node);\n node.children.forEach(debug);\n}\n\nfunction makeWalkTree(data: VgData[]) {\n // to name datasources\n let datasetIndex = 0;\n\n /**\n * Recursively walk down the tree.\n */\n function walkTree(node: DataFlowNode, dataSource: VgData) {\n if (node instanceof SourceNode) {\n // If the source is a named data source or a data source with values, we need\n // to put it in a different data source. Otherwise, Vega may override the data.\n if (!isUrlData(node.data)) {\n data.push(dataSource);\n const newData: VgData = {\n name: null,\n source: dataSource.name,\n transform: []\n };\n dataSource = newData;\n }\n }\n\n if (node instanceof ParseNode) {\n if (node.parent instanceof SourceNode && !dataSource.source) {\n // If node's parent is a root source and the data source does not refer to another data source, use normal format parse\n dataSource.format = {\n ...dataSource.format || {},\n parse: node.assembleFormatParse()\n };\n\n // add calculates for all nested fields\n dataSource.transform = dataSource.transform.concat(node.assembleTransforms(true));\n } else {\n // Otherwise use Vega expression to parse\n dataSource.transform = dataSource.transform.concat(node.assembleTransforms());\n }\n }\n\n if (node instanceof FacetNode) {\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n\n if (!dataSource.source || dataSource.transform.length > 0) {\n data.push(dataSource);\n node.data = dataSource.name;\n } else {\n node.data = dataSource.source;\n }\n\n node.assemble().forEach(d => data.push(d));\n\n // break here because the rest of the tree has to be taken care of by the facet.\n return;\n }\n\n if (node instanceof FilterNode ||\n node instanceof CalculateNode ||\n node instanceof GeoPointNode ||\n node instanceof GeoJSONNode ||\n node instanceof AggregateNode ||\n node instanceof LookupNode ||\n node instanceof WindowTransformNode ||\n node instanceof IdentifierNode) {\n dataSource.transform.push(node.assemble());\n }\n\n if (node instanceof FilterInvalidNode ||\n node instanceof BinNode ||\n node instanceof TimeUnitNode ||\n node instanceof StackNode) {\n dataSource.transform = dataSource.transform.concat(node.assemble());\n }\n\n if (node instanceof AggregateNode) {\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n }\n\n if (node instanceof OutputNode) {\n if (dataSource.source && dataSource.transform.length === 0) {\n node.setSource(dataSource.source);\n } else if (node.parent instanceof OutputNode) {\n // Note that an output node may be required but we still do not assemble a\n // separate data source for it.\n node.setSource(dataSource.name);\n } else {\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n\n // Here we set the name of the datasource we generated. From now on\n // other assemblers can use it.\n node.setSource(dataSource.name);\n\n // if this node has more than one child, we will add a datasource automatically\n if (node.numChildren() === 1) {\n data.push(dataSource);\n const newData: VgData = {\n name: null,\n source: dataSource.name,\n transform: []\n };\n dataSource = newData;\n }\n }\n }\n\n switch (node.numChildren()) {\n case 0:\n // done\n if (node instanceof OutputNode && (!dataSource.source || dataSource.transform.length > 0)) {\n // do not push empty datasources that are simply references\n data.push(dataSource);\n }\n break;\n case 1:\n walkTree(node.children[0], dataSource);\n break;\n default:\n if (!dataSource.name) {\n dataSource.name = `data_${datasetIndex++}`;\n }\n\n let source = dataSource.name;\n if (!dataSource.source || dataSource.transform.length > 0) {\n data.push(dataSource);\n } else {\n source = dataSource.source;\n }\n\n node.children.forEach(child => {\n const newData: VgData = {\n name: null,\n source: source,\n transform: []\n };\n walkTree(child, newData);\n });\n break;\n }\n }\n\n return walkTree;\n}\n\n/**\n * Assemble data sources that are derived from faceted data.\n */\nexport function assembleFacetData(root: FacetNode): VgData[] {\n const data: VgData[] = [];\n const walkTree = makeWalkTree(data);\n\n root.children.forEach(child => walkTree(child, {\n source: root.name,\n name: null,\n transform: []\n }));\n\n return data;\n}\n\n/**\n * Create Vega Data array from a given compiled model and append all of them to the given array\n *\n * @param model\n * @param data array\n * @return modified data array\n */\nexport function assembleRootData(dataComponent: DataComponent, datasets: Dict): VgData[] {\n const roots: SourceNode[] = vals(dataComponent.sources);\n const data: VgData[] = [];\n\n // roots.forEach(debug);\n\n const walkTree = makeWalkTree(data);\n\n let sourceIndex = 0;\n\n roots.forEach(root => {\n // assign a name if the source does not have a name yet\n if (!root.hasName()) {\n root.dataName = `source_${sourceIndex++}`;\n }\n\n const newData: VgData = root.assemble();\n\n walkTree(root, newData);\n });\n\n // remove empty transform arrays for cleaner output\n data.forEach(d => {\n if (d.transform.length === 0) {\n delete d.transform;\n }\n });\n\n // move sources without transforms (the ones that are potentially used in lookups) to the beginning\n let whereTo = 0;\n for (let i = 0; i < data.length; i++) {\n const d = data[i];\n if ((d.transform || []).length === 0 && !d.source) {\n data.splice(whereTo++, 0, data.splice(i, 1)[0]);\n }\n }\n\n // now fix the from references in lookup transforms\n for (const d of data) {\n for (const t of d.transform || []) {\n if (t.type === 'lookup') {\n t.from = dataComponent.outputNodes[t.from].getSource();\n }\n }\n }\n\n // inline values for datasets that are in the datastore\n for (const d of data) {\n if (d.name in datasets) {\n d.values = datasets[d.name];\n }\n }\n\n return data;\n}\n","import {defaultScaleConfig, hasDiscreteDomain} from '../../scale';\nimport {isVgRangeStep} from '../../vega.schema';\nimport {ConcatModel} from '../concat';\nimport {Model} from '../model';\nimport {Explicit, mergeValuesWithExplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {LayoutSize, LayoutSizeIndex} from './component';\n\nexport function parseLayerLayoutSize(model: Model) {\n parseChildrenLayoutSize(model);\n\n const layoutSizeCmpt = model.component.layoutSize;\n layoutSizeCmpt.setWithExplicit('width', parseNonUnitLayoutSizeForChannel(model, 'width'));\n layoutSizeCmpt.setWithExplicit('height', parseNonUnitLayoutSizeForChannel(model, 'height'));\n}\n\nexport const parseRepeatLayoutSize = parseLayerLayoutSize;\n\nexport function parseConcatLayoutSize(model: ConcatModel) {\n parseChildrenLayoutSize(model);\n const layoutSizeCmpt = model.component.layoutSize;\n\n const sizeTypeToMerge = model.isVConcat ? 'width' : 'height';\n layoutSizeCmpt.setWithExplicit(sizeTypeToMerge, parseNonUnitLayoutSizeForChannel(model, sizeTypeToMerge));\n}\n\nexport function parseChildrenLayoutSize(model: Model) {\n for (const child of model.children) {\n child.parseLayoutSize();\n }\n}\n\nfunction parseNonUnitLayoutSizeForChannel(model: Model, sizeType: 'width' | 'height'): Explicit {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const resolve = model.component.resolve;\n\n let mergedSize: Explicit;\n // Try to merge layout size\n for (const child of model.children) {\n const childSize = child.component.layoutSize.getWithExplicit(sizeType);\n const scaleResolve = resolve.scale[channel];\n if (scaleResolve === 'independent' && childSize.value === 'range-step') {\n // Do not merge independent scales with range-step as their size depends\n // on the scale domains, which can be different between scales.\n mergedSize = undefined;\n break;\n }\n\n if (mergedSize) {\n if (scaleResolve === 'independent' && mergedSize.value !== childSize.value) {\n // For independent scale, only merge if all the sizes are the same.\n // If the values are different, abandon the merge!\n mergedSize = undefined;\n break;\n }\n mergedSize = mergeValuesWithExplicit(\n mergedSize, childSize, sizeType, ''\n );\n } else {\n mergedSize = childSize;\n }\n }\n\n if (mergedSize) {\n // If merged, rename size and set size of all children.\n for (const child of model.children) {\n model.renameLayoutSize(child.getName(sizeType), model.getName(sizeType));\n child.component.layoutSize.set(sizeType, 'merged', false);\n }\n return mergedSize;\n } else {\n // Otherwise, there is no merged size.\n return {\n explicit: false,\n value: undefined\n };\n }\n}\n\nexport function parseUnitLayoutSize(model: UnitModel) {\n const layoutSizeComponent = model.component.layoutSize;\n if (!layoutSizeComponent.explicit.width) {\n const width = defaultUnitSize(model, 'width');\n layoutSizeComponent.set('width', width, false);\n }\n\n if (!layoutSizeComponent.explicit.height) {\n const height = defaultUnitSize(model, 'height');\n layoutSizeComponent.set('height', height, false);\n }\n}\n\nfunction defaultUnitSize(model: UnitModel, sizeType: 'width' | 'height'): LayoutSize {\n const channel = sizeType === 'width' ? 'x' : 'y';\n const config = model.config;\n const scaleComponent = model.getScaleComponent(channel);\n\n if (scaleComponent) {\n const scaleType = scaleComponent.get('type');\n const range = scaleComponent.get('range');\n\n if (hasDiscreteDomain(scaleType) && isVgRangeStep(range)) {\n // For discrete domain with range.step, use dynamic width/height\n return 'range-step';\n } else {\n return config.view[sizeType];\n }\n } else if (model.hasProjection) {\n return config.view[sizeType];\n } else {\n // No scale - set default size\n if (sizeType === 'width' && model.mark === 'text') {\n // width for text mark without x-field is a bit wider than typical range step\n return config.scale.textXRangeStep;\n }\n\n // Set width/height equal to rangeStep config or if rangeStep is null, use value from default scale config.\n return config.scale.rangeStep || defaultScaleConfig.rangeStep;\n }\n\n}\n","import {isArray} from 'vega-util';\nimport {Encoding} from '../encoding';\nimport {FacetMapping} from '../facet';\nimport {Field, hasConditionalFieldDef, isConditionalDef, isFieldDef, isRepeatRef, ValueDef} from '../fielddef';\nimport {ChannelDef, ScaleFieldDef} from '../fielddef';\nimport * as log from '../log';\nimport {isSortField} from '../sort';\n\nexport type RepeaterValue = {\n row?: string,\n column?: string\n};\n\nexport function replaceRepeaterInFacet(facet: FacetMapping, repeater: RepeaterValue): FacetMapping {\n return replaceRepeater(facet, repeater) as FacetMapping;\n}\n\nexport function replaceRepeaterInEncoding(encoding: Encoding, repeater: RepeaterValue): Encoding {\n return replaceRepeater(encoding, repeater) as Encoding;\n}\n\n/**\n * Replaces repeated value and returns if the repeated value is valid.\n */\nfunction replaceRepeat(o: T, repeater: RepeaterValue): T {\n if (isRepeatRef(o.field)) {\n if (o.field.repeat in repeater) {\n // any needed to calm down ts compiler\n return {...o as any, field: repeater[o.field.repeat]};\n } else {\n log.warn(log.message.noSuchRepeatedValue(o.field.repeat));\n return undefined;\n }\n }\n return o;\n}\n\n/**\n * Replace repeater values in a field def with the concrete field name.\n */\nfunction replaceRepeaterInFieldDef(fieldDef: ScaleFieldDef, repeater: RepeaterValue): ScaleFieldDef {\n fieldDef = replaceRepeat(fieldDef, repeater);\n\n if (fieldDef === undefined) {\n // the field def should be ignored\n return undefined;\n }\n\n if (fieldDef.sort && isSortField(fieldDef.sort)) {\n const sort = replaceRepeat(fieldDef.sort, repeater);\n fieldDef = {\n ...fieldDef,\n ...(sort ? {sort} : {})\n };\n }\n\n return fieldDef as ScaleFieldDef;\n}\n\nfunction replaceRepeaterInChannelDef(channelDef: ChannelDef, repeater: RepeaterValue): ChannelDef {\n if (isFieldDef(channelDef)) {\n const fd = replaceRepeaterInFieldDef(channelDef, repeater);\n if (fd) {\n return fd;\n } else if (isConditionalDef(channelDef)) {\n return {condition: channelDef.condition};\n }\n } else {\n if (hasConditionalFieldDef(channelDef)) {\n const fd = replaceRepeaterInFieldDef(channelDef.condition, repeater);\n if (fd) {\n return {\n ...channelDef,\n condition: fd\n } as ChannelDef;\n } else {\n const {condition, ...channelDefWithoutCondition} = channelDef;\n return channelDefWithoutCondition as ChannelDef;\n }\n }\n return channelDef as ValueDef;\n }\n return undefined;\n}\n\ntype EncodingOrFacet = Encoding | FacetMapping;\n\nfunction replaceRepeater(mapping: EncodingOrFacet, repeater: RepeaterValue): EncodingOrFacet {\n const out: EncodingOrFacet = {};\n for (const channel in mapping) {\n if (mapping.hasOwnProperty(channel)) {\n const channelDef: ChannelDef | ChannelDef[] = mapping[channel];\n\n if (isArray(channelDef)) {\n // array cannot have condition\n out[channel] = channelDef.map(cd => replaceRepeaterInChannelDef(cd, repeater))\n .filter(cd => cd);\n } else {\n const cd = replaceRepeaterInChannelDef(channelDef, repeater);\n if (cd) {\n out[channel] = cd;\n }\n }\n }\n }\n return out;\n}\n","import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {Channel, COLUMN, ROW, ScaleChannel} from '../channel';\nimport {Config} from '../config';\nimport {reduce} from '../encoding';\nimport {FacetFieldDef, FacetMapping} from '../facet';\nimport {FieldDef, normalize, title as fieldDefTitle, vgField} from '../fielddef';\nimport * as log from '../log';\nimport {hasDiscreteDomain} from '../scale';\nimport {EncodingSortField, isSortField, SortOrder} from '../sort';\nimport {NormalizedFacetSpec} from '../spec';\nimport {contains} from '../util';\nimport {isVgRangeStep, VgData, VgLayout, VgMarkGroup, VgSignal} from '../vega.schema';\nimport {assembleAxis} from './axis/assemble';\nimport {buildModel} from './buildmodel';\nimport {assembleFacetData} from './data/assemble';\nimport {sortArrayIndexField} from './data/calculate';\nimport {parseData} from './data/parse';\nimport {getHeaderType, HeaderChannel, HeaderComponent} from './header/index';\nimport {parseChildrenLayoutSize} from './layoutsize/parse';\nimport {Model, ModelWithField} from './model';\nimport {RepeaterValue, replaceRepeaterInFacet} from './repeater';\nimport {parseGuideResolve} from './resolve';\nimport {assembleDomain, getFieldFromDomain} from './scale/domain';\n\nexport function facetSortFieldName(fieldDef: FacetFieldDef, sort: EncodingSortField, expr?: 'datum') {\n return vgField(sort, {expr, suffix: `by_${vgField(fieldDef)}`});\n}\n\nexport class FacetModel extends ModelWithField {\n public readonly type: 'facet' = 'facet';\n public readonly facet: FacetMapping;\n\n public readonly child: Model;\n\n public readonly children: Model[];\n\n constructor(spec: NormalizedFacetSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, repeater, spec.resolve);\n\n\n this.child = buildModel(spec.spec, this, this.getName('child'), undefined, repeater, config, false);\n this.children = [this.child];\n\n const facet: FacetMapping = replaceRepeaterInFacet(spec.facet, repeater);\n\n this.facet = this.initFacet(facet);\n }\n\n private initFacet(facet: FacetMapping): FacetMapping {\n // clone to prevent side effect to the original spec\n return reduce(facet, function(normalizedFacet, fieldDef: FieldDef, channel: Channel) {\n if (!contains([ROW, COLUMN], channel)) {\n // Drop unsupported channel\n log.warn(log.message.incompatibleChannel(channel, 'facet'));\n return normalizedFacet;\n }\n\n if (fieldDef.field === undefined) {\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n return normalizedFacet;\n }\n\n // Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n normalizedFacet[channel] = normalize(fieldDef, channel);\n return normalizedFacet;\n }, {});\n }\n\n public channelHasField(channel: Channel): boolean {\n return !!this.facet[channel];\n }\n\n public fieldDef(channel: Channel): FieldDef {\n return this.facet[channel];\n }\n\n public parseData() {\n this.component.data = parseData(this);\n this.child.parseData();\n }\n\n public parseLayoutSize() {\n parseChildrenLayoutSize(this);\n }\n\n public parseSelection() {\n // As a facet has a single child, the selection components are the same.\n // The child maintains its selections to assemble signals, which remain\n // within its unit.\n this.child.parseSelection();\n this.component.selection = this.child.component.selection;\n }\n\n public parseMarkGroup() {\n this.child.parseMarkGroup();\n }\n\n public parseAxisAndHeader() {\n this.child.parseAxisAndHeader();\n\n this.parseHeader('column');\n this.parseHeader('row');\n\n this.mergeChildAxis('x');\n this.mergeChildAxis('y');\n }\n\n private parseHeader(channel: HeaderChannel) {\n\n if (this.channelHasField(channel)) {\n const fieldDef = this.facet[channel];\n const header = fieldDef.header || {};\n let title = fieldDef.title !== undefined ? fieldDef.title :\n header.title !== undefined ? header.title : fieldDefTitle(fieldDef, this.config);\n\n if (this.child.component.layoutHeaders[channel].title) {\n // merge title with child to produce \"Title / Subtitle / Sub-subtitle\"\n title += ' / ' + this.child.component.layoutHeaders[channel].title;\n this.child.component.layoutHeaders[channel].title = null;\n }\n\n this.component.layoutHeaders[channel] = {\n title,\n facetFieldDef: fieldDef,\n // TODO: support adding label to footer as well\n header: [this.makeHeaderComponent(channel, true)]\n };\n }\n }\n\n private makeHeaderComponent(channel: HeaderChannel, labels: boolean): HeaderComponent {\n const sizeType = channel === 'row' ? 'height' : 'width';\n\n return {\n labels,\n sizeSignal: this.child.component.layoutSize.get(sizeType) ? this.child.getSizeSignalRef(sizeType) : undefined,\n axes: []\n };\n }\n\n private mergeChildAxis(channel: 'x' | 'y') {\n const {child} = this;\n if (child.component.axes[channel]) {\n const {layoutHeaders, resolve} = this.component;\n resolve.axis[channel] = parseGuideResolve(resolve, channel);\n\n if (resolve.axis[channel] === 'shared') {\n // For shared axis, move the axes to facet's header or footer\n const headerChannel = channel === 'x' ? 'column' : 'row';\n\n const layoutHeader = layoutHeaders[headerChannel];\n for (const axisComponent of child.component.axes[channel]) {\n const headerType = getHeaderType(axisComponent.get('orient'));\n layoutHeader[headerType] = layoutHeader[headerType] ||\n [this.makeHeaderComponent(headerChannel, false)];\n\n const mainAxis = assembleAxis(axisComponent, 'main', this.config, {header: true});\n // LayoutHeader no longer keep track of property precedence, thus let's combine.\n layoutHeader[headerType][0].axes.push(mainAxis);\n axisComponent.mainExtracted = true;\n }\n } else {\n // Otherwise do nothing for independent axes\n }\n }\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return this.child.assembleSelectionTopLevelSignals(signals);\n }\n\n public assembleSelectionSignals(): VgSignal[] {\n this.child.assembleSelectionSignals();\n return [];\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return this.child.assembleSelectionData(data);\n }\n\n private getHeaderLayoutMixins(): VgLayout {\n const layoutMixins: VgLayout = {};\n\n ['row', 'column'].forEach((channel: 'row' | 'column') => {\n ['header', 'footer'].forEach((headerType: 'header' | 'footer') => {\n const layoutHeaderComponent = this.component.layoutHeaders[channel];\n const headerComponent = layoutHeaderComponent[headerType];\n if (headerComponent && headerComponent[0]) {\n // set header/footerBand\n const sizeType = channel === 'row' ? 'height' : 'width';\n const bandType = headerType === 'header' ? 'headerBand' : 'footerBand';\n if (!this.child.component.layoutSize.get(sizeType)) {\n // If facet child does not have size signal, then apply headerBand\n layoutMixins[bandType] = layoutMixins[bandType] || {};\n layoutMixins[bandType][channel] = 0.5;\n }\n\n if (layoutHeaderComponent.title) {\n layoutMixins.offset = layoutMixins.offset || {};\n layoutMixins.offset[channel === 'row' ? 'rowTitle' : 'columnTitle'] = 10;\n }\n }\n });\n });\n return layoutMixins;\n }\n\n protected assembleDefaultLayout(): VgLayout {\n const columns = this.channelHasField('column') ? this.columnDistinctSignal() : 1;\n\n // TODO: determine default align based on shared / independent scales\n\n return {\n ...this.getHeaderLayoutMixins(),\n\n columns,\n bounds: 'full',\n align: 'all'\n };\n }\n\n public assembleLayoutSignals(): VgSignal[] {\n // FIXME(https://github.com/vega/vega-lite/issues/1193): this can be incorrect if we have independent scales.\n return this.child.assembleLayoutSignals();\n }\n\n private columnDistinctSignal() {\n if (this.parent && (this.parent instanceof FacetModel)) {\n // For nested facet, we will add columns to group mark instead\n // See discussion in https://github.com/vega/vega/issues/952\n // and https://github.com/vega/vega-view/releases/tag/v1.2.6\n return undefined;\n } else {\n // In facetNode.assemble(), the name is always this.getName('column') + '_layout'.\n const facetLayoutDataName = this.getName('column_domain');\n return {signal: `length(data('${facetLayoutDataName}'))`};\n }\n }\n\n public assembleGroup(signals: VgSignal[]) {\n if (this.parent && (this.parent instanceof FacetModel)) {\n // Provide number of columns for layout.\n // See discussion in https://github.com/vega/vega/issues/952\n // and https://github.com/vega/vega-view/releases/tag/v1.2.6\n return {\n ...(this.channelHasField('column') ? {\n encode: {\n update: {\n // TODO(https://github.com/vega/vega-lite/issues/2759):\n // Correct the signal for facet of concat of facet_column\n columns: {field: vgField(this.facet.column, {prefix: 'distinct'})}\n }\n }\n } : {}),\n ...super.assembleGroup(signals)\n };\n }\n return super.assembleGroup(signals);\n }\n\n /**\n * Aggregate cardinality for calculating size\n */\n private getCardinalityAggregateForChild() {\n const fields: string[] = [];\n const ops: AggregateOp[] = [];\n const as: string[] = [];\n\n if (this.child instanceof FacetModel) {\n if (this.child.channelHasField('column')) {\n const field = vgField(this.child.facet.column);\n fields.push(field);\n ops.push('distinct');\n as.push(`distinct_${field}`);\n }\n } else {\n for (const channel of ['x', 'y'] as ScaleChannel[]) {\n const childScaleComponent = this.child.component.scales[channel];\n if (childScaleComponent && !childScaleComponent.merged) {\n const type = childScaleComponent.get('type');\n const range = childScaleComponent.get('range');\n\n if (hasDiscreteDomain(type) && isVgRangeStep(range)) {\n const domain = assembleDomain(this.child, channel);\n const field = getFieldFromDomain(domain);\n if (field) {\n fields.push(field);\n ops.push('distinct');\n as.push(`distinct_${field}`);\n } else {\n log.warn('Unknown field for ${channel}. Cannot calculate view size.');\n }\n }\n }\n }\n }\n return {fields, ops, as};\n }\n\n\n private assembleFacet() {\n const {name, data} = this.component.data.facetRoot;\n const {row, column} = this.facet;\n const {fields, ops, as} = this.getCardinalityAggregateForChild();\n const groupby: string[] = [];\n\n ['row', 'column'].forEach((channel: 'row' | 'column') => {\n const fieldDef = this.facet[channel];\n if (fieldDef) {\n groupby.push(vgField(fieldDef));\n const {sort} = fieldDef;\n if (isSortField(sort)) {\n const {field, op} = sort;\n const outputName = facetSortFieldName(fieldDef, sort);\n if (row && column) {\n // For crossed facet, use pre-calculate field as it requires a different groupby\n // For each calculated field, apply max and assign them to the same name as\n // all values of the same group should be the same anyway.\n fields.push(outputName);\n ops.push('max');\n as.push(outputName);\n } else {\n fields.push(field);\n ops.push(op);\n as.push(outputName);\n }\n } else if (isArray(sort)) {\n const outputName = sortArrayIndexField(fieldDef, channel);\n fields.push(outputName);\n ops.push('max');\n as.push(outputName);\n }\n }\n });\n\n const cross = !!row && !!column;\n\n return {\n name,\n data,\n groupby,\n ...(cross || fields.length ? {\n aggregate: {\n ...(cross ? {cross} : {}),\n ...(fields.length ? {fields, ops, as} : {})\n }\n } : {})\n };\n }\n\n\n private headerSortFields(channel: 'row' | 'column'): string[] {\n const {facet} = this;\n const fieldDef = facet[channel];\n\n if (fieldDef) {\n if (isSortField(fieldDef.sort)) {\n return [facetSortFieldName(fieldDef, fieldDef.sort, 'datum')];\n } else if (isArray(fieldDef.sort)) {\n return [sortArrayIndexField(fieldDef, channel, 'datum')];\n }\n return [vgField(fieldDef, {expr: 'datum'})];\n }\n return [];\n }\n\n private headerSortOrder(channel: 'row' | 'column'): SortOrder[] {\n const {facet} = this;\n const fieldDef = facet[channel];\n if (fieldDef) {\n const {sort} = fieldDef;\n const order = (isSortField(sort) ? sort.order : !isArray(sort) && sort) || 'ascending';\n return [order];\n }\n return [];\n }\n\n public assembleMarks(): VgMarkGroup[] {\n const {child} = this;\n const facetRoot = this.component.data.facetRoot;\n const data = assembleFacetData(facetRoot);\n\n // If we facet by two dimensions, we need to add a cross operator to the aggregation\n // so that we create all groups\n const layoutSizeEncodeEntry = child.assembleLayoutSize();\n\n const title = child.assembleTitle();\n const style = child.assembleGroupStyle();\n\n const markGroup = {\n name: this.getName('cell'),\n type: 'group',\n ...(title? {title} : {}),\n ...(style? {style} : {}),\n from: {\n facet: this.assembleFacet()\n },\n // TODO: move this to after data\n sort: {\n field: [\n ...this.headerSortFields('row'),\n ...this.headerSortFields('column')\n ],\n order: [\n ...this.headerSortOrder('row'),\n ...this.headerSortOrder('column')\n ]\n },\n ...(data.length > 0 ? {data: data} : {}),\n ...(layoutSizeEncodeEntry ? {encode: {update: layoutSizeEncodeEntry}} : {}),\n ...child.assembleGroup()\n };\n\n return [markGroup];\n }\n\n\n protected getMapping() {\n return this.facet;\n }\n}\n\n","import {AggregateOp} from 'vega';\nimport {FacetMapping} from '../../facet';\nimport {vgField} from '../../fielddef';\nimport {isSortField} from '../../sort';\nimport {WindowFieldDef, WindowOnlyOp, WindowTransform} from '../../transform';\nimport {duplicate} from '../../util';\nimport {VgComparator, VgComparatorOrder, VgWindowTransform} from '../../vega.schema';\nimport {facetSortFieldName} from '../facet';\nimport {DataFlowNode} from './dataflow';\n\n/**\n * A class for the window transform nodes\n */\nexport class WindowTransformNode extends DataFlowNode {\n public static makeFromFacet(parent: DataFlowNode, facet: FacetMapping): WindowTransformNode {\n const {row, column} = facet;\n if (row && column) {\n let newParent = null;\n // only need to make one for crossed facet\n for (const fieldDef of [row, column]) {\n if (isSortField(fieldDef.sort)) {\n const {field, op} = fieldDef.sort;\n parent = newParent = new WindowTransformNode(parent, {\n window: [{\n op,\n field,\n as: facetSortFieldName(fieldDef, fieldDef.sort)\n }],\n groupby: [vgField(fieldDef)],\n frame: [null, null]\n });\n }\n }\n return newParent;\n }\n return null;\n }\n\n\n public clone() {\n return new WindowTransformNode(this.parent, duplicate(this.transform));\n }\n\n constructor(parent: DataFlowNode, private transform: WindowTransform) {\n super(parent);\n }\n\n public producedFields() {\n const out = {};\n this.transform.window.forEach(windowFieldDef => {\n out[this.getDefaultName(windowFieldDef)] = true;\n });\n\n return out;\n }\n\n private getDefaultName(windowFieldDef: WindowFieldDef): string {\n return windowFieldDef.as || vgField(windowFieldDef);\n }\n\n public assemble(): VgWindowTransform {\n const fields: string[] = [];\n const ops: (AggregateOp | WindowOnlyOp)[] = [];\n const as = [];\n const params = [];\n for (const window of this.transform.window) {\n ops.push(window.op);\n as.push(this.getDefaultName(window));\n params.push(window.param === undefined ? null : window.param);\n fields.push(window.field === undefined ? null : window.field);\n }\n\n const frame = this.transform.frame;\n const groupby = this.transform.groupby;\n const sortFields: string[] = [];\n const sortOrder: VgComparatorOrder[] = [];\n if (this.transform.sort !== undefined) {\n for (const sortField of this.transform.sort) {\n sortFields.push(sortField.field);\n sortOrder.push(sortField.order || 'ascending');\n }\n }\n const sort: VgComparator = {\n field: sortFields,\n order: sortOrder,\n };\n const ignorePeers = this.transform.ignorePeers;\n\n const result: VgWindowTransform = {\n type: 'window',\n params,\n as,\n ops,\n fields,\n sort,\n };\n\n if (ignorePeers !== undefined) {\n result.ignorePeers = ignorePeers;\n }\n\n if (groupby !== undefined) {\n result.groupby = groupby;\n }\n\n if (frame !== undefined) {\n result.frame = frame;\n }\n\n return result;\n }\n}\n","import {MAIN, RAW} from '../../data';\nimport * as log from '../../log';\nimport {isAggregate, isBin, isCalculate, isFilter, isLookup, isStack, isTimeUnit, isWindow} from '../../transform';\nimport {Dict, keys} from '../../util';\nimport {isFacetModel, isLayerModel, isUnitModel, Model} from '../model';\nimport {requiresSelectionId} from '../selection/selection';\nimport {AggregateNode} from './aggregate';\nimport {BinNode} from './bin';\nimport {CalculateNode} from './calculate';\nimport {DataFlowNode, OutputNode} from './dataflow';\nimport {FacetNode} from './facet';\nimport {FilterNode} from './filter';\nimport {FilterInvalidNode} from './filterinvalid';\nimport {ParseNode} from './formatparse';\nimport {GeoJSONNode} from './geojson';\nimport {GeoPointNode} from './geopoint';\nimport {IdentifierNode} from './identifier';\nimport {AncestorParse, DataComponent} from './index';\nimport {LookupNode} from './lookup';\nimport {SourceNode} from './source';\nimport {StackNode} from './stack';\nimport {TimeUnitNode} from './timeunit';\nimport {WindowTransformNode} from './window';\n\nfunction parseRoot(model: Model, sources: Dict): DataFlowNode {\n if (model.data || !model.parent) {\n // if the model defines a data source or is the root, create a source node\n const source = new SourceNode(model.data);\n const hash = source.hash();\n if (hash in sources) {\n // use a reference if we already have a source\n return sources[hash];\n } else {\n // otherwise add a new one\n sources[hash] = source;\n return source;\n }\n } else {\n // If we don't have a source defined (overriding parent's data), use the parent's facet root or main.\n return model.parent.component.data.facetRoot ? model.parent.component.data.facetRoot : model.parent.component.data.main;\n }\n}\n\n\n/**\n * Parses a transforms array into a chain of connected dataflow nodes.\n */\nexport function parseTransformArray(head: DataFlowNode, model: Model, ancestorParse: AncestorParse): DataFlowNode {\n let lookupCounter = 0;\n\n model.transforms.forEach(t => {\n if (isCalculate(t)) {\n head = new CalculateNode(head, t);\n ancestorParse.set(t.as, 'derived', false);\n } else if (isFilter(t)) {\n head = ParseNode.makeImplicitFromFilterTransform(head, t, ancestorParse) || head;\n\n head = new FilterNode(head, model, t.filter);\n } else if (isBin(t)) {\n const bin = head = BinNode.makeFromTransform(head, t, model);\n\n for (const field of keys(bin.producedFields())) {\n ancestorParse.set(field, 'number', false);\n }\n\n } else if (isTimeUnit(t)) {\n head = TimeUnitNode.makeFromTransform(head, t);\n\n ancestorParse.set(t.as, 'date', false);\n } else if (isAggregate(t)) {\n const agg = head = AggregateNode.makeFromTransform(head, t);\n\n if (requiresSelectionId(model)) {\n head = new IdentifierNode(head);\n }\n\n for (const field of keys(agg.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else if (isLookup(t)) {\n const lookup = head = LookupNode.make(head, model, t, lookupCounter++);\n\n for (const field of keys(lookup.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else if (isWindow(t)) {\n const window = head = new WindowTransformNode(head, t);\n\n for (const field of keys(window.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else if (isStack(t)) {\n const stack = head = StackNode.makeFromTransform(head, t);\n\n for (const field of keys(stack.producedFields())) {\n ancestorParse.set(field, 'derived', false);\n }\n } else {\n log.warn(log.message.invalidTransformIgnored(t));\n return;\n }\n });\n\n return head;\n}\n\n/*\nDescription of the dataflow (http://asciiflow.com/):\n +--------+\n | Source |\n +---+----+\n |\n v\n FormatParse\n (explicit)\n |\n v\n Transforms\n(Filter, Calculate, Binning, TimeUnit, Aggregate, Window, ...)\n |\n v\n FormatParse\n (implicit)\n |\n v\n Binning (in `encoding`)\n |\n v\n Timeunit (in `encoding`)\n |\n v\nFormula From Sort Array\n |\n v\n +--+--+\n | Raw |\n +-----+\n |\n v\n Aggregate (in `encoding`)\n |\n v\n Stack (in `encoding`)\n |\n v\n Invalid Filter\n |\n v\n +----------+\n | Main |\n +----------+\n |\n v\n +-------+\n | Facet |----> \"column\", \"column-layout\", and \"row\"\n +-------+\n |\n v\n ...Child data...\n*/\n\nexport function parseData(model: Model): DataComponent {\n let head = parseRoot(model, model.component.data.sources);\n\n const {outputNodes, outputNodeRefCounts} = model.component.data;\n const ancestorParse = model.parent ? model.parent.component.data.ancestorParse.clone() : new AncestorParse();\n\n // format.parse: null means disable parsing\n if (model.data && model.data.format && model.data.format.parse === null) {\n ancestorParse.parseNothing = true;\n }\n\n head = ParseNode.makeExplicit(head, model, ancestorParse) || head;\n\n // Default discrete selections require an identifier transform to\n // uniquely identify data points as the _id field is volatile. Add\n // this transform at the head of our pipeline such that the identifier\n // field is available for all subsequent datasets. Additional identifier\n // transforms will be necessary when new tuples are constructed\n // (e.g., post-aggregation).\n if (requiresSelectionId(model) && (isUnitModel(model) || isLayerModel(model))) {\n head = new IdentifierNode(head);\n }\n\n // HACK: This is equivalent for merging bin extent for union scale.\n // FIXME(https://github.com/vega/vega-lite/issues/2270): Correctly merge extent / bin node for shared bin scale\n const parentIsLayer = model.parent && isLayerModel(model.parent);\n if (isUnitModel(model) || isFacetModel(model)) {\n if (parentIsLayer) {\n head = BinNode.makeFromEncoding(head, model) || head;\n }\n }\n\n if (model.transforms.length > 0) {\n head = parseTransformArray(head, model, ancestorParse);\n }\n\n head = ParseNode.makeImplicitFromEncoding(head, model, ancestorParse) || head;\n\n if (isUnitModel(model)) {\n head = GeoJSONNode.parseAll(head, model);\n head = GeoPointNode.parseAll(head, model);\n }\n\n if (isUnitModel(model) || isFacetModel(model)) {\n\n if (!parentIsLayer) {\n head = BinNode.makeFromEncoding(head, model) || head;\n }\n\n head = TimeUnitNode.makeFromEncoding(head, model) || head;\n head = CalculateNode.parseAllForSortIndex(head, model);\n }\n\n // add an output node pre aggregation\n const rawName = model.getName(RAW);\n const raw = new OutputNode(head, rawName, RAW, outputNodeRefCounts);\n outputNodes[rawName] = raw;\n head = raw;\n\n if (isUnitModel(model)) {\n const agg = AggregateNode.makeFromEncoding(head, model);\n if (agg) {\n head = agg;\n\n if (requiresSelectionId(model)) {\n head = new IdentifierNode(head);\n }\n }\n\n head = StackNode.makeFromEncoding(head, model) || head;\n }\n\n if (isUnitModel(model)) {\n head = FilterInvalidNode.make(head, model) || head;\n }\n\n // output node for marks\n const mainName = model.getName(MAIN);\n const main = new OutputNode(head, mainName, MAIN, outputNodeRefCounts);\n outputNodes[mainName] = main;\n head = main;\n\n // add facet marker\n let facetRoot = null;\n if (isFacetModel(model)) {\n const facetName = model.getName('facet');\n\n // Derive new sort index field for facet's sort array\n head = CalculateNode.parseAllForSortIndex(head, model);\n\n // Derive new aggregate (via window) for facet's sort field\n // TODO: use JoinAggregate once we have it\n // augment data source with new fields for crossed facet\n head = WindowTransformNode.makeFromFacet(head, model.facet) || head;\n\n facetRoot = new FacetNode(head, model, facetName, main.getSource());\n outputNodes[facetName] = facetRoot;\n head = facetRoot;\n }\n\n return {\n ...model.component.data,\n outputNodes,\n outputNodeRefCounts,\n raw,\n main,\n facetRoot,\n ancestorParse\n };\n}\n","import {Config} from '../config';\nimport {Resolve} from '../resolve';\nimport {BaseSpec} from '../spec';\nimport {keys} from '../util';\nimport {VgData, VgSignal} from '../vega.schema';\nimport {parseData} from './data/parse';\nimport {assembleLayoutSignals} from './layoutsize/assemble';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\n\nexport abstract class BaseConcatModel extends Model {\n constructor(spec: BaseSpec, parent: Model, parentGivenName: string, config: Config, repeater: RepeaterValue, resolve: Resolve) {\n super(spec, parent, parentGivenName, config, repeater, resolve);\n }\n\n public parseData() {\n this.component.data = parseData(this);\n this.children.forEach((child) => {\n child.parseData();\n });\n }\n public parseSelection() {\n // Merge selections up the hierarchy so that they may be referenced\n // across unit specs. Persist their definitions within each child\n // to assemble signals which remain within output Vega unit groups.\n this.component.selection = {};\n for (const child of this.children) {\n child.parseSelection();\n keys(child.component.selection).forEach((key) => {\n this.component.selection[key] = child.component.selection[key];\n });\n }\n }\n\n public parseMarkGroup() {\n for (const child of this.children) {\n child.parseMarkGroup();\n }\n }\n\n public parseAxisAndHeader() {\n for (const child of this.children) {\n child.parseAxisAndHeader();\n }\n\n // TODO(#2415): support shared axes\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return this.children.reduce((sg, child) => child.assembleSelectionTopLevelSignals(sg), signals);\n }\n\n public assembleSelectionSignals(): VgSignal[] {\n this.children.forEach((child) => child.assembleSelectionSignals());\n return [];\n }\n\n public assembleLayoutSignals(): VgSignal[] {\n return this.children.reduce((signals, child) => {\n return signals.concat(child.assembleLayoutSignals());\n }, assembleLayoutSignals(this));\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return this.children.reduce((db, child) => child.assembleSelectionData(db), data);\n }\n\n public assembleMarks(): any[] {\n // only children have marks\n return this.children.map(child => {\n const title = child.assembleTitle();\n const style = child.assembleGroupStyle();\n const layoutSizeEncodeEntry = child.assembleLayoutSize();\n return {\n type: 'group',\n name: child.getName('group'),\n ...(title ? {title} : {}),\n ...(style ? {style} : {}),\n ...(layoutSizeEncodeEntry ? {\n encode: {\n update: layoutSizeEncodeEntry\n }\n } : {}),\n ...child.assembleGroup()\n };\n });\n }\n}\n","import {Config} from '../config';\nimport * as log from '../log';\nimport {isVConcatSpec, NormalizedConcatSpec} from '../spec';\nimport {VgLayout} from '../vega.schema';\nimport {BaseConcatModel} from './baseconcat';\nimport {buildModel} from './buildmodel';\nimport {parseConcatLayoutSize} from './layoutsize/parse';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\n\nexport class ConcatModel extends BaseConcatModel {\n public readonly type: 'concat' = 'concat';\n\n public readonly children: Model[];\n\n public readonly isVConcat: boolean;\n\n constructor(spec: NormalizedConcatSpec, parent: Model, parentGivenName: string, repeater: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, repeater, spec.resolve);\n\n if (spec.resolve && spec.resolve.axis && (spec.resolve.axis.x === 'shared' || spec.resolve.axis.y === 'shared')) {\n log.warn(log.message.CONCAT_CANNOT_SHARE_AXIS);\n }\n\n this.isVConcat = isVConcatSpec(spec);\n\n this.children = (isVConcatSpec(spec) ? spec.vconcat : spec.hconcat).map((child, i) => {\n return buildModel(child, this, this.getName('concat_' + i), undefined, repeater, config, false);\n });\n }\n\n public parseLayoutSize() {\n parseConcatLayoutSize(this);\n }\n\n\n public parseAxisGroup(): void {\n return null;\n }\n\n protected assembleDefaultLayout(): VgLayout {\n return {\n ...(this.isVConcat ? {columns: 1} : {}),\n bounds: 'full',\n // Use align each so it can work with multiple plots with different size\n align: 'each'\n };\n }\n}\n","import {Axis, AxisPart} from '../../axis';\nimport {FieldDefBase} from '../../fielddef';\nimport {duplicate, Omit} from '../../util';\nimport {VgAxis} from '../../vega.schema';\nimport {Split} from '../split';\n\n\nfunction isFalseOrNull(v: boolean | null) {\n return v === false || v === null;\n}\n\nexport type AxisComponentProps = Omit & {\n\n title: string | FieldDefBase[];\n};\n\nexport class AxisComponent extends Split {\n constructor(\n public readonly explicit: Partial = {},\n public readonly implicit: Partial = {},\n public mainExtracted = false\n ) {\n super();\n }\n\n public clone() {\n return new AxisComponent(\n duplicate(this.explicit),\n duplicate(this.implicit), this.mainExtracted\n );\n }\n\n public hasAxisPart(part: AxisPart) {\n // FIXME(https://github.com/vega/vega-lite/issues/2552) this method can be wrong if users use a Vega theme.\n\n if (part === 'axis') { // always has the axis container part\n return true;\n }\n\n if (part === 'grid' || part === 'title') {\n return !!this.get(part);\n }\n // Other parts are enabled by default, so they should not be false or null.\n return !isFalseOrNull(this.get(part));\n }\n}\n\nexport interface AxisComponentIndex {\n x?: AxisComponent[];\n y?: AxisComponent[];\n}\n\nexport interface AxisIndex {\n x?: Axis;\n y?: Axis;\n}\n","import {PositionScaleChannel} from '../../channel';\nimport {Config} from '../../config';\nimport {ScaleType} from '../../scale';\n\nexport function getAxisConfig(property: string, config: Config, channel: PositionScaleChannel, orient: string = '', scaleType: ScaleType) {\n // configTypes to loop, starting from higher precedence\n const configTypes = (scaleType === 'band' ? ['axisBand'] : []).concat([\n channel === 'x' ? 'axisX' : 'axisY',\n 'axis' + orient.substr(0,1).toUpperCase() + orient.substr(1), // axisTop, axisBottom, ...\n 'axis'\n ]);\n for (const configType of configTypes) {\n if (config[configType] && config[configType][property] !== undefined) {\n return config[configType][property];\n }\n }\n\n return undefined;\n}\n","import {Axis} from '../../axis';\nimport {Channel, PositionScaleChannel, X} from '../../channel';\nimport {FieldDef, isTimeFieldDef} from '../../fielddef';\nimport {ScaleType} from '../../scale';\nimport {NOMINAL, ORDINAL} from '../../type';\nimport {contains, keys} from '../../util';\nimport {AxisOrient, HorizontalAlign} from '../../vega.schema';\nimport {timeFormatExpression} from '../common';\nimport {UnitModel} from '../unit';\nimport {getAxisConfig} from './config';\n\nexport function labels(model: UnitModel, channel: PositionScaleChannel, specifiedLabelsSpec: any, orient: AxisOrient) {\n const fieldDef = model.fieldDef(channel) ||\n (\n channel === 'x' ? model.fieldDef('x2') :\n channel === 'y' ? model.fieldDef('y2') :\n undefined\n );\n const axis = model.axis(channel);\n const config = model.config;\n\n let labelsSpec: any = {};\n\n // Text\n if (isTimeFieldDef(fieldDef)) {\n const isUTCScale = model.getScaleComponent(channel).get('type') === ScaleType.UTC;\n\n const expr = timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat, isUTCScale);\n\n if (expr) {\n labelsSpec.text = {signal: expr};\n }\n }\n\n // Label Angle\n let angle = getAxisConfig('labelAngle', model.config, channel, orient, model.getScaleComponent(channel).get('type'));\n if (angle === undefined) {\n angle = labelAngle(axis, channel, fieldDef);\n if (angle) {\n labelsSpec.angle = {value: angle};\n }\n }\n\n if (angle !== undefined) {\n const align = labelAlign(angle, orient);\n if (align) {\n labelsSpec.align = {value: align};\n }\n\n labelsSpec.baseline = labelBaseline(angle, orient);\n }\n\n labelsSpec = {\n ...labelsSpec,\n ...specifiedLabelsSpec\n };\n\n return keys(labelsSpec).length === 0 ? undefined : labelsSpec;\n}\n\nexport function labelBaseline(angle: number, orient: AxisOrient) {\n if (orient === 'top' || orient === 'bottom') {\n if (angle <= 45 || 315 <= angle) {\n return {value: orient === 'top' ? 'bottom' : 'top'};\n } else if (135 <= angle && angle <= 225) {\n return {value: orient === 'top' ? 'top': 'bottom'};\n } else {\n return {value: 'middle'};\n }\n } else {\n if ((angle <= 45 || 315 <= angle) || (135 <= angle && angle <= 225)) {\n return {value: 'middle'};\n } else if (45 <= angle && angle <= 135) {\n return {value: orient === 'left' ? 'top' : 'bottom'};\n } else {\n return {value: orient === 'left' ? 'bottom' : 'top'};\n }\n }\n}\n\nexport function labelAngle(axis: Axis, channel: Channel, fieldDef: FieldDef) {\n if (axis.labelAngle !== undefined) {\n // Make angle within [0,360)\n return ((axis.labelAngle % 360) + 360) % 360;\n } else {\n if (channel === X && contains([NOMINAL, ORDINAL], fieldDef.type)) {\n return 270;\n }\n }\n return undefined;\n}\n\nexport function labelAlign(angle: number, orient: AxisOrient): HorizontalAlign {\n angle = ((angle % 360) + 360) % 360;\n if (orient === 'top' || orient === 'bottom') {\n if (angle % 180 === 0) {\n return 'center';\n } else if (0 < angle && angle < 180) {\n return orient === 'top' ? 'right' : 'left';\n } else {\n return orient === 'top' ? 'left' : 'right';\n }\n } else {\n if ((angle + 90) % 180 === 0) {\n return 'center';\n } else if (90 <= angle && angle < 270) {\n return orient === 'left' ? 'left' : 'right';\n } else {\n return orient === 'left' ? 'right' : 'left';\n }\n }\n}\n\n","import {Axis, AXIS_PARTS, AxisEncoding, isAxisProperty, VG_AXIS_PROPERTIES} from '../../axis';\nimport {POSITION_SCALE_CHANNELS, PositionScaleChannel, X, Y} from '../../channel';\nimport {FieldDefBase, toFieldDefBase} from '../../fielddef';\nimport {keys} from '../../util';\nimport {AxisOrient, VgAxis, VgAxisEncode} from '../../vega.schema';\nimport {getSpecifiedOrDefaultValue, guideEncodeEntry, mergeTitle, mergeTitleComponent, mergeTitleFieldDefs, numberFormat} from '../common';\nimport {LayerModel} from '../layer';\nimport {parseGuideResolve} from '../resolve';\nimport {defaultTieBreaker, Explicit, mergeValuesWithExplicit} from '../split';\nimport {UnitModel} from '../unit';\nimport {AxisComponent, AxisComponentIndex, AxisComponentProps} from './component';\nimport {getAxisConfig} from './config';\nimport * as encode from './encode';\nimport * as properties from './properties';\n\n\nexport function parseUnitAxis(model: UnitModel): AxisComponentIndex {\n return POSITION_SCALE_CHANNELS.reduce(function(axis, channel) {\n if (model.component.scales[channel] && model.axis(channel)) {\n axis[channel] = [parseAxis(channel, model)];\n }\n return axis;\n }, {} as AxisComponentIndex);\n}\n\nconst OPPOSITE_ORIENT: {[K in AxisOrient]: AxisOrient} = {\n bottom: 'top',\n top: 'bottom',\n left: 'right',\n right: 'left'\n};\n\nexport function parseLayerAxis(model: LayerModel) {\n const {axes, resolve} = model.component;\n const axisCount: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in AxisOrient]: number\n } = {top: 0, bottom: 0, right: 0, left: 0};\n\n for (const child of model.children) {\n child.parseAxisAndHeader();\n\n for (const channel of keys(child.component.axes)) {\n resolve.axis[channel] = parseGuideResolve(model.component.resolve, channel);\n if (resolve.axis[channel] === 'shared') {\n // If the resolve says shared (and has not been overridden)\n // We will try to merge and see if there is a conflict\n\n axes[channel] = mergeAxisComponents(axes[channel], child.component.axes[channel]);\n\n if (!axes[channel]) {\n // If merge returns nothing, there is a conflict so we cannot make the axis shared.\n // Thus, mark axis as independent and remove the axis component.\n resolve.axis[channel] = 'independent';\n delete axes[channel];\n }\n }\n }\n }\n\n // Move axes to layer's axis component and merge shared axes\n for (const channel of [X, Y]) {\n for (const child of model.children) {\n if (!child.component.axes[channel]) {\n // skip if the child does not have a particular axis\n continue;\n }\n\n if (resolve.axis[channel] === 'independent') {\n // If axes are independent, concat the axisComponent array.\n axes[channel] = (axes[channel] || []).concat(child.component.axes[channel]);\n\n // Automatically adjust orient\n for (const axisComponent of child.component.axes[channel]) {\n const {value: orient, explicit} = axisComponent.getWithExplicit('orient');\n if (axisCount[orient] > 0 && !explicit) {\n // Change axis orient if the number do not match\n const oppositeOrient = OPPOSITE_ORIENT[orient];\n if (axisCount[orient] > axisCount[oppositeOrient]) {\n axisComponent.set('orient', oppositeOrient, false);\n }\n }\n axisCount[orient]++;\n\n // TODO(https://github.com/vega/vega-lite/issues/2634): automaticaly add extra offset?\n }\n }\n\n // After merging, make sure to remove axes from child\n delete child.component.axes[channel];\n }\n }\n}\n\nfunction mergeAxisComponents(mergedAxisCmpts: AxisComponent[], childAxisCmpts: AxisComponent[]): AxisComponent[] {\n if (mergedAxisCmpts) {\n // FIXME: this is a bit wrong once we support multiple axes\n if (mergedAxisCmpts.length !== childAxisCmpts.length) {\n return undefined; // Cannot merge axis component with different number of axes.\n }\n const length = mergedAxisCmpts.length;\n for (let i = 0; i < length ; i++) {\n const merged = mergedAxisCmpts[i];\n const child = childAxisCmpts[i];\n\n if ((!!merged) !== (!!child)) {\n return undefined;\n } else if (merged && child) {\n const mergedOrient = merged.getWithExplicit('orient');\n const childOrient = child.getWithExplicit('orient');\n\n if (mergedOrient.explicit && childOrient.explicit && mergedOrient.value !== childOrient.value) {\n // TODO: throw warning if resolve is explicit (We don't have info about explicit/implicit resolve yet.)\n\n // Cannot merge due to inconsistent orient\n return undefined;\n } else {\n mergedAxisCmpts[i] = mergeAxisComponent(merged, child);\n }\n }\n }\n } else {\n // For first one, return a copy of the child\n return childAxisCmpts.map(axisComponent => axisComponent.clone());\n }\n return mergedAxisCmpts;\n}\n\nfunction mergeAxisComponent(merged: AxisComponent, child: AxisComponent): AxisComponent {\n for (const prop of VG_AXIS_PROPERTIES) {\n const mergedValueWithExplicit = mergeValuesWithExplicit(\n merged.getWithExplicit(prop),\n child.getWithExplicit(prop),\n prop, 'axis',\n\n // Tie breaker function\n (v1: Explicit, v2: Explicit) => {\n switch (prop) {\n case 'title':\n return mergeTitleComponent(v1, v2);\n case 'gridScale':\n return {\n explicit: v1.explicit, // keep the old explicit\n value: v1.value || v2.value\n };\n }\n return defaultTieBreaker(v1, v2, prop, 'axis');\n }\n );\n merged.setWithExplicit(prop, mergedValueWithExplicit);\n }\n return merged;\n}\n\nfunction getFieldDefTitle(model: UnitModel, channel: 'x' | 'y') {\n const channel2 = channel === 'x' ? 'x2' : 'y2';\n const fieldDef = model.fieldDef(channel);\n const fieldDef2 = model.fieldDef(channel2);\n\n const title1 = fieldDef ? fieldDef.title : undefined;\n const title2 = fieldDef2 ? fieldDef2.title : undefined;\n\n if (title1 && title2) {\n return mergeTitle(title1, title2);\n } else if (title1) {\n return title1;\n } else if (title2) {\n return title2;\n } else if (title1 !== undefined) { // falsy value to disable config\n return title1;\n } else if (title2 !== undefined) { // falsy value to disable config\n return title2;\n }\n\n return undefined;\n}\n\nfunction parseAxis(channel: PositionScaleChannel, model: UnitModel): AxisComponent {\n const axis = model.axis(channel);\n\n const axisComponent = new AxisComponent();\n\n // 1.2. Add properties\n VG_AXIS_PROPERTIES.forEach(function(property) {\n const value = getProperty(property, axis, channel, model);\n if (value !== undefined) {\n const explicit =\n // specified axis.values is already respected, but may get transformed.\n property === 'values' ? !!axis.values :\n // both VL axis.encoding and axis.labelAngle affect VG axis.encode\n property === 'encode' ? !!axis.encoding || !!axis.labelAngle :\n // title can be explicit if fieldDef.title is set\n property === 'title' && value === getFieldDefTitle(model, channel) ? true :\n // Otherwise, things are explicit if the returned value matches the specified property\n value === axis[property];\n\n const configValue = getAxisConfig(property, model.config, channel, axisComponent.get('orient'), model.getScaleComponent(channel).get('type'));\n\n // only set property if it is explicitly set or has no config value (otherwise we will accidentally override config)\n if (explicit || configValue === undefined) {\n // Do not apply implicit rule if there is a config value\n axisComponent.set(property, value, explicit);\n } else if (property === 'grid' && configValue) {\n // Grid is an exception because we need to set grid = true to generate another grid axis\n axisComponent.set(property, configValue, false);\n }\n }\n });\n\n // 2) Add guide encode definition groups\n const axisEncoding = axis.encoding || {};\n const axisEncode = AXIS_PARTS.reduce((e: VgAxisEncode, part) => {\n if (!axisComponent.hasAxisPart(part)) {\n // No need to create encode for a disabled part.\n return e;\n }\n\n const axisEncodingPart = guideEncodeEntry(axisEncoding[part] || {}, model);\n\n const value = part === 'labels' ?\n encode.labels(model, channel, axisEncodingPart, axisComponent.get('orient')) :\n axisEncodingPart;\n\n if (value !== undefined && keys(value).length > 0) {\n e[part] = {update: value};\n }\n return e;\n }, {} as VgAxisEncode);\n\n // FIXME: By having encode as one property, we won't have fine grained encode merging.\n if (keys(axisEncode).length > 0) {\n axisComponent.set('encode', axisEncode, !!axis.encoding || axis.labelAngle !== undefined);\n }\n\n return axisComponent;\n}\n\nfunction getProperty(property: K, specifiedAxis: Axis, channel: PositionScaleChannel, model: UnitModel): AxisComponentProps[K] {\n const fieldDef = model.fieldDef(channel);\n switch (property) {\n case 'scale':\n return model.scaleName(channel);\n case 'gridScale':\n return properties.gridScale(model, channel);\n case 'format':\n // We don't include temporal field here as we apply format in encode block\n return numberFormat(fieldDef, specifiedAxis.format, model.config);\n case 'grid': {\n const scaleType = model.getScaleComponent(channel).get('type');\n return getSpecifiedOrDefaultValue(specifiedAxis.grid, properties.grid(scaleType, fieldDef));\n }\n case 'labelFlush':\n return properties.labelFlush(fieldDef, channel, specifiedAxis);\n case 'labelOverlap': {\n const scaleType = model.getScaleComponent(channel).get('type');\n return properties.labelOverlap(fieldDef, specifiedAxis, channel, scaleType);\n }\n case 'orient':\n return getSpecifiedOrDefaultValue(specifiedAxis.orient, properties.orient(channel));\n case 'tickCount': {\n const scaleType = model.getScaleComponent(channel).get('type');\n const sizeType = channel === 'x' ? 'width' : channel === 'y' ? 'height' : undefined;\n const size = sizeType ? model.getSizeSignalRef(sizeType)\n : undefined;\n return getSpecifiedOrDefaultValue(specifiedAxis.tickCount, properties.tickCount(channel, fieldDef, scaleType, size));\n }\n case 'title':\n const channel2 = channel === 'x' ? 'x2' : 'y2';\n const fieldDef2 = model.fieldDef(channel2);\n // Keep undefined so we use default if title is unspecified.\n // For other falsy value, keep them so we will hide the title.\n const fieldDefTitle = getFieldDefTitle(model, channel);\n const specifiedTitle = fieldDefTitle !== undefined ? fieldDefTitle :\n specifiedAxis.title === undefined ? undefined : specifiedAxis.title;\n\n return getSpecifiedOrDefaultValue[]>(\n specifiedTitle,\n // If title not specified, store base parts of fieldDef (and fieldDef2 if exists)\n mergeTitleFieldDefs(\n [toFieldDefBase(fieldDef)],\n fieldDef2 ? [toFieldDefBase(fieldDef2)] : []\n )\n );\n case 'values':\n return properties.values(specifiedAxis, model, fieldDef, channel);\n }\n // Otherwise, return specified property.\n return isAxisProperty(property) ? specifiedAxis[property] : undefined;\n}\n","import {truncate} from 'vega-util';\nimport {Axis} from '../../axis';\nimport {binToString} from '../../bin';\nimport {PositionScaleChannel, X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {FieldDef, title as fieldDefTitle, valueArray} from '../../fielddef';\nimport * as log from '../../log';\nimport {hasDiscreteDomain, isSelectionDomain, ScaleType} from '../../scale';\nimport {QUANTITATIVE} from '../../type';\nimport {contains} from '../../util';\nimport {VgSignalRef} from '../../vega.schema';\nimport {UnitModel} from '../unit';\n\n\n// TODO: we need to refactor this method after we take care of config refactoring\n/**\n * Default rules for whether to show a grid should be shown for a channel.\n * If `grid` is unspecified, the default value is `true` for ordinal scales that are not binned\n */\nexport function grid(scaleType: ScaleType, fieldDef: FieldDef) {\n return !hasDiscreteDomain(scaleType) && !fieldDef.bin;\n}\n\nexport function gridScale(model: UnitModel, channel: PositionScaleChannel) {\n const gridChannel: PositionScaleChannel = channel === 'x' ? 'y' : 'x';\n if (model.getScaleComponent(gridChannel)) {\n return model.scaleName(gridChannel);\n }\n return undefined;\n}\n\nexport function labelFlush(fieldDef: FieldDef, channel: PositionScaleChannel, specifiedAxis: Axis) {\n if (specifiedAxis.labelFlush !== undefined) {\n return specifiedAxis.labelFlush;\n }\n if (channel === 'x' && contains(['quantitative', 'temporal'], fieldDef.type)) {\n return true;\n }\n return undefined;\n}\n\nexport function labelOverlap(fieldDef: FieldDef, specifiedAxis: Axis, channel: PositionScaleChannel, scaleType: ScaleType) {\n if (specifiedAxis.labelOverlap !== undefined) {\n return specifiedAxis.labelOverlap;\n }\n\n // do not prevent overlap for nominal data because there is no way to infer what the missing labels are\n if (fieldDef.type !== 'nominal') {\n if (scaleType === 'log') {\n return 'greedy';\n }\n return true;\n }\n\n return undefined;\n}\n\nexport function orient(channel: PositionScaleChannel) {\n switch (channel) {\n case X:\n return 'bottom';\n case Y:\n return 'left';\n }\n /* istanbul ignore next: This should never happen. */\n throw new Error(log.message.INVALID_CHANNEL_FOR_AXIS);\n}\n\nexport function tickCount(channel: PositionScaleChannel, fieldDef: FieldDef, scaleType: ScaleType, size: VgSignalRef) {\n if (!hasDiscreteDomain(scaleType) && scaleType !== 'log' && !contains(['month', 'hours', 'day', 'quarter'], fieldDef.timeUnit)) {\n\n if (fieldDef.bin) {\n // for binned data, we don't want more ticks than maxbins\n return {signal: `ceil(${size.signal}/20)`};\n }\n return {signal: `ceil(${size.signal}/40)`};\n }\n\n return undefined;\n}\n\nexport function title(maxLength: number, fieldDef: FieldDef, config: Config) {\n // if not defined, automatically determine axis title from field def\n const fieldTitle = fieldDefTitle(fieldDef, config);\n return maxLength ? truncate(fieldTitle, maxLength) : fieldTitle;\n}\n\nexport function values(specifiedAxis: Axis, model: UnitModel, fieldDef: FieldDef, channel: PositionScaleChannel) {\n const vals = specifiedAxis.values;\n\n if (vals) {\n return valueArray(fieldDef, vals);\n }\n\n if (fieldDef.bin && fieldDef.type === QUANTITATIVE) {\n const domain = model.scaleDomain(channel);\n if (domain && domain !== 'unaggregated' && !isSelectionDomain(domain)) { // explicit value\n return undefined;\n }\n\n const signal = model.getName(`${binToString(fieldDef.bin)}_${fieldDef.field}_bins`);\n return {signal: `sequence(${signal}.start, ${signal}.stop + ${signal}.step, ${signal}.step)`};\n }\n\n return undefined;\n}\n","\nimport {Config} from '../../config';\nimport {Encoding, isAggregate} from '../../encoding';\nimport {FieldDef, isContinuous, isFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {AREA, BAR, CIRCLE, isMarkDef, LINE, Mark, MarkDef, POINT, RECT, RULE, SQUARE, TEXT, TICK} from '../../mark';\nimport {QUANTITATIVE, TEMPORAL} from '../../type';\nimport {contains} from '../../util';\nimport {getMarkConfig} from '../common';\nimport {Orient} from './../../vega.schema';\n\n\nexport function normalizeMarkDef(mark: Mark | MarkDef, encoding: Encoding, config: Config) {\n const markDef: MarkDef = isMarkDef(mark) ? {...mark} : {type: mark};\n\n // set orient, which can be overridden by rules as sometimes the specified orient is invalid.\n const specifiedOrient = markDef.orient || getMarkConfig('orient', markDef, config);\n markDef.orient = orient(markDef.type, encoding, specifiedOrient);\n if (specifiedOrient !== undefined && specifiedOrient !== markDef.orient) {\n log.warn(log.message.orientOverridden(markDef.orient,specifiedOrient));\n }\n\n // set opacity and filled if not specified in mark config\n const specifiedOpacity = markDef.opacity !== undefined ? markDef.opacity : getMarkConfig('opacity', markDef, config);\n if (specifiedOpacity === undefined) {\n markDef.opacity = opacity(markDef.type, encoding);\n }\n\n const specifiedFilled = markDef.filled;\n if (specifiedFilled === undefined) {\n markDef.filled = filled(markDef, config);\n }\n\n // set cursor, which should be pointer if href channel is present unless otherwise specified\n const specifiedCursor = markDef.cursor || getMarkConfig('cursor', markDef, config);\n if (specifiedCursor === undefined) {\n markDef.cursor = cursor(markDef, encoding, config);\n }\n\n return markDef;\n}\n\nfunction cursor(markDef: MarkDef, encoding: Encoding, config: Config) {\n if (encoding.href || markDef.href || getMarkConfig('href', markDef, config)) {\n return 'pointer';\n }\n return markDef.cursor;\n}\n\nfunction opacity(mark: Mark, encoding: Encoding) {\n if (contains([POINT, TICK, CIRCLE, SQUARE], mark)) {\n // point-based marks\n if (!isAggregate(encoding)) {\n return 0.7;\n }\n }\n return undefined;\n}\n\nfunction filled(markDef: MarkDef, config: Config) {\n const filledConfig = getMarkConfig('filled', markDef, config);\n const mark = markDef.type;\n return filledConfig !== undefined ? filledConfig : mark !== POINT && mark !== LINE && mark !== RULE;\n}\n\nfunction orient(mark: Mark, encoding: Encoding, specifiedOrient: Orient): Orient {\n switch (mark) {\n case POINT:\n case CIRCLE:\n case SQUARE:\n case TEXT:\n case RECT:\n // orient is meaningless for these marks.\n return undefined;\n }\n\n const yIsRange = encoding.y2;\n const xIsRange = encoding.x2;\n\n switch (mark) {\n case BAR:\n if (yIsRange || xIsRange) {\n // Ranged bar does not always have clear orientation, so we allow overriding\n if (specifiedOrient) {\n return specifiedOrient;\n }\n\n // If y is range and x is non-range, non-bin Q, y is likely a prebinned field\n const xDef = encoding.x;\n if (!xIsRange && isFieldDef(xDef) && xDef.type === QUANTITATIVE && !xDef.bin) {\n return 'horizontal';\n }\n\n // If x is range and y is non-range, non-bin Q, x is likely a prebinned field\n const yDef = encoding.y;\n if (!yIsRange && isFieldDef(yDef) && yDef.type === QUANTITATIVE && !yDef.bin) {\n return 'vertical';\n }\n }\n /* tslint:disable */\n case RULE: // intentionally fall through\n // return undefined for line segment rule and bar with both axis ranged\n if (xIsRange && yIsRange) {\n return undefined;\n }\n\n case AREA: // intentionally fall through\n // If there are range for both x and y, y (vertical) has higher precedence.\n if (yIsRange) {\n return 'vertical';\n } else if (xIsRange) {\n return 'horizontal';\n } else if (mark === RULE) {\n if (encoding.x && !encoding.y) {\n return 'vertical';\n } else if (encoding.y && !encoding.x) {\n return 'horizontal';\n }\n }\n\n\n case LINE: // intentional fall through\n case TICK: // Tick is opposite to bar, line, area and never have ranged mark.\n\n /* tslint:enable */\n const xIsContinuous = isFieldDef(encoding.x) && isContinuous(encoding.x);\n const yIsContinuous = isFieldDef(encoding.y) && isContinuous(encoding.y);\n if (xIsContinuous && !yIsContinuous) {\n return mark !== 'tick' ? 'horizontal' : 'vertical';\n } else if (!xIsContinuous && yIsContinuous) {\n return mark !== 'tick' ? 'vertical' : 'horizontal';\n } else if (xIsContinuous && yIsContinuous) {\n const xDef = encoding.x as FieldDef; // we can cast here since they are surely fieldDef\n const yDef = encoding.y as FieldDef;\n\n const xIsTemporal = xDef.type === TEMPORAL;\n const yIsTemporal = yDef.type === TEMPORAL;\n\n // temporal without timeUnit is considered continuous, but better serves as dimension\n if (xIsTemporal && !yIsTemporal) {\n return mark !== 'tick' ? 'vertical' : 'horizontal';\n } else if (!xIsTemporal && yIsTemporal) {\n return mark !== 'tick' ? 'horizontal' : 'vertical';\n }\n\n if (!xDef.aggregate && yDef.aggregate) {\n return mark !== 'tick' ? 'vertical' : 'horizontal';\n } else if (xDef.aggregate && !yDef.aggregate) {\n return mark !== 'tick' ? 'horizontal' : 'vertical';\n }\n\n if (specifiedOrient) {\n // When ambiguous, use user specified one.\n return specifiedOrient;\n }\n\n return 'vertical';\n } else {\n // Discrete x Discrete case\n if (specifiedOrient) {\n // When ambiguous, use user specified one.\n return specifiedOrient;\n }\n\n return undefined;\n }\n }\n return 'vertical';\n}\n\n","import {isNumber} from 'vega-util';\nimport {X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {isFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {MarkDef} from '../../mark';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {isVgRangeStep, VgEncodeEntry} from '../../vega.schema';\nimport {VgValueRef} from '../../vega.schema';\nimport {ScaleComponent} from '../scale/component';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nexport const bar: MarkCompiler = {\n vgMark: 'rect',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...x(model),\n ...y(model),\n };\n }\n};\n\nfunction x(model: UnitModel): VgEncodeEntry {\n const {config, encoding, markDef, width} = model;\n const orient = markDef.orient;\n const sizeDef = encoding.size;\n\n const xDef = encoding.x;\n const x2Def = encoding.x2;\n const xScaleName = model.scaleName(X);\n const xScale = model.getScaleComponent(X);\n // x, x2, and width -- we must specify two of these in all conditions\n if (orient === 'horizontal' || x2Def) {\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'x2'),\n };\n } else { // vertical\n if (isFieldDef(xDef)) {\n const xScaleType = xScale.get('type');\n if (xDef.bin && !sizeDef && !hasDiscreteDomain(xScaleType)) {\n return mixins.binnedPosition(\n xDef, 'x', model.scaleName('x'), markDef.binSpacing === undefined ? config.bar.binSpacing : markDef.binSpacing,\n xScale.get('reverse')\n );\n } else {\n if (xScaleType === ScaleType.BAND) {\n return mixins.bandPosition(xDef, 'x', model);\n }\n }\n }\n // sized bin, normal point-ordinal axis, quantitative x-axis, or no x\n\n return mixins.centeredBandPosition('x', model,\n {...ref.mid(width)},\n defaultSizeRef(markDef, xScaleName, xScale, config)\n );\n }\n}\n\nfunction y(model: UnitModel) {\n const {config, encoding, height, markDef} = model;\n const orient = markDef.orient;\n const sizeDef = encoding.size;\n\n const yDef = encoding.y;\n const y2Def = encoding.y2;\n const yScaleName = model.scaleName(Y);\n const yScale = model.getScaleComponent(Y);\n\n // y, y2 & height -- we must specify two of these in all conditions\n if (orient === 'vertical' || y2Def) {\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'y2'),\n };\n } else {\n if (isFieldDef(yDef)) {\n const yScaleType = yScale.get('type');\n if (yDef.bin && !sizeDef && !hasDiscreteDomain(yScaleType)) {\n return mixins.binnedPosition(\n yDef, 'y', model.scaleName('y'),\n markDef.binSpacing === undefined ? config.bar.binSpacing : markDef.binSpacing,\n yScale.get('reverse')\n );\n } else if (yScaleType === ScaleType.BAND) {\n return mixins.bandPosition(yDef, 'y', model);\n }\n }\n return mixins.centeredBandPosition('y', model, ref.mid(height),\n defaultSizeRef(markDef, yScaleName, yScale, config)\n );\n }\n}\n\nfunction defaultSizeRef(markDef: MarkDef, scaleName: string, scale: ScaleComponent, config: Config): VgValueRef {\n if (markDef.size !== undefined) {\n return {value: markDef.size};\n } else if (config.bar.discreteBandSize) {\n return {value: config.bar.discreteBandSize};\n } else if (scale) {\n const scaleType = scale.get('type');\n if (scaleType === ScaleType.POINT) {\n const scaleRange = scale.get('range');\n if (isVgRangeStep(scaleRange) && isNumber(scaleRange.step)) {\n return {value: scaleRange.step - 1};\n }\n log.warn(log.message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL);\n } else if (scaleType === ScaleType.BAND) {\n return ref.bandRef(scaleName);\n } else { // non-ordinal scale\n return {value: config.bar.continuousBandSize};\n }\n } else if (config.scale.rangeStep && config.scale.rangeStep !== null) {\n return {value: config.scale.rangeStep - 1};\n }\n return {value: 20};\n}\n\n","import {Config} from '../../config';\nimport {VgEncodeEntry} from '../../vega.schema';\nimport {getMarkConfig} from '../common';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nfunction encodeEntry(model: UnitModel, fixedShape?: 'circle' | 'square') {\n const {config, width, height} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'include', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.nonPosition('size', model),\n ...shapeMixins(model, config, fixedShape),\n };\n}\n\nexport function shapeMixins(model: UnitModel, config: Config, fixedShape?: 'circle' | 'square'): VgEncodeEntry {\n if (fixedShape) {\n return {shape: {value: fixedShape}};\n }\n return mixins.nonPosition('shape', model, {defaultValue: getMarkConfig('shape', model.markDef, config) as string});\n}\n\nexport const point: MarkCompiler = {\n vgMark: 'symbol',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model);\n }\n};\n\nexport const circle: MarkCompiler = {\n vgMark: 'symbol',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model, 'circle');\n }\n};\n\nexport const square: MarkCompiler = {\n vgMark: 'symbol',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model, 'square');\n }\n};\n","import {isArray} from 'vega-util';\nimport {MAIN} from '../../data';\nimport {Encoding, isAggregate} from '../../encoding';\nimport {getFieldDef, isFieldDef, isValueDef, vgField} from '../../fielddef';\nimport {AREA, isPathMark, LINE, Mark, TRAIL} from '../../mark';\nimport {isSortField} from '../../sort';\nimport {contains, keys} from '../../util';\nimport {getStyles, sortParams} from '../common';\nimport {UnitModel} from '../unit';\nimport {area} from './area';\nimport {bar} from './bar';\nimport {MarkCompiler} from './base';\nimport {geoshape} from './geoshape';\nimport {line, trail} from './line';\nimport {circle, point, square} from './point';\nimport {rect} from './rect';\nimport {rule} from './rule';\nimport {text} from './text';\nimport {tick} from './tick';\n\n\nconst markCompiler: {[m in Mark]: MarkCompiler} = {\n area,\n bar,\n circle,\n geoshape,\n line,\n point,\n rect,\n rule,\n square,\n text,\n tick,\n trail\n};\n\nexport function parseMarkGroup(model: UnitModel): any[] {\n if (contains([LINE, AREA, TRAIL], model.mark)) {\n return parsePathMark(model);\n } else {\n return getMarkGroups(model);\n }\n}\n\nconst FACETED_PATH_PREFIX = 'faceted_path_';\n\nfunction parsePathMark(model: UnitModel) {\n const details = pathGroupingFields(model.mark, model.encoding);\n\n const pathMarks = getMarkGroups(model, {\n // If has subfacet for line/area group, need to use faceted data from below.\n fromPrefix: (details.length > 0 ? FACETED_PATH_PREFIX : '')\n });\n\n if (details.length > 0) { // have level of details - need to facet line into subgroups\n // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?)\n\n return [{\n name: model.getName('pathgroup'),\n type: 'group',\n from: {\n facet: {\n name: FACETED_PATH_PREFIX + model.requestDataName(MAIN),\n data: model.requestDataName(MAIN),\n groupby: details,\n }\n },\n encode: {\n update: {\n width: {field: {group: 'width'}},\n height: {field: {group: 'height'}}\n }\n },\n marks: pathMarks\n }];\n } else {\n return pathMarks;\n }\n}\n\nexport function getSort(model: UnitModel) {\n const {encoding, stack, mark, markDef} = model;\n const order = encoding.order;\n if (!isArray(order) && isValueDef(order)) {\n return undefined;\n } else if ((isArray(order) || isFieldDef(order)) && !stack) {\n // Sort by the order field if it is specified and the field is not stacked. (For stacked field, order specify stack order.)\n return sortParams(order, {expr: 'datum'});\n } else if (isPathMark(mark)) {\n // For both line and area, we sort values based on dimension by default\n const dimensionChannelDef = encoding[markDef.orient === 'horizontal' ? 'y' : 'x'];\n if (isFieldDef(dimensionChannelDef)) {\n const s = dimensionChannelDef.sort;\n const sortField = isSortField(s) ?\n vgField({\n // FIXME: this op might not already exist?\n // FIXME: what if dimensionChannel (x or y) contains custom domain?\n aggregate: isAggregate(model.encoding) ? s.op : undefined,\n field: s.field\n }, {expr: 'datum'}) :\n vgField(dimensionChannelDef, {\n // For stack with imputation, we only have bin_mid\n binSuffix: model.stack && model.stack.impute ? 'mid' : undefined,\n expr: 'datum'\n });\n\n return {\n field: sortField,\n order: 'descending'\n };\n }\n return undefined;\n }\n return undefined;\n}\n\nfunction getMarkGroups(model: UnitModel, opt: {\n fromPrefix: string\n} = {fromPrefix: ''}) {\n const mark = model.mark;\n\n const clip = model.markDef.clip !== undefined ?\n !!model.markDef.clip : scaleClip(model);\n const style = getStyles(model.markDef);\n const key = model.encoding.key;\n const sort = getSort(model);\n\n const postEncodingTransform = markCompiler[mark].postEncodingTransform ? markCompiler[mark].postEncodingTransform(model) : null;\n\n return [{\n name: model.getName('marks'),\n type: markCompiler[mark].vgMark,\n ...(clip ? {clip: true} : {}),\n ...(style ? {style} : {}),\n ...(key ? {key: {field: key.field}} : {}),\n ...(sort ? {sort} : {}),\n from: {data: opt.fromPrefix + model.requestDataName(MAIN)},\n encode: {\n update: markCompiler[mark].encodeEntry(model)\n },\n ...(postEncodingTransform ? {\n transform: postEncodingTransform\n } : {})\n }];\n\n}\n\n/**\n * Returns list of path grouping fields\n * that the model's spec contains.\n */\nexport function pathGroupingFields(mark: Mark, encoding: Encoding): string[] {\n return keys(encoding).reduce((details, channel) => {\n switch (channel) {\n // x, y, x2, y2, lat, long, lat1, long2, order, tooltip, href, cursor should not cause lines to group\n case 'x':\n case 'y':\n case 'order':\n case 'tooltip':\n case 'href':\n case 'x2':\n case 'y2':\n\n case 'latitude':\n case 'longitude':\n case 'latitude2':\n case 'longitude2':\n // TODO: case 'cursor':\n\n // text, shape, shouldn't be a part of line/trail/area\n case 'text':\n case 'shape':\n return details;\n\n case 'detail':\n case 'key':\n const channelDef = encoding[channel];\n if (channelDef) {\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((fieldDef) => {\n if (!fieldDef.aggregate) {\n details.push(vgField(fieldDef, {}));\n }\n });\n }\n return details;\n\n case 'size':\n if (mark === 'trail') {\n // For trail, size should not group trail lines.\n return details;\n }\n // For line, it should group lines.\n\n /* tslint:disable */\n // intentional fall through\n\n case 'color':\n case 'fill':\n case 'stroke':\n case 'opacity':\n // TODO strokeDashOffset:\n\n /* tslint:enable */\n const fieldDef = getFieldDef(encoding[channel]);\n if (fieldDef && !fieldDef.aggregate) {\n details.push(vgField(fieldDef, {}));\n }\n return details;\n default:\n throw new Error(`Bug: Channel ${channel} unimplemented for line mark`);\n }\n }, []);\n}\n\n/**\n * If scales are bound to interval selections, we want to automatically clip\n * marks to account for panning/zooming interactions. We identify bound scales\n * by the domainRaw property, which gets added during scale parsing.\n */\nfunction scaleClip(model: UnitModel) {\n const xScale = model.getScaleComponent('x');\n const yScale = model.getScaleComponent('y');\n return (xScale && xScale.get('domainRaw')) ||\n (yScale && yScale.get('domainRaw')) ? true : false;\n}\n","import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\n\n\nexport const area: MarkCompiler = {\n vgMark: 'area',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'include'}),\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin', model.markDef.orient === 'horizontal' ? 'x2' : 'y2'),\n ...mixins.defined(model)\n };\n }\n};\n","import {UnitModel} from '../unit';\nimport * as mixins from './mixins';\n\nimport {isFieldDef, vgField} from '../../fielddef';\nimport {GEOJSON} from '../../type';\nimport {VgGeoShapeTransform, VgPostEncodingTransform} from '../../vega.schema';\nimport {MarkCompiler} from './base';\n\nexport const geoshape: MarkCompiler = {\n vgMark: 'shape',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'})\n };\n },\n postEncodingTransform: (model: UnitModel): VgPostEncodingTransform[] => {\n const {encoding} = model;\n const shapeDef = encoding.shape;\n\n const transform: VgGeoShapeTransform = {\n type: 'geoshape',\n projection: model.projectionName(),\n // as: 'shape',\n ...(shapeDef && isFieldDef(shapeDef) && shapeDef.type === GEOJSON ? {field: vgField(shapeDef, {expr: 'datum'})} : {})\n };\n return [transform];\n }\n};\n","import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\nexport const line: MarkCompiler = {\n vgMark: 'line',\n encodeEntry: (model: UnitModel) => {\n const {width, height} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth' // VL's line size is strokeWidth\n }),\n ...mixins.defined(model)\n };\n }\n};\n\n\nexport const trail: MarkCompiler = {\n vgMark: 'trail',\n encodeEntry: (model: UnitModel) => {\n const {width, height} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'include', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.nonPosition('size', model),\n ...mixins.defined(model)\n };\n }\n};\n","import {X, Y} from '../../channel';\nimport {isFieldDef} from '../../fielddef';\nimport * as log from '../../log';\nimport {RECT} from '../../mark';\nimport {hasDiscreteDomain, ScaleType} from '../../scale';\nimport {VgEncodeEntry} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\n\nexport const rect: MarkCompiler = {\n vgMark: 'rect',\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...x(model),\n ...y(model),\n };\n }\n};\n\nexport function x(model: UnitModel): VgEncodeEntry {\n const xDef = model.encoding.x;\n const x2Def = model.encoding.x2;\n const xScale = model.getScaleComponent(X);\n const xScaleType = xScale ? xScale.get('type') : undefined;\n\n if (isFieldDef(xDef) && xDef.bin && !x2Def) {\n return mixins.binnedPosition(xDef, 'x', model.scaleName('x'), 0, xScale.get('reverse'));\n } else if (isFieldDef(xDef) && xScale && hasDiscreteDomain(xScaleType)) {\n /* istanbul ignore else */\n if (xScaleType === ScaleType.BAND) {\n return mixins.bandPosition(xDef, 'x', model);\n } else {\n // We don't support rect mark with point/ordinal scale\n throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, xScaleType));\n }\n } else { // continuous scale or no scale\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMax'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'x2')\n };\n }\n}\n\nexport function y(model: UnitModel): VgEncodeEntry {\n const yDef = model.encoding.y;\n const y2Def = model.encoding.y2;\n const yScale = model.getScaleComponent(Y);\n const yScaleType = yScale ? yScale.get('type') : undefined;\n\n if (isFieldDef(yDef) && yDef.bin && !y2Def) {\n return mixins.binnedPosition(yDef, 'y', model.scaleName('y'), 0, yScale.get('reverse'));\n } else if (isFieldDef(yDef) && yScale && hasDiscreteDomain(yScaleType)) {\n /* istanbul ignore else */\n if (yScaleType === ScaleType.BAND) {\n return mixins.bandPosition(yDef, 'y', model);\n } else {\n // We don't support rect mark with point/ordinal scale\n throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, yScaleType));\n }\n } else { // continuous scale or no scale\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMax'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'y2')\n };\n }\n}\n","import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\nexport const rule: MarkCompiler = {\n vgMark: 'rule',\n encodeEntry: (model: UnitModel) => {\n const {config: _config, markDef, width, height} = model;\n const orient = markDef.orient;\n\n if (!model.encoding.x && !model.encoding.y && !model.encoding.latitude && !model.encoding.longitude) {\n // Show nothing if we have none of x, y, lat, and long.\n return {};\n }\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, orient === 'horizontal' ? 'zeroOrMin' : ref.mid(width)),\n ...mixins.pointPosition('y', model, orient === 'vertical' ? 'zeroOrMin' : ref.mid(height)),\n\n // include x2 for horizontal or line segment rule\n ...(orient !== 'vertical' ? mixins.pointPosition2(model, 'zeroOrMax', 'x2') : {}),\n\n // include y2 for vertical or line segment rule\n ...(orient !== 'horizontal' ? mixins.pointPosition2(model, 'zeroOrMax', 'y2') : {}),\n\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth', // VL's rule size is strokeWidth\n defaultValue: markDef.size\n })\n };\n }\n};\n","import {Config} from '../../config';\nimport {Encoding} from '../../encoding';\nimport {MarkDef} from '../../mark';\nimport {getMarkConfig} from '../common';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nexport const text: MarkCompiler = {\n vgMark: 'text',\n\n encodeEntry: (model: UnitModel) => {\n const {config, encoding, width, height, markDef} = model;\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n ...mixins.pointPosition('x', model, ref.mid(width)),\n ...mixins.pointPosition('y', model, ref.mid(height)),\n ...mixins.text(model),\n ...mixins.nonPosition('size', model, {\n ...(markDef.size ? {defaultValue: markDef.size} : {}),\n vgChannel: 'fontSize' // VL's text size is fontSize\n }),\n ...mixins.valueIfDefined('align', align(model.markDef, encoding, config))\n };\n }\n};\nfunction align(markDef: MarkDef, encoding: Encoding, config: Config) {\n const a = markDef.align || getMarkConfig('align', markDef, config);\n if (a === undefined) {\n return 'center';\n }\n // If there is a config, Vega-parser will process this already.\n return undefined;\n}\n","import {isVgRangeStep} from '../../vega.schema';\nimport {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\nimport * as ref from './valueref';\n\n\nexport const tick: MarkCompiler = {\n vgMark: 'rect',\n\n encodeEntry: (model: UnitModel) => {\n const {config, markDef, width, height} = model;\n const orient = markDef.orient;\n\n const vgSizeChannel = orient === 'horizontal' ? 'width' : 'height';\n const vgThicknessChannel = orient === 'horizontal' ? 'height' : 'width';\n\n return {\n ...mixins.baseEncodeEntry(model, {size: 'ignore', orient: 'ignore'}),\n\n ...mixins.pointPosition('x', model, ref.mid(width), 'xc'),\n ...mixins.pointPosition('y', model, ref.mid(height), 'yc'),\n\n // size / thickness => width / height\n ...mixins.nonPosition('size', model, {\n defaultValue: defaultSize(model),\n vgChannel: vgSizeChannel\n }),\n [vgThicknessChannel]: {value: markDef.thickness || config.tick.thickness},\n };\n }\n};\n\nfunction defaultSize(model: UnitModel): number {\n const {config, markDef} = model;\n const orient = markDef.orient;\n const scale = model.getScaleComponent(orient === 'horizontal' ? 'x' : 'y');\n\n if (markDef.size !== undefined) {\n return markDef.size;\n } else if (config.tick.bandSize !== undefined) {\n return config.tick.bandSize;\n } else {\n const scaleRange = scale ? scale.get('range') : undefined;\n const rangeStep = scaleRange && isVgRangeStep(scaleRange) ?\n scaleRange.step :\n config.scale.rangeStep;\n if (typeof rangeStep !== 'number') {\n // FIXME consolidate this log\n throw new Error('Function does not handle non-numeric rangeStep');\n }\n return rangeStep / 1.5;\n }\n}\n","import {Axis} from '../axis';\nimport {Channel, GEOPOSITION_CHANNELS, NONPOSITION_SCALE_CHANNELS, SCALE_CHANNELS, ScaleChannel, SingleDefChannel, X, Y} from '../channel';\nimport {Config} from '../config';\nimport * as vlEncoding from '../encoding';\nimport {Encoding, normalizeEncoding} from '../encoding';\nimport {ChannelDef, FieldDef, getFieldDef, hasConditionalFieldDef, isFieldDef} from '../fielddef';\nimport {Legend} from '../legend';\nimport {GEOSHAPE, isMarkDef, Mark, MarkDef} from '../mark';\nimport {Projection} from '../projection';\nimport {Domain, Scale} from '../scale';\nimport {SelectionDef} from '../selection';\nimport {LayoutSizeMixins, NormalizedUnitSpec} from '../spec';\nimport {stack, StackProperties} from '../stack';\nimport {Dict, duplicate} from '../util';\nimport {VgData, VgEncodeEntry, VgLayout, VgSignal} from '../vega.schema';\nimport {AxisIndex} from './axis/component';\nimport {parseUnitAxis} from './axis/parse';\nimport {parseData} from './data/parse';\nimport {assembleLayoutSignals} from './layoutsize/assemble';\nimport {parseUnitLayoutSize} from './layoutsize/parse';\nimport {LegendIndex} from './legend/component';\nimport {normalizeMarkDef} from './mark/init';\nimport {parseMarkGroup} from './mark/mark';\nimport {isLayerModel, Model, ModelWithField} from './model';\nimport {RepeaterValue, replaceRepeaterInEncoding} from './repeater';\nimport {ScaleIndex} from './scale/component';\nimport {assembleTopLevelSignals, assembleUnitSelectionData, assembleUnitSelectionMarks, assembleUnitSelectionSignals, parseUnitSelection} from './selection/selection';\n\n\n/**\n * Internal model of Vega-Lite specification for the compiler.\n */\nexport class UnitModel extends ModelWithField {\n public readonly type: 'unit' = 'unit';\n public readonly markDef: MarkDef;\n public readonly encoding: Encoding;\n\n public readonly specifiedScales: ScaleIndex = {};\n\n public readonly stack: StackProperties;\n\n protected specifiedAxes: AxisIndex = {};\n\n protected specifiedLegends: LegendIndex = {};\n\n public specifiedProjection: Projection = {};\n\n public readonly selection: Dict = {};\n public children: Model[] = [];\n\n constructor(spec: NormalizedUnitSpec, parent: Model, parentGivenName: string,\n parentGivenSize: LayoutSizeMixins = {}, repeater: RepeaterValue, config: Config, public fit: boolean) {\n\n super(spec, parent, parentGivenName, config, repeater, undefined);\n this.initSize({\n ...parentGivenSize,\n ...(spec.width ? {width: spec.width} : {}),\n ...(spec.height ? {height: spec.height} : {})\n });\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n\n const encoding = this.encoding = normalizeEncoding(replaceRepeaterInEncoding(spec.encoding || {}, repeater), mark);\n\n this.markDef = normalizeMarkDef(spec.mark, encoding, config);\n\n // calculate stack properties\n this.stack = stack(mark, encoding, this.config.stack);\n this.specifiedScales = this.initScales(mark, encoding);\n\n this.specifiedAxes = this.initAxes(encoding);\n this.specifiedLegends = this.initLegend(encoding);\n this.specifiedProjection = spec.projection;\n\n // Selections will be initialized upon parse.\n this.selection = spec.selection;\n }\n\n public get hasProjection(): boolean {\n const {encoding} = this;\n const isGeoShapeMark = this.mark === GEOSHAPE;\n const hasGeoPosition = encoding && GEOPOSITION_CHANNELS.some(\n channel => isFieldDef(encoding[channel])\n );\n return isGeoShapeMark || hasGeoPosition;\n }\n\n /**\n * Return specified Vega-lite scale domain for a particular channel\n * @param channel\n */\n public scaleDomain(channel: ScaleChannel): Domain {\n const scale = this.specifiedScales[channel];\n return scale ? scale.domain : undefined;\n }\n\n public axis(channel: Channel): Axis {\n return this.specifiedAxes[channel];\n }\n\n public legend(channel: Channel): Legend {\n return this.specifiedLegends[channel];\n }\n\n private initScales(mark: Mark, encoding: Encoding): ScaleIndex {\n return SCALE_CHANNELS.reduce((scales, channel) => {\n let fieldDef: FieldDef;\n let specifiedScale: Scale;\n\n const channelDef = encoding[channel];\n\n if (isFieldDef(channelDef)) {\n fieldDef = channelDef;\n specifiedScale = channelDef.scale;\n } else if (hasConditionalFieldDef(channelDef)) {\n fieldDef = channelDef.condition;\n specifiedScale = channelDef.condition['scale'];\n } else if (channel === 'x') {\n fieldDef = getFieldDef(encoding.x2);\n } else if (channel === 'y') {\n fieldDef = getFieldDef(encoding.y2);\n }\n\n if (fieldDef) {\n scales[channel] = specifiedScale || {};\n }\n return scales;\n }, {} as ScaleIndex);\n }\n\n private initAxes(encoding: Encoding): AxisIndex {\n return [X, Y].reduce(function(_axis, channel) {\n // Position Axis\n\n // TODO: handle ConditionFieldDef\n const channelDef = encoding[channel];\n if (isFieldDef(channelDef) ||\n (channel === X && isFieldDef(encoding.x2)) ||\n (channel === Y && isFieldDef(encoding.y2))) {\n\n const axisSpec = isFieldDef(channelDef) ? channelDef.axis : null;\n\n // We no longer support false in the schema, but we keep false here for backward compatibility.\n if (axisSpec !== null && axisSpec !== false) {\n _axis[channel] = {\n ...axisSpec\n };\n }\n }\n return _axis;\n }, {});\n }\n\n private initLegend(encoding: Encoding): LegendIndex {\n return NONPOSITION_SCALE_CHANNELS.reduce(function(_legend, channel) {\n const channelDef = encoding[channel];\n if (channelDef) {\n const legend = isFieldDef(channelDef) ? channelDef.legend :\n (hasConditionalFieldDef(channelDef)) ? channelDef.condition['legend'] : null;\n\n if (legend !== null && legend !== false) {\n _legend[channel] = {...legend};\n }\n }\n\n return _legend;\n }, {});\n }\n\n public parseData() {\n this.component.data = parseData(this);\n }\n\n public parseLayoutSize() {\n parseUnitLayoutSize(this);\n }\n\n public parseSelection() {\n this.component.selection = parseUnitSelection(this, this.selection);\n }\n\n public parseMarkGroup() {\n this.component.mark = parseMarkGroup(this);\n }\n\n public parseAxisAndHeader() {\n this.component.axes = parseUnitAxis(this);\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return assembleTopLevelSignals(this, signals);\n }\n\n public assembleSelectionSignals(): VgSignal[] {\n return assembleUnitSelectionSignals(this, []);\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return assembleUnitSelectionData(this, data);\n }\n\n public assembleLayout(): VgLayout {\n return null;\n }\n\n public assembleLayoutSignals(): VgSignal[] {\n return assembleLayoutSignals(this);\n }\n\n public assembleMarks() {\n let marks = this.component.mark || [];\n\n // If this unit is part of a layer, selections should augment\n // all in concert rather than each unit individually. This\n // ensures correct interleaving of clipping and brushed marks.\n if (!this.parent || !isLayerModel(this.parent)) {\n marks = assembleUnitSelectionMarks(this, marks);\n }\n\n return marks.map(this.correctDataNames);\n }\n\n public assembleLayoutSize(): VgEncodeEntry {\n return {\n width: this.getSizeSignalRef('width'),\n height: this.getSizeSignalRef('height')\n };\n }\n\n protected getMapping() {\n return this.encoding;\n }\n\n public toSpec(excludeConfig?: any, excludeData?: any) {\n const encoding = duplicate(this.encoding);\n let spec: any;\n\n spec = {\n mark: this.markDef,\n encoding: encoding\n };\n\n if (!excludeConfig) {\n spec.config = duplicate(this.config);\n }\n\n if (!excludeData) {\n spec.data = duplicate(this.data);\n }\n\n // remove defaults\n return spec;\n }\n\n public get mark(): Mark {\n return this.markDef.type;\n }\n\n public channelHasField(channel: Channel) {\n return vlEncoding.channelHasField(this.encoding, channel);\n }\n\n public fieldDef(channel: SingleDefChannel): FieldDef {\n const channelDef = this.encoding[channel] as ChannelDef;\n return getFieldDef(channelDef);\n }\n}\n","import {Config} from '../config';\nimport * as log from '../log';\nimport {isLayerSpec, isUnitSpec, LayoutSizeMixins, NormalizedLayerSpec} from '../spec';\nimport {flatten, keys} from '../util';\nimport {VgData, VgLayout, VgLegend, VgSignal, VgTitle} from '../vega.schema';\nimport {parseLayerAxis} from './axis/parse';\nimport {parseData} from './data/parse';\nimport {assembleLayoutSignals} from './layoutsize/assemble';\nimport {parseLayerLayoutSize} from './layoutsize/parse';\nimport {assembleLegends} from './legend/assemble';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\nimport {assembleLayerSelectionMarks} from './selection/selection';\nimport {UnitModel} from './unit';\n\n\nexport class LayerModel extends Model {\n public readonly type: 'layer' = 'layer';\n\n // HACK: This should be (LayerModel | UnitModel)[], but setting the correct type leads to weird error.\n // So I'm just putting generic Model for now.\n public readonly children: Model[];\n\n\n\n constructor(spec: NormalizedLayerSpec, parent: Model, parentGivenName: string,\n parentGivenSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean) {\n\n super(spec, parent, parentGivenName, config, repeater, spec.resolve);\n\n const layoutSize = {\n ...parentGivenSize,\n ...(spec.width ? {width: spec.width} : {}),\n ...(spec.height ? {height: spec.height} : {})\n };\n\n this.initSize(layoutSize);\n\n this.children = spec.layer.map((layer, i) => {\n if (isLayerSpec(layer)) {\n return new LayerModel(layer, this, this.getName('layer_'+i), layoutSize, repeater, config, fit);\n }\n\n if (isUnitSpec(layer)) {\n return new UnitModel(layer, this, this.getName('layer_'+i), layoutSize, repeater, config, fit);\n }\n\n throw new Error(log.message.INVALID_SPEC);\n });\n }\n\n public parseData() {\n this.component.data = parseData(this);\n for (const child of this.children) {\n child.parseData();\n }\n }\n\n public parseLayoutSize() {\n parseLayerLayoutSize(this);\n }\n\n public parseSelection() {\n // Merge selections up the hierarchy so that they may be referenced\n // across unit specs. Persist their definitions within each child\n // to assemble signals which remain within output Vega unit groups.\n this.component.selection = {};\n for (const child of this.children) {\n child.parseSelection();\n keys(child.component.selection).forEach((key) => {\n this.component.selection[key] = child.component.selection[key];\n });\n }\n }\n\n public parseMarkGroup() {\n for (const child of this.children) {\n child.parseMarkGroup();\n }\n }\n\n public parseAxisAndHeader() {\n parseLayerAxis(this);\n }\n\n public assembleSelectionTopLevelSignals(signals: any[]): VgSignal[] {\n return this.children.reduce((sg, child) => child.assembleSelectionTopLevelSignals(sg), signals);\n }\n\n // TODO: Support same named selections across children.\n public assembleSelectionSignals(): VgSignal[] {\n return this.children.reduce((signals, child) => {\n return signals.concat(child.assembleSelectionSignals());\n }, []);\n }\n\n\n public assembleLayoutSignals(): VgSignal[] {\n return this.children.reduce((signals, child) => {\n return signals.concat(child.assembleLayoutSignals());\n }, assembleLayoutSignals(this));\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return this.children.reduce((db, child) => child.assembleSelectionData(db), data);\n }\n\n public assembleTitle(): VgTitle {\n let title = super.assembleTitle();\n if (title) {\n return title;\n }\n // If title does not provide layer, look into children\n for (const child of this.children) {\n title = child.assembleTitle();\n if (title) {\n return title;\n }\n }\n return undefined;\n }\n\n public assembleLayout(): VgLayout {\n return null;\n }\n\n public assembleMarks(): any[] {\n return assembleLayerSelectionMarks(this, flatten(this.children.map((child) => {\n return child.assembleMarks();\n })));\n }\n\n public assembleLegends(): VgLegend[] {\n return this.children.reduce((legends, child) => {\n return legends.concat(child.assembleLegends());\n }, assembleLegends(this));\n }\n}\n","\nimport {Config} from '../config';\nimport * as log from '../log';\nimport {Repeat} from '../repeat';\nimport {NormalizedRepeatSpec} from '../spec';\nimport {VgLayout} from '../vega.schema';\nimport {BaseConcatModel} from './baseconcat';\nimport {buildModel} from './buildmodel';\nimport {parseRepeatLayoutSize} from './layoutsize/parse';\nimport {Model} from './model';\nimport {RepeaterValue} from './repeater';\n\nexport class RepeatModel extends BaseConcatModel {\n public readonly type: 'repeat' = 'repeat';\n public readonly repeat: Repeat;\n\n public readonly children: Model[];\n\n constructor(spec: NormalizedRepeatSpec, parent: Model, parentGivenName: string, repeatValues: RepeaterValue, config: Config) {\n super(spec, parent, parentGivenName, config, repeatValues, spec.resolve);\n\n if (spec.resolve && spec.resolve.axis && (spec.resolve.axis.x === 'shared' || spec.resolve.axis.y === 'shared')) {\n log.warn(log.message.REPEAT_CANNOT_SHARE_AXIS);\n }\n\n this.repeat = spec.repeat;\n this.children = this._initChildren(spec, this.repeat, repeatValues, config);\n }\n\n private _initChildren(spec: NormalizedRepeatSpec, repeat: Repeat, repeater: RepeaterValue, config: Config): Model[] {\n const children: Model[] = [];\n const row = repeat.row || [repeater ? repeater.row : null];\n const column = repeat.column || [repeater ? repeater.column : null];\n\n // cross product\n for (const rowField of row) {\n for (const columnField of column) {\n const name = (rowField ? '_' + rowField : '') + (columnField ? '_' + columnField : '');\n\n const childRepeat = {\n row: rowField,\n column: columnField\n };\n\n children.push(buildModel(spec.spec, this, this.getName('child' + name), undefined, childRepeat, config, false));\n }\n }\n\n return children;\n }\n\n public parseLayoutSize() {\n parseRepeatLayoutSize(this);\n }\n\n protected assembleDefaultLayout(): VgLayout {\n return {\n columns: this.repeat && this.repeat.column ? this.repeat.column.length : 1,\n bounds: 'full',\n align: 'all'\n };\n }\n}\n","import {Config} from '../config';\nimport * as log from '../log';\nimport {isConcatSpec, isFacetSpec, isLayerSpec, isRepeatSpec, isUnitSpec, LayoutSizeMixins, NormalizedSpec} from '../spec';\nimport {ConcatModel} from './concat';\nimport {FacetModel} from './facet';\nimport {LayerModel} from './layer';\nimport {Model} from './model';\nimport {RepeatModel} from './repeat';\nimport {RepeaterValue} from './repeater';\nimport {UnitModel} from './unit';\n\nexport function buildModel(spec: NormalizedSpec, parent: Model, parentGivenName: string,\n unitSize: LayoutSizeMixins, repeater: RepeaterValue, config: Config, fit: boolean): Model {\n if (isFacetSpec(spec)) {\n return new FacetModel(spec, parent, parentGivenName, repeater, config);\n }\n\n if (isLayerSpec(spec)) {\n return new LayerModel(spec, parent, parentGivenName, unitSize, repeater, config, fit);\n }\n\n if (isUnitSpec(spec)) {\n return new UnitModel(spec, parent, parentGivenName, unitSize, repeater, config, fit);\n }\n\n if (isRepeatSpec(spec)) {\n return new RepeatModel(spec, parent, parentGivenName, repeater, config);\n }\n\n if (isConcatSpec(spec)) {\n return new ConcatModel(spec, parent, parentGivenName, repeater, config);\n }\n\n throw new Error(log.message.INVALID_SPEC);\n}\n","import {toSet} from 'vega-util';\nimport {isMarkDef} from './mark';\nimport {BAR} from './mark';\nimport {FacetedCompositeUnitSpec} from './spec';\n\n\n\n// TODO: move to vl.spec.validator?\nexport interface RequiredChannelMap {\n [mark: string]: Array;\n}\n\n/**\n * Required Encoding Channels for each mark type\n */\nexport const DEFAULT_REQUIRED_CHANNEL_MAP: RequiredChannelMap = {\n text: ['text'],\n line: ['x', 'y'],\n trail: ['x', 'y'],\n area: ['x', 'y']\n};\n\nexport interface SupportedChannelMap {\n [mark: string]: {\n [channel: string]: boolean\n };\n}\n\n/**\n * Supported Encoding Channel for each mark type\n */\nexport const DEFAULT_SUPPORTED_CHANNEL_TYPE: SupportedChannelMap = {\n bar: toSet(['row', 'column', 'x', 'y', 'size', 'color', 'fill', 'stroke', 'detail']),\n line: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'color', 'detail']),\n trail: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'color', 'detail', 'size']),\n area: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'detail']),\n tick: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'detail']),\n circle: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail']),\n square: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail']),\n point: toSet(['row', 'column', 'x', 'y', 'color', 'fill', 'stroke', 'size', 'detail', 'shape']),\n geoshape: toSet(['row', 'column', 'color', 'fill', 'stroke', 'detail', 'shape']),\n text: toSet(['row', 'column', 'size', 'color', 'fill', 'stroke', 'text']) // TODO(#724) revise\n};\n\n// TODO: consider if we should add validate method and\n// requires ZSchema in the main vega-lite repo\n\n/**\n * Further check if encoding mapping of a spec is invalid and\n * return error if it is invalid.\n *\n * This checks if\n * (1) all the required encoding channels for the mark type are specified\n * (2) all the specified encoding channels are supported by the mark type\n * @param {[type]} spec [description]\n * @param {RequiredChannelMap = DefaultRequiredChannelMap} requiredChannelMap\n * @param {SupportedChannelMap = DefaultSupportedChannelMap} supportedChannelMap\n * @return {String} Return one reason why the encoding is invalid,\n * or null if the encoding is valid.\n */\nexport function getEncodingMappingError(spec: FacetedCompositeUnitSpec,\n requiredChannelMap: RequiredChannelMap = DEFAULT_REQUIRED_CHANNEL_MAP,\n supportedChannelMap: SupportedChannelMap = DEFAULT_SUPPORTED_CHANNEL_TYPE\n ) {\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n const encoding = spec.encoding;\n const requiredChannels = requiredChannelMap[mark];\n const supportedChannels = supportedChannelMap[mark];\n\n for (const i in requiredChannels) { // all required channels are in encoding`\n if (!(requiredChannels[i] in encoding)) {\n return 'Missing encoding channel \\\"' + requiredChannels[i] +\n '\\\" for mark \\\"' + mark + '\\\"';\n }\n }\n\n for (const channel in encoding) { // all channels in encoding are supported\n if (!supportedChannels[channel]) {\n return 'Encoding channel \\\"' + channel +\n '\\\" is not supported by mark type \\\"' + mark + '\\\"';\n }\n }\n\n if (mark === BAR && !encoding.x && !encoding.y) {\n return 'Missing both x and y for bar';\n }\n\n return null;\n}\n","import * as aggregate from './aggregate';\nimport * as axis from './axis';\nimport * as bin from './bin';\nimport * as channel from './channel';\nimport * as compositeMark from './compositemark';\nexport {TopLevelSpec} from './spec';\nexport {compile} from './compile/compile';\nexport {Config} from './config';\nimport * as config from './config';\nimport * as data from './data';\nimport * as datetime from './datetime';\nimport * as encoding from './encoding';\nimport * as facet from './facet';\nimport * as fieldDef from './fielddef';\nimport * as header from './header';\nimport * as legend from './legend';\nimport * as mark from './mark';\nimport * as scale from './scale';\nimport * as sort from './sort';\nimport * as spec from './spec';\nimport * as stack from './stack';\nimport * as timeUnit from './timeunit';\nimport * as transform from './transform';\nimport * as type from './type';\nimport * as util from './util';\nimport * as validate from './validate';\n\nimport pkg from '../package.json';\nconst version = pkg.version;\n\nexport {aggregate, axis, bin, channel, compositeMark, config, data, datetime, encoding, facet, fieldDef, header, legend, mark, scale, sort, spec, stack, timeUnit, transform, type, util, validate, version};\n","import {Config, initConfig, stripAndRedirectConfig} from '../config';\nimport * as vlFieldDef from '../fielddef';\nimport * as log from '../log';\nimport {isLayerSpec, isUnitSpec, LayoutSizeMixins, normalize, TopLevel, TopLevelSpec} from '../spec';\nimport {AutoSizeParams, extractTopLevelProperties, normalizeAutoSize, TopLevelProperties} from '../toplevelprops';\nimport {keys, mergeDeep} from '../util';\nimport {buildModel} from './buildmodel';\nimport {assembleRootData} from './data/assemble';\nimport {optimizeDataflow} from './data/optimize';\nimport {Model} from './model';\n\nexport interface CompileOptions {\n config?: Config;\n logger?: log.LoggerInterface;\n\n fieldTitle?: vlFieldDef.FieldTitleFormatter;\n}\n\n/**\n * Vega-Lite's main function, for compiling Vega-lite spec into Vega spec.\n *\n * At a high-level, we make the following transformations in different phases:\n *\n * Input spec\n * |\n * | (Normalization)\n * v\n * Normalized Spec (Row/Column channels in single-view specs becomes faceted specs, composite marks becomes layered specs.)\n * |\n * | (Build Model)\n * v\n * A model tree of the spec\n * |\n * | (Parse)\n * v\n * A model tree with parsed components (intermediate structure of visualization primitives in a format that can be easily merged)\n * |\n * | (Optimize)\n * v\n * A model tree with parsed components with the data component optimized\n * |\n * | (Assemble)\n * v\n * Vega spec\n */\nexport function compile(inputSpec: TopLevelSpec, opt: CompileOptions = {}) {\n // 0. Augment opt with default opts\n if (opt.logger) {\n // set the singleton logger to the provided logger\n log.set(opt.logger);\n }\n\n if (opt.fieldTitle) {\n // set the singleton field title formatter\n vlFieldDef.setTitleFormatter(opt.fieldTitle);\n }\n\n try {\n // 1. Initialize config by deep merging default config with the config provided via option and the input spec.\n const config = initConfig(mergeDeep({}, opt.config, inputSpec.config));\n\n // 2. Normalize: Convert input spec -> normalized spec\n\n // - Decompose all extended unit specs into composition of unit spec. For example, a box plot get expanded into multiple layers of bars, ticks, and rules. The shorthand row/column channel is also expanded to a facet spec.\n const spec = normalize(inputSpec, config);\n // - Normalize autosize to be a autosize properties object.\n const autosize = normalizeAutoSize(inputSpec.autosize, config.autosize, isLayerSpec(spec) || isUnitSpec(spec));\n\n // 3. Build Model: normalized spec -> Model (a tree structure)\n\n // This phases instantiates the models with default config by doing a top-down traversal. This allows us to pass properties that child models derive from their parents via their constructors.\n // See the abstract `Model` class and its children (UnitModel, LayerModel, FacetModel, RepeatModel, ConcatModel) for different types of models.\n const model: Model = buildModel(spec, null, '', undefined, undefined, config, autosize.type === 'fit');\n\n // 4 Parse: Model --> Model with components\n\n // Note that components = intermediate representations that are equivalent to Vega specs.\n // We need these intermediate representation because we need to merge many visualizaiton \"components\" like projections, scales, axes, and legends.\n // We will later convert these components into actual Vega specs in the assemble phase.\n\n // In this phase, we do a bottom-up traversal over the whole tree to\n // parse for each type of components once (e.g., data, layout, mark, scale).\n // By doing bottom-up traversal, we start parsing components of unit specs and\n // then merge child components of parent composite specs.\n //\n // Please see inside model.parse() for order of different components parsed.\n model.parse();\n\n // 5. Optimize the dataflow. This will modify the data component of the model.\n optimizeDataflow(model.component.data);\n\n // 6. Assemble: convert model components --> Vega Spec.\n return assembleTopLevelModel(model, getTopLevelProperties(inputSpec, config, autosize));\n } finally {\n // Reset the singleton logger if a logger is provided\n if (opt.logger) {\n log.reset();\n }\n // Reset the singleton field title formatter if provided\n if (opt.fieldTitle) {\n vlFieldDef.resetTitleFormatter();\n }\n }\n}\n\n\nfunction getTopLevelProperties(topLevelSpec: TopLevel, config: Config, autosize: AutoSizeParams) {\n return {\n autosize: keys(autosize).length === 1 && autosize.type ? autosize.type : autosize,\n ...extractTopLevelProperties(config),\n ...extractTopLevelProperties(topLevelSpec)\n };\n}\n\n/*\n * Assemble the top-level model.\n *\n * Note: this couldn't be `model.assemble()` since the top-level model\n * needs some special treatment to generate top-level properties.\n */\nfunction assembleTopLevelModel(model: Model, topLevelProperties: TopLevelProperties & LayoutSizeMixins) {\n // TODO: change type to become VgSpec\n\n // Config with Vega-Lite only config removed.\n const vgConfig = model.config ? stripAndRedirectConfig(model.config) : undefined;\n\n const data = [].concat(\n model.assembleSelectionData([]),\n // only assemble data in the root\n assembleRootData(model.component.data, topLevelProperties.datasets || {})\n );\n\n delete topLevelProperties.datasets;\n\n const projections = model.assembleProjections();\n const title = model.assembleTitle();\n const style = model.assembleGroupStyle();\n\n let layoutSignals = model.assembleLayoutSignals();\n\n // move width and height signals with values to top level\n layoutSignals = layoutSignals.filter(signal => {\n if ((signal.name === 'width' || signal.name === 'height') && signal.value !== undefined) {\n topLevelProperties[signal.name] = +signal.value;\n return false;\n }\n return true;\n });\n\n const output = {\n $schema: 'https://vega.github.io/schema/vega/v3.json',\n ...(model.description ? {description: model.description} : {}),\n ...topLevelProperties,\n ...(title? {title} : {}),\n ...(style? {style} : {}),\n data: data,\n ...(projections.length > 0 ? {projections: projections} : {}),\n ...model.assembleGroup([\n ...layoutSignals,\n ...model.assembleSelectionTopLevelSignals([])\n ]),\n ...(vgConfig ? {config: vgConfig} : {})\n };\n\n return {\n spec: output\n // TODO: add warning / errors here\n };\n}\n"]} \ No newline at end of file